From: Dan White Date: Sun, 8 Jan 2012 00:40:19 +0000 (-0600) Subject: Add TI Chronos linux software X-Git-Tag: calibrations~379 X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=33b43481f0332d26152acb90a3041d849e53416b;p=430.git Add TI Chronos linux software --- diff --git a/chronos-ti/Chronos-Setup b/chronos-ti/Chronos-Setup new file mode 100755 index 0000000..63177cf Binary files /dev/null and b/chronos-ti/Chronos-Setup differ diff --git a/chronos-ti/Control Center/Chronos Control Center/Media Player Control.ini b/chronos-ti/Control Center/Chronos Control Center/Media Player Control.ini new file mode 100755 index 0000000..07dfcd8 --- /dev/null +++ b/chronos-ti/Control Center/Chronos Control Center/Media Player Control.ini @@ -0,0 +1,16 @@ +pd_m1=F +pd_m2=P +pd_s1=B +cb_m1_windows=0 +cb_m1_alt=0 +cb_m1_ctrl=1 +cb_m1_shift=0 +cb_s1_windows=0 +cb_s1_alt=0 +cb_s1_ctrl=1 +cb_s1_shift=0 +cb_m2_windows=0 +cb_m2_alt=0 +cb_m2_ctrl=1 +cb_m2_shift=0 +sync_use_metric_units=1 diff --git a/chronos-ti/Control Center/Chronos Control Center/eZ430-Chronos CC 1_2.tcl b/chronos-ti/Control Center/Chronos Control Center/eZ430-Chronos CC 1_2.tcl new file mode 100755 index 0000000..61415dc --- /dev/null +++ b/chronos-ti/Control Center/Chronos Control Center/eZ430-Chronos CC 1_2.tcl @@ -0,0 +1,2324 @@ +#!/usr/bin/tclsh8.5 + + +# ************************************************************************************************* +# +# Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# Neither the name of Texas Instruments Incorporated nor the names of +# its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# ************************************************************************************************* +# ez430-Chronos Control Center TCL/Tk script +# ************************************************************************************************* +# +# Rev 1.2 +# - Use of combobox +# - Bug fix windows 7 +# - Removed obsolete variables +# - checks for leap years +# +# Rev 1.1 +# - added ini file load/save dialog to load/save key settings to "Key Config" pane +# - added 12H / 24H format switch for "Sync" pane +# - added "RF BSL" pane and related functions +# +# Rev 1.0 +# - initial version released to manufacturing +# ************************************************************************************************* + +# ---------------------------------------------------------------------------------------- +# Load TCL packages and C library -------------------------------------------------------- + +set exit_prog 0 + +# load libraries ----------------------------------------------------- +package require Tk + +# Set COM port where RF access point is mounted +set com "/dev/ttyACM0" + +# Include BlueRobin BM-USBD1 driver +# This script file replaces the Windows DLL and adds the global handle "vcp" for the COM channel +source "eZ430-Chronos_driver.tcl" + +# Open COM port +if { [BM_OpenCOM $com 115200 30 0 0] == 0 } { + tk_dialog .dialog1 "Error" "Could not detect USB dongle. Press OK to close application." info 0 OK + set com_available 0 + exit 0 +} else { + set com_available 1 + flush $vcp + # Reset hardware + BM_Reset + after 20 + # Flush channel + for {set i 0} {$i < 10} {incr i} { + BM_GetStatus + after 10 + } +} + +# Global variables ----------------------------------------------------------------------- + +# Script revision number +set revision 1.2 + +# BlueRobin variables +set bluerobin_on 0 +set heartrate 0 +set speed 0.0 +set speed_limit_hi 25.0 +set distance 0.0 +set hr_sweep 0 +set speed_sweep 0 +set txid [expr 0xFFFF00 + round( rand() * 250)] +set msg 0 +set speed_is_mph 0 +set speed_is_mph0 0 + +# SimpliciTi variables +set simpliciti_on 0 +set simpliciti_sync_on 0 +set simpliciti_acc_on 0 +set simpliciti_ap_started 0 +set x 0 +set y 0 +set accel_x 0 +set accel_y 0 +set accel_z 0 +set accel_x_offset 0 +set accel_y_offset 0 +set accel_z_offset 0 +set mouse_control 0 +set move_x 0 +set move_y 0 +set wave_x { 0 50 600 50 } +set wave_y { 0 50 600 50 } +set wave_z { 0 50 600 50 } + +# Key variables +set ini_file "eZ430-Chronos-CC.ini" +set all_ini_files { } +set button_event_text "No button" +set button_event 0 +set button_timeout 0 +set event1 { Arrow-Left Arrow-Right A B C D E F G H I J \ + K L M N O P Q R S T U V W X Y Z F5 Space } +set event2 { None Ctrl Alt Windows } +set pd_m1 "Arrow-Left" +set pd_s1 "Arrow-Right" +set pd_m2 "F5" +set cb_m1_windows 0 +set cb_m1_alt 0 +set cb_m1_ctrl 0 +set cb_m1_shift 0 +set cb_s1_windows 0 +set cb_s1_alt 0 +set cb_s1_ctrl 0 +set cb_s1_shift 0 +set cb_m2_windows 0 +set cb_m2_alt 0 +set cb_m2_ctrl 0 +set cb_m2_shift 0 + +# Sync global variables +set sync_time_hours_24 4 +set sync_time_is_am 1 +set sync_time_hours_12 4 +set sync_time_minutes 30 +set sync_time_seconds 0 +set sync_date_year 2009 +set sync_date_month 9 +set sync_date_day 1 +set sync_alarm_hours 6 +set sync_alarm_minutes 30 +set sync_altitude_24 500 +set sync_altitude_12 1640 +set sync_temperature_24 22 +set sync_temperature_12 72 +set sync_use_metric_units 1 + +set i -10 +while {$i < 41} { + lappend value_temperature_C $i + incr i + } +set i 14 +while {$i < 105} { + lappend value_temperature_F $i + incr i +} +set i 0 +while {$i < 60} { + lappend values_60 $i + incr i +} +set i 1 +while {$i < 32} { + lappend values_31 $i + incr i +} +set i 1 +while {$i < 31} { + lappend values_30 $i + incr i +} + +set i 1 +while {$i < 30} { + lappend values_29 $i + incr i +} + +set i 1 +while {$i < 29} { + lappend values_28 $i + incr i +} + + +set i 0 +while {$i < 24} { + lappend values_24 $i + incr i +} +set i 1 +while {$i < 13} { + lappend values_12 $i + incr i +} +set i 2010 +while {$i < 2016} { + lappend values_years $i + incr i +} +set i -100 +while {$i < 2001} { + lappend values_altitude_meters $i + incr i +} +set i -328 +while {$i < 6563} { + lappend values_altitude_feet $i + incr i +} + +# WBSL global variables +set select_input_file "" +set call_wbsl_timer 0 +set call_wbsl_1 2 +set call_wbsl_2 3 +set wbsl_progress 0 +set wbsl_on 0 +set wbsl_ap_started 0 +set fsize 0 +set fp 0 +set rData [list] +set rData_index 0 +set low_index 0 +set list_count 0 +set wbsl_opcode 0 +set maxPayload 0 +set ram_updater_downloaded 0 +set wirelessUpdateStarted 0 +set wbsl_timer_enabled 0 +set wbsl_timer_counter 0 +set wbsl_timer_flag 0 +set wbsl_timer_timeout 0 + +# Function required by WBSL +proc ceil x {expr {ceil($x)} } + + +# ---------------------------------------------------------------------------------------- +# Function prototypes -------------------------------------------------------------------- +proc get_spl_data {} {} +proc update_br_data {} {} +proc check_rx_serial {} {} +proc inc_heartrate {} {} +proc inc_speed {} {} +proc move_cursor {} {} +proc get_wbsl_status {} {} +proc wbsl_set_timer { timeout } {} +proc wbsl_reset_timer {} {} + +# ---------------------------------------------------------------------------------------- +# Graphical user interface setup --------------------------------------------------------- + +# Some custom styles for graphical elements +ttk::setTheme clam +ttk::style configure custom.TCheckbutton -font "Helvetica 10" +ttk::style configure custom.TLabelframe -font "Helvetica 12 bold" + +# Set default font size for the app +font configure TkDefaultFont -family "tahoma" -size 8 + +# Define basic window geometry +wm title . "Texas Instruments eZ430-Chronos Control Center $revision" +wm geometry . 700x490 +wm resizable . 0 0 +wm iconname . "ttknote" +ttk::frame .f +pack .f -fill both -expand 1 +set w .f + +# Map keys to internal functions +bind . { exitpgm } +bind . { calibrate_sensor } +bind . { allow_mouse_control } + +# Make the notebook and set up Ctrl+Tab traversal +ttk::notebook $w.note +pack $w.note -fill both -expand 1 -padx 2 -pady 3 +ttk::notebook::enableTraversal $w.note + +# ---------------------------------------------------------------------------------------- +# SimpliciTI pane ------------------------------------------------------------------------ +ttk::frame $w.note.spl -style custom.TFrame +$w.note add $w.note.spl -text "SimpliciTI\u2122 Acc / PPT" -underline 0 -padding 2 +grid columnconfigure $w.note.spl {0 1} -weight 1 -uniform 1 + +# Control buttons +ttk::frame $w.note.spl.frame0 -borderwidth 0 -style custom.TLabelframe +ttk::button $w.note.spl.frame0.btnStartStop -text "Start Access Point" -command { start_simpliciti_ap_acc } -width 16 +ttk::label $w.note.spl.frame0.key -textvariable button_event_text -width 20 -font "Helvetica 10 bold" -relief sunk -style custom1.TLabel +ttk::button $w.note.spl.frame0.btnMouseContrl -text "Mouse On (M)" -command { allow_mouse_control } -width 16 +ttk::button $w.note.spl.frame0.btnCalSensor -text "Calibrate (C)" -command { calibrate_sensor } -width 16 +grid $w.note.spl.frame0 -row 0 -column 0 -pady 10 -padx 10 -sticky ew -columnspan 2 +pack $w.note.spl.frame0.btnStartStop -side left -fill x -padx 10 +pack $w.note.spl.frame0.key -side left -fill x -padx 10 +pack $w.note.spl.frame0.btnCalSensor -side right -fill x -padx 10 +pack $w.note.spl.frame0.btnMouseContrl -side right -fill x -padx 10 + +# X acceleration sensor values +ttk::frame $w.note.spl.frame2x -style custom.TFrame +ttk::label $w.note.spl.frame2x.txt -text "X" -font "Helvetica 48 bold" -width 2 -anchor center -style custom.TLabel +canvas $w.note.spl.frame2x.canvas -width 600 -height 100 -background "gray95" +grid $w.note.spl.frame2x -row 1 -column 0 -pady 5 -padx 10 -sticky ew -columnspan 2 -rowspan 1 +pack $w.note.spl.frame2x.txt -side left -fill x +pack $w.note.spl.frame2x.canvas -side left -fill x + +# Y acceleration sensor values +ttk::frame $w.note.spl.frame2y -style custom.TFrame +ttk::label $w.note.spl.frame2y.txt -text "Y" -font "Helvetica 48 bold" -width 2 -anchor center -style custom.TLabel +canvas $w.note.spl.frame2y.canvas -width 600 -height 100 -background "gray95" +grid $w.note.spl.frame2y -row 2 -column 0 -pady 5 -padx 10 -sticky ew -columnspan 2 -rowspan 1 +pack $w.note.spl.frame2y.txt -side left -fill x +pack $w.note.spl.frame2y.canvas -side left -fill x + +# Z acceleration sensor values +ttk::frame $w.note.spl.frame2z -style custom.TFrame +ttk::label $w.note.spl.frame2z.txt -text "Z" -font "Helvetica 48 bold" -width 2 -anchor center -style custom.TLabel +canvas $w.note.spl.frame2z.canvas -width 600 -height 100 -background "gray95" +grid $w.note.spl.frame2z -row 3 -column 0 -pady 5 -padx 10 -sticky ew -columnspan 2 -rowspan 1 +pack $w.note.spl.frame2z.txt -side left -fill x +pack $w.note.spl.frame2z.canvas -side left -fill x + +# Status line +labelframe $w.note.spl.frame0b -borderwidth 1 -background "Yellow" +ttk::label $w.note.spl.frame0b.lblStatus -text "Status:" -font "Helvetica 10 bold" -background "Yellow" +ttk::label $w.note.spl.frame0b.lblStatusText -text "Access Point is off." -font "Helvetica 10" -background "Yellow" +grid $w.note.spl.frame0b -row 5 -column 0 -columnspan 2 -pady 18 -padx 10 -sticky ew +pack $w.note.spl.frame0b.lblStatus -side left -fill y +pack $w.note.spl.frame0b.lblStatusText -side left -fill x + + +# ---------------------------------------------------------------------------------------- +# Keys pane ------------------------------------------------------------------------------ +ttk::frame $w.note.keys -style custom.TFrame +$w.note add $w.note.keys -text "Key Config" -underline 0 -padding 2 +grid columnconfigure $w.note.keys {0 1} -weight 1 -uniform 1 + +# Heading +ttk::label $w.note.keys.label0 -font "Helvetica 10" -wraplength 6i -text "Select the key events that will be triggered when pressing one of the watch buttons in PPT mode." +grid $w.note.keys.label0 -row 0 -column 0 -pady 10 -padx 10 -sticky ew -columnspan 2 -rowspan 1 + +# Load / save configuration file +ttk::labelframe $w.note.keys.fSel -borderwidth 0 +ttk::label $w.note.keys.fSel.lbl -text "Select file:" -anchor e -font "Helvetica 10 bold" +ttk::combobox $w.note.keys.fSel.combo1 -textvariable ini_file -state readonly -values $all_ini_files -width 50 +ttk::button $w.note.keys.fSel.btn2 -text "Load" -command { load_ini_file } -width 10 +ttk::button $w.note.keys.fSel.btn3 -text "Save" -command { save_ini_file } -width 10 +grid $w.note.keys.fSel -row 1 -column 0 -pady 10 -sticky ew -columnspan 2 +pack $w.note.keys.fSel.lbl -side left -fill x -padx 10 +pack $w.note.keys.fSel.combo1 -side left -fill x -padx 5 +pack $w.note.keys.fSel.btn2 -side left -fill x -padx 5 +pack $w.note.keys.fSel.btn3 -side left -fill x -padx 5 + +# Button * +ttk::labelframe $w.note.keys.m1 -borderwidth 1 -text "Button (*)" +ttk::label $w.note.keys.m1.label1 -text "First key" -width 15 -font "Helvetica 10 bold" +ttk::combobox $w.note.keys.m1.combo1 -textvariable pd_m1 -state readonly -values $event1 -width 20 +ttk::label $w.note.keys.m1.label2 -text "Second key" -width 15 -font "Helvetica 10 bold" +ttk::checkbutton $w.note.keys.m1.cb1 -text "Windows" -variable cb_m1_windows +ttk::checkbutton $w.note.keys.m1.cb2 -text "Alt" -variable cb_m1_alt +ttk::checkbutton $w.note.keys.m1.cb3 -text "Ctrl" -variable cb_m1_ctrl +ttk::checkbutton $w.note.keys.m1.cb4 -text "Shift" -variable cb_m1_shift +grid $w.note.keys.m1 -row 2 -column 0 -pady 5 -padx 10 -sticky ew -columnspan 2 -rowspan 1 +pack $w.note.keys.m1.label1 -side left -pady 5 -padx 10 +pack $w.note.keys.m1.combo1 -side left -pady 5 -padx 10 +pack $w.note.keys.m1.label2 -side left -pady 5 -padx 10 +pack $w.note.keys.m1.cb1 -side top -fill x -padx 10 +pack $w.note.keys.m1.cb2 -side top -fill x -padx 10 +pack $w.note.keys.m1.cb3 -side top -fill x -padx 10 +pack $w.note.keys.m1.cb4 -side top -fill x -padx 10 + +# Button Up +ttk::labelframe $w.note.keys.s1 -borderwidth 1 -text "Button (Up)" +ttk::label $w.note.keys.s1.label1 -text "First key" -width 15 -font "Helvetica 10 bold" +ttk::combobox $w.note.keys.s1.combo1 -textvariable pd_s1 -state readonly -values $event1 -width 20 +ttk::label $w.note.keys.s1.label2 -text "Second key" -width 15 -font "Helvetica 10 bold" +ttk::checkbutton $w.note.keys.s1.cb1 -text "Windows" -variable cb_s1_windows +ttk::checkbutton $w.note.keys.s1.cb2 -text "Alt" -variable cb_s1_alt +ttk::checkbutton $w.note.keys.s1.cb3 -text "Ctrl" -variable cb_s1_ctrl +ttk::checkbutton $w.note.keys.s1.cb4 -text "Shift" -variable cb_s1_shift +grid $w.note.keys.s1 -row 3 -column 0 -pady 5 -padx 10 -sticky ew -columnspan 2 -rowspan 1 +pack $w.note.keys.s1.label1 -side left -pady 5 -padx 10 +pack $w.note.keys.s1.combo1 -side left -pady 5 -padx 10 +pack $w.note.keys.s1.label2 -side left -pady 5 -padx 10 +pack $w.note.keys.s1.cb1 -side top -fill x -padx 10 +pack $w.note.keys.s1.cb2 -side top -fill x -padx 10 +pack $w.note.keys.s1.cb3 -side top -fill x -padx 10 +pack $w.note.keys.s1.cb4 -side top -fill x -padx 10 + +# Button # +ttk::labelframe $w.note.keys.m2 -borderwidth 1 -text "Button (#)" +ttk::label $w.note.keys.m2.label1 -text "First key" -width 15 -font "Helvetica 10 bold" +ttk::combobox $w.note.keys.m2.combo1 -textvariable pd_m2 -state readonly -values $event1 -width 20 +ttk::label $w.note.keys.m2.label2 -text "Second key" -width 15 -font "Helvetica 10 bold" +ttk::checkbutton $w.note.keys.m2.cb1 -text "Windows" -variable cb_m2_windows +ttk::checkbutton $w.note.keys.m2.cb2 -text "Alt" -variable cb_m2_alt +ttk::checkbutton $w.note.keys.m2.cb3 -text "Ctrl" -variable cb_m2_ctrl +ttk::checkbutton $w.note.keys.m2.cb4 -text "Shift" -variable cb_m2_shift +grid $w.note.keys.m2 -row 4 -column 0 -pady 5 -padx 10 -sticky ew -columnspan 2 -rowspan 1 +pack $w.note.keys.m2.label1 -side left -pady 5 -padx 10 +pack $w.note.keys.m2.combo1 -side left -pady 5 -padx 10 +pack $w.note.keys.m2.label2 -side left -pady 5 -padx 10 +pack $w.note.keys.m2.cb1 -side top -fill x -padx 10 +pack $w.note.keys.m2.cb2 -side top -fill x -padx 10 +pack $w.note.keys.m2.cb3 -side top -fill x -padx 10 +pack $w.note.keys.m2.cb4 -side top -fill x -padx 10 + + +# ---------------------------------------------------------------------------------------- +# Sync pane ------------------------------------------------------------------------------ +ttk::frame $w.note.sync -style custom.TFrame +$w.note add $w.note.sync -text "SimpliciTI\u2122 Sync" -underline 0 -padding 2 +grid columnconfigure $w.note.sync {0 1} -weight 1 -uniform 1 + +# Control buttons +ttk::labelframe $w.note.sync.f0 -borderwidth 0 +ttk::button $w.note.sync.f0.btn_start_ap -text "Start Access Point" -command { start_simpliciti_ap_sync } -width 16 +ttk::button $w.note.sync.f0.btn_get_watch_settings -text "Read Watch" -command { sync_read_watch } -width 16 +ttk::button $w.note.sync.f0.btn_get_time_and_date -text "Copy System Time" -command { sync_get_time_and_date } -width 16 +ttk::button $w.note.sync.f0.btn_set_watch -text "Set Watch" -command { sync_write_watch } -width 12 +grid $w.note.sync.f0 -row 0 -column 0 -pady 5 -padx 8 -sticky ew -columnspan 2 +pack $w.note.sync.f0.btn_start_ap -side left -fill x -padx 8 +pack $w.note.sync.f0.btn_set_watch -side right -fill x -padx 8 +pack $w.note.sync.f0.btn_get_time_and_date -side right -fill x -padx 8 +pack $w.note.sync.f0.btn_get_watch_settings -side right -fill x -padx 8 + +# Time +ttk::labelframe $w.note.sync.f1 -borderwidth 0 +ttk::label $w.note.sync.f1.l1 -text "Time" -width 18 -font "Helvetica 10 bold" +ttk::combobox $w.note.sync.f1.sb1 -values $values_24 -textvariable sync_time_hours_24 -justify right -width 2 -postcommand {check_time } +ttk::combobox $w.note.sync.f1.sb2 -values $values_60 -textvariable sync_time_minutes -justify right -width 2 -postcommand check_time +ttk::combobox $w.note.sync.f1.sb3 -values $values_60 -textvariable sync_time_seconds -justify right -width 2 -postcommand check_time +grid $w.note.sync.f1 -row 2 -column 0 -columnspan 1 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f1.l1 -side left -fill x +pack $w.note.sync.f1.sb1 -side left -fill x -padx 5 +pack $w.note.sync.f1.sb2 -side left -fill x -padx 5 +pack $w.note.sync.f1.sb3 -side left -fill x -padx 5 + +# Time format AM/PM +ttk::labelframe $w.note.sync.ampm -borderwidth 0 +ttk::radiobutton $w.note.sync.ampm.rb1 -text "AM" -variable sync_time_is_am -value 1 -style custom.TRadiobutton -state disabled -command { update_time_12 } +ttk::radiobutton $w.note.sync.ampm.rb2 -text "PM" -variable sync_time_is_am -value 0 -style custom.TRadiobutton -state disabled -command { update_time_12 } +grid $w.note.sync.ampm -row 2 -column 1 -columnspan 2 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.ampm.rb1 -side left -fill x -padx 5 +pack $w.note.sync.ampm.rb2 -side left -fill x -padx 5 + +# Date +ttk::labelframe $w.note.sync.f2 -borderwidth 0 +ttk::label $w.note.sync.f2.l1 -text "Date (dd.mm.yyyy)" -width 18 -font "Helvetica 10 bold" +ttk::combobox $w.note.sync.f2.sb1 -values $values_30 -textvariable sync_date_day -justify right -width 2 -postcommand {check_date } +ttk::combobox $w.note.sync.f2.sb2 -values $values_12 -textvariable sync_date_month -justify right -width 2 -postcommand {check_date } +ttk::combobox $w.note.sync.f2.sb3 -values $values_years -textvariable sync_date_year -justify right -width 4 -postcommand {check_date } +grid $w.note.sync.f2 -row 3 -column 0 -columnspan 1 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f2.l1 -side left -fill x +pack $w.note.sync.f2.sb1 -side left -fill x -padx 5 +pack $w.note.sync.f2.sb2 -side left -fill x -padx 5 +pack $w.note.sync.f2.sb3 -side left -fill x -padx 5 + +# Time / Date format +ttk::labelframe $w.note.sync.f1r -borderwidth 0 +ttk::radiobutton $w.note.sync.f1r.rb1 -text "Metric units" -variable sync_use_metric_units -value 1 -style custom.TRadiobutton -command switch_to_metric_units +ttk::radiobutton $w.note.sync.f1r.rb2 -text "Imperial units" -variable sync_use_metric_units -value 0 -style custom.TRadiobutton -command switch_to_imperial_units +grid $w.note.sync.f1r -row 3 -column 1 -columnspan 2 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f1r.rb1 -side left -fill x -padx 5 +pack $w.note.sync.f1r.rb2 -side left -fill x -padx 5 + +# Temperature +ttk::labelframe $w.note.sync.f4 -borderwidth 0 +ttk::label $w.note.sync.f4.l1 -text "Temperature (\u00B0C)" -width 18 -font "Helvetica 10 bold" +ttk::combobox $w.note.sync.f4.sb1 -values $value_temperature_C -textvariable sync_temperature_24 -justify right -width 4 -postcommand {check_temperature} +#spinbox $w.note.sync.f4.sb1 -textvariable sync_temperature_24 -justify right -width 3 -from -10 -to 60 +grid $w.note.sync.f4 -row 5 -column 0 -columnspan 2 -padx 10 -sticky ew +pack $w.note.sync.f4.l1 -side left -fill x +pack $w.note.sync.f4.sb1 -side left -fill x -padx 5 + +# Altitude +ttk::labelframe $w.note.sync.f5 -borderwidth 0 +ttk::label $w.note.sync.f5.l1 -text "Altitude (m)" -width 18 -font "Helvetica 10 bold" +ttk::combobox $w.note.sync.f5.sb1 -values $values_altitude_meters -textvariable sync_altitude_24 -justify right -width 4 -postcommand {check_altitude} +grid $w.note.sync.f5 -row 6 -column 0 -columnspan 1 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f5.l1 -side left -fill x +pack $w.note.sync.f5.sb1 -side left -fill x -padx 5 + +# Status +labelframe $w.note.sync.status -borderwidth 1 -background "Yellow" +ttk::label $w.note.sync.status.l1 -text "Status:" -font "Helvetica 10 bold" -background "Yellow" +ttk::label $w.note.sync.status.l2 -text "Access Point is off." -font "Helvetica 10" -background "Yellow" +grid $w.note.sync.status -row 10 -column 0 -pady 177 -padx 10 -sticky ew -columnspan 2 +pack $w.note.sync.status.l1 -side left -fill x +pack $w.note.sync.status.l2 -side left -fill x + + +# ---------------------------------------------------------------------------------------- +# BlueRobin pane ------------------------------------------------------------------------- +ttk::frame $w.note.br -style custom.TFrame +$w.note add $w.note.br -text "BlueRobin\u2122 HR Sim" -underline 0 -padding 2 +grid columnconfigure $w.note.br {0 1} -weight 1 -uniform 1 + +# Control buttons +ttk::frame $w.note.br.frame0 -style custom.TFrame +ttk::button $w.note.br.frame0.btnStartStop -text "Start transmitter" -command { start_bluerobin } -width 20 +grid $w.note.br.frame0 -row 0 -column 0 -pady 10 -padx 10 -sticky ew +pack $w.note.br.frame0.btnStartStop -side left -fill x + +# Transmitter ID +ttk::frame $w.note.br.frame0a -style custom.TFrame +ttk::label $w.note.br.frame0a.lblTXID -text "TX ID: " -font "Helvetica 10 bold" -style custom.TLabel +ttk::entry $w.note.br.frame0a.e -textvariable txid -justify "right" -width 7 -state readonly -style custom.TLabel +grid $w.note.br.frame0a -row 0 -column 1 -pady 10 -padx 10 -sticky ew +pack $w.note.br.frame0a.lblTXID -side left -fill x +pack $w.note.br.frame0a.e -side left -fill x + +# Heart rate sweep control +ttk::checkbutton $w.note.br.btn_sweephr -text " Sweep Heart Rate (bpm)" -variable hr_sweep -onvalue "1" -offvalue "0" -style custom.TCheckbutton +grid $w.note.br.btn_sweephr -row 1 -column 0 -pady 0 -padx 2m -sticky ew +scale $w.note.br.scale_hr -length 300 -showvalue 0 -orient h -from 40 -to 220 -variable heartrate -tickinterval 20 -borderwidth 0 -background "#DEDBD6" -highlightbackground "#DEDBD6" +grid $w.note.br.scale_hr -row 2 -column 0 -pady 10 -padx 2m -sticky ew + +# Heart rate value +ttk::label $w.note.br.label_heartrate -textvariable heartrate -font "Helvetica 96 bold" -justify "right" -width 4 -anchor center -background "gray95" +grid $w.note.br.label_heartrate -row 3 -column 0 -pady 30 -padx 10 -sticky ew + +# Speed sweep control +ttk::frame $w.note.br.frame3 -style custom.TFrame +ttk::checkbutton $w.note.br.frame3.btn -text " Sweep Speed" -variable speed_sweep -onvalue "1" -offvalue "0" -style custom.TCheckbutton +ttk::radiobutton $w.note.br.frame3.btn1 -text "km/h" -variable speed_is_mph -value 0 -style custom.TCheckbutton -command { change_speed_unit } +ttk::radiobutton $w.note.br.frame3.btn2 -text "mph" -variable speed_is_mph -value 1 -style custom.TCheckbutton -command { change_speed_unit } +pack $w.note.br.frame3.btn -side left -fill x -pady 10 -padx 2m +pack $w.note.br.frame3.btn2 -side right -fill x -padx 5 +pack $w.note.br.frame3.btn1 -side right -fill x -padx 5 +grid $w.note.br.frame3 -row 1 -column 1 -pady 10 -padx 2m -sticky ew +scale $w.note.br.scale_speed -length 300 -showvalue 0 -orient h -from 0 -to $speed_limit_hi -variable speed -tickinterval 5 -resolution 0.1 -borderwidth 0 -background "#DEDBD6" -highlightbackground "#DEDBD6" +grid $w.note.br.scale_speed -row 2 -column 1 -pady 0 -padx 2m -sticky ew + +# Speed value +ttk::label $w.note.br.label_speed -textvariable speed -font "Helvetica 96 bold" -justify "right" -width 4 -anchor center -background "gray95" +grid $w.note.br.label_speed -row 3 -column 1 -pady 10 -padx 10 -sticky ew + +# Status line +labelframe $w.note.br.frame0b -borderwidth 1 -background "Yellow" +ttk::label $w.note.br.frame0b.lblStatus -text "Status:" -font "Helvetica 10 bold" -background "Yellow" +ttk::label $w.note.br.frame0b.lblStatusText -text "BlueRobin transmitter off." -font "Helvetica 10" -background "Yellow" +grid $w.note.br.frame0b -row 4 -column 0 -pady 20 -padx 10 -sticky ew -columnspan 2 +pack $w.note.br.frame0b.lblStatus -side left -fill x +pack $w.note.br.frame0b.lblStatusText -side left -fill x + + +# ---------------------------------------------------------------------------------------- +# Wireless Update pane ------------------------------------------------------------------- +ttk::frame $w.note.wbsl -style custom.TFrame +$w.note add $w.note.wbsl -text "Wireless Update" -underline 0 -padding 2 +grid columnconfigure $w.note.wbsl {0 1} -weight 1 -uniform 1 + +ttk::label $w.note.wbsl.label0 -font "Helvetica 10 bold" -width 80 -wraplength 550 -justify center -text "Only use this update function with watch firmware that allows to invoke the Wireless Update on the watch again.\n\nOlder eZ430-Chronos kits require a manual software update of the watch and access point. See Chronoswiki." +grid $w.note.wbsl.label0 -row 0 -column 0 -sticky ew -columnspan 3 -pady 10 -padx 10 + +ttk::label $w.note.wbsl.label1 -font "Helvetica 10" -text "Select the firmware file that you want to download to the watch:" +ttk::entry $w.note.wbsl.entry0 -state readonly -textvariable select_input_file + +grid $w.note.wbsl.label1 -row 1 -column 0 -sticky ew -columnspan 3 -pady 15 -padx 10 +grid $w.note.wbsl.entry0 -row 2 -column 0 -sticky ew -columnspan 2 -padx 10 + +ttk::button $w.note.wbsl.btnBrowse -text "Browse..." -command { open_file } -width 16 +grid $w.note.wbsl.btnBrowse -row 2 -column 2 -sticky ew -padx 10 + +ttk::button $w.note.wbsl.btnDwnld -text "Update Chronos Watch" -command { start_wbsl_ap } -width 16 -default "active" +grid $w.note.wbsl.btnDwnld -row 3 -column 0 -sticky ew -pady 15 -padx 8 -columnspan 3 + +# Progress bar +labelframe $w.note.wbsl.frame1p -borderwidth 0 +ttk::label $w.note.wbsl.frame1p.lblProgress -text "Progress " -font "Helvetica 10 bold" +ttk::progressbar $w.note.wbsl.frame1p.progBar -orient horizontal -value 0 -variable wbsl_progress -mode determinate +grid $w.note.wbsl.frame1p -row 4 -column 0 -sticky ew -pady 16 -padx 10 -columnspan 3 +pack $w.note.wbsl.frame1p.lblProgress -side left +pack $w.note.wbsl.frame1p.progBar -side left -fill x -expand 1 + +#Dummy Labels to fill Space +ttk::label $w.note.wbsl.importantNote -width 80 -wraplength 550 -justify center -text "Important: If the wireless update fails during the firmware download to flash memory, the watch display will be blank and the watch will be in sleep mode. To restart the update, press the down button." -font "Helvetica 10 bold" +grid $w.note.wbsl.importantNote -row 5 -column 0 -sticky ew -columnspan 3 -pady 20 -padx 10 + +# Frame for status display +labelframe $w.note.wbsl.frame0b -borderwidth 1 -background "Yellow" +ttk::label $w.note.wbsl.frame0b.lblStatus -text "Status:" -font "Helvetica 10 bold" -background "Yellow" +ttk::label $w.note.wbsl.frame0b.lblStatusText -text "Access Point is off." -font "Helvetica 10" -background "Yellow" +grid $w.note.wbsl.frame0b -row 6 -column 0 -pady 13 -padx 10 -sticky ew -columnspan 3 +pack $w.note.wbsl.frame0b.lblStatus -side left -fill x +pack $w.note.wbsl.frame0b.lblStatusText -side left -fill x + +# ---------------------------------------------------------------------------------------- +# About pane ----------------------------------------------------------------------------- +ttk::frame $w.note.about -style custom.TFrame +$w.note add $w.note.about -text "About" -underline 0 -padding 2 +grid columnconfigure $w.note.about {0 1} -weight 1 -uniform 1 + +# SimpliciTI box +ttk::labelframe $w.note.about.s -borderwidth 1 +ttk::label $w.note.about.s.txt1 -font "Helvetica 12 bold" -justify "left" -width 4 -anchor center -style custom.TLabel -text "SimpliciTI\u2122" +ttk::label $w.note.about.s.txt2 -font "Helvetica 10" -width 80 -wraplength 550 -justify left -anchor n -style custom.TLabel \ +-text "SimpliciTI\u2122 is a simple low-power RF network protocol aimed at small RF networks.\ +\n\nSuch networks typically contain battery operated devices which require long battery life, low data rate and low duty cycle and have a limited number of nodes talking directly to each other or through an access point or range extenders. Access point and range extenders are not required but provide extra functionality such as store and forward messages.\ +\n\nWith SimpliciTI\u2122 the MCU resource requirements are minimal which results in low system cost." +ttk::label $w.note.about.s.txt3 -font "Helvetica 10 bold" -wraplength 550 -justify left -anchor n -style custom.TLabel -text "Learn more about SimpliciTI\u2122 at http://www.ti.com/simpliciti" +grid $w.note.about.s -row 0 -column 0 -sticky new -pady 0 -columnspan 2 +pack $w.note.about.s.txt1 -side top -fill x -pady 5 -padx 2m +pack $w.note.about.s.txt2 -side top -fill x -pady 0 -padx 2m +pack $w.note.about.s.txt3 -side top -fill x -pady 5 -padx 2m + +# BlueRobin box +ttk::labelframe $w.note.about.b -borderwidth 1 +ttk::label $w.note.about.b.txt1 -font "Helvetica 12 bold italic" -foreground "Dark Blue" -justify "left" -width 4 -anchor center -text "BlueRobin\u2122" -style custom.TLabel +ttk::label $w.note.about.b.txt2 -font "Helvetica 10" -width 80 -wraplength 550 -justify left -anchor n -style custom.TLabel \ +-text "The BlueRobin\u2122 protocol provides low data rate transmission for wireless body area sensor networks and team monitoring systems. Ultra-low power consumption, high reliability and low hardware costs are key elements of BlueRobin\u2122.\ +\n\nBlueRobin\u2122 is successfully used in personal and multi-user heart rate monitoring systems, sports watches, chest straps, foot pods, cycle computers and other fitness equipment." +ttk::label $w.note.about.b.txt3 -font "Helvetica 10 bold" -wraplength 550 -justify left -anchor n -style custom.TLabel -text "Learn more about BlueRobin\u2122 at http://www.bm-innovations.com" +grid $w.note.about.b -row 1 -column 0 -sticky new -pady 5 -columnspan 2 +pack $w.note.about.b.txt1 -side top -fill x -pady 5 -padx 2m +pack $w.note.about.b.txt2 -side top -fill x -pady 0 -padx 2m +pack $w.note.about.b.txt3 -side top -fill x -pady 5 -padx 2m + + +# ---------------------------------------------------------------------------------------- +# Help pane ------------------------------------------------------------------------------ +ttk::frame $w.note.help -style custom.TFrame +$w.note add $w.note.help -text "Help" -underline 0 -padding 2 +grid columnconfigure $w.note.help {0 1} -weight 1 -uniform 1 + +# Help text +ttk::labelframe $w.note.help.frame -borderwidth 1 +ttk::label $w.note.help.frame.head -font "Helvetica 12 bold" -justify "left" -width 4 -anchor center -style custom.TLabel -text "Help" +ttk::label $w.note.help.frame.txt1 -font "Helvetica 10" -width 80 -wraplength 550 -justify left -anchor n -style custom.TLabel \ +-text "If you cannot communicate with the RF Access Point, please check the following points in the Windows Device Manager:\n\ +\n1) Do you have another instance of the GUI open? If so, please close it, since it may block the COM port.\ +\n\n2) Does the RF Access Point appear under the friendly name \"TI CC1111 Low-Power RF to USB CDC Serial Port (COMxx)\". xx is the number of the COM port through which the RF Access Point can be accessed. If the RF Access Point is not listed, disconnect it from the USB port and reconnect it. If it still is not listed, or an error is shown, uninstall the RF Access Point (if possible) and reinstall the Windows driver manually.\ +\n\n3) Have you applied the following settings to the RF Access Point?\n\ +\n - Bits per second: \t115200 \ +\n - Data bits: \t\t8 \ +\n - Parity: \t\tNone \ +\n - Stop bits: \t\t1 \ +\n - Flow control: \t\tNone \ +\n \ +\n \ +\n " + +grid $w.note.help.frame -row 0 -column 0 -sticky new -pady 0 -columnspan 2 +pack $w.note.help.frame.head -side top -fill x -pady 5 -padx 2m +pack $w.note.help.frame.txt1 -side top -fill x -pady 0 -padx 2m + +# ---------------------------------------------------------------------------------------- +# Generic SimpliciTI functions ----------------------------------------------------------- + + +proc start_simpliciti_ap_acc { } { + global w + global simpliciti_on simpliciti_acc_on simpliciti_sync_on + + # AP already on? + if { $simpliciti_on == 1 } { return } + + set simpliciti_acc_on 1 + set simpliciti_sync_on 0 + + start_simpliciti_ap +} + + +proc start_simpliciti_ap_sync { } { + global w + global simpliciti_on simpliciti_sync_on simpliciti_acc_on + + # AP already on? + if { $simpliciti_on == 1 } { return } + + set simpliciti_sync_on 1 + set simpliciti_acc_on 0 + + start_simpliciti_ap + + after 1000 + catch { BM_GetStatus } status + + # Check RF Access Point status byte + if { $status == 3 } { + updateStatusSPL "Access point started. Now start watch in sync mode." + } + +} + + + +# Start RF Access Point +proc start_simpliciti_ap { } { + global w + global simpliciti_on bluerobin_on com_available + global simpliciti_ap_started + global wbsl_on + + # No com port? + if { $com_available == 0 } { return } + + # Wireless Update on? + if { $wbsl_on == 1 } { return } + + # In BlueRobin mode? -> Stop BlueRobin transmission + if { $bluerobin_on == 1 } { + stop_bluerobin + after 500 + } + + updateStatusSPL "Starting access point." + after 500 + + # Link with SimpliciTI transmitter + set result [ BM_SPL_Start ] + if { $result == 0 } { + updateStatusSPL "Failed to start access point." + return + } + after 500 + + # Set on flag after some waiting time + set simpliciti_on 1 + + # Ignore dummy data from RF Access Point until it sends real values + set simpliciti_ap_started 0 + + # Reconfigure control buttons + $w.note.spl.frame0.btnStartStop configure -text "Stop Access Point" -command { stop_simpliciti_ap } + $w.note.sync.f0.btn_start_ap configure -text "Stop Access Point" -command { stop_simpliciti_ap } +} + + +# Stop RF Access Point +proc stop_simpliciti_ap {} { + global w + global simpliciti_ap_started simpliciti_on simpliciti_acc_on simpliciti_sync_on bluerobin_on com_available + global accel_x accel_y accel_z accel_x_offset accel_y_offset accel_z_offset + + # AP off? + if { $simpliciti_on == 0 } { return } + + # Clear on flag + set simpliciti_on 0 + set simpliciti_acc_on 0 + set simpliciti_sync_on 0 + + # Send sync exit command (this will exit sync mode on watch side) + BM_SYNC_SendCommand 0x07 + after 750 + + # Stop SimpliciTI + BM_SPL_Stop + + # Link is now off + updateStatusSPL "Access point is off." + + # Clear values + set accel_x 0 + set accel_y 0 + set accel_z 0 + set accel_x_offset 0 + set accel_y_offset 0 + set accel_z_offset 0 + set simpliciti_ap_started 0 + update + + # Reconfig button + $w.note.spl.frame0.btnStartStop configure -text "Start Access Point" -command { start_simpliciti_ap_acc } + $w.note.sync.f0.btn_start_ap configure -text "Start Access Point" -command { start_simpliciti_ap_sync } +} + +# ---------------------------------------------------------------------------------------- +# SimpliciTI acc / ppt ------------------------------------------------------------------- + +# Zero-set x-y-z values +proc calibrate_sensor {} { + global simpliciti_on + global accel_x accel_y accel_z accel_x_offset accel_y_offset accel_z_offset + + # return if SPL is not active + if { $simpliciti_on == 0 } { return } + + # Wait until new frame has arrived + after 100 + + # Clear offset + set accel_x_offset 0 + set accel_y_offset 0 + set accel_z_offset 0 + set accel_x 0 + set accel_y 0 + set accel_z 0 + + # get new data + get_spl_data + + # set new offset + set accel_x_offset $accel_x + set accel_y_offset $accel_y + set accel_z_offset $accel_z +} + +# Read received SimpliciTI data from RF Access Point point +proc get_spl_data {} { + global w + global simpliciti_on simpliciti_acc_on simpliciti_ap_started + global accel_x accel_y accel_z accel_x_offset accel_y_offset accel_z_offset + global button_event_text button_event previous_button_event button_timeout + + # SimpliciTI off? + if { !$simpliciti_on } { return } + if { !$simpliciti_acc_on } { return } + + # Update status box + catch { BM_GetStatus } status + + # Check RF Access Point status byte + if { $status == 2 } { + + # Trying to link + updateStatusSPL "Starting access point." + return + + } elseif { $status == 3 } { + + # Read 32-bit SimpliciTI data from dongle + # Data format is [Z-Y-X-KEY] + catch { BM_SPL_GetData } data + + # Just started? Ignore first data + if { $simpliciti_ap_started == 0} { + + updateStatusSPL "Access point started. Now start watch in acc or ppt mode." + set simpliciti_ap_started 1 + return + + } else { + + # if Byte0 is 0xFF, data has already been read from USB buffer, so do nothing + if { ($data & 0xFF) == 0xFF } { return } + + } + + # Extract watch button event from SimpliciTi data bits 7:0 + set button_event 0 + + if { [expr ($data & 0xF0) ] != 0 } { + + set button_event [expr ($data & 0xF0) ] + + if { $button_event == 0x10 } { + set button_event_text "Button (*)" + } elseif { $button_event == 0x20 } { + set button_event_text "Button (#)" + } elseif { $button_event == 0x30 } { + set button_event_text "Button (Up)" + } + + # Watch can send either key events (2) or mouse clicks (1) - distinguish mode here + if { [expr ($data & 0x0F) ] == 0x01 } { + switch $button_event { + 16 { catch { BM_SetMouseClick 1 } res + updateStatusSPL "Left mouse click." } + 32 { catch { BM_SetMouseClick 3 } res + updateStatusSPL "Left mouse doubleclick." } + 48 { catch { BM_SetMouseClick 2 } res + updateStatusSPL "Right mouse click." } + } + } elseif { [expr ($data & 0x0F) ] == 0x02 } { + updateStatusSPL "$button_event_text was pressed." + switch $button_event { + 16 { button_set M1 } + 32 { button_set M2 } + 48 { button_set S1 } + } + } + update + after 500 + # Dummy read to clear USB buffer + catch { BM_SPL_GetData } data + after 20 + catch { BM_SPL_GetData } data + return + } + + # Keep on drawing X-Y-Z values + + # Keep previous values for low pass filtering + set prev_x $accel_x + set prev_y $accel_y + set prev_z $accel_z + + # Extract acceleration values from upper data bits + set accel_x [expr (($data >> 8) & 0xFF)] + set accel_y [expr (($data >> 16) & 0xFF)] + set accel_z [expr (($data >> 24) & 0xFF)] + + # Convert raw data to signed integer + + # Get sign (1=minus, 0=plus) + set sign_x [expr ($accel_x&0x80) >> 7] + set sign_y [expr ($accel_y&0x80) >> 7] + set sign_z [expr ($accel_z&0x80) >> 7] + + # Convert negative 2's complement number to signed decimal + if { $sign_x == 1 } { + set accel_x [ expr (((~$accel_x) & 0xFF ) + 1)*(-1) ] + } + if { $sign_y == 1 } { + set accel_y [ expr (((~$accel_y) & 0xFF ) + 1)*(-1) ] + } + if { $sign_z == 1 } { + set accel_z [ expr (((~$accel_z) & 0xFF ) + 1)*(-1) ] + } + + # Low pass filter values from acceleration sensor to avoid jitter + set accel_x [expr ($accel_x*18*0.5) + $prev_x*0.5 - $accel_x_offset] + set accel_y [expr ($accel_y*18*0.5) + $prev_y*0.5 - $accel_y_offset] + set accel_z [expr ($accel_z*18*0.5) + $prev_z*0.5 - $accel_z_offset] + + # Display values in status line + updateStatusSPL "Receiving data from acceleration sensor X=[format %4.0f $accel_x] Y=[format %4.0f $accel_y] Z=[format %4.0f $accel_z]" + + # Use values to move mouse cursor + move_cursor + + # Update wave graphs + add_wave_coords + } +} + +# Turn on/off mouse cursor control +proc allow_mouse_control {} { + global w mouse_control + + if { $mouse_control == 0 } { + set mouse_control 1 + $w.note.spl.frame0.btnMouseContrl configure -text "Mouse Off (M)" + } else { + set mouse_control 0 + $w.note.spl.frame0.btnMouseContrl configure -text "Mouse On (M)" + } +} + +# Move mouse cursor through TCL event function +proc move_cursor {} { + global w + global simpliciti_on mouse_control + global x y accel_x accel_y accel_z accel_x_offset accel_y_offset accel_z_offset + + # SimpliciTI off? + if { $simpliciti_on == 0 } { return } + if { $mouse_control == 0 } { return } + + # Calculate new mouse cursor position + set delta_x [format %.0f [expr $accel_y/40]] + set delta_y [format %.0f [expr $accel_x/40]] + + # Get current mouse position + event generate $w + update + set X [expr [winfo pointerx .] - [winfo rootx .]] + set Y [expr [winfo pointery .] - [winfo rooty .]] + + # Set new mouse position + event generate $w -warp 1 -x [expr $X + $delta_x] -y [expr $Y + $delta_y] +} + +# Grab all files in current directory and return list of files with right extension +proc get_files { ext } { + + set dir [pwd] + set files { } + + foreach file0 [glob -nocomplain -directory $dir *$ext] { + set file1 [file tail [file rootname $file0]]$ext + lappend files "$file1" + } + + return $files +} +set all_ini_files [get_files ".ini"] +$w.note.keys.fSel.combo1 configure -values $all_ini_files + +# Read variables from file +proc load_ini_file { } { + global w + global ini_file + global pd_m1 pd_m2 pd_s1 + global cb_m1_windows cb_m1_alt cb_m1_ctrl cb_m1_shift + global cb_s1_windows cb_s1_alt cb_s1_ctrl cb_s1_shift + global cb_m2_windows cb_m2_alt cb_m2_ctrl cb_m2_shift + global sync_use_metric_units + + # Try to open file with key definitions + catch { set fhandle [open "$ini_file" r] } res + + # Exit if file is missing + if { [string first "couldn't open" $res] == 0 } { return } + + fconfigure $fhandle -buffering line + + # Read file line by line and set global variables + while { ![eof $fhandle] } { + # Get next line + gets $fhandle line + # Split line + set data [ split $line "=" ] + # Verify that extracted strings consist of ASCII characters + if { [string is ascii [ lindex $data 0 ]] && [string is ascii [ lindex $data 1 ]] } { + # Set variable + set [ lindex $data 0 ] [ lindex $data 1 ] + } + } + + close $fhandle +} + +# Save variables to file +proc save_ini_file { } { + global w + global ini_file all_ini_files + global pd_m1 pd_m2 pd_s1 + global cb_m1_windows cb_m1_alt cb_m1_ctrl cb_m1_shift + global cb_s1_windows cb_s1_alt cb_s1_ctrl cb_s1_shift + global cb_m2_windows cb_m2_alt cb_m2_ctrl cb_m2_shift + global sync_use_metric_units + + # Open file save dialog first + file_save_dialog $w + + # Delete existing ini file + catch { file delete "$ini_file" } + + # No file selected? + if { $ini_file == "" } { return } + + # Break if directory is write only + catch { set fhandle [open "$ini_file" a] } res + if { [string first "permission denied" $res] == 0 } { + return + } + + fconfigure $fhandle -buffering line + + # Make a list of all key variables + set keylist { pd_m1 pd_m2 pd_s1 \ + cb_m1_windows cb_m1_alt cb_m1_ctrl cb_m1_shift \ + cb_s1_windows cb_s1_alt cb_s1_ctrl cb_s1_shift \ + cb_m2_windows cb_m2_alt cb_m2_ctrl cb_m2_shift \ + sync_use_metric_units } + + # Walk through list and save variables to file + foreach { el } $keylist { + set val [expr $$el] + puts $fhandle "$el=$val" + } + + close $fhandle + + # Update ini file selection + set all_ini_files [get_files ".ini"] + $w.note.keys.fSel.combo1 configure -values $all_ini_files + set ini_file [lindex $all_ini_files 0] +} + +# Generic file save dialog +proc file_save_dialog { w } { + global ini_file + + # Define default file type + set types { + {"eZ430-Chronos configuration" {.ini} } + {"All files" *} + } + + # Use standard Windows file dialog + set selected_type "eZ430-Chronos configuration" + set ini_file [tk_getSaveFile -filetypes $types -parent $w -initialfile "eZ430-Chronos.ini" -defaultextension .ini] +} +# ---------------------------------------------------------------------------------------- +# SimpliciTI sync functions -------------------------------------------------------------- + +# Read watch settings +proc sync_read_watch {} { + global w simpliciti_on simpliciti_sync_on + global sync_time_is_am sync_time_hours_24 sync_time_hours_12 sync_time_minutes sync_time_seconds + global sync_date_year sync_date_month sync_date_day + global sync_alarm_hours sync_alarm_minutes + global sync_use_metric_units + global sync_temperature_24 sync_altitude_24 + + # SimpliciTI off? + if { !$simpliciti_on } { return } + if { !$simpliciti_sync_on } { return } + + # Dummy read to clean RF Access Point buffer + catch { BM_SYNC_ReadBuffer } bin + + # Send command to watch + BM_SYNC_SendCommand 0x02 + updateStatusSYNC "Requesting watch data." + + # Wait for buffer to be filled with data - or timeout + set repeat 10 + while { $repeat > 0 } { + after 100 + set status [ BM_SYNC_GetBufferStatus ] + if { $status == 1 } { + set repeat -1 + catch { BM_SYNC_ReadBuffer } data + + # Decode received data + # Received hours is always 24H format + set sync_time_hours_24 [format "%d" [expr [lindex $data 1] & 0x7F]] + set sync_use_metric_units [expr ([lindex $data 1] >> 7) & 0x01] + set sync_time_minutes [format "%d" [lindex $data 2]] + set sync_time_seconds [format "%d" [lindex $data 3]] + set sync_date_year [format "%d" [expr ([lindex $data 4]<<8) + [lindex $data 5]]] + set sync_date_month [format "%d" [lindex $data 6]] + set sync_date_day [format "%d" [lindex $data 7]] + set sync_alarm_hours [format "%d" [lindex $data 8]] + set sync_alarm_minutes [format "%d" [lindex $data 9]] + set sync_temperature_24 [format "%2.0f" [expr [format "%2.1f" [expr ([lindex $data 10]<<8) + [lindex $data 11]]] / 10]] + set sync_altitude_24 [format "%d" [expr ([lindex $data 12]<<8) + [lindex $data 13]]] + + # Calculate new 24H / 12H time + update_time_24 + update_time_12 + + # Reconfigure display + if { $sync_use_metric_units == 1 } { + switch_to_metric_units + } else { + switch_to_imperial_units + } + + updateStatusSYNC "Received watch data." + } else { + set repeat [expr $repeat-1] + } + } + + if { $repeat == 0 } { + updateStatusSYNC "Failed to read watch data." + } +} + + +# Write watch settings +proc sync_write_watch {} { + global w simpliciti_on + global sync_use_metric_units sync_time_is_am sync_time_hours_24 sync_time_minutes sync_time_seconds + global sync_date_year sync_date_month sync_date_day + global sync_alarm_hours sync_alarm_minutes + global sync_temperature_24 sync_altitude_24 + # AP not enabled? + if { !$simpliciti_on } { return } + + # Assemble command string + lappend cmd 0x03 + lappend cmd [format "0x%02X" [expr $sync_time_hours_24 | (($sync_use_metric_units<<7)&0x80)]] + lappend cmd [format "0x%02X" $sync_time_minutes] + lappend cmd [format "0x%02X" $sync_time_seconds] + lappend cmd [format "0x%02X" [expr $sync_date_year >> 8]] + lappend cmd [format "0x%02X" [expr $sync_date_year & 0xFF]] + lappend cmd [format "0x%02X" $sync_date_month] + lappend cmd [format "0x%02X" $sync_date_day] + lappend cmd [format "0x%02X" $sync_alarm_hours] + lappend cmd [format "0x%02X" $sync_alarm_minutes] + set t1 [format "%.0f" [expr $sync_temperature_24*10]] + lappend cmd [format "0x%02X" [expr $t1 >> 8]] + lappend cmd [format "0x%02X" [expr $t1 & 0xFF]] + lappend cmd [format "0x%02X" [expr $sync_altitude_24 >> 8]] + lappend cmd [format "0x%02X" [expr $sync_altitude_24 & 0xFF]] + + # Transfer command to RF Access Point point + BM_SYNC_SendCommand $cmd + + updateStatusSYNC "Sent data to watch." +} + + +# Read system time and date +proc sync_get_time_and_date {} { + global w + global sync_use_metric_units sync_time_is_am sync_time_hours_24 sync_time_minutes sync_time_seconds + global sync_date_year sync_date_month sync_date_day + + # Get date + set sync_date_year [expr [format "%04.0f" [expr [clock format [clock seconds] -format "%Y"]]]] + set sync_date_month [expr [clock format [clock seconds] -format "%m"]] + if { [string first 0 $sync_date_month] == 0 } { + set sync_date_month [expr [string replace $sync_date_month 0 0]] + } + set sync_date_day [expr [clock format [clock seconds] -format "%e"]] + + # Get hours in 24H time format + set sync_time_hours_24 [clock format [clock seconds] -format "%H"] + if { [string first 0 $sync_time_hours_24] == 0 } { + set sync_time_hours_24 [string replace $sync_time_hours_24 0 0] + } + + # Calculate hours in 12H time format + update_time_24 + + # Get minutes and seconds + set sync_time_minutes [clock format [clock seconds] -format "%M"] + if { [string first 0 $sync_time_minutes] == 0 } { + set sync_time_minutes [string replace $sync_time_minutes 0 0] + } + set sync_time_seconds [clock format [clock seconds] -format "%S"] + if { [string first 0 $sync_time_seconds] == 0 } { + set sync_time_seconds [string replace $sync_time_seconds 0 0] + } + updateStatusSYNC "Copied system time and date to watch settings." +} + + +# Change all affected parameters to metric units / 24H time format +proc switch_to_metric_units {} { + global w + global sync_date_month sync_date_day + global sync_temperature_24 sync_temperature_12 + global sync_altitude_24 sync_altitude_12 + global values_24 + global values_12 + global values_30 + global value_temperature_C + global values_altitude_meters + + # Update 24H time + update_time_12 + + # Reconfigure hours + $w.note.sync.f1.sb1 configure -textvariable sync_time_hours_24 -values $values_24 -postcommand { check_time } + $w.note.sync.ampm.rb1 configure -state disabled + $w.note.sync.ampm.rb2 configure -state disabled + + # Configure date fields + $w.note.sync.f2.l1 configure -text "Date (dd.mm.yyyy)" + $w.note.sync.f2.sb1 configure -textvariable sync_date_day -values $values_30 + $w.note.sync.f2.sb2 configure -textvariable sync_date_month -values $values_12 + + # Change temperature + $w.note.sync.f4.l1 configure -text "Temperature (\u00B0C)" + $w.note.sync.f4.sb1 configure -textvariable sync_temperature_24 -values $value_temperature_C + + # Change altitude + $w.note.sync.f5.l1 configure -text "Altitude (m)" + $w.note.sync.f5.sb1 configure -textvariable sync_altitude_24 -values $values_altitude_meters +} + +# Change all affected parameters to imperial units / 12H time format +proc switch_to_imperial_units {} { + global w + global sync_date_year sync_date_month sync_date_day + global sync_temperature_12 sync_temperature_24 + global sync_altitude_12 sync_altitude_24 + global values_12 + global values_30 + global value_temperature_F + global values_altitude_feet + + # Update 12H time + update_time_24 + + # Reconfigure hours + $w.note.sync.f1.sb1 configure -textvariable sync_time_hours_12 -values $values_12 -postcommand {check_time} + $w.note.sync.ampm.rb1 configure -state normal + $w.note.sync.ampm.rb2 configure -state normal + + # Change date + $w.note.sync.f2.l1 configure -text "Date (mm.dd.yyyy)" + $w.note.sync.f2.sb1 configure -textvariable sync_date_month -values $values_12 + $w.note.sync.f2.sb2 configure -textvariable sync_date_day -values $values_30 + + # Change temperature + $w.note.sync.f4.l1 configure -text "Temperature (\u00B0F)" + $w.note.sync.f4.sb1 configure -textvariable sync_temperature_12 -values $value_temperature_F + + # Change altitude + $w.note.sync.f5.l1 configure -text "Altitude (ft)" + $w.note.sync.f5.sb1 configure -textvariable sync_altitude_12 -values $values_altitude_feet +} + + +# Keep 24H and 12H time variable in sync +proc update_time_24 {} { + global sync_use_metric_units sync_time_is_am sync_time_hours_24 sync_time_hours_12 + + # Checks if the variable is a number. If not, set it to 1 + if {[string is digit -strict $sync_time_hours_24]==0} { set sync_time_hours_24 4} + + # Calculate 12H time + if { $sync_time_hours_24 == 0 } { + set sync_time_hours_12 [expr $sync_time_hours_24 + 12] + set sync_time_is_am 1 + } elseif { $sync_time_hours_24 <= 12 } { + set sync_time_hours_12 $sync_time_hours_24 + set sync_time_is_am 1 + } else { + set sync_time_hours_12 [expr $sync_time_hours_24 - 12] + set sync_time_is_am 0 + } +} + +# Keep 24H and 12H time variable in sync +proc update_time_12 {} { + global sync_use_metric_units sync_time_is_am sync_time_hours_24 sync_time_hours_12 + + # Calculate 12H time + if { $sync_time_is_am == 1 } { + if { $sync_time_hours_12 == 12 } { + set sync_time_hours_24 0 + } else { + set sync_time_hours_24 $sync_time_hours_12 + } + } else { + set sync_time_hours_24 [expr $sync_time_hours_12 + 12] + } +} + +# Trace altitude and temperature and update internal units +proc update_temperature args { + global sync_use_metric_units sync_temperature_24 sync_temperature_12 + + # Convert to internal format + if {([string is digit -strict $sync_temperature_24 ]==1) && ([string is digit -strict $sync_temperature_12 ]==1)} { + if { $sync_use_metric_units == 1 } { + set sync_temperature_12 [format "%2.0f" [expr ($sync_temperature_24*9/5)+32]] + } else { + set sync_temperature_24 [format "%2.0f" [expr ($sync_temperature_12-32)/9*5]] + } + } + if {([string is digit -strict $sync_temperature_24 ]==0) && ($sync_use_metric_units == 0)} { + set sync_temperature_24 [format "%2.0f" [expr ($sync_temperature_12-32)/9*5]] + } +} + +proc update_altitude args { + global sync_use_metric_units sync_altitude_24 sync_altitude_12 + + # Convert to internal format + if {([string is digit -strict $sync_altitude_24 ]==1) && ([string is digit -strict $sync_altitude_12 ]==1)} { + if { $sync_use_metric_units == 1 } { + set sync_altitude_12 [format "%4.0f" [expr {round ($sync_altitude_24*3.28084)}]] + } else { + set sync_altitude_24 [format "%4.0f" [expr {round ( $sync_altitude_12/3.28084)}]] + } + } + if {([string is digit -strict $sync_altitude_24 ]==0) && ($sync_use_metric_units == 0)} { + set sync_altitude_24 [format "%4.0f" [expr {round ( $sync_altitude_12/3.28084)}]] + } +} +trace add variable sync_temperature_24 write update_temperature +trace add variable sync_temperature_12 write update_temperature +trace add variable sync_altitude_24 write update_altitude +trace add variable sync_altitude_12 write update_altitude + +# ---------------------------------------------------------------------------------------- +# BlueRobin functions -------------------------------------------------------------------- + +# Start BlueRobin transmission +proc start_bluerobin { } { + global w bluerobin_on simpliciti_on + global sweep_hr txid heartrate + global com_available + global wbsl_on + # No com port? + if { $com_available == 0} { return } + + # Already sending BlueRobin + if { $bluerobin_on == 1 } { return } + + # Wireless Update on? + if { $wbsl_on == 1 } { return } + + # SimpliciTI on? + if { $simpliciti_on == 1 } { + stop_simpliciti_ap + after 500 + } + + updateStatusBR "Initialising BlueRobin transmitter." + after 500 + + # Set transmitter ID + catch { BM_BR_SetID $txid } result + if { $result == 0 } { + updateStatusBR "Failed to set BlueRobin ID." + return + } + after 500 + + # Start BlueRobin channel + catch { BM_BR_Start } result + if { $result == 0 } { + updateStatusBR "Failed to start BlueRobin transmission." + return + } + # Update status box + updateStatusBR "Starting BlueRobin heart rate transmission." + after 500 + + # Set auto receive mode flag after some waiting time + after 500 + set bluerobin_on 1 + + # Reconfigure control button + $w.note.br.frame0.btnStartStop configure -text "Stop Transmitter" -command { stop_bluerobin } +} + + +# Stop BlueRobin transmission +proc stop_bluerobin { } { + global w bluerobin_on simpliciti_on + + # Not on? + if { $simpliciti_on == 1 || $bluerobin_on == 0 } { return } + + # Clear on flag + set bluerobin_on 0 + + # Stop BlueRobin channel + catch { BM_BR_Stop } result + updateStatusBR "Stopping BlueRobin transmission." + after 1000 + updateStatusBR "BlueRobin transmitter off." + + # Reconfigure control button + $w.note.br.frame0.btnStartStop configure -text "Start Transmitter" -command { start_bluerobin } +} + + +# Set BlueRobin transmit data +proc update_br_data {} { + global bluerobin_on heartrate speed distance speed_is_mph + + # BlueRobin off? + if { $bluerobin_on == 0 } { return } + + # Send heart rate to RF access point + catch { BM_BR_SetHeartrate $heartrate } res + update + + # Convert english units to metric units + if { $speed_is_mph == 1 } { + set speed1 [format "%0.2f" [expr $speed/0.6214 + 0.049]] + } else { + set speed1 $speed + } + + # Calculate new distance (1km/h = 1000m/3600sec) + # Use 0.1m resolution to enable speed < 3.6km/h + set distance [expr $distance + ($speed1*1.5*10*1000/3600)] + + # Transmit distance [m] and speed [0.1m] in decimal format + set distance1 [format "%.0f" [expr $distance/10 ]] + set speedx [format "%.0f" [expr $speed1*10]] + + # Send updated speed/distance to RF Access Point + catch { BM_BR_SetSpeed $speedx $distance1 } res + + # Update status line + if { $speed_is_mph == 1 } { + updateStatusBR "Transmitting heart rate ($heartrate bpm), speed ([format "%0.1f" $speed] mph) and distance ([format "%0.2f" [expr [format %f $distance1]/1000 * 0.621371192]] mls)." + } else { + updateStatusBR "Transmitting heart rate ($heartrate bpm), speed ([format "%0.1f" $speed] km/h) and distance ($distance1 m)." + } +} + + +# Automatically increase heart rate +proc inc_heartrate {} { + global hr_sweep heartrate bluerobin_on + + # BlueRobin off? + if { $bluerobin_on == 0 } { return } + + # Sweep heart rate + if { $hr_sweep == 1 } { + set heartrate [expr $heartrate + 1] + if { $heartrate >= 220 } { set heartrate 40 } + } +} + + +# Automatically increase speed +proc inc_speed {} { + global speed_sweep speed speed_limit_hi bluerobin_on + + # BlueRobin off? + if { $bluerobin_on == 0 } { return } + + # Sweep speed + if { $speed_sweep == 1 } { + set speed [expr $speed + 1] + if { $speed >= $speed_limit_hi } { set speed 0 } + } +} + + +# Change speed / distance format between km and miles +proc change_speed_unit {} { + global w speed speed_limit_hi speed_is_mph speed_is_mph0 + + # No change? + if { $speed_is_mph == $speed_is_mph0 } { return } + + if { $speed_is_mph == 1} { + # From metric to imperial units + set speed [format "%0.1f" [expr $speed*0.6214]] + set speed_limit_hi 15.5 + } else { + # From imperial units to metric + set speed [format "%0.1f" [expr $speed/0.6214]] + set speed_limit_hi 25.0 + } + $w.note.br.scale_speed configure -to $speed_limit_hi + + # Remember current speed unit + set speed_is_mph0 $speed_is_mph +} + +# ---------------------------------------------------------------------------------------- +# WBSL Update functions ------------------------------------------------------------------ + +# Prompt the user to select a file +proc open_file {} { + global select_input_file + global w + set types { + {{CC430 Firmware} {.txt} } + } + set select_input_file [tk_getOpenFile -title "Select File" -filetypes $types] + +} + + +# Safely execute WBSL service functions (non-overlapping) +proc call_wbsl_funcs {} { + global call_wbsl_timer call_wbsl_1 call_wbsl_2 + + if { $call_wbsl_timer == $call_wbsl_1 } { + get_wbsl_packet_status + set call_wbsl_1 [expr $call_wbsl_timer + 2] + } + if { $call_wbsl_timer == $call_wbsl_2 } { + get_wbsl_status + set call_wbsl_2 [expr $call_wbsl_timer + 3] + } + + incr call_wbsl_timer +} + + +# Start the Wireless update procedure, and put RF Access Point in RX mode +proc start_wbsl_ap {} { + global w + global simpliciti_on bluerobin_on com_available + global wbsl_on select_input_file + global wbsl_ap_started + global fsize + global fp + global rData + global rData_index + global low_index + global list_count maxPayload + global ram_updater_downloaded + global wirelessUpdateStarted + + # init needed variables + set rData [list] + set rData_index 0 + set low_index 0 + + # No com port? + if { $com_available == 0} { return } + + # Testing REMOVE + # set ram_updater_downloaded 1 + + set ram_updater_file "ram_based_updater.txt" + + if { $ram_updater_downloaded == 0 } { + # Check that the user has selected a file + if { [string length $select_input_file] == 0 } { + tk_dialog .dialog1 "No file selected" {Please select a watch firmware file (*.txt) to download to the watch.} info 0 OK + return + } + + # Check that the file selected by the user has the extension .txt + if { [string first ".txt" $select_input_file] == -1 } { + tk_dialog .dialog1 "Invalid .txt File" {The file selected is not a .txt file.} info 0 OK + return + } + } + + # First off check that the file trying to be downloaded has the right format + catch { file size $select_input_file } fsize + + # Check if the file exist + if { [string first "no such file" $fsize] != -1 } { + tk_dialog .dialog1 "File doesnt exist" {The selected file doesnt exist, please verify the path.} info 0 OK + return + } + + # Open the file for reading + catch { open $select_input_file r } fp + fconfigure $fp -translation binary + + # read the first character of the file, it should be an @ symbol + set test_at [read $fp 1] + + if { $test_at != "@" } { + tk_dialog .dialog1 "Invalid .txt File" {The .txt file is NOT formatted correctly.} info 0 OK + close $fp + return + } + + # read the complete file + set rawdata [read $fp $fsize] + close $fp + # Remove spaces, tabs, endlines from the data + regsub -all {[ \r\t\nq]*} $rawdata "" stripped_data + set lines 0 + # Divide the file by the symbol @ so that in each list there is data to be written consecutively at the address indicated by the first 2 bytes + set datainlist [split $stripped_data "@"] + set list_count 0 + set byteCounter 0 + + # For each line, convert the ASCII format in which is saved to Raw HEX format + foreach lines $datainlist { + set lines [join $lines] + regsub -all {[ \r\t\nq]*} $lines "" line + if { [catch { binary format H* $line } line] } { + tk_dialog .dialog1 "Invalid .txt File" {The .txt file is NOT formatted correctly.} info 0 OK + return + } + lappend rData $line + incr list_count + } + + # Check if the RAM_UPDATER is not yet on the watch so that we download this first + if { $ram_updater_downloaded == 0 } { + # init needed variables + set rData [list] + set rData_index 0 + set low_index 0 + + catch { file size $ram_updater_file} fsize + + # Check that the RAM Updater file is present on the GUI working directory + if { [string first "no such file" $fsize] != -1 } { + tk_dialog .dialog1 "No Updater File" {The RAM Updater File is not present on the working directory. Filename should be:ram_based_updater.txt} info 0 OK + return + } + + catch { open $ram_updater_file r } fp + fconfigure $fp -translation binary + + set test_at [read $fp 1] + + if { $test_at != "@" } { + tk_dialog .dialog1 "Invalid .txt File" {The ram_based_updater.txt file is NOT formatted correctly.} info 0 OK + close $fp + return + } + + set rawdata [read $fp $fsize] + close $fp + # Remove spaces, tabs, endlines from the data + regsub -all {[ \r\t\nq]*} $rawdata "" stripped_data + + set datainlist [split $stripped_data "@"] + set list_count 0 + set byteCounter 0 + foreach lines $datainlist { + set lines [join $lines] + regsub -all {[ \r\t\nq]*} $lines "" line + if { [catch { binary format H* $line } line] } { + tk_dialog .dialog1 "Invalid .txt File" {The ram_based_updater.txt file is NOT formatted correctly.} info 0 OK + return + } + lappend rData $line + incr list_count + } + } + # In AP mode? + if { $simpliciti_on == 1 } { + stop_simpliciti_ap + after 500 + } + + # In BlueRobin mode? + if { $bluerobin_on == 1 } { + stop_bluerobin + after 500 + } + + updateStatusWBSL "Starting Wireless Update." + after 200 + + # Link with WBSL transmitter + BM_WBSL_Start + after 100 + + set result [ BM_WBSL_GetMaxPayload ] + after 10 + set result [ BM_WBSL_GetMaxPayload ] + + if { $result < 2 } { + updateStatusWBSL "$result Failed to start Wireless Update." + return + } + + + set maxPayload $result + + # Calculate the number of packets needed to be sent + + #initialize the number of packets + set fsize 0 + + # sum up all the bytes to be sent + foreach block $rData { + set byteCounter [string length $block] + set dByte [expr {double($byteCounter)}] + set dMax [expr {double($maxPayload)} ] + set temp [ceil [expr $dByte / $dMax]] + set fsize [expr $fsize + $temp] + } + + # Set on WBSL flag + set wbsl_on 1 + + # Cancel out first received data + set wbsl_ap_started 0 + + # Reconfig buttons + $w.note.wbsl.btnDwnld configure -text "Cancel Update" -command { stop_wbsl_ap } + +} + +# Stop the wireless update procedure +proc stop_wbsl_ap {} { + global w + global simpliciti_on bluerobin_on com_available wbsl_on + global ram_updater_downloaded + global wirelessUpdateStarted + + # AP off? + if { $wbsl_on == 0 } { return } + + # Clear on flags + set wbsl_on 0 + set ram_updater_downloaded 0 + + after 500 + + BM_WBSL_Stop + + # Show that link is inactive + updateStatusWBSL "Wireless Update is off." + + update + + # Initialize the variable that tell us when the update procedure has been initiated by the Watch + set wirelessUpdateStarted 0 + + # Reconfig button and re-enable it in case the update procedure was started and it was disabled during the procedure + $w.note.wbsl.btnDwnld configure -text "Update Chronos Watch" -command { start_wbsl_ap } -state enabled + +} + +proc get_wbsl_packet_status {} { + global w + global wbsl_on + global wbsl_ap_started + global fsize + global fp + global rData + global rData_index + global low_index + global list_count maxPayload + global wbsl_opcode + global ram_updater_downloaded + global vcp_reply + + set status 0 + + # return if WBSL is not active + if { $wbsl_on == 0 } { return } + + # Check packet status + set status [ BM_WBSL_GetPacketStatus ] + + if { $status == 1 } { + # WBSL_DISABLED Not started by watch + return + } elseif { $status == 2 } { + # WBSL Is processing a packet + return + } elseif { $status == 4 } { + # Send the size of the file + set packets [expr {int($fsize)} ] + # send opcode 0 which is a info packet, which contains the total packets to be sent + catch { BM_WBSL_SendData 0 $packets } status + # The next packet will contain an address + set wbsl_opcode 1 + } elseif { $status == 8 } { + # Send the next data packet + + if { $rData_index < $list_count } { + # Choose the appropriate block of data + set data_block [lindex $rData $rData_index] + # Get the size of the block of data, to know if we have sent all of the data in this block and move to the next + set block_size [string length $data_block] + # Read MaxPayload Bytes from the list + set c_data [string range $data_block $low_index [expr $low_index + [expr $maxPayload - 1]]] + + # Send the read bytes to the dongle + set status [BM_WBSL_SendData $wbsl_opcode $c_data] + + #update the low index + set low_index [expr $low_index + $maxPayload] + + # Next packet is a normal data packet + set wbsl_opcode 2 + + if { $low_index >= $block_size } { + incr rData_index + set low_index 0 + # Next packet will include an address at the beginning of the packet + set wbsl_opcode 1 + } + } + } else { + # ERROR only the previous options should be returned + if { $ram_updater_downloaded == 0 } { + tk_dialog .dialog1 "Error in communication" {There was an error in the communication between the RF Access Point and the watch during the download to RAM. The watch should have reset itself. Please retry the update the same way as before.} info 0 OK + } else { + tk_dialog .dialog1 "Error in communication" {There was an error in the communication between the RF Access Point and the watch during the download to Flash. The watch is in a sleep mode now. Please press the "Update Chronos Watch" first and then press the down button on the watch to restart the update.} info 0 OK + } + after 200 + stop_wbsl_ap + return + } +} + +# Get the global status of the AP, check if the state in which the GUI is, matches the state of the AP +proc get_wbsl_status {} { + global w vcp + global wbsl_on + global wbsl_ap_started wbsl_progress + global ram_updater_downloaded + global wirelessUpdateStarted + global wbsl_timer_flag + global vcp_reply fh + + set status 0 + + # return if WBSL is not active + if { $wbsl_on == 0 } { return } + + # Check if the flag has been set, which means the communication was lost while trying to link to download the update image + if { $wbsl_timer_flag == 1 } { + tk_dialog .dialog1 "Error in communication" {There was an error in the communication between the AP and the Watch while trying to start the download to Flash. The watch should have reset itself. Please retry the update the same way as before.} info 0 OK + wbsl_reset_timer + after 300 + stop_wbsl_ap + return + } + + # Update status box + set status [ BM_GetStatus1 ] + + if { $status == 9 } { + # just starting AP + updateStatusWBSL "Starting access point." + return + # Check if there was an error during the communication between the AP and the watch + } elseif { $status == 11 || $status == 12 } { + + if { $ram_updater_downloaded == 0 } { + tk_dialog .dialog1 "Error in communication" {There was an error in the communication between the RF Access Point and the watch during the download to RAM. The watch should have reset itself. Please retry the update the same way as before.} info 0 OK + } else { + tk_dialog .dialog1 "Error in communication" {There was an error in the communication between the RF Access Point and the watch during the download to Flash. The watch is in sleep mode now. Please press the "Update Chronos Watch" first and then press the down button on the watch to restart the update.} info 0 OK + } + after 300 + stop_wbsl_ap + + } elseif { $status == 10 } { + + # Read WBSL data from dongle + set data [ BM_WBSL_GetStatus ] + # if { $data == "" } { return } + + if { $wbsl_ap_started == 0} { + if { $ram_updater_downloaded == 0 } { + updateStatusWBSL "Access point started. Now start watch in rFbSL mode." +after 2000 + } else { + updateStatusWBSL "Starting to download update image to watch." + # We will now try to link with the watch to start downloading the Update Image, we need a timer in case the communication is lost + # while trying to link, since for the linking to start, the Dongle normally waits until the watch initiates the procedure. + wbsl_set_timer 1 + update + } + set wbsl_ap_started 1 + return + } else { + + # Check if data is valid + if { $data < 0 } { + return + } + + set wbsl_progress $data + + if { $wbsl_progress != 0 } { + + if { $wirelessUpdateStarted == 0 } { + + set wirelessUpdateStarted 1 + # Reconfig buttons + $w.note.wbsl.btnDwnld configure -state disabled + } + + if { $ram_updater_downloaded == 1 } { + # The download to FLASH has started, we don't need the timer to keep running + wbsl_reset_timer + update + updateStatusWBSL "Downloading update image to watch. Progress: [format %d $wbsl_progress]%" + + if { $wbsl_progress >= 100 } { + updateStatusWBSL "Image has been successfully downloaded to the watch" + after 1500 + stop_wbsl_ap + } + + } else { + updateStatusWBSL "Downloading the RAM Based Updater. Progress: [format %d $wbsl_progress]%" + +#puts $fh "\nDownloading the RAM Based Updater.\n" + + if { $wbsl_progress >= 100 } { + updateStatusWBSL "RAM Based Updater downloaded. Starting download of update image." + set ram_updater_downloaded 1 + BM_WBSL_Stop + set wbsl_on 0 + start_wbsl_ap + } + } + } + return + } + } +} + +# Stop and reset the timer variables +proc wbsl_reset_timer { } { + global wbsl_timer_enabled + global wbsl_timer_counter + global wbsl_timer_flag + global wbsl_timer_timeout + + set wbsl_timer_counter 0 + set wbsl_timer_flag 0 + set wbsl_timer_timeout 0 + set wbsl_timer_enabled 0 + } + +# Set the timeout variable and start the timer +proc wbsl_set_timer { timeout } { + global wbsl_timer_enabled + global wbsl_timer_counter + global wbsl_timer_flag + global wbsl_timer_timeout + + set wbsl_timer_counter 0 + set wbsl_timer_flag 0 + set wbsl_timer_timeout $timeout + set wbsl_timer_enabled 1 + } + +# Called every 2.5 seconds, acts as the timer, it only counts if it's enabled +proc wbsl_simple_timer {} { + global wbsl_timer_enabled + global wbsl_timer_counter + global wbsl_timer_flag + global wbsl_timer_timeout + + if { $wbsl_timer_enabled == 0 } { + return + } + set wbsl_timer_counter [expr $wbsl_timer_counter+1] + if { $wbsl_timer_counter > $wbsl_timer_timeout } { + set wbsl_timer_flag 1 + set wbsl_timer_enabled 0 + } + +} + +# ---------------------------------------------------------------------------------------- +# System functions ----------------------------------------------------------------------- + +# Create Windows key events +proc button_set { btn } { + global pd_m1 pd_m2 pd_s1 + global cb_m1_windows cb_m1_alt cb_m1_ctrl cb_m1_shift + global cb_s1_windows cb_s1_alt cb_s1_ctrl cb_s1_shift + global cb_m2_windows cb_m2_alt cb_m2_ctrl cb_m2_shift + + # Button select + switch $btn { + "M1" { set pd $pd_m1 + set cb_windows $cb_m1_windows + set cb_alt $cb_m1_alt + set cb_ctrl $cb_m1_ctrl + set cb_shift $cb_m1_shift } + "M2" { set pd $pd_m2 + set cb_windows $cb_m2_windows + set cb_alt $cb_m2_alt + set cb_ctrl $cb_m2_ctrl + set cb_shift $cb_m2_shift } + "S1" { set pd $pd_s1 + set cb_windows $cb_s1_windows + set cb_alt $cb_s1_alt + set cb_ctrl $cb_s1_ctrl + set cb_shift $cb_s1_shift } + default { return } + } + + # Convert key to key symbol + set keysymbol 0 + + if { [string length $pd] == 1 } { + set keysymbol $pd + } else { + # Convert special keys + switch $pd { + "Space" { set keysymbol "space" } + "Arrow-Left" { set keysymbol "Left" } + "Arrow-Right" { set keysymbol "Right" } + "F5" { set keysymbol "F5" } + } + } + + # Simulate complex key event + BM_SetKey $keysymbol $cb_windows $cb_alt $cb_ctrl $cb_shift +} + + +# ---------------------------------------------------------------------------------------- +# Wave graph functions ------------------------------------------------------------------- + + +# Add new wave samples and delete the oldest ones +proc add_wave_coords { } { + global w + global accel_x accel_y accel_z accel_x_offset accel_y_offset accel_z_offset + global wave_x wave_y wave_z + + # cut away oldest sample + set nb_of_samples [ expr [ llength $wave_x ] / 2 ] + if { $nb_of_samples > 61 } { + set wave_x [lreplace $wave_x 0 1] + set wave_y [lreplace $wave_y 0 1] + set wave_z [lreplace $wave_z 0 1] + } + + # shift all waves to left --> decrease all x coordinates by 10 + set wave_temp { } + foreach {x y} $wave_x { + if { $y != "" } { + lappend wave_temp [expr $x-10] $y + } + } + set wave_x $wave_temp + + set wave_temp { } + foreach {x y} $wave_y { + if { $y != "" } { + lappend wave_temp [expr $x-10] $y + } + } + set wave_y $wave_temp + + set wave_temp { } + foreach {x y} $wave_z { + if { $y != "" } { + lappend wave_temp [expr $x-10] $y + } + } + set wave_z $wave_temp + + # Map values to 100 pixel high window + set new_x [expr 50 - ($accel_x / 35) ] + set new_y [expr 50 - ($accel_y / 35) ] + set new_z [expr 50 - ($accel_z / 35) ] + if { $new_x > 99 } { set new_x 99 } + if { $new_y > 99 } { set new_y 99 } + if { $new_z > 99 } { set new_z 99 } + if { $new_x < 5 } { set new_x 5 } + if { $new_y < 5 } { set new_y 5 } + if { $new_z < 5 } { set new_z 5 } + + # Append new samples + lappend wave_x 600 $new_x + lappend wave_y 600 $new_y + lappend wave_z 600 $new_z +} + +# Ensure that this this is an array +array set animationCallbacks {} + +# Create a smoothed line and arrange for its coordinates to be the +# contents of the variable waveCoords. +$w.note.spl.frame2x.canvas create line $wave_x -tags wave -width 1 -fill black -smooth 1 +$w.note.spl.frame2y.canvas create line $wave_y -tags wave -width 1 -fill black -smooth 1 +$w.note.spl.frame2z.canvas create line $wave_z -tags wave -width 1 -fill black -smooth 1 + +# +proc waveCoordsTracer {w args} { + global wave_x + global wave_y + global wave_z + + # Actual visual update will wait until we have finished + # processing; Tk does that for us automatically. + $w.note.spl.frame2x.canvas coords wave $wave_x + $w.note.spl.frame2y.canvas coords wave $wave_y + $w.note.spl.frame2z.canvas coords wave $wave_z +} +trace add variable wave_x write [list waveCoordsTracer $w] + +proc move {} { + # Theoretically 100 frames-per-second (==10ms between frames) + global animationCallbacks + set animationCallbacks(simpleWave) [after 10 move] +} + +# Initialise our remaining animation variables +set animateAfterCallback {} + +# Start the animation processing +move + + + +# ---------------------------------------------------------------------------------------- +# Status output functions ---------------------------------------------------------------- + +proc updateStatusBR { msg } { + global w + $w.note.br.frame0b.lblStatusText configure -text $msg + update +} +proc updateStatusSPL { msg } { + global w + $w.note.spl.frame0b.lblStatusText configure -text $msg + $w.note.sync.status.l2 configure -text $msg + update +} +proc updateStatusSYNC { msg } { + global w + $w.note.sync.status.l2 configure -text $msg + $w.note.spl.frame0b.lblStatusText configure -text $msg + update +} +proc updateStatusWBSL { msg } { + global w + $w.note.wbsl.frame0b.lblStatusText configure -text $msg + update +} + +# ---------------------------------------------------------------------------------------- +# Start / stop application --------------------------------------------------------------- + +# Exit application +proc exitpgm {} { + catch { stop_simpliciti_ap } + catch { stop_bluerobin } + catch { BM_CloseCOM } + exit 0 +} + +proc check_time args { + global sync_time_hours_12 sync_time_hours_24 sync_time_minutes sync_time_seconds + global sync_use_metric_units + global w + + if { $sync_time_hours_12 > 12 } { set sync_time_hours_12 1 } + if { $sync_time_hours_24 > 23 } { set sync_time_hours_24 4 } + if { $sync_time_minutes > 59 } { set sync_time_minutes 30 } + if { $sync_time_seconds > 59 } { set sync_time_seconds 0 } + + if {[string is digit -strict $sync_time_hours_12 ]==0} { set sync_time_hours_12 1} + if {[string is digit -strict $sync_time_hours_24 ]==0} { set sync_time_hours_24 0} + if {[string is digit -strict $sync_time_minutes ]==0} { set sync_time_minutes 0} + if {[string is digit -strict $sync_time_seconds ]==0} { set sync_time_seconds 0} + update_time_24 +} + +proc check_date args { + global values_31 values_30 values_29 values_28 + global sync_date_day sync_date_month sync_date_year + global sync_use_metric_units + global w + set actual_day $sync_date_day + + # Check if we are using metric system, and switch the combobox + if { $sync_use_metric_units == 1 } { + set combobox $w.note.sync.f2.sb1 + } else { + set combobox $w.note.sync.f2.sb2 + } + + switch $sync_date_month { + 1 { $combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 3 {$combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 5 {$combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 7 { $combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 8 { $combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 10 {$combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 12 { $combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 4 { $combobox configure -textvariable sync_date_day -values $values_30 -postcommand {check_date }} + 6 { $combobox configure -textvariable sync_date_day -values $values_30 -postcommand {check_date }} + 9 { $combobox configure -textvariable sync_date_day -values $values_30 -postcommand {check_date } + set sync_date_day $actual_day + } + 11 { $combobox configure -textvariable sync_date_day -values $values_30 -postcommand {check_date }} + + ## A year that is divisible by 4 is a leap year. (Y % 4) == 0 + ## Exception to rule 1: a year that is divisible by 100 is not a leap year. (Y % 100) != 0 + ## Exception to rule 2: a year that is divisible by 400 is a leap year. (Y % 400) == 0 + 2 { + if {( [expr $sync_date_year%4] == 0) && ([ expr $sync_date_year%100 != 0] || [expr $sync_date_year%400 == 0 ])} { $combobox configure -textvariable sync_date_day -values $values_29 -postcommand {check_date } } \ + else { $combobox configure -textvariable sync_date_day -values $values_28 -postcommand {check_date } } + } + } + + # Set boundaries for variables + if { $sync_date_month > 12 || $sync_date_month < 0 } { set sync_date_month 1} + if { $sync_date_day < 0 || $sync_date_day > 31 } { set sync_date_day 1} + if { $sync_date_year < 0 } { set sync_date_year 2010 } + if {[string is digit -strict $sync_date_year]==0} { set sync_date_year 2010} +} + +proc check_altitude {} { + global w + global sync_altitude_24 sync_altitude_12 + global sync_use_metric_units + + if { $sync_use_metric_units == 1 } { + if {[string is digit -strict $sync_altitude_24]==0} { set sync_altitude_24 430} + } else { + if {[string is digit -strict $sync_altitude_12]==0} { set sync_altitude_12 1411} + } +} + +proc check_temperature {} { + global w + global sync_temperature_24 sync_temperature_12 + global sync_use_metric_units + if { $sync_use_metric_units == 1 } { + if {[string is digit -strict $sync_temperature_24]==0} { set sync_temperature_24 22} + } else { + if {[string is digit -strict $sync_temperature_12]==0} { set sync_temperature_12 71} + } +} + +# Execute function once at startup +load_ini_file + +# Reconfigure display +if { $sync_use_metric_units == 1 } { + switch_to_metric_units +} else { + switch_to_imperial_units +} + +# Exit program +if { $exit_prog == 1 } { exitpgm } + +# ---------------------------------------------------------------------------------------- +# Periodic functions -------------------------------------------------------------------- +proc every {ms body} {eval $body; after $ms [info level 0]} +every 1500 { update_br_data } +every 3000 { inc_heartrate } +every 2000 { inc_speed } +every 25 { get_spl_data } +every 10 { call_wbsl_funcs } +every 2500 { wbsl_simple_timer } diff --git a/chronos-ti/Control Center/Chronos Control Center/eZ430-Chronos-CC.ini b/chronos-ti/Control Center/Chronos Control Center/eZ430-Chronos-CC.ini new file mode 100755 index 0000000..3c1ae45 --- /dev/null +++ b/chronos-ti/Control Center/Chronos Control Center/eZ430-Chronos-CC.ini @@ -0,0 +1,16 @@ +pd_m1=Arrow-Left +pd_m2=F5 +pd_s1=Arrow-Right +cb_m1_windows=0 +cb_m1_alt=0 +cb_m1_ctrl=0 +cb_m1_shift=0 +cb_s1_windows=0 +cb_s1_alt=0 +cb_s1_ctrl=0 +cb_s1_shift=0 +cb_m2_windows=0 +cb_m2_alt=0 +cb_m2_ctrl=0 +cb_m2_shift=0 +sync_use_metric_units=1 diff --git a/chronos-ti/Control Center/Chronos Control Center/eZ430-Chronos_driver.tcl b/chronos-ti/Control Center/Chronos Control Center/eZ430-Chronos_driver.tcl new file mode 100755 index 0000000..45e5f74 --- /dev/null +++ b/chronos-ti/Control Center/Chronos Control Center/eZ430-Chronos_driver.tcl @@ -0,0 +1,358 @@ +set vcp 0 +set vcp_reply "" +set vcp_len 0 +set vcp_pending 0 +set vcp_debug 0 +if { $vcp_debug == 1 } { + set fh [open "log.txt" w] +} else { + set fh 0 +} + +# Send string through UART +proc SendCmd { command } { + global vcp vcp_reply vcp_len vcp_pending vcp_debug fh + + set timeout 0 + while { $vcp_pending == 1 } { + if { $vcp_debug == 1 } { puts $fh "Waiting for reply. Delaying command $command." } + after 5 + update + incr timeout + if {$timeout > 100} { + set vcp_pending 0 + if { $vcp_debug == 1 } { puts $fh "Terminating delay loop." } + } + } + update + if { $vcp_debug == 1 } { puts $fh "Sending $command" } + + # Send command + set vcp_reply "" + set vcp_pending 1 + set len [string length $command] + set vcp_len [expr $len / 2] + for {set i 0} {$i < $len} {incr i} { + set hex 0x[string range $command $i [expr $i+1]] + set letter [format %c $hex] + puts -nonewline $vcp $letter + incr i + } + puts -nonewline $vcp "\n" + flush $vcp +} + +# Get UART buffer content +proc GetReply {} { + global vcp vcp_reply vcp_len vcp_pending vcp_debug fh + + set cap [read $vcp] + binary scan $cap cu* valueList + foreach value $valueList { + append vcp_reply [format "0x%02X " $value] + } + if { $vcp_debug == 1 } { puts $fh "Received: $vcp_reply" } + flush $vcp + set vcp_pending 0 +} + +# Open COM port +proc BM_OpenCOM { port baudrate timeout dts rts } { + global vcp + catch { open $port w+ } vcp + if { [string first "couldn't" $vcp] != -1 } { + set vcp 0 + } else { + fconfigure $vcp -mode 115200,n,8,1 + fconfigure $vcp -blocking 0 + fconfigure $vcp -buffering full -encoding binary -translation binary + fileevent $vcp readable [list GetReply] + } +} + + +# Close COM port +proc BM_CloseCOM {} { + global vcp fh + close $vcp + flush $fh + close $fh +} + +# Reset hardware +proc BM_Reset {} { + SendCmd "FF0103" + after 15 +} + +# Set BlueRobin TX ID +proc BM_BR_SetID { id } { + SendCmd "FF0307[format %02X [expr $id & 0xFF]][format %02X [expr ($id>>8) & 0xFF]][format %02X [expr ($id>>16) & 0xFF]][format %02X [expr ($id>>24) & 0xFF]]" + after 15 +} + +# Start BlueRobin TX +proc BM_BR_Start {} { + SendCmd "FF0203" + after 15 +} + +# Stop BlueRobin TX +proc BM_BR_Stop {} { + SendCmd "FF0603" + after 15 +} + + +# Set BlueRobin heart rate value +proc BM_BR_SetHeartrate { hr } { + SendCmd "FF0504[format %02X [expr $hr & 0xFF]]" + after 15 +} + +# Set BlueRobin speed and distance value +proc BM_BR_SetSpeed { spd dist } { + SendCmd "FF0A06[format %02X [expr $spd & 0xFF]][format %02X [expr $dist & 0xFF]][format %02X [expr ($dist>>8) & 0xFF]]" + after 15 +} + +# Start SimpliciTI stack +proc BM_SPL_Start {} { + SendCmd "FF0703" + after 15 +} + +# Stop SimpliciTI stack +proc BM_SPL_Stop {} { + SendCmd "FF0903" + after 15 +} + +# Get 4 bytes payload from SimpliciTI stack +proc BM_SPL_GetData {} { + global vcp_reply + + SendCmd "FF080700000000" + after 15 + update + + while { [llength $vcp_reply] <= 6 } { + lappend vcp_reply 0x00 + } + + return [format "0x%02X" [expr ([lindex $vcp_reply 6]<<24) + ([lindex $vcp_reply 5]<<16) + ([lindex $vcp_reply 4]<<8) + [lindex $vcp_reply 3]]] +} + + +# Get HW status +proc BM_GetStatus {} { + global vcp_reply vcp_pending vcp_debug fh + SendCmd "FF000400" + after 15 + update + if { $vcp_debug == 1 } { puts $fh "BM_GetStatus = [lindex $vcp_reply 3]" } + return [lindex $vcp_reply 3] +} + + +# Simulate mouse clicks +proc BM_SetMouseClick { btn } { + global w + + set X [expr [winfo pointerx .]] + set Y [expr [winfo pointery .]] + set path [winfo containing $X $Y] + + switch $btn { + 1 { exec xdotool mousedown 1 + after 10 + exec xdotool mouseup 1 } + + 2 { exec xdotool mousedown 3 + after 10 + exec xdotool mouseup 3 } + + 3 { exec xdotool mousedown 1 + after 10 + exec xdotool mouseup 1 + after 10 + exec xdotool mousedown 1 + after 10 + exec xdotool mouseup 1 } + } +} + +# Simulate complex key events +proc BM_SetKey { keysymbol win alt ctrl shift } { + global w + + # Press keys and release them immediately + if { $win == 1 } { exec xdotool keydown "Super_L" } + if { $alt == 1 } { exec xdotool keydown "Alt_L" } + if { $ctrl == 1 } { exec xdotool keydown "Control_L" } + if { $shift == 1 } { exec xdotool keydown "Shift_L" } + if { $keysymbol > 0 } { exec xdotool keydown $keysymbol } + after 10 + if { $keysymbol > 0 } { exec xdotool keyup $keysymbol } + if { $shift == 1 } { exec xdotool keyup "Shift_L" } + if { $ctrl == 1 } { exec xdotool keyup "Control_L" } + if { $alt == 1 } { exec xdotool keyup "Alt_L" } + if { $win == 1 } { exec xdotool keyup "Super_L" } +} + + +# Start SimpliciTI sync mode +proc BM_SYNC_Start {} { + SndCmd "FF3003" + after 15 +} + +# Send sync command +proc BM_SYNC_SendCommand { ldata } { + + # take data from list and append it to command + set str "FF3116" + set i 0 + foreach value $ldata { + append str [format "%02X" $value] + incr i + } + + # byte stuff with 0x00 until 19 bytes are set + for {set j $i} {$j < 19} {incr j} { + append str "00" + } + + SendCmd $str + after 15 +} + +# Get sync buffer +proc BM_SYNC_ReadBuffer {} { + global vcp_reply + + SendCmd "FF3303" + after 15 + update + return [lrange $vcp_reply 3 22] +} + +# Get sync buffer state (empty/full) +proc BM_SYNC_GetBufferStatus {} { + global vcp_reply + + SendCmd "FF320400" + after 15 + update + return [lindex $vcp_reply 3] +} + + +# Get HW status +proc BM_GetStatus1 {} { + global vcp_reply vcp_pending vcp_debug fh + SendCmd "FF000400" + while { $vcp_pending == 1 } { update } + set reply [lindex $vcp_reply 3] + if { $vcp_debug == 1 } { puts $fh "BM_GetStatus1 = $reply" } + return $reply +} + +# BM_WBSL_Start +proc BM_WBSL_Start { } { + SendCmd "FF4003" + after 15 +} + +# BM_WBSL_Stop +proc BM_WBSL_Stop { } { + SendCmd "FF4603" + after 15 +} + +# BM_WBSL_GetMaxPayload +proc BM_WBSL_GetMaxPayload { } { + global vcp_reply vcp_pending vcp_debug fh + + SendCmd "FF490400" + while { $vcp_pending == 1 } { update } + if { $vcp_debug == 1 } { puts $fh "BM_WBSL_GetMaxPayload = [lindex $vcp_reply 3]" } + return [lindex $vcp_reply 3] +} + +# BM_WBSL_GetPacketStatus +proc BM_WBSL_GetPacketStatus { } { + global vcp_reply vcp_pending vcp_debug fh + + SendCmd "FF480400" + while { $vcp_pending == 1 } { update } + if { $vcp_debug == 1 } { puts $fh "BM_WBSL_GetPacketStatus = [lindex $vcp_reply 3]" } + return [lindex $vcp_reply 3] +} + +# BM_WBSL_GetStatus +proc BM_WBSL_GetStatus { } { + global vcp_reply vcp_pending vcp_debug fh + + SendCmd "FF410400" + while { $vcp_pending == 1 } { update } + if { $vcp_debug == 1 } { puts $fh "BM_WBSL_GetStatus = [lindex $vcp_reply 3]" } + return [lindex $vcp_reply 3] +} + +# BM_WBSL_SendData +proc BM_WBSL_SendData { data_or_info data } { + global vcp_reply vcp_pending vcp_debug fh + + if { $data_or_info == 0 } { + + set byte0 "00" + set byte1 [format %02X [expr $data&0xFF]] + set byte2 [format %02X [expr $data>>8]] + + set str "FF4706$byte0$byte1$byte2" + SendCmd $str + return 3 + + } else { + + # Send several packets until data has been transmitted + if { $data_or_info == 1 } { + set byte0 "01" + } else { + set byte0 "02" + } + + # Convert ASCII data string to hex values + set len 0 + set data_to_send "" + binary scan $data cu* valueList + foreach value $valueList { + append data_to_send [format "%02X" $value] + incr len + } + + set len1 [expr $len + 2] + set byte1 [format %02X [expr $len&0xFF]] + set data_to_send "$byte0$byte1$data_to_send" + + if { $vcp_debug == 1 } { puts $fh "\nBM_WBSL_SendData $data_to_send\n" } + + while { $len1 > 28 } { + # Send 28 bytes + SendCmd "FF471F[string range $data_to_send 0 55]" + # Cut away data that has been sent + set data_to_send [string range $data_to_send 56 [string length $data_to_send]] + set len1 [expr $len1-28] + update + } + + # Send last bytes + set len1 [expr [string length $data_to_send]/2 + 3] + SendCmd "FF47[format %02X $len1]$data_to_send" + update + return $len1 + } +} + + diff --git a/chronos-ti/Control Center/Chronos Control Center/iTunes Control.ini b/chronos-ti/Control Center/Chronos Control Center/iTunes Control.ini new file mode 100755 index 0000000..1bdfe83 --- /dev/null +++ b/chronos-ti/Control Center/Chronos Control Center/iTunes Control.ini @@ -0,0 +1,16 @@ +pd_m1=Arrow-Right +pd_m2=Space +pd_s1=Arrow-Left +cb_m1_windows=0 +cb_m1_alt=1 +cb_m1_ctrl=1 +cb_m1_shift=1 +cb_s1_windows=0 +cb_s1_alt=1 +cb_s1_ctrl=1 +cb_s1_shift=1 +cb_m2_windows=0 +cb_m2_alt=0 +cb_m2_ctrl=0 +cb_m2_shift=0 +sync_use_metric_units=1 diff --git a/chronos-ti/Control Center/Chronos Control Center/ram_based_updater.txt b/chronos-ti/Control Center/Chronos Control Center/ram_based_updater.txt new file mode 100755 index 0000000..0e610cb --- /dev/null +++ b/chronos-ti/Control Center/Chronos Control Center/ram_based_updater.txt @@ -0,0 +1,180 @@ +@1D30 +31 40 FE 2B 3C 40 88 29 3D 40 1C 01 B0 13 78 27 +3C 40 52 29 3D 40 84 1E 3E 40 36 00 B0 13 18 28 +B0 13 48 26 B0 13 20 28 20 20 00 20 20 20 20 20 +20 00 30 30 00 F5 60 B6 F2 63 D3 D7 70 F7 F3 00 +00 00 00 00 86 00 77 C7 95 E6 97 17 F3 67 05 F0 +87 85 75 46 C6 37 F5 06 D3 87 C4 C4 02 67 E3 B6 +10 08 08 08 F7 F7 F7 F7 20 40 04 80 7F 7F 7F 7F +7F 10 01 80 30 30 30 31 30 32 30 33 30 34 30 35 +30 36 30 37 30 38 30 39 31 30 31 31 31 32 31 33 +31 34 31 35 31 36 31 37 31 38 31 39 32 30 32 31 +32 32 32 33 32 34 32 35 32 36 32 37 32 38 32 39 +33 30 33 31 33 32 33 33 33 34 33 35 33 36 33 37 +33 38 33 39 34 30 34 31 34 32 34 33 34 34 34 35 +34 36 34 37 34 38 34 39 35 30 35 31 35 32 35 33 +35 34 35 35 35 36 35 37 35 38 35 39 36 30 36 31 +36 32 36 33 36 34 36 35 36 36 36 37 36 38 36 39 +37 30 37 31 37 32 37 33 37 34 37 35 37 36 37 37 +37 38 37 39 38 30 38 31 38 32 38 33 38 34 38 35 +38 36 38 37 38 38 38 39 39 30 39 31 39 32 39 33 +39 34 39 35 39 36 39 37 39 38 39 39 20 20 00 20 +20 44 4F 4E 45 00 20 20 46 41 49 4C 00 20 52 46 +42 53 4C 00 24 0A 24 0A 25 0A 26 0A 21 0A 22 0A +23 0A 25 0A 20 0A 20 0A 24 0A 2B 0A 2B 0A 2A 0A +29 0A 28 0A 27 0A 20 0A 24 0A 28 0A 07 00 AD 00 +BA 5E BA 11 05 00 AD 00 00 00 1B 15 7A 40 03 00 +4B 4A C2 93 A3 2A 76 20 B0 13 94 26 82 43 34 0F +B0 13 18 27 B0 13 D4 27 6D 43 5C 43 B0 13 CE 26 +6D 43 6C 43 B0 13 CE 26 6D 43 B0 13 FC 27 5D 43 +B0 13 12 28 D2 43 88 29 D2 43 9D 2A B0 13 BE 24 +5C 93 3D 20 E2 43 9D 2A 4D 4A 5C 43 B0 13 CE 26 +4D 4A 6C 43 B0 13 CE 26 4D 4A 4C 4A B0 13 CE 26 +B0 13 CC 1F 92 92 94 2A 96 2A 03 28 C2 93 A3 2A +26 20 B0 13 B2 20 5C 93 17 20 F2 90 64 00 A0 2A +0A 2C 4F 43 6E 43 5C 42 A0 2A 0D 43 B0 13 76 24 +0D 4C 5C 43 07 3C B0 13 F2 27 B0 13 10 28 3D 40 +6F 1E 6C 43 B0 13 32 25 F2 90 20 00 9D 2A 07 24 +92 92 94 2A 96 2A D6 2B C2 93 A3 2A DA 27 6D 42 +5C 43 B0 13 CE 26 6D 42 6C 43 B0 13 CE 26 6D 42 +B0 13 FC 27 B0 13 10 28 C2 43 88 29 92 92 94 2A +96 2A 0A 28 C2 93 A3 2A 07 24 B2 40 04 A5 20 01 +7B 53 87 23 1A 17 10 01 4B 93 FA 23 B0 13 F2 27 +3D 40 76 1E 6C 43 B0 13 32 25 F4 3F B0 13 A0 20 +B2 40 00 A5 44 01 B0 13 A0 20 B2 40 06 A5 40 01 +C2 43 E0 FF B0 13 A0 20 B2 40 10 A5 44 01 10 01 +3B 15 82 93 38 0F B2 C0 00 02 32 0F E2 93 9E 2A +32 20 3E 40 02 01 0D 43 3C 40 90 29 B0 13 54 27 +7A 40 3B 00 B0 13 78 20 4C 93 25 24 7C 40 3F 00 +B0 13 F2 25 C2 4C 90 29 39 40 91 29 6C 53 C2 4C +9C 2A 7B 90 41 00 05 28 B0 13 02 27 B0 13 8A 27 +12 3C E2 93 9C 2A 0B 28 B0 13 78 20 6B 93 F9 2B +B0 13 6A 20 19 53 F2 53 9C 2A 7B 53 F7 3F B0 13 +6A 20 D2 43 9F 2A 38 17 10 01 7C 40 3F 00 B0 13 +F2 25 C9 4C 00 00 10 01 4C 4A B0 13 F2 25 4B 4C +48 4B 4C 4A B0 13 F2 25 4B 4C 48 9C F9 23 10 01 +B0 13 A0 20 8C 4D 00 00 B0 13 A0 20 5C 43 10 01 +92 B3 44 01 FD 2F 10 01 B0 13 A0 20 CC 4D 00 00 +F3 3F 1B 15 4A 43 D2 53 A2 2A F2 90 05 00 A2 2A +05 28 F2 40 20 00 9D 2A 4C 43 5F 3C B0 13 98 25 +3B 40 96 2A D2 93 9F 2A 07 24 C2 93 A3 2A 04 24 +2D 4B 3D 53 5C 43 4E 3C D2 93 9F 2A 4D 20 C2 43 +9F 2A 5F 42 90 29 5F 4F 92 29 7F F0 80 00 D2 92 +A1 2A 92 29 41 20 5E 42 93 29 C2 93 A3 2A 14 20 +4F 93 10 24 C2 43 A2 2A 5F 42 94 29 47 18 0F 5F +0E 5F 82 4E 94 2A 3D 43 5C 43 B0 13 FC 24 D2 43 +A3 2A 2A 3C 3D 43 25 3C 4F 93 22 24 5F 42 94 29 +47 18 0E 5E 0F 5E 2F 9B CB 23 B0 13 9A 22 5C 93 +17 20 C2 43 A2 2A 2D 4B 5C 43 B0 13 FC 24 92 53 +96 2A 2C 4B 5C 06 0F 4C 5C 0A 0F 5C 0C 5C 0C 5F +1E 42 94 2A B0 13 B6 26 C2 4C A0 2A 5A 43 04 3C +2D 4B 4C 43 B0 13 FC 24 4C 4A 1A 17 10 01 1B 15 +0B 4C 4A 4D B0 13 02 27 4E 4A 0D 4B 7C 40 7F 00 +B0 13 68 25 6A 42 07 3C 3C 40 0F 00 B0 13 E8 26 +B0 13 E8 27 7A 53 7C 40 34 00 B0 13 14 22 A2 B3 +30 0F FD 2B 92 C3 32 0F 7C 40 35 00 B0 13 14 22 +3C 40 19 00 B0 13 E8 26 B0 13 E8 27 92 B3 32 0F +0A 28 92 C3 32 0F 92 B3 30 0F FD 2B 7C 40 3B 00 +B0 13 14 22 0D 3C 7C 40 36 00 B0 13 14 22 7C B0 +70 00 F9 23 7C 40 3A 00 B0 13 14 22 4A 93 CC 23 +1A 17 10 01 3B 15 4B 4C 4C 43 7B 90 BD 00 06 24 +7B 90 31 00 38 28 7B 90 3D 00 35 2C 08 42 32 C2 +03 43 B2 C0 40 00 02 0F B0 13 06 28 7B 90 31 00 +25 28 7B 90 3D 00 22 2C B0 13 F2 25 4A 4C 7D 40 +29 00 4C 43 B0 13 72 26 C2 4B 11 0F A2 B2 30 0F +10 28 7B 90 32 00 0D 24 7B 90 39 00 0A 24 7B 90 +38 00 07 24 A2 B2 30 0F FD 2F 3F 40 C1 0C 3F 53 +FE 2F 4D 4A 4C 43 B0 13 72 26 02 3C C2 4B 11 0F +5C 42 21 0F 02 48 38 17 10 01 2A 15 5C 43 5A 42 +90 29 3A 50 FB FF 7D 40 06 00 D2 93 95 29 0B 20 +5E 42 96 29 47 18 0E 5E 5F 42 97 29 0E 5F 82 4E +92 2A 2A 83 7D 42 B0 13 BA 27 0A 93 1A 24 1C 42 +92 2A 3C 90 00 80 09 28 08 4C 09 43 08 5A 09 63 +19 93 05 28 02 20 18 93 02 28 4C 43 0A 3C 4E 4D +3E 50 90 29 4D 4A B0 13 76 23 5C 93 02 20 82 5A +92 2A B2 40 00 A5 40 01 B2 40 10 A5 44 01 28 17 +10 01 0A 12 6C 92 2D 28 7C 90 14 00 2A 2C 7D 90 +30 00 07 28 7D 90 5B 00 09 2C 4D 4D 5A 4D 35 1D +06 3C 7D 90 2D 00 02 20 6A 43 01 3C 4A 43 7C 90 +0B 00 11 28 4F 4A 43 19 4F 10 43 18 4A 5A 4A DF +7C 90 0B 00 08 20 7D 90 31 00 03 24 7D 90 4C 00 +02 20 7A 40 80 00 4C 4C 4F 4E 5E 4C 90 1D B0 13 +C8 27 3A 41 10 01 5B 15 08 4C 09 4E 5C 43 0A 48 +0B 43 0E 48 0F 43 46 4D 0A 56 0B 63 02 3C 1E 53 +0F 63 0F 9B 03 28 18 20 0E 9A 16 2C 0C 4E 58 B3 +08 20 06 4A 07 4B 36 53 37 63 0E 96 06 20 0F 97 +04 20 7D 49 B0 13 A8 20 05 3C 3D 49 B0 13 90 20 +1E 53 0F 63 5C 93 E3 27 56 17 10 01 F2 D0 03 00 +4A 02 B2 F0 3E FF 6C 01 B2 D0 0C 00 6C 01 82 43 +66 01 B2 40 44 00 68 01 32 D0 40 00 82 43 60 01 +B2 40 50 00 62 01 B2 40 6E 11 64 01 32 C0 40 00 +3F 40 22 F4 03 43 0E 43 3F 53 3E 63 FD 2F B2 F0 +F0 FF 6E 01 A2 C3 02 01 A2 B3 02 01 F8 2F 80 00 +1E 26 7E E3 5F 93 05 20 6E FC 4E DD CC 4E 00 00 +10 01 4F 93 03 20 CC FE 00 00 10 01 6F 93 09 20 +CC FE 00 00 CC FE 20 00 CC DD 00 00 CC DD 20 00 +10 01 7F 90 03 00 08 20 4F 4E 6F FC 4F DD CC 4F +00 00 CC FE 20 00 10 01 6F 92 04 20 CC FE 00 00 +CC FE 20 00 10 01 3B 15 0A 4C 0B 4D 48 4E 39 40 +98 2A 2E 43 3D 40 62 1D 0C 49 B0 13 66 27 48 93 +13 24 78 90 03 00 10 2C 0B 93 0E 20 3A 90 64 00 +0B 2C 4E 48 4D 48 3D E3 1D 53 0A 5A 0D 5A 3D 50 +A6 1D 0C 49 B0 13 66 27 0C 49 38 17 10 01 0A 12 +4A 43 7D 42 3C 40 7A 29 B0 13 8E 21 B0 13 98 25 +D2 93 9F 2A 10 20 C2 43 9F 2A D2 93 93 29 05 20 +5F 42 90 29 CF 93 92 29 02 38 4C 43 05 3C D2 42 +92 29 A1 2A 5A 43 4C 4A 3A 41 10 01 4E 4C 3C 40 +09 00 B0 13 E8 26 B0 13 E8 27 D2 42 A1 2A 83 29 +C2 4E 85 29 0F 4D 47 19 0F 10 7F F0 7F 00 C2 4F +86 29 C2 4D 87 29 7D 40 06 00 3C 40 82 29 80 00 +8E 21 3B 15 0A 4D 6C 93 05 20 7B 40 0B 00 78 40 +06 00 03 3C 7B 40 06 00 68 43 49 43 09 3C 5E 43 +0F 4A 0F 59 6D 4F 4C 4B 4C 59 B0 13 12 23 59 53 +49 98 F5 2B 38 17 10 01 0A 12 0A 42 B0 13 40 27 +6F 4D 0C 5F 82 4C 10 0F 5F 43 07 3C B0 13 DE 27 +0C 4D 0C 5F E2 4C 10 0F 5F 53 4F 9E F7 2B C2 93 +20 0F 02 4A 3A 41 10 01 B0 13 8A 27 3C 40 00 40 +B0 13 E8 26 06 3C B2 B0 00 02 32 0F 02 28 B0 13 +F0 1F 92 B3 44 03 03 2C D2 93 9F 2A F4 23 B0 13 +9A 27 80 00 02 27 21 83 82 43 32 0F 7C 40 30 00 +B0 13 14 22 81 43 00 00 02 3C 91 53 00 00 B1 90 +64 00 00 00 FA 2B B0 13 AA 27 82 43 06 0F 21 53 +10 01 0F 42 32 C2 03 43 B0 13 06 28 7C 90 2F 00 +03 28 7C 90 3E 00 03 20 7C D0 80 00 02 3C 7C D0 +C0 00 C2 4C 13 0F 5C 42 20 0F 02 4F 10 01 B2 D0 +06 00 06 0A B2 40 1D 7B 00 0A B2 40 ED 00 04 0A +F2 D0 E0 00 4A 02 F2 D0 E0 00 44 02 B2 43 0A 0A +B2 40 FF 00 0C 0A 10 01 B2 40 80 5A 5C 01 32 C2 +03 43 B0 13 CC 23 B0 13 D4 27 3C 40 33 73 B0 13 +E8 26 B0 13 E8 27 B0 13 BA 1E B2 40 04 A5 20 01 +F4 3F 21 83 0E 42 B0 13 40 27 4D 4D 0C 5D 82 4C +10 0F B0 13 DE 27 5F 42 20 0F 81 4F 00 00 02 4E +21 53 10 01 C2 43 88 29 C2 43 A0 2A 82 43 96 2A +82 43 94 2A C2 43 A2 2A C2 43 A3 2A 82 43 32 0F +10 01 7C F3 7E F3 0F 4E 0D 4C 0E 43 1C 43 0D 5D +0E 6E 0E 9F 01 28 0E 8F 0C 6C F9 2B 10 01 0A 12 +7C 90 14 00 07 2C 4C 4C 5A 4C 90 1D 4F 4D 4E 4A +B0 13 C8 27 3A 41 10 01 3C 90 00 80 02 28 3C 40 +FF 7F 82 4C 54 03 92 C3 44 03 B2 D0 24 01 40 03 +10 01 D2 43 9E 2A B0 13 AA 27 7C 40 3A 00 B0 13 +14 22 82 43 32 0F 10 01 3D 40 58 1D 5C 43 B0 13 +32 25 3D 40 5B 1D 6C 43 80 00 32 25 0A 12 21 83 +0A 4C 81 4A 00 00 0D 41 5C 43 B0 13 24 28 F9 3F +32 C2 03 43 B0 13 06 28 4C 4C 3C D0 40 00 47 18 +0C 5C 10 01 0F 4C 04 3C CF 4D 00 00 1F 53 3E 53 +0E 93 FA 23 10 01 0F 4C 04 3C FF 4D 00 00 1F 53 +3E 53 0E 93 FA 23 10 01 0F 4C 0F 5D 03 3C CC 43 +00 00 1C 53 0C 9F FB 23 10 01 82 43 32 0F E2 43 +9E 2A 7C 40 34 00 80 00 14 22 92 C3 44 03 B2 F0 +CF FF 40 03 82 43 50 03 10 01 7C 40 36 00 B0 13 +14 22 7C B0 70 00 F9 23 10 01 B2 40 00 A5 44 01 +B2 40 40 A5 40 01 10 01 4D 4A 0C 5C 1C 4C 52 29 +80 00 22 24 3D 40 7D 1E 6C 43 80 00 32 25 B2 B0 +20 00 02 0F FC 2B 10 01 92 B3 44 03 FD 2B 80 00 +9A 27 3D 40 6C 1E 5C 43 80 00 32 25 4C 4A B0 13 +CE 26 80 00 C6 25 B2 B0 10 00 02 0F FC 2B 10 01 +4D 43 4C 43 80 00 CE 26 80 00 66 27 80 00 2C 27 +80 00 1C 28 10 01 +@FFFE +30 1D +q diff --git a/chronos-ti/Control Center/Chronos Data Logger/eZ430-Chronos Datalogger 1_2.tcl b/chronos-ti/Control Center/Chronos Data Logger/eZ430-Chronos Datalogger 1_2.tcl new file mode 100755 index 0000000..bc308fb --- /dev/null +++ b/chronos-ti/Control Center/Chronos Data Logger/eZ430-Chronos Datalogger 1_2.tcl @@ -0,0 +1,1915 @@ +#!/usr/bin/tclsh8.5 + +# ************************************************************************************************* +# +# Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# Neither the name of Texas Instruments Incorporated nor the names of +# its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# ************************************************************************************************* +# ez430-Chronos Datalogger Application TCL/Tk script +# ************************************************************************************************* +# +# Rev 1.2 +# - Use of combobox +# - Bug fix windows 7 +# - Removed obsolete variables +# - checks for leap years +# +# Rev 1.1 +# - extended 12H / 24H format switch function +# - added "RF BSL" pane and related functions +# +# Rev 1.0 +# - initial version released to manufacturing +# ************************************************************************************************* + + +# ---------------------------------------------------------------------------------------- +# Load TCL packages and C library -------------------------------------------------------- +set exit_prog 0 +# load libraries ----------------------------------------------------- +package require Tk + +# Set COM port where RF Access Point is mounted +set com "/dev/ttyACM0" + +# Include BlueRobin BM-USBD1 driver +# Adds global variable "vcp" +source "eZ430-Chronos_driver.tcl" + +# Open COM port +if { [BM_OpenCOM $com 115200 30 0 0] == 0 } { + tk_dialog .dialog1 "Error" "Could not detect USB dongle. Press OK to close application." info 0 OK + + set com_available 0 + exit 0 +} else { + set com_available 1 + # Reset hardware + BM_Reset + after 20 + # Flush channel + for {set i 0} {$i < 10} {incr i} { + BM_GetStatus + after 10 + } +} + + +# ---------------------------------------------------------------------------------------- +# Global variables ----------------------------------------------------------------------- + +# Script revision number +set revision 1.2 + +# Ini file for variables +set ini_file "ez430-Chronos-DL.ini" + +# SimpliciTi variables +set simpliciti_on 0 +set simpliciti_ap_started 0 + +# Initial settings for Sync +set sync_time_is_am 1 +set sync_time_hours_24 4 +set sync_time_hours_12 4 +set sync_time_minutes 30 +set sync_time_seconds 0 +set sync_date_year 2010 +set sync_date_month 9 +set sync_date_day 1 +set sync_altitude_24 500 +set sync_altitude_12 1640 +set sync_temperature_24 22 +set sync_temperature_12 72 +set sync_file "ez430_data.log" +set sync_data_log_mode 0 +set sync_data_log_interval 1 +set sync_data_log_bytes 0 +set sync_data_log_mode_hr 1 +set sync_data_log_mode_temp 0 +set sync_data_log_mode_alt 0 +set sync_data_log_mode_acc 0 +set packets_max [expr 8192/16] +set packets_expected 0 +set sync_use_metric_units 1 + +for { set i 0 } { $i < $packets_max } {incr i } { + set packet($i) "m" +} +for { set i 0 } { $i < 8192 } {incr i } { + set hex_arr($i) 0 +} + +set i -10 +while {$i < 41} { + lappend value_temperature_C $i + incr i + } +set i 14 +while {$i < 105} { + lappend value_temperature_F $i + incr i +} +set i 0 +while {$i < 60} { + lappend values_60 $i + incr i +} +set i 1 +while {$i < 32} { + lappend values_31 $i + incr i +} +set i 1 +while {$i < 31} { + lappend values_30 $i + incr i +} + +set i 1 +while {$i < 30} { + lappend values_29 $i + incr i +} + +set i 1 +while {$i < 29} { + lappend values_28 $i + incr i +} + +set i 0 +while {$i < 24} { + lappend values_24 $i + incr i +} +set i 1 +while {$i < 13} { + lappend values_12 $i + incr i +} +set i 2010 +while {$i < 2016} { + lappend values_years $i + incr i +} +set i -100 +while {$i < 2001} { + lappend values_altitude_meters $i + incr i +} +set i -328 +while {$i < 6563} { + lappend values_altitude_feet $i + incr i +} + +# WBSL global variables +set select_input_file "" +set call_wbsl_timer 0 +set call_wbsl_1 2 +set call_wbsl_2 3 +set wbsl_progress 0 +set wbsl_on 0 +set wbsl_ap_started 0 +set fsize 0 +set fp 0 +set rData [list] +set rData_index 0 +set low_index 0 +set list_count 0 +set wbsl_opcode 0 +set maxPayload 0 +set ram_updater_downloaded 0 +set wirelessUpdateStarted 0 +set wbsl_timer_enabled 0 +set wbsl_timer_counter 0 +set wbsl_timer_flag 0 +set wbsl_timer_timeout 0 + +# Function required by WBSL +proc ceil x {expr {ceil($x)} } + +# ---------------------------------------------------------------------------------------- +# Function prototypes -------------------------------------------------------------------- +proc get_wbsl_status {} {} +proc wbsl_set_timer { timeout } {} +proc wbsl_reset_timer {} {} + +# ---------------------------------------------------------------------------------------- +# Graphical user interface setup --------------------------------------------------------- + +# Some custom styles for graphical elements +ttk::setTheme clam +ttk::style configure custom.TCheckbutton -font "Helvetica 10" +ttk::style configure custom.TLabelframe -font "Helvetica 12 bold" +ttk::style configure custom.TRadiobutton -font "Helvetica 9" + +# Define basic window geometry +wm title . "Texas Instruments eZ430-Chronos Datalogger $revision" +wm geometry . 640x510 +wm resizable . 0 0 +wm iconname . "ttknote" +ttk::frame .f +pack .f -fill both -expand 1 +set w .f + +# Map keys to internal functions +bind . { exitpgm } + +## Make the notebook and set up Ctrl+Tab traversal +ttk::notebook $w.note +pack $w.note -fill both -expand 1 -padx 2 -pady 3 +ttk::notebook::enableTraversal $w.note + + +# ---------------------------------------------------------------------------------------- +# Sync pane ------------------------------------------------------------------------------ +ttk::frame $w.note.sync -style custom.TFrame +$w.note add $w.note.sync -text "SimpliciTI\u2122 Datalogger" -underline 0 -padding 2 +grid columnconfigure $w.note.sync {0 1} -weight 1 -uniform 1 + +# Buttons +ttk::labelframe $w.note.sync.f0 -borderwidth 0 +ttk::button $w.note.sync.f0.btn_start_ap -text "Start Access Point" -command { start_simpliciti_ap } -width 14 +ttk::button $w.note.sync.f0.btn_get_watch_settings -text "Read Watch" -command { sync_read_watch } -width 11 +ttk::button $w.note.sync.f0.btn_get_time_and_date -text "Copy System Time" -command { sync_get_time_and_date } -width 14 +ttk::button $w.note.sync.f0.btn_set_watch -text "Set Watch" -command { sync_write_watch } -width 8 +ttk::button $w.note.sync.f0.btn_erase_mem -text "Erase Memory" -command { sync_erase } -width 11 +grid $w.note.sync.f0 -row 0 -column 0 -pady 5 -padx 8 -sticky ew -columnspan 2 +pack $w.note.sync.f0.btn_start_ap -side left -fill x -padx 8 +pack $w.note.sync.f0.btn_erase_mem -side right -fill x -padx 8 +pack $w.note.sync.f0.btn_set_watch -side right -fill x -padx 8 +pack $w.note.sync.f0.btn_get_time_and_date -side right -fill x -padx 8 +pack $w.note.sync.f0.btn_get_watch_settings -side right -fill x -padx 8 + +# Download data +ttk::labelframe $w.note.sync.fdl -borderwidth 0 +ttk::button $w.note.sync.fdl.btn1 -text "Download" -command { sync_download } -width 16 +ttk::label $w.note.sync.fdl.lbl -text "Save data to:" -anchor e -font "Helvetica 9" +entry $w.note.sync.fdl.entry -textvariable sync_file -width 30 +ttk::button $w.note.sync.fdl.btn2 -text "Browse" -command "fileDialog $w $w.note.sync.fdl.entry save" -width 10 +grid $w.note.sync.fdl -row 1 -column 0 -pady 5 -padx 8 -sticky ew -columnspan 2 +pack $w.note.sync.fdl.btn1 -side left -fill x -padx 8 +pack $w.note.sync.fdl.lbl -side left -fill x -padx 8 +pack $w.note.sync.fdl.entry -side left -fill x -padx 8 +pack $w.note.sync.fdl.btn2 -side left -fill x -padx 8 + +# Time +ttk::labelframe $w.note.sync.f1 -borderwidth 0 +ttk::label $w.note.sync.f1.l1 -text "Time " -width 20 -font "Helvetica 10 bold" +ttk::combobox $w.note.sync.f1.sb1 -values $values_24 -textvariable sync_time_hours_24 -justify right -width 2 -postcommand {check_time } +ttk::combobox $w.note.sync.f1.sb2 -values $values_60 -textvariable sync_time_minutes -justify right -width 2 -postcommand check_time +ttk::combobox $w.note.sync.f1.sb3 -values $values_60 -textvariable sync_time_seconds -justify right -width 2 -postcommand check_time +grid $w.note.sync.f1 -row 2 -column 0 -columnspan 1 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f1.l1 -side left -fill x +pack $w.note.sync.f1.sb1 -side left -fill x -padx 5 +pack $w.note.sync.f1.sb2 -side left -fill x -padx 5 +pack $w.note.sync.f1.sb3 -side left -fill x -padx 5 + +# Time format AM/PM +ttk::labelframe $w.note.sync.ampm -borderwidth 0 +ttk::radiobutton $w.note.sync.ampm.rb1 -text "AM" -variable sync_time_is_am -value 1 -style custom.TRadiobutton -state disabled -command { update_time_12 } +ttk::radiobutton $w.note.sync.ampm.rb2 -text "PM" -variable sync_time_is_am -value 0 -style custom.TRadiobutton -state disabled -command { update_time_12 } +grid $w.note.sync.ampm -row 2 -column 1 -columnspan 2 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.ampm.rb1 -side left -fill x -padx 5 +pack $w.note.sync.ampm.rb2 -side left -fill x -padx 5 + +# Date +ttk::labelframe $w.note.sync.f2 -borderwidth 0 +ttk::label $w.note.sync.f2.l1 -text "Date (dd.mm.yyyy)" -width 20 -font "Helvetica 10 bold" +ttk::combobox $w.note.sync.f2.sb1 -values $values_30 -textvariable sync_date_day -justify right -width 2 -postcommand {check_date } +ttk::combobox $w.note.sync.f2.sb2 -values $values_12 -textvariable sync_date_month -justify right -width 2 -postcommand {check_date } +ttk::combobox $w.note.sync.f2.sb3 -values $values_years -textvariable sync_date_year -justify right -width 4 -postcommand {check_date } +grid $w.note.sync.f2 -row 3 -column 0 -columnspan 3 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f2.l1 -side left -fill x +pack $w.note.sync.f2.sb1 -side left -fill x -padx 5 +pack $w.note.sync.f2.sb2 -side left -fill x -padx 5 +pack $w.note.sync.f2.sb3 -side left -fill x -padx 5 + +# Time / Date format +ttk::labelframe $w.note.sync.f1r -borderwidth 0 +ttk::radiobutton $w.note.sync.f1r.rb1 -text "Metric units" -variable sync_use_metric_units -value 1 -style custom.TRadiobutton -command { switch_to_metric_units } +ttk::radiobutton $w.note.sync.f1r.rb2 -text "Imperial units" -variable sync_use_metric_units -value 0 -style custom.TRadiobutton -command { switch_to_imperial_units } +grid $w.note.sync.f1r -row 3 -column 1 -columnspan 2 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f1r.rb1 -side left -fill x -padx 5 +pack $w.note.sync.f1r.rb2 -side left -fill x -padx 5 + +# Temperature +ttk::labelframe $w.note.sync.f4 -borderwidth 0 +ttk::label $w.note.sync.f4.l1 -text "Temperature (\u00B0C)" -width 18 -font "Helvetica 10 bold" +ttk::combobox $w.note.sync.f4.sb1 -values $value_temperature_C -textvariable sync_temperature_24 -justify right -width 4 -postcommand {check_temperature} +grid $w.note.sync.f4 -row 4 -column 0 -columnspan 1 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f4.l1 -side left -fill x +pack $w.note.sync.f4.sb1 -side left -fill x -padx 20 + +# Altitude +ttk::labelframe $w.note.sync.f5 -borderwidth 0 +ttk::label $w.note.sync.f5.l1 -text "Altitude (m)" -width 18 -font "Helvetica 10 bold" +ttk::combobox $w.note.sync.f5.sb1 -values $values_altitude_meters -textvariable sync_altitude_24 -justify right -width 4 -postcommand {check_altitude} +grid $w.note.sync.f5 -row 5 -column 0 -columnspan 1 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f5.l1 -side left -fill x +pack $w.note.sync.f5.sb1 -side left -fill x -padx 20 + +# Data log mode +ttk::labelframe $w.note.sync.f6 -borderwidth 0 +ttk::label $w.note.sync.f6.l1 -text "Data log mode" -width 20 -font "Helvetica 10 bold" +ttk::checkbutton $w.note.sync.f6.cb1 -text "Heartrate" -variable sync_data_log_mode_hr +ttk::checkbutton $w.note.sync.f6.cb2 -text "Temperature" -variable sync_data_log_mode_temp +ttk::checkbutton $w.note.sync.f6.cb3 -text "Altitude" -variable sync_data_log_mode_alt +grid $w.note.sync.f6 -row 7 -column 0 -columnspan 2 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f6.l1 -side left -fill x +pack $w.note.sync.f6.cb1 -side left -fill x -padx 5 +pack $w.note.sync.f6.cb2 -side left -fill x -padx 5 +pack $w.note.sync.f6.cb3 -side left -fill x -padx 5 + +# Data log interval +ttk::labelframe $w.note.sync.f7 -borderwidth 0 +ttk::label $w.note.sync.f7.l1 -text "Data log interval (s)" -width 20 -font "Helvetica 10 bold" +ttk::combobox $w.note.sync.f7.sb1 -values $values_30 -textvariable sync_data_log_interval -justify right -width 2 -postcommand {check_data_log_interval} +grid $w.note.sync.f7 -row 8 -column 0 -columnspan 1 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f7.l1 -side left -fill x +pack $w.note.sync.f7.sb1 -side left -fill x -padx 5 + +# Data log bytes +ttk::labelframe $w.note.sync.f8 -borderwidth 0 +ttk::label $w.note.sync.f8.l1 -text "Bytes logged" -width 20 -font "Helvetica 10 bold" +entry $w.note.sync.f8.sb1 -textvariable sync_data_log_bytes -justify right -width 5 -state readonly +grid $w.note.sync.f8 -row 9 -column 0 -columnspan 1 -pady 0 -padx 10 -sticky ew +pack $w.note.sync.f8.l1 -side left -fill x +pack $w.note.sync.f8.sb1 -side left -fill x -padx 5 + +# Status +labelframe $w.note.sync.status -borderwidth 1 -background "Yellow" +ttk::label $w.note.sync.status.l1 -text "Status:" -font "Helvetica 10 bold" -background "Yellow" +ttk::label $w.note.sync.status.l2 -text "Access Point is off." -font "Helvetica 10" -background "Yellow" +grid $w.note.sync.status -row 10 -column 0 -pady 20 -padx 10 -sticky ew -columnspan 2 +pack $w.note.sync.status.l1 -side left -fill x +pack $w.note.sync.status.l2 -side left -fill x + + + +# ---------------------------------------------------------------------------------------- +# Wireless Update pane ------------------------------------------------------------------- +ttk::frame $w.note.wbsl -style custom.TFrame +$w.note add $w.note.wbsl -text "Wireless Update" -underline 0 -padding 2 +grid columnconfigure $w.note.wbsl {0 1} -weight 1 -uniform 1 + +ttk::label $w.note.wbsl.label0 -font "Helvetica 10 bold" -width 40 -wraplength 600 -justify center -text "Only use this update function with watch firmware that allows to invoke the Wireless Update on the watch again.\n\nOlder eZ430-Chronos kits require a manual software update of the watch and access point. See Chronoswiki." +grid $w.note.wbsl.label0 -row 0 -column 0 -sticky ew -columnspan 3 -pady 10 -padx 10 + +#ttk::labelframe $w.note.wbsl.lf -borderwidth 0 +ttk::label $w.note.wbsl.label1 -font "Helvetica 10" -text "Select the firmware file that you want to download to the watch:" +ttk::entry $w.note.wbsl.entry0 -state readonly -textvariable select_input_file + +grid $w.note.wbsl.label1 -row 1 -column 0 -sticky ew -columnspan 3 -pady 10 -padx 10 +grid $w.note.wbsl.entry0 -row 2 -column 0 -sticky ew -columnspan 2 -padx 10 + +ttk::button $w.note.wbsl.btnBrowse -text "Browse..." -command { open_file } -width 16 +grid $w.note.wbsl.btnBrowse -row 2 -column 2 -sticky ew -padx 10 + +ttk::button $w.note.wbsl.btnDwnld -text "Update Chronos Watch" -command { start_wbsl_ap } -width 16 -default "active" +grid $w.note.wbsl.btnDwnld -row 3 -column 0 -sticky ew -pady 20 -padx 8 -columnspan 3 + +# Progress bar +labelframe $w.note.wbsl.frame1p -borderwidth 0 +ttk::label $w.note.wbsl.frame1p.lblProgress -text "Progress " -font "Helvetica 10 bold" +ttk::progressbar $w.note.wbsl.frame1p.progBar -orient horizontal -value 0 -variable wbsl_progress -mode determinate +grid $w.note.wbsl.frame1p -row 4 -column 0 -sticky ew -pady 15 -padx 10 -columnspan 3 +pack $w.note.wbsl.frame1p.lblProgress -side left +pack $w.note.wbsl.frame1p.progBar -side left -fill x -expand 1 + +#Dummy Labels to fill Space +ttk::label $w.note.wbsl.importantNote -width 80 -wraplength 640 -justify center -text "Important: If the wireless update fails during the firmware download to flash memory, the watch display will be blank and the watch will be in sleep mode. To restart the update, press the down button." -font "Helvetica 10 bold" +grid $w.note.wbsl.importantNote -row 5 -column 0 -sticky ew -columnspan 3 -pady 5 -padx 10 + +# Frame for status display +labelframe $w.note.wbsl.frame0b -borderwidth 1 -background "Yellow" +ttk::label $w.note.wbsl.frame0b.lblStatus -text "Status:" -font "Helvetica 10 bold" -background "Yellow" +ttk::label $w.note.wbsl.frame0b.lblStatusText -text "Access Point is off." -font "Helvetica 10" -background "Yellow" +grid $w.note.wbsl.frame0b -row 6 -column 0 -pady 48 -padx 10 -sticky ew -columnspan 3 +pack $w.note.wbsl.frame0b.lblStatus -side left -fill x +pack $w.note.wbsl.frame0b.lblStatusText -side left -fill x + + +# ----------------------------------------------------------------------------------- +# About pane +ttk::frame $w.note.about -style custom.TFrame +$w.note add $w.note.about -text "About" -underline 0 -padding 2 +grid rowconfigure $w.note.about 1 -weight 1 -uniform 1 +grid columnconfigure $w.note.about {0 1} -weight 1 -uniform 1 + +ttk::labelframe $w.note.about.s -borderwidth 1 +ttk::label $w.note.about.s.txt1 -font "Helvetica 12 bold" -justify "left" -width 4 -anchor center -style custom.TLabel -text "SimpliciTI\u2122" +ttk::label $w.note.about.s.txt2 -font "Helvetica 10" -width 80 -wraplength 6i -justify left -anchor n -style custom.TLabel \ +-text "SimpliciTI\u2122 is a simple low-power RF network protocol aimed at small RF networks.\ +\n\nSuch networks typically contain battery operated devices which require long battery life, low data rate and low duty cycle and have a limited number of nodes talking directly to each other or through an access point or range extenders. Access point and range extenders are not required but provide extra functionality such as store and forward messages.\ +\n\nWith SimpliciTI\u2122 the MCU resource requirements are minimal which results in low system cost." +ttk::label $w.note.about.s.txt3 -font "Helvetica 10 bold" -wraplength 6i -justify left -anchor n -style custom.TLabel -text "Learn more about SimpliciTI\u2122 at http://www.ti.com/simpliciti" +grid $w.note.about.s -row 0 -column 0 -sticky new -pady 0 -columnspan 2 +pack $w.note.about.s.txt1 -side top -fill x -pady 5 -padx 2m +pack $w.note.about.s.txt2 -side top -fill x -pady 0 -padx 2m +pack $w.note.about.s.txt3 -side top -fill x -pady 5 -padx 2m + +ttk::labelframe $w.note.about.b -borderwidth 1 +ttk::label $w.note.about.b.txt1 -font "Helvetica 12 bold italic" -foreground "Dark Blue" -justify "left" -width 4 -anchor center -text "BlueRobin\u2122" -style custom.TLabel +ttk::label $w.note.about.b.txt2 -font "Helvetica 10" -wraplength 6i -justify left -anchor n -style custom.TLabel \ +-text "The BlueRobin\u2122 protocol provides low data rate transmission for wireless body area sensor networks and team monitoring systems. Ultra-low power consumption, high reliability and low hardware costs are key elements of BlueRobin\u2122.\ +\n\nBlueRobin\u2122 is successfully used in personal and multi-user heartrate monitoring systems, sports watches, chest straps, foot pods, cycle computers and other sports and fitness equipment." +ttk::label $w.note.about.b.txt3 -font "Helvetica 10 bold" -wraplength 6i -justify left -anchor n -style custom.TLabel -text "Learn more about BlueRobin\u2122 at http://www.bm-innovations.com" + +grid $w.note.about.b -row 1 -column 0 -sticky new -pady 10 -columnspan 2 +pack $w.note.about.b.txt1 -side top -fill x -pady 5 -padx 2m +pack $w.note.about.b.txt2 -side top -fill x -pady 0 -padx 2m +pack $w.note.about.b.txt3 -side top -fill x -pady 5 -padx 2m + + +# ----------------------------------------------------------------------------------- +# Help pane +ttk::frame $w.note.help -style custom.TFrame +$w.note add $w.note.help -text "Help" -underline 0 -padding 2 +grid rowconfigure $w.note.help 1 -weight 1 -uniform 1 +grid columnconfigure $w.note.help {0 1} -weight 1 -uniform 1 + +ttk::labelframe $w.note.help.frame -borderwidth 1 +ttk::label $w.note.help.frame.head -font "Helvetica 12 bold" -justify "right" -width 4 -anchor center -style custom.TLabel -text "Help" +ttk::label $w.note.help.frame.txt1 -font "Helvetica 10" -width 80 -wraplength 500 -justify left -anchor n -style custom.TLabel \ +-text "If you cannot communicate with the RF access point, please check the following points:\ +\n\n1) Do you have another instance of the GUI open?\n\nIf so, please close it, since it may block the COM port.\ +\n\n2) Is the RF Access Point mounted (will be done automatically by Linux)?\n\nIt must appear as '/dev/ttyACM0'. You might also want to run the 'lsusb' command. The RF Access Point should be listed as 'Bus xxx Device xxx: ID 0451:16a6 Texas Instruments, Inc.'. If not, disconnect the RF Access Point from the USB port and reconnect it." +pack $w.note.help.frame.head -side top -fill x -pady 10 -padx 5m +pack $w.note.help.frame.txt1 -side top -fill x -pady 10 -padx 5m +grid $w.note.help.frame -row 0 -column 0 -sticky ew -pady 0 -columnspan 2 + + +# ---------------------------------------------------------------------------------------- +# Generic SimpliciTI functions ----------------------------------------------------------- + +# Start RF access point +proc start_simpliciti_ap { } { + global w + global simpliciti_on com_available + global simpliciti_ap_started + + + + # No com port? + if { $com_available == 0} { return } + + # SimpliciTI on? + if { $simpliciti_on == 1 } { return } + + updateStatusSYNC "Starting access point." + after 500 + + # Link with SimpliciTI transmitter + catch { BM_SPL_Start } result + if { $result == 0 } { + updateStatusSYNC "Failed to start access point." + return + } + after 500 + + # Set on flag after some waiting time + set simpliciti_on 1 + # Cancel out first received data + set simpliciti_ap_started 0 + + # Reconfig buttons + $w.note.sync.f0.btn_start_ap configure -text "Stop Access Point" -command { stop_simpliciti_ap } + + updateStatusSYNC "Access point started. Now start watch in sync mode." +} + +# Stop RF access point +proc stop_simpliciti_ap {} { + global w + global simpliciti_on com_available + global simpliciti_ap_started + + # AP off? + if { $simpliciti_on == 0 } { return } + + # Clear on flags + set simpliciti_on 0 + + # Send sync exit command + BM_SYNC_SendCommand 7 + + after 750 + + # Now stop SimpliciTI + BM_SPL_Stop + + # Show that link is inactive + updateStatusSYNC "Access point is off." + + # Clear values + set simpliciti_ap_started 0 + update + + # Reconfig button + $w.note.sync.f0.btn_start_ap configure -text "Start Access Point" -command { start_simpliciti_ap } +} + +# ---------------------------------------------------------------------------------------- +# SimpliciTI sync functions -------------------------------------------------------------- +# Read watch settings +proc sync_read_watch {} { + global w simpliciti_on + global sync_use_metric_units sync_time_is_am sync_time_hours_24 sync_time_hours_12 sync_time_minutes sync_time_seconds + global sync_date_year sync_date_month sync_date_day + global sync_data_log_bytes sync_data_log_mode sync_data_log_interval + global sync_data_log_mode_hr sync_data_log_mode_temp sync_data_log_mode_alt sync_data_log_mode_acc + global sync_temperature_24 sync_altitude_24 + + + # AP not enabled? + if { !$simpliciti_on } { return } + + # Dummy read to clean buffer + catch { BM_SYNC_ReadBuffer } bin + + # Request watch data + + BM_SYNC_SendCommand 2 + + updateStatusSYNC "Requesting watch data." + + # Wait for buffer to be filled with RX packet - or timeout + set repeat 10 + while { $repeat > 0 } { + after 100 + set status [ BM_SYNC_GetBufferStatus ] + if { $status == 1 } { + updateStatusSYNC "Received watch status information." + set repeat 0 + + catch { BM_SYNC_ReadBuffer } data + + # Decode received data + # Received hours is always 24H format + set sync_use_metric_units [format "%d" [expr ([lindex $data 1]>>7) & 0x01 ]] + set sync_time_hours_24 [expr [lindex $data 1] & 0x7F] + set sync_time_minutes [format "%d" [lindex $data 2]] + set sync_time_seconds [format "%d" [lindex $data 3]] + set sync_date_year [format "%d" [expr ([lindex $data 4]<<8) + [lindex $data 5]]] + set sync_date_month [format "%d" [lindex $data 6]] + set sync_date_day [format "%d" [lindex $data 7]] + set sync_alarm_hours [format "%d" [lindex $data 8]] + + + set sync_alarm_minutes [format "%d" [lindex $data 9]] + set sync_temperature_24 [format "%2.0f" [expr [format "%2.1f" [expr ([lindex $data 10]<<8) + [lindex $data 11]]] / 10]] + set sync_altitude_24 [format "%d" [expr ([lindex $data 12]<<8) + [lindex $data 13]]] + + set sync_data_log_mode [format "%d" [lindex $data 14]] + set sync_data_log_interval [format "%d" [lindex $data 15]] + set sync_data_log_bytes [format "%d" [expr ([lindex $data 16]<<8) + [lindex $data 17]]] + + + # Decode data log mode bits + if { [expr $sync_data_log_mode & 0x01] } { set sync_data_log_mode_hr 1 } + if { [expr $sync_data_log_mode & 0x02] } { set sync_data_log_mode_temp 1 } + if { [expr $sync_data_log_mode & 0x04] } { set sync_data_log_mode_alt 1 } + + + # Calculate new 24H / 12H time + update_time_24 + update_time_12 + + # Reconfigure display + if { $sync_use_metric_units == 1 } { + switch_to_metric_units + } else { + switch_to_imperial_units + } + + return + + } else { + set repeat [expr $repeat-1] + } + } + updateStatusSYNC "Error: Did not receive watch status information." +} + +# Write watch settings +proc sync_write_watch {} { + global w simpliciti_on + global sync_use_metric_units sync_time_is_am sync_time_hours_24 sync_time_minutes sync_time_seconds + global sync_date_year sync_date_month sync_date_day + global sync_data_log_mode sync_data_log_interval + global sync_data_log_mode_hr sync_data_log_mode_temp sync_data_log_mode_alt sync_data_log_mode_acc + global sync_temperature_24 sync_altitude_24 + + # AP not enabled? + if { !$simpliciti_on } { return } + + # Assemble mode bits + set sync_data_log_mode [expr ($sync_data_log_mode_hr&0x01) | (($sync_data_log_mode_temp<<1)&0x02) | (($sync_data_log_mode_alt<<2)&0x04)] + + # Assemble command string + lappend cmd 0x03 + + lappend cmd [format "0x%02X" [expr $sync_time_hours_24 | (($sync_use_metric_units<<7)&0x80)]] + lappend cmd [format "0x%02X" $sync_time_minutes] + lappend cmd [format "0x%02X" $sync_time_seconds] + lappend cmd [format "0x%02X" [expr $sync_date_year >> 8]] + lappend cmd [format "0x%02X" [expr $sync_date_year & 0xFF]] + lappend cmd [format "0x%02X" $sync_date_month] + lappend cmd [format "0x%02X" $sync_date_day] + lappend cmd "0x00 " + lappend cmd "0x00 " + set t1 [format "%.0f" [expr $sync_temperature_24*10]] + lappend cmd [format "0x%02X" [expr $t1 >> 8]] + lappend cmd [format "0x%02X" [expr $t1 & 0xFF]] + lappend cmd [format "0x%02X" [expr $sync_altitude_24 >> 8]] + lappend cmd [format "0x%02X" [expr $sync_altitude_24 & 0xFF]] + lappend cmd [format "0x%02X" $sync_data_log_mode] + lappend cmd [format "0x%02X" $sync_data_log_interval] + + # Transfer command to RF access point + BM_SYNC_SendCommand $cmd + + updateStatusSYNC "Sent data to watch." +} + +# Read system time and date +proc sync_get_time_and_date {} { + global w + global sync_use_metric_units sync_time_is_am sync_time_hours_24 sync_time_minutes sync_time_seconds + global sync_date_year sync_date_month sync_date_day + + # Get date + set sync_date_year [expr [format "%04.0f" [expr [clock format [clock seconds] -format "%Y"]]]] + set sync_date_month [expr [clock format [clock seconds] -format "%m"]] + if { [string first 0 $sync_date_month] == 0 } { + set sync_date_month [expr [string replace $sync_date_month 0 0]] + } + set sync_date_day [expr [clock format [clock seconds] -format "%e"]] + + # Get hours in 24H time format + set sync_time_hours_24 [clock format [clock seconds] -format "%H"] + if { [string first 0 $sync_time_hours_24] == 0 } { + set sync_time_hours_24 [string replace $sync_time_hours_24 0 0] + } + + # Calculate hours in 12H time format + update_time_24 + + # Get minutes and seconds + set sync_time_minutes [clock format [clock seconds] -format "%M"] + if { [string first 0 $sync_time_minutes] == 0 } { + set sync_time_minutes [string replace $sync_time_minutes 0 0] + } + set sync_time_seconds [clock format [clock seconds] -format "%S"] + if { [string first 0 $sync_time_seconds] == 0 } { + set sync_time_seconds [string replace $sync_time_seconds 0 0] + } + updateStatusSYNC "Copied system time and date to watch settings." +} + +# Download packets, first in a burst, then missed packets packet-by-packet +proc sync_download {} { + global w simpliciti_on + global sync_data_log_bytes sync_file + global packets_max packet packets_expected + + # AP not enabled? + if { $simpliciti_on == 0 } { return } + + # No bytes to download? + sync_read_watch + if { $sync_data_log_bytes == 0 } { return } + + updateStatusSYNC "Requesting watch data." + + # Dummy read to clean buffer + catch { BM_SYNC_ReadBuffer } bin + after 10 + + # Calculate how many packets (1 packet = 16 bytes data) are available for download + set packet_start 0 + set packet_end [expr $sync_data_log_bytes / 16] + set packets_expected [expr $packet_end + 1] + set packets_per_burst 50 + set packets_received 0 + + # Prepare received packet buffer + for { set i 0 } { $i < $packets_max } {incr i } { + set packet($i) "m" + } + + # Request packet bursts until all packets have been requested once + for { set i 0 } { $i < $packets_expected } {set i [expr $i + $packets_per_burst]} { + + # Request burst + set start_hi [expr ($i >> 8) & 0xFF] + set start_lo [expr $i & 0xFF] + if { $packet_end > [expr $i + $packets_per_burst] } { + set end_hi [expr (($i + $packets_per_burst - 1) >> 8) & 0xFF] + set end_lo [expr ($i + $packets_per_burst - 1) & 0xFF] + } else { + # Last burst request + set end_hi [expr ($packet_end >> 8) & 0xFF] + set end_lo [expr $packet_end & 0xFF] + } + + # Assemble command string + lappend cmd 0x04 + lappend cmd [format "0x%02X" $start_hi] + lappend cmd [format "0x%02X" $start_lo] + lappend cmd [format "0x%02X" $end_hi] + lappend cmd [format "0x%02X" $end_lo] + + # Transfer command to RF access point + BM_SYNC_SendCommand $cmd + + # Wait for buffer to be filled - or timeout + set repeat 200 + while { $repeat > 0 } { + set status [ BM_SYNC_GetBufferStatus ] + if { $status == 1 } { + catch { BM_SYNC_ReadBuffer } data + #binary scan $bin H* hex + # Store packet + set idx [format "%d" [expr ([lindex $data 1]<<8) + [lindex $data 2]]] + #set idx [expr 0x[string range $hex 2 5]] + if { $packet($idx) == "m" } { + #set packet($idx) $hex + set packet($idx) $data + incr packets_received + updateStatusSYNC "Received [format %4d [expr $packets_received*16]] bytes." + } + set repeat 10 + } else { + set repeat [expr $repeat-1] + after 2 + } + } + } + + # Clear buffer + catch { BM_SYNC_ReadBuffer } bin + + # While packets are missing, download them separately (up to 180 missed packets) + set packets_missed_count 1 + set repeats 0 + while { $packets_missed_count > 0 && $repeats < 20 } { + + incr repeats + + # Create list of missed packets + catch { unset packets_missed } + set packets_missed_count 0 + for { set i 0 } { $i < $packets_expected } {incr i } { + if { $packet($i) == "m" } { + lappend packets_missed $i + incr packets_missed_count + } + } + + # Packets missed? + if { $packets_missed_count > 0 } { + # Request 9 packets per command + set packets_single [lrange $packets_missed 0 8] + # Add dummy packets + while { [llength $packets_single] < 9 } { + lappend packets_single [lindex $packets_missed 0] + } + # Split packet indizes into high and low byte + for { set i 0 } { $i < 9 } {incr i } { + set ps_hi($i) [expr ([lindex $packets_single $i] >> 8) & 0xFF] + set ps_lo($i) [expr [lindex $packets_single $i] & 0xFF] + } + + # Request packets + updateStatusSYNC "Requesting missed packets $packets_single" + + # Assemble command string + unset cmd + lappend cmd "0x05" + + for { set i 0 } { $i < 9 } {incr i } { + lappend cmd [format "0x%02X" $ps_hi($i)] + lappend cmd [format "0x%02X" $ps_lo($i)] + + + } + + + + + + + # Transfer command to RF access point + BM_SYNC_SendCommand $cmd + + # Wait for buffer to be filled - or timeout + set repeat 100 + while { $repeat > 0 } { + set status [ BM_SYNC_GetBufferStatus ] + if { $status == 1 } { + + catch { BM_SYNC_ReadBuffer } data + + + # Store packet + set idx [format "%d" [expr ([lindex $data 1]<<8) + [lindex $data 2]]] + + if { $packet($idx) == "m" } { + set packet($idx) $data + incr packets_received + updateStatusSYNC "Received [format %4d [expr $packets_received*16]] bytes." + } + set repeat 20 + } else { + set repeat [expr $repeat-1] + after 2 + } + } + } + } + + # Output received data + if { $packets_received >= $packets_expected } { + sync_decode_data + } else { + updateStatusSYNC "Error: Did not receive all logged data." + } + + # Dummy read to clean buffer + catch { BM_SYNC_ReadBuffer } bin +} + +# Decode datastream +proc sync_decode_data {} { + global sync_file sync_data_log_mode + global packets_max packet packets_expected + #global hex_arr + global sync_use_metric_units + + updateStatusSYNC "Writing data to file." + set wp [open $sync_file w] + + # Write raw data and create a hex array + set decode 1 + set hex_arr_len 0 + set data_stream "" + for { set i 0 } { $i < $packets_expected } {incr i } { + + # Uncomment next line to output raw data at start of file + #puts $wp "$i $packet($i)" + + if { $packet($i) != "m" } { + + # Split data line in separate bytes + set data [ split $packet($i) " " ] + + # Append data bytes to raw data stream + for { set j 3 } { $j <= 18 } { incr j } { + lappend hex_arr [lindex $data $j] + } + + } else { + + # Data missing? + updateStatusSYNC "Error: Not all data has been received." + return + + } + } + # Append dummy byte to eof + lappend hex_arr 0x00 + lappend hex_arr 0x00 + lappend hex_arr 0x00 + lappend hex_arr 0x00 + + # Decode data (format is lo-hi) and write to file + set session 0 + for { set i 0 } { $i < [expr [llength $hex_arr] - 2] } {incr i } { + + # Scan for markers + # Markers can appear only at 16-bit boundaries + if { [lindex $hex_arr $i]==0 && [expr $i%2]==1 } { + set next_word [expr ([lindex $hex_arr [expr $i+2]]<<8) | [lindex $hex_arr [expr $i+1]]] + } else { + set next_word [expr ([lindex $hex_arr [expr $i+1]]<<8) | [lindex $hex_arr $i]] + } + + # Check for start marker + if { $session == 0 } { + + if { $next_word == 0xFFFB } { + set session 1 + # Decode header + incr i + incr i + set rec_mode [format "0x%02X" [lindex $hex_arr $i]] + incr i + set rec_interval [format %02d [lindex $hex_arr $i]] + incr i + set rec_day [format %02d [lindex $hex_arr $i]] + incr i + set rec_month [format %02d [lindex $hex_arr $i]] + incr i + set rec_year [expr ([lindex $hex_arr [expr $i+1]]<<8) | [lindex $hex_arr $i]] + incr i + incr i + set rec_hour [format %02d [lindex $hex_arr $i]] + incr i + set rec_minute [format %02d [lindex $hex_arr $i]] + incr i + set rec_second [format %02d [lindex $hex_arr $i]] + set start_time [clock scan "$rec_year-$rec_month-$rec_day $rec_hour:$rec_minute:$rec_second" -format {%Y-%m-%d %H:%M:%S}] + + } + } elseif { $next_word == 0xFFFE } { + + # End marker found + set session 0 + + } else { + + # Get the next data set bytes + set byte0 [lindex $hex_arr $i] + set byte1 [lindex $hex_arr [expr $i+1]] + set byte2 [lindex $hex_arr [expr $i+2]] + set byte3 [lindex $hex_arr [expr $i+3]] + set rec_hr 0 + set rec_temp 0 + set rec_alt 0 + + # Decode data + switch $rec_mode { + 0x01 { # HR + set rec_hr [format %d $byte0] + } + 0x02 { # TEMP + set rec_temp [format %2.1f [expr [format %2.1f [expr (($byte0<<8) | $byte1)]]/10]] + # Move to next data set + set i [expr $i+2-1] + } + 0x04 { # ALT + set rec_alt [format %d [expr ($byte0<<8) | $byte1]] + # Move to next data set + set i [expr $i+2-1] + } + 0x07 { # HR + TEMP + ALT + set rec_hr [format %d $byte0] + set rec_temp [format %2.1f [expr [format %2.1f [expr (($byte1<<4) | (($byte2>>4)&0x0F))]]/10]] + set rec_alt [format %d [expr (($byte2&0x0F)<<8) | $byte3]] + # Move to next data set + set i [expr $i+4-1] + } + 0x03 { # HR + TEMP + set rec_hr [format %d $byte0] + set rec_temp [format %2.1f [expr [format %2.1f [expr (($byte1<<8) | $byte2)]]/10]] + # Move to next data set + set i [expr $i+3-1] + } + 0x05 { # HR + ALT + set rec_hr [format %d $byte0] + set rec_alt [format %d [expr ($byte1<<8) | $byte2]] + # Move to next data set + set i [expr $i+3-1] + } + 0x06 { # TEMP + ALT + set rec_temp [format %2.1f [expr [format %2.1f [expr (($byte0<<4) | (($byte1>>4)&0x0F))]]/10]] + set rec_alt [format %d [expr (($byte1&0x0F)<<8) | $byte2]] + # Move to next data set + set i [expr $i+3-1] + } + } + + # Convert metric temperature and altitude to Imperial units + if { $sync_use_metric_units == 0 } { + set rec_temp [format %2.1f [expr ($rec_temp*9)/5+32]] + set rec_alt [format %.0f [expr $rec_alt*3.28084]] + } + + # Write data set to file + puts $wp "[clock format $start_time -format {%d.%m.%Y}],[clock format $start_time -format {%H:%M:%S}],$rec_hr,$rec_temp,$rec_alt" + + # Calculate time for next data sample + set start_time [expr $start_time + $rec_interval] + } + } + close $wp + + after 500 + updateStatusSYNC "Data download finished." +} + + +# Erase memory on watch +proc sync_erase {} { + global w simpliciti_on + global sync_data_log_bytes + + # AP not enabled? + if { !$simpliciti_on } { return } + + # Transfer command to RF access point + BM_SYNC_SendCommand 6 + + updateStatusSYNC "Sent erase command to watch." + after 1000 + + updateStatusSYNC "Updating watch status." + sync_read_watch + + # Check if erase was successful + if { $sync_data_log_bytes != 0 } { + updateStatusSYNC "Error: Memory erase or status update failed. Please try again." + } +} + + +# Change all affected parameters to metric units / 24H time format +proc switch_to_metric_units {} { + global w + global sync_time_is_am sync_time_hours + global sync_date_year sync_date_month sync_date_day + global sync_temperature_24 sync_altitude_24 + global values_24 + global values_12 + global values_30 + global value_temperature_C + global values_altitude_meters + + # Update 24H time + update_time_12 + + # Reconfigure hours + $w.note.sync.f1.sb1 configure -textvariable sync_time_hours_24 -values $values_24 -postcommand { check_time } + $w.note.sync.ampm.rb1 configure -state disabled + $w.note.sync.ampm.rb2 configure -state disabled + + # Configure date fields + $w.note.sync.f2.l1 configure -text "Date (dd.mm.yyyy)" + $w.note.sync.f2.sb1 configure -textvariable sync_date_day -values $values_30 + $w.note.sync.f2.sb2 configure -textvariable sync_date_month -values $values_12 + + # Change temperature + $w.note.sync.f4.l1 configure -text "Temperature (\u00B0C)" + $w.note.sync.f4.sb1 configure -textvariable sync_temperature_24 -values $value_temperature_C + + # Change altitude + $w.note.sync.f5.l1 configure -text "Altitude (m)" + $w.note.sync.f5.sb1 configure -textvariable sync_altitude_24 -values $values_altitude_meters +} + +# Change all affected parameters to imperial units / 12H time format +proc switch_to_imperial_units {} { + global w + global sync_time_is_am sync_time_hours + global sync_date_year sync_date_month sync_date_day + global sync_temperature_12 sync_temperature_24 sync_altitude_12 + global values_12 + global values_30 + global value_temperature_F + global values_altitude_feet + + # Update 12H time + update_time_24 + + # Reconfigure hours + $w.note.sync.f1.sb1 configure -textvariable sync_time_hours_12 -values $values_12 -postcommand {check_time} + $w.note.sync.ampm.rb1 configure -state normal + $w.note.sync.ampm.rb2 configure -state normal + + # Change date + $w.note.sync.f2.l1 configure -text "Date (mm.dd.yyyy)" + $w.note.sync.f2.sb1 configure -textvariable sync_date_month -values $values_12 + $w.note.sync.f2.sb2 configure -textvariable sync_date_day -values $values_30 + + # Change temperature + $w.note.sync.f4.l1 configure -text "Temperature (\u00B0F)" + $w.note.sync.f4.sb1 configure -textvariable sync_temperature_12 -values $value_temperature_F + + # Change altitude + $w.note.sync.f5.l1 configure -text "Altitude (ft)" + $w.note.sync.f5.sb1 configure -textvariable sync_altitude_12 -values $values_altitude_feet +} + + +# Keep 24H and 12H time variable in sync +proc update_time_24 {} { + global sync_use_metric_units sync_time_is_am sync_time_hours_24 sync_time_hours_12 + + # Calculate 12H time + if { $sync_time_hours_24 == 0 } { + set sync_time_hours_12 [expr $sync_time_hours_24 + 12] + set sync_time_is_am 1 + } elseif { $sync_time_hours_24 <= 12 } { + set sync_time_hours_12 $sync_time_hours_24 + set sync_time_is_am 1 + } else { + set sync_time_hours_12 [expr $sync_time_hours_24 - 12] + set sync_time_is_am 0 + } +} + +# Keep 24H and 12H time variable in sync +proc update_time_12 {} { + global sync_use_metric_units sync_time_is_am sync_time_hours_24 sync_time_hours_12 + + # Calculate 12H time + if { $sync_time_is_am == 1 } { + if { $sync_time_hours_12 == 12 } { + set sync_time_hours_24 0 + } else { + set sync_time_hours_24 $sync_time_hours_12 + } + } else { + set sync_time_hours_24 [expr $sync_time_hours_12 + 12] + } +} + +# Trace altitude and temperature and update internal units +proc update_temperature args { + global sync_use_metric_units sync_temperature_24 sync_temperature_12 + + # Convert to internal format + if {([string is digit -strict $sync_temperature_24 ]==1) && ([string is digit -strict $sync_temperature_12 ]==1)} { + if { $sync_use_metric_units == 1 } { + set sync_temperature_12 [format "%2.0f" [expr ($sync_temperature_24*9/5)+32]] + } else { + set sync_temperature_24 [format "%2.0f" [expr ($sync_temperature_12-32)/9*5]] + } + } + if {([string is digit -strict $sync_temperature_24 ]==0) && ($sync_use_metric_units == 0)} { + set sync_temperature_24 [format "%2.0f" [expr ($sync_temperature_12-32)/9*5]] + } +} + +proc update_altitude args { + global sync_use_metric_units sync_altitude_24 sync_altitude_12 + + # Convert to internal format + if {([string is digit -strict $sync_altitude_24 ]==1) && ([string is digit -strict $sync_altitude_12 ]==1)} { + if { $sync_use_metric_units == 1 } { + set sync_altitude_12 [expr {round(($sync_altitude_24*3)+($sync_altitude_24*140/500))}] + } else { + set sync_altitude_24 [expr {round(($sync_altitude_12*1000/(3000+(140*1000/500))))}] + } + } + if {([string is digit -strict $sync_altitude_24 ]==0) && ($sync_use_metric_units == 0)} { + set sync_altitude_24 [expr {round(($sync_altitude_12*1000/(3000+(140*1000/500))))}] + } +} +trace add variable sync_temperature_24 write update_temperature +trace add variable sync_temperature_12 write update_temperature +trace add variable sync_altitude_24 write update_altitude +trace add variable sync_altitude_12 write update_altitude + +# ---------------------------------------------------------------------------------------- +# WBSL Update functions ------------------------------------------------------------------ + +# Prompt the user to select a file +proc open_file {} { + global select_input_file + global w + set types { + {{CC430 Firmware} {.txt} } + } + set select_input_file [tk_getOpenFile -title "Select File" -filetypes $types] +} + +# Safely execute WBSL service functions (non-overlapping) +proc call_wbsl_funcs {} { + global call_wbsl_timer call_wbsl_1 call_wbsl_2 + + if { $call_wbsl_timer == $call_wbsl_1 } { + get_wbsl_packet_status + set call_wbsl_1 [expr $call_wbsl_timer + 2] + } + if { $call_wbsl_timer == $call_wbsl_2 } { + get_wbsl_status + set call_wbsl_2 [expr $call_wbsl_timer + 3] + } + + incr call_wbsl_timer +} +# Start the Wireless update procedure, and put RF Access Point in RX mode +proc start_wbsl_ap {} { + global w + global simpliciti_on com_available + global wbsl_on select_input_file + global wbsl_ap_started + global fsize + global fp + global rData + global rData_index + global low_index + global list_count maxPayload + global ram_updater_downloaded + global wirelessUpdateStarted + + # init needed variables + set rData [list] + set rData_index 0 + set low_index 0 + + # No com port? + if { $com_available == 0} { return } + + # Testing REMOVE + # set ram_updater_downloaded 1 + + set ram_updater_file "ram_based_updater.txt" + + + if { $ram_updater_downloaded == 0 } { + # Check that the user has selected a file + if { [string length $select_input_file] == 0 } { + tk_dialog .dialog1 "No file selected" {Please select a watch firmware file (*.txt) to download to the watch.} info 0 OK + return + } + + # Check that the file selected by the user has the extension .txt + if { [string first ".txt" $select_input_file] == -1 } { + tk_dialog .dialog1 "Invalid .txt File" {The file selected is not a .txt file.} info 0 OK + return + } + } + + # First off check that the file trying to be downloaded has the right format + catch { file size $select_input_file } fsize + + # Check if the file exist + if { [string first "no such file" $fsize] != -1 } { + tk_dialog .dialog1 "File doesnt exist" {The selected file doesnt exist, please verify the path.} info 0 OK + return + } + + # Open the file for reading + catch { open $select_input_file r } fp + fconfigure $fp -translation binary + + # read the first character of the file, it should be an @ symbol + set test_at [read $fp 1] + + if { $test_at != "@" } { + tk_dialog .dialog1 "Invalid .txt File" {The .txt file is NOT formatted correctly.} info 0 OK + close $fp + return + } + + # read the complete file + set rawdata [read $fp $fsize] + close $fp + # Remove spaces, tabs, endlines from the data + regsub -all {[ \r\t\nq]*} $rawdata "" stripped_data + set lines 0 + # Divide the file by the symbol @ so that in each list there is data to be written consecutively at the address indicated by the first 2 bytes + set datainlist [split $stripped_data "@"] + set list_count 0 + set byteCounter 0 + + # For each line, convert the ASCII format in which is saved to Raw HEX format + foreach lines $datainlist { + set lines [join $lines] + regsub -all {[ \r\t\nq]*} $lines "" line + if { [catch { binary format H* $line } line] } { + tk_dialog .dialog1 "Invalid .txt File" {The .txt file is NOT formatted correctly.} info 0 OK + return + } + lappend rData $line + incr list_count + } + + # Check if the RAM_UPDATER is not yet on the watch so that we download this first + if { $ram_updater_downloaded == 0 } { + # init needed variables + set rData [list] + set rData_index 0 + set low_index 0 + + catch { file size $ram_updater_file} fsize + + # Check that the RAM Updater file is present on the GUI working directory + if { [string first "no such file" $fsize] != -1 } { + tk_dialog .dialog1 "No Updater File" {The RAM Updater File is not present on the working directory. Filename should be:ram_based_updater.txt} info 0 OK + return + } + + catch { open $ram_updater_file r } fp + fconfigure $fp -translation binary + + set test_at [read $fp 1] + + if { $test_at != "@" } { + tk_dialog .dialog1 "Invalid .txt File" {The ram_based_updater.txt file is NOT formatted correctly.} info 0 OK + close $fp + return + } + + set rawdata [read $fp $fsize] + close $fp + # Remove spaces, tabs, endlines from the data + regsub -all {[ \r\t\nq]*} $rawdata "" stripped_data + + set datainlist [split $stripped_data "@"] + set list_count 0 + set byteCounter 0 + foreach lines $datainlist { + set lines [join $lines] + regsub -all {[ \r\t\nq]*} $lines "" line + if { [catch { binary format H* $line } line] } { + tk_dialog .dialog1 "Invalid .txt File" {The ram_based_updater.txt file is NOT formatted correctly.} info 0 OK + return + } + lappend rData $line + incr list_count + } + } + # In AP mode? + if { $simpliciti_on == 1 } { + stop_simpliciti_ap + after 500 + } + + updateStatusWBSL "Starting Wireless Update." + after 200 + + # Link with WBSL transmitter + BM_WBSL_Start + after 100 + + + + + + set result [ BM_WBSL_GetMaxPayload ] + after 10 + set result [ BM_WBSL_GetMaxPayload ] + + if { $result < 2 } { + updateStatusWBSL "$result Failed to start Wireless Update." + return + } + + + + set maxPayload $result + + # Calculate the number of packets needed to be sent + + #initialize the number of packets + set fsize 0 + + # sum up all the bytes to be sent + foreach block $rData { + set byteCounter [string length $block] + set dByte [expr {double($byteCounter)}] + set dMax [expr {double($maxPayload)} ] + set temp [ceil [expr $dByte / $dMax]] + set fsize [expr $fsize + $temp] + } + + # Set on WBSL flag + set wbsl_on 1 + + # Cancel out first received data + set wbsl_ap_started 0 + + # Reconfig buttons + $w.note.wbsl.btnDwnld configure -text "Cancel Update" -command { stop_wbsl_ap } + +} + +# Stop the wireless update procedure +proc stop_wbsl_ap {} { + global w + global simpliciti_on com_available wbsl_on + global ram_updater_downloaded + global wirelessUpdateStarted + + # AP off? + if { $wbsl_on == 0 } { return } + + # Clear on flags + set wbsl_on 0 + set ram_updater_downloaded 0 + + after 500 + + BM_WBSL_Stop + + # Show that link is inactive + updateStatusWBSL "Wireless Update is off." + + update + + # Initialize the variable that tell us when the update procedure has been initiated by the Watch + set wirelessUpdateStarted 0 + + # Reconfig button and re-enable it in case the update procedure was started and it was disabled during the procedure + $w.note.wbsl.btnDwnld configure -text "Update Chronos Watch" -command { start_wbsl_ap } -state enabled + +} + +proc get_wbsl_packet_status {} { + global w + global wbsl_on + global wbsl_ap_started + global fsize + global fp + global rData + global rData_index + global low_index + global list_count maxPayload + global wbsl_opcode + global ram_updater_downloaded + global vcp_reply + + set status 0 + + # return if WBSL is not active + if { $wbsl_on == 0 } { return } + + # Check packet status + set status [ BM_WBSL_GetPacketStatus ] + + if { $status == 1 } { + # WBSL_DISABLED Not started by watch + return + } elseif { $status == 2 } { + # WBSL Is processing a packet + return + } elseif { $status == 4 } { + # Send the size of the file + set packets [expr {int($fsize)} ] + # send opcode 0 which is a info packet, which contains the total packets to be sent + catch { BM_WBSL_SendData 0 $packets } status + # The next packet will contain an address + set wbsl_opcode 1 + } elseif { $status == 8 } { + # Send the next data packet + + if { $rData_index < $list_count } { + # Choose the appropriate block of data + set data_block [lindex $rData $rData_index] + # Get the size of the block of data, to know if we have sent all of the data in this block and move to the next + set block_size [string length $data_block] + # Read MaxPayload Bytes from the list + set c_data [string range $data_block $low_index [expr $low_index + [expr $maxPayload - 1]]] + + # Send the read bytes to the dongle + set status [BM_WBSL_SendData $wbsl_opcode $c_data] + + #update the low index + set low_index [expr $low_index + $maxPayload] + + # Next packet is a normal data packet + set wbsl_opcode 2 + + if { $low_index >= $block_size } { + incr rData_index + set low_index 0 + # Next packet will include an address at the beginning of the packet + set wbsl_opcode 1 + } + } + } else { + # ERROR only the previous options should be returned + if { $ram_updater_downloaded == 0 } { + tk_dialog .dialog1 "Error in communication" {There was an error in the communication between the RF Access Point and the watch during the download to RAM. The watch should have reset itself. Please retry the update the same way as before.} info 0 OK + } else { + tk_dialog .dialog1 "Error in communication" {There was an error in the communication between the RF Access Point and the watch during the download to Flash. The watch is in a sleep mode now. Please press the "Update Chronos Watch" first and then press the down button on the watch to restart the update.} info 0 OK + } + after 200 + stop_wbsl_ap + return + } +} +# Get the global status of the AP, check if the state in which the GUI is, matches the state of the AP +proc get_wbsl_status {} { + global w vcp + global wbsl_on + global wbsl_ap_started wbsl_progress + global ram_updater_downloaded + global wirelessUpdateStarted + global wbsl_timer_flag + global vcp_reply fh + + set status 0 + + # return if WBSL is not active + if { $wbsl_on == 0 } { return } + + # Check if the flag has been set, which means the communication was lost while trying to link to download the update image + if { $wbsl_timer_flag == 1 } { + tk_dialog .dialog1 "Error in communication" {There was an error in the communication between the AP and the Watch while trying to start the download to Flash. The watch should have reset itself. Please retry the update the same way as before.} info 0 OK + wbsl_reset_timer + after 300 + stop_wbsl_ap + return + } + + # Update status box + set status [ BM_GetStatus1 ] + + + + if { $status == 9 } { + # just starting AP + updateStatusWBSL "Starting access point." + return + # Check if there was an error during the communication between the AP and the watch + } elseif { $status == 11 || $status == 12 } { + + if { $ram_updater_downloaded == 0 } { + tk_dialog .dialog1 "Error in communication" {There was an error in the communication between the RF Access Point and the watch during the download to RAM. The watch should have reset itself. Please retry the update the same way as before.} info 0 OK + } else { + tk_dialog .dialog1 "Error in communication" {There was an error in the communication between the RF Access Point and the watch during the download to Flash. The watch is in sleep mode now. Please press the "Update Chronos Watch" first and then press the down button on the watch to restart the update.} info 0 OK + } + after 300 + stop_wbsl_ap + + } elseif { $status == 10 } { + + # Read WBSL data from dongle + set data [ BM_WBSL_GetStatus ] + # if { $data == "" } { return } + + if { $wbsl_ap_started == 0} { + if { $ram_updater_downloaded == 0 } { + updateStatusWBSL "Access point started. Now start watch in rFbSL mode." +after 2000 + } else { + updateStatusWBSL "Starting to download update image to watch." + # We will now try to link with the watch to start downloading the Update Image, we need a timer in case the communication is lost + # while trying to link, since for the linking to start, the Dongle normally waits until the watch initiates the procedure. + wbsl_set_timer 1 + update + } + set wbsl_ap_started 1 + return + } else { + + # Check if data is valid + if { $data < 0 } { + return + } + + set wbsl_progress $data + + if { $wbsl_progress != 0 } { + + if { $wirelessUpdateStarted == 0 } { + + set wirelessUpdateStarted 1 + # Reconfig buttons + $w.note.wbsl.btnDwnld configure -state disabled + } + + if { $ram_updater_downloaded == 1 } { + # The download to FLASH has started, we don't need the timer to keep running + wbsl_reset_timer + update + updateStatusWBSL "Downloading update image to watch. Progress: [format %d $wbsl_progress]%" + + if { $wbsl_progress >= 100 } { + updateStatusWBSL "Image has been successfully downloaded to the watch" + after 1500 + stop_wbsl_ap + } + + } else { + updateStatusWBSL "Downloading the RAM Based Updater. Progress: [format %d $wbsl_progress]%" + +#puts $fh "\nDownloading the RAM Based Updater.\n" + + if { $wbsl_progress >= 100 } { + updateStatusWBSL "RAM Based Updater downloaded. Starting download of update image." + set ram_updater_downloaded 1 + BM_WBSL_Stop + set wbsl_on 0 + start_wbsl_ap + } + } + } + return + } + } +} +# Stop and reset the timer variables +proc wbsl_reset_timer { } { + global wbsl_timer_enabled + global wbsl_timer_counter + global wbsl_timer_flag + global wbsl_timer_timeout + + set wbsl_timer_counter 0 + set wbsl_timer_flag 0 + set wbsl_timer_timeout 0 + set wbsl_timer_enabled 0 + } +# Set the timeout variable and start the timer +proc wbsl_set_timer { timeout } { + global wbsl_timer_enabled + global wbsl_timer_counter + global wbsl_timer_flag + global wbsl_timer_timeout + + set wbsl_timer_counter 0 + set wbsl_timer_flag 0 + set wbsl_timer_timeout $timeout + set wbsl_timer_enabled 1 + } +# Called every 2.5 seconds, acts as the timer, it only counts if it's enabled +proc wbsl_simple_timer {} { + global wbsl_timer_enabled + global wbsl_timer_counter + global wbsl_timer_flag + global wbsl_timer_timeout + + if { $wbsl_timer_enabled == 0 } { + return + } + set wbsl_timer_counter [expr $wbsl_timer_counter+1] + if { $wbsl_timer_counter > $wbsl_timer_timeout } { + set wbsl_timer_flag 1 + set wbsl_timer_enabled 0 + } + +} + + + +# -------------------------------------------------------------------------- +# System procedures + + + +# Generic file browse dialog +proc fileDialog {w ent operation} { + global selected_type + + # Define default file types + set types { + {"eZ430-Chronos datalogger files" {.log} } + {"All files" *} + } + + # Use standard Windows file dialog + if {$operation == "open"} { + if {![info exists selected_type]} { + set selected_type "eZ430-Chronos datalogger files" + } + set file [tk_getOpenFile -filetypes $types -parent $w -typevariable selected_type] + } else { + set file [tk_getSaveFile -filetypes $types -parent $w -initialfile Untitled -defaultextension .log] + } + + # Copy selected file to entry + if {[string compare $file ""]} { + $ent delete 0 end + $ent insert 0 $file + $ent xview end + } +} + + +# Read variables from file +proc load_ini_file {} { + global w + global ini_file + global sync_use_metric_units + + # Try to open file with key definitions + catch { set fhandle [open "$ini_file" r] } res + + # Exit if file is missing + if { [string first "couldn't open" $res] == 0 } { return } + + fconfigure $fhandle -buffering line + + # Read file line by line and set global variables + while { ![eof $fhandle] } { + # Get next line + gets $fhandle line + # Split line + set data [ split $line "=" ] + # Verify that extracted strings consist of ASCII characters + if { [string is ascii [ lindex $data 0 ]] && [string is ascii [ lindex $data 1 ]] } { + # Set variable + set [ lindex $data 0 ] [ lindex $data 1 ] + } + } + + close $fhandle +} + + +# Save variables to file +proc save_ini_file { } { + global w + global ini_file + global sync_use_metric_units + + # Delete existing key file + catch { file delete "$ini_file" } + + # Break if directory is write only + catch { set fhandle [open "$ini_file" a] } res + if { [string first "permission denied" $res] == 0 } { + return + } + + fconfigure $fhandle -buffering line + + # Make a list of all variables to save + set varlist { sync_use_metric_units } + + # Walk through list and save variables to file + foreach { el } $varlist { + set val [expr $$el] + puts $fhandle "$el=$val" + } + + close $fhandle +} + +# ---------------------------------------------------------------------------------------- +# Status output functions ---------------------------------------------------------------- + +# Status output +proc updateStatusSYNC { msg } { + global w + $w.note.sync.status.l2 configure -text $msg + update +} +proc updateStatusWBSL { msg } { + global w + $w.note.wbsl.frame0b.lblStatusText configure -text $msg + update +} + + +# ---------------------------------------------------------------------------------------- +# Start / stop application --------------------------------------------------------------- + +# Exit program +proc exitpgm {} { + catch { stop_simpliciti_ap } + catch { BM_CloseCOM } + save_ini_file + exit 0 +} + + + + proc check_time args { + global sync_time_hours_12 sync_time_hours_24 sync_time_minutes sync_time_seconds + global w + + if { $sync_time_hours_12 > 12 } { set sync_time_hours_12 1 } + if { $sync_time_hours_24 > 23 } { set sync_time_hours_24 4 } + if { $sync_time_minutes > 59 } { set sync_time_minutes 30 } + if { $sync_time_seconds > 59 } { set sync_time_seconds 0 } + + if {[string is digit -strict $sync_time_hours_12 ]==0} { set sync_time_hours_12 1} + if {[string is digit -strict $sync_time_hours_24 ]==0} { set sync_time_hours_24 0} + if {[string is digit -strict $sync_time_minutes ]==0} { set sync_time_minutes 0} + if {[string is digit -strict $sync_time_seconds ]==0} { set sync_time_seconds 0} + update_time_24 +} + +proc check_date args { + global values_31 values_30 values_29 values_28 + global sync_date_day sync_date_month sync_date_year + global w + global sync_use_metric_units + set actual_day $sync_date_day + + # Check if we are using metric system, and switch the combobox + if { $sync_use_metric_units == 1 } { + set combobox $w.note.sync.f2.sb1 + } else { + set combobox $w.note.sync.f2.sb2 + } + + switch $sync_date_month { + 1 { $combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 3 {$combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 5 {$combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 7 { $combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 8 { $combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 10 {$combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 12 { $combobox configure -textvariable sync_date_day -values $values_31 -postcommand {check_date }} + + 4 { $combobox configure -textvariable sync_date_day -values $values_30 -postcommand {check_date }} + 6 { $combobox configure -textvariable sync_date_day -values $values_30 -postcommand {check_date }} + 9 { $combobox configure -textvariable sync_date_day -values $values_30 -postcommand {check_date } + set sync_date_day $actual_day + } + 11 { $combobox configure -textvariable sync_date_day -values $values_30 -postcommand {check_date }} + + ## A year that is divisible by 4 is a leap year. (Y % 4) == 0 + ## Exception to rule 1: a year that is divisible by 100 is not a leap year. (Y % 100) != 0 + ## Exception to rule 2: a year that is divisible by 400 is a leap year. (Y % 400) == 0 + 2 { + if {( [expr $sync_date_year%4] == 0) && ([ expr $sync_date_year%100 != 0] || [expr $sync_date_year%400 == 0 ])} { $combobox configure -textvariable sync_date_day -values $values_29 -postcommand {check_date } } \ + else { $combobox configure -textvariable sync_date_day -values $values_28 -postcommand {check_date } } + } + } + + # Set boundaries for variables + if { $sync_date_month > 12 || $sync_date_month < 0 } { set sync_date_month 1} + if { $sync_date_day < 0 || $sync_date_day > 31 } { set sync_date_day 1} + if { $sync_date_year < 0 } { set sync_date_year 2010 } + if {[string is digit -strict $sync_date_year]==0} { set sync_date_year 2010} +} + +proc check_altitude {} { + global w + global sync_altitude_24 sync_altitude_12 + global sync_use_metric_units + + if { $sync_use_metric_units == 1 } { + if {[string is digit -strict $sync_altitude_24]==0} { set sync_altitude_24 430} + } else { + if {[string is digit -strict $sync_altitude_12]==0} { set sync_altitude_12 1411} + } +} + +proc check_temperature {} { + global w + global sync_temperature_24 sync_temperature_12 + global sync_use_metric_units + if { $sync_use_metric_units == 1 } { + if {[string is digit -strict $sync_temperature_24]==0} { set sync_temperature_24 22} + } else { + if {[string is digit -strict $sync_temperature_12]==0} { set sync_temperature_12 71} + } +} + +proc check_data_log_interval {} { + global w + global sync_data_log_interval + + if {[string is digit -strict $sync_data_log_interval]==0} { set sync_data_log_interval 5} +} + + +# Load variables from ini file +load_ini_file + +# Reconfigure display +if { $sync_use_metric_units == 1 } { + switch_to_metric_units +} else { + switch_to_imperial_units +} + +# Exit program +if { $exit_prog == 1 } { exitpgm } + + +# ---------------------------------------------------------------------------------------- +# Periodic functions -------------------------------------------------------------------- + +proc every {ms body} {eval $body; after $ms [info level 0]} +every 10 { call_wbsl_funcs } +every 2500 { wbsl_simple_timer } + diff --git a/chronos-ti/Control Center/Chronos Data Logger/eZ430-Chronos_driver.tcl b/chronos-ti/Control Center/Chronos Data Logger/eZ430-Chronos_driver.tcl new file mode 100755 index 0000000..45e5f74 --- /dev/null +++ b/chronos-ti/Control Center/Chronos Data Logger/eZ430-Chronos_driver.tcl @@ -0,0 +1,358 @@ +set vcp 0 +set vcp_reply "" +set vcp_len 0 +set vcp_pending 0 +set vcp_debug 0 +if { $vcp_debug == 1 } { + set fh [open "log.txt" w] +} else { + set fh 0 +} + +# Send string through UART +proc SendCmd { command } { + global vcp vcp_reply vcp_len vcp_pending vcp_debug fh + + set timeout 0 + while { $vcp_pending == 1 } { + if { $vcp_debug == 1 } { puts $fh "Waiting for reply. Delaying command $command." } + after 5 + update + incr timeout + if {$timeout > 100} { + set vcp_pending 0 + if { $vcp_debug == 1 } { puts $fh "Terminating delay loop." } + } + } + update + if { $vcp_debug == 1 } { puts $fh "Sending $command" } + + # Send command + set vcp_reply "" + set vcp_pending 1 + set len [string length $command] + set vcp_len [expr $len / 2] + for {set i 0} {$i < $len} {incr i} { + set hex 0x[string range $command $i [expr $i+1]] + set letter [format %c $hex] + puts -nonewline $vcp $letter + incr i + } + puts -nonewline $vcp "\n" + flush $vcp +} + +# Get UART buffer content +proc GetReply {} { + global vcp vcp_reply vcp_len vcp_pending vcp_debug fh + + set cap [read $vcp] + binary scan $cap cu* valueList + foreach value $valueList { + append vcp_reply [format "0x%02X " $value] + } + if { $vcp_debug == 1 } { puts $fh "Received: $vcp_reply" } + flush $vcp + set vcp_pending 0 +} + +# Open COM port +proc BM_OpenCOM { port baudrate timeout dts rts } { + global vcp + catch { open $port w+ } vcp + if { [string first "couldn't" $vcp] != -1 } { + set vcp 0 + } else { + fconfigure $vcp -mode 115200,n,8,1 + fconfigure $vcp -blocking 0 + fconfigure $vcp -buffering full -encoding binary -translation binary + fileevent $vcp readable [list GetReply] + } +} + + +# Close COM port +proc BM_CloseCOM {} { + global vcp fh + close $vcp + flush $fh + close $fh +} + +# Reset hardware +proc BM_Reset {} { + SendCmd "FF0103" + after 15 +} + +# Set BlueRobin TX ID +proc BM_BR_SetID { id } { + SendCmd "FF0307[format %02X [expr $id & 0xFF]][format %02X [expr ($id>>8) & 0xFF]][format %02X [expr ($id>>16) & 0xFF]][format %02X [expr ($id>>24) & 0xFF]]" + after 15 +} + +# Start BlueRobin TX +proc BM_BR_Start {} { + SendCmd "FF0203" + after 15 +} + +# Stop BlueRobin TX +proc BM_BR_Stop {} { + SendCmd "FF0603" + after 15 +} + + +# Set BlueRobin heart rate value +proc BM_BR_SetHeartrate { hr } { + SendCmd "FF0504[format %02X [expr $hr & 0xFF]]" + after 15 +} + +# Set BlueRobin speed and distance value +proc BM_BR_SetSpeed { spd dist } { + SendCmd "FF0A06[format %02X [expr $spd & 0xFF]][format %02X [expr $dist & 0xFF]][format %02X [expr ($dist>>8) & 0xFF]]" + after 15 +} + +# Start SimpliciTI stack +proc BM_SPL_Start {} { + SendCmd "FF0703" + after 15 +} + +# Stop SimpliciTI stack +proc BM_SPL_Stop {} { + SendCmd "FF0903" + after 15 +} + +# Get 4 bytes payload from SimpliciTI stack +proc BM_SPL_GetData {} { + global vcp_reply + + SendCmd "FF080700000000" + after 15 + update + + while { [llength $vcp_reply] <= 6 } { + lappend vcp_reply 0x00 + } + + return [format "0x%02X" [expr ([lindex $vcp_reply 6]<<24) + ([lindex $vcp_reply 5]<<16) + ([lindex $vcp_reply 4]<<8) + [lindex $vcp_reply 3]]] +} + + +# Get HW status +proc BM_GetStatus {} { + global vcp_reply vcp_pending vcp_debug fh + SendCmd "FF000400" + after 15 + update + if { $vcp_debug == 1 } { puts $fh "BM_GetStatus = [lindex $vcp_reply 3]" } + return [lindex $vcp_reply 3] +} + + +# Simulate mouse clicks +proc BM_SetMouseClick { btn } { + global w + + set X [expr [winfo pointerx .]] + set Y [expr [winfo pointery .]] + set path [winfo containing $X $Y] + + switch $btn { + 1 { exec xdotool mousedown 1 + after 10 + exec xdotool mouseup 1 } + + 2 { exec xdotool mousedown 3 + after 10 + exec xdotool mouseup 3 } + + 3 { exec xdotool mousedown 1 + after 10 + exec xdotool mouseup 1 + after 10 + exec xdotool mousedown 1 + after 10 + exec xdotool mouseup 1 } + } +} + +# Simulate complex key events +proc BM_SetKey { keysymbol win alt ctrl shift } { + global w + + # Press keys and release them immediately + if { $win == 1 } { exec xdotool keydown "Super_L" } + if { $alt == 1 } { exec xdotool keydown "Alt_L" } + if { $ctrl == 1 } { exec xdotool keydown "Control_L" } + if { $shift == 1 } { exec xdotool keydown "Shift_L" } + if { $keysymbol > 0 } { exec xdotool keydown $keysymbol } + after 10 + if { $keysymbol > 0 } { exec xdotool keyup $keysymbol } + if { $shift == 1 } { exec xdotool keyup "Shift_L" } + if { $ctrl == 1 } { exec xdotool keyup "Control_L" } + if { $alt == 1 } { exec xdotool keyup "Alt_L" } + if { $win == 1 } { exec xdotool keyup "Super_L" } +} + + +# Start SimpliciTI sync mode +proc BM_SYNC_Start {} { + SndCmd "FF3003" + after 15 +} + +# Send sync command +proc BM_SYNC_SendCommand { ldata } { + + # take data from list and append it to command + set str "FF3116" + set i 0 + foreach value $ldata { + append str [format "%02X" $value] + incr i + } + + # byte stuff with 0x00 until 19 bytes are set + for {set j $i} {$j < 19} {incr j} { + append str "00" + } + + SendCmd $str + after 15 +} + +# Get sync buffer +proc BM_SYNC_ReadBuffer {} { + global vcp_reply + + SendCmd "FF3303" + after 15 + update + return [lrange $vcp_reply 3 22] +} + +# Get sync buffer state (empty/full) +proc BM_SYNC_GetBufferStatus {} { + global vcp_reply + + SendCmd "FF320400" + after 15 + update + return [lindex $vcp_reply 3] +} + + +# Get HW status +proc BM_GetStatus1 {} { + global vcp_reply vcp_pending vcp_debug fh + SendCmd "FF000400" + while { $vcp_pending == 1 } { update } + set reply [lindex $vcp_reply 3] + if { $vcp_debug == 1 } { puts $fh "BM_GetStatus1 = $reply" } + return $reply +} + +# BM_WBSL_Start +proc BM_WBSL_Start { } { + SendCmd "FF4003" + after 15 +} + +# BM_WBSL_Stop +proc BM_WBSL_Stop { } { + SendCmd "FF4603" + after 15 +} + +# BM_WBSL_GetMaxPayload +proc BM_WBSL_GetMaxPayload { } { + global vcp_reply vcp_pending vcp_debug fh + + SendCmd "FF490400" + while { $vcp_pending == 1 } { update } + if { $vcp_debug == 1 } { puts $fh "BM_WBSL_GetMaxPayload = [lindex $vcp_reply 3]" } + return [lindex $vcp_reply 3] +} + +# BM_WBSL_GetPacketStatus +proc BM_WBSL_GetPacketStatus { } { + global vcp_reply vcp_pending vcp_debug fh + + SendCmd "FF480400" + while { $vcp_pending == 1 } { update } + if { $vcp_debug == 1 } { puts $fh "BM_WBSL_GetPacketStatus = [lindex $vcp_reply 3]" } + return [lindex $vcp_reply 3] +} + +# BM_WBSL_GetStatus +proc BM_WBSL_GetStatus { } { + global vcp_reply vcp_pending vcp_debug fh + + SendCmd "FF410400" + while { $vcp_pending == 1 } { update } + if { $vcp_debug == 1 } { puts $fh "BM_WBSL_GetStatus = [lindex $vcp_reply 3]" } + return [lindex $vcp_reply 3] +} + +# BM_WBSL_SendData +proc BM_WBSL_SendData { data_or_info data } { + global vcp_reply vcp_pending vcp_debug fh + + if { $data_or_info == 0 } { + + set byte0 "00" + set byte1 [format %02X [expr $data&0xFF]] + set byte2 [format %02X [expr $data>>8]] + + set str "FF4706$byte0$byte1$byte2" + SendCmd $str + return 3 + + } else { + + # Send several packets until data has been transmitted + if { $data_or_info == 1 } { + set byte0 "01" + } else { + set byte0 "02" + } + + # Convert ASCII data string to hex values + set len 0 + set data_to_send "" + binary scan $data cu* valueList + foreach value $valueList { + append data_to_send [format "%02X" $value] + incr len + } + + set len1 [expr $len + 2] + set byte1 [format %02X [expr $len&0xFF]] + set data_to_send "$byte0$byte1$data_to_send" + + if { $vcp_debug == 1 } { puts $fh "\nBM_WBSL_SendData $data_to_send\n" } + + while { $len1 > 28 } { + # Send 28 bytes + SendCmd "FF471F[string range $data_to_send 0 55]" + # Cut away data that has been sent + set data_to_send [string range $data_to_send 56 [string length $data_to_send]] + set len1 [expr $len1-28] + update + } + + # Send last bytes + set len1 [expr [string length $data_to_send]/2 + 3] + SendCmd "FF47[format %02X $len1]$data_to_send" + update + return $len1 + } +} + + diff --git a/chronos-ti/Control Center/Chronos Data Logger/ez430-Chronos-DL.ini b/chronos-ti/Control Center/Chronos Data Logger/ez430-Chronos-DL.ini new file mode 100755 index 0000000..498517c --- /dev/null +++ b/chronos-ti/Control Center/Chronos Data Logger/ez430-Chronos-DL.ini @@ -0,0 +1 @@ +sync_use_metric_units=1 diff --git a/chronos-ti/Control Center/Chronos Data Logger/ram_based_updater.txt b/chronos-ti/Control Center/Chronos Data Logger/ram_based_updater.txt new file mode 100755 index 0000000..0e610cb --- /dev/null +++ b/chronos-ti/Control Center/Chronos Data Logger/ram_based_updater.txt @@ -0,0 +1,180 @@ +@1D30 +31 40 FE 2B 3C 40 88 29 3D 40 1C 01 B0 13 78 27 +3C 40 52 29 3D 40 84 1E 3E 40 36 00 B0 13 18 28 +B0 13 48 26 B0 13 20 28 20 20 00 20 20 20 20 20 +20 00 30 30 00 F5 60 B6 F2 63 D3 D7 70 F7 F3 00 +00 00 00 00 86 00 77 C7 95 E6 97 17 F3 67 05 F0 +87 85 75 46 C6 37 F5 06 D3 87 C4 C4 02 67 E3 B6 +10 08 08 08 F7 F7 F7 F7 20 40 04 80 7F 7F 7F 7F +7F 10 01 80 30 30 30 31 30 32 30 33 30 34 30 35 +30 36 30 37 30 38 30 39 31 30 31 31 31 32 31 33 +31 34 31 35 31 36 31 37 31 38 31 39 32 30 32 31 +32 32 32 33 32 34 32 35 32 36 32 37 32 38 32 39 +33 30 33 31 33 32 33 33 33 34 33 35 33 36 33 37 +33 38 33 39 34 30 34 31 34 32 34 33 34 34 34 35 +34 36 34 37 34 38 34 39 35 30 35 31 35 32 35 33 +35 34 35 35 35 36 35 37 35 38 35 39 36 30 36 31 +36 32 36 33 36 34 36 35 36 36 36 37 36 38 36 39 +37 30 37 31 37 32 37 33 37 34 37 35 37 36 37 37 +37 38 37 39 38 30 38 31 38 32 38 33 38 34 38 35 +38 36 38 37 38 38 38 39 39 30 39 31 39 32 39 33 +39 34 39 35 39 36 39 37 39 38 39 39 20 20 00 20 +20 44 4F 4E 45 00 20 20 46 41 49 4C 00 20 52 46 +42 53 4C 00 24 0A 24 0A 25 0A 26 0A 21 0A 22 0A +23 0A 25 0A 20 0A 20 0A 24 0A 2B 0A 2B 0A 2A 0A +29 0A 28 0A 27 0A 20 0A 24 0A 28 0A 07 00 AD 00 +BA 5E BA 11 05 00 AD 00 00 00 1B 15 7A 40 03 00 +4B 4A C2 93 A3 2A 76 20 B0 13 94 26 82 43 34 0F +B0 13 18 27 B0 13 D4 27 6D 43 5C 43 B0 13 CE 26 +6D 43 6C 43 B0 13 CE 26 6D 43 B0 13 FC 27 5D 43 +B0 13 12 28 D2 43 88 29 D2 43 9D 2A B0 13 BE 24 +5C 93 3D 20 E2 43 9D 2A 4D 4A 5C 43 B0 13 CE 26 +4D 4A 6C 43 B0 13 CE 26 4D 4A 4C 4A B0 13 CE 26 +B0 13 CC 1F 92 92 94 2A 96 2A 03 28 C2 93 A3 2A +26 20 B0 13 B2 20 5C 93 17 20 F2 90 64 00 A0 2A +0A 2C 4F 43 6E 43 5C 42 A0 2A 0D 43 B0 13 76 24 +0D 4C 5C 43 07 3C B0 13 F2 27 B0 13 10 28 3D 40 +6F 1E 6C 43 B0 13 32 25 F2 90 20 00 9D 2A 07 24 +92 92 94 2A 96 2A D6 2B C2 93 A3 2A DA 27 6D 42 +5C 43 B0 13 CE 26 6D 42 6C 43 B0 13 CE 26 6D 42 +B0 13 FC 27 B0 13 10 28 C2 43 88 29 92 92 94 2A +96 2A 0A 28 C2 93 A3 2A 07 24 B2 40 04 A5 20 01 +7B 53 87 23 1A 17 10 01 4B 93 FA 23 B0 13 F2 27 +3D 40 76 1E 6C 43 B0 13 32 25 F4 3F B0 13 A0 20 +B2 40 00 A5 44 01 B0 13 A0 20 B2 40 06 A5 40 01 +C2 43 E0 FF B0 13 A0 20 B2 40 10 A5 44 01 10 01 +3B 15 82 93 38 0F B2 C0 00 02 32 0F E2 93 9E 2A +32 20 3E 40 02 01 0D 43 3C 40 90 29 B0 13 54 27 +7A 40 3B 00 B0 13 78 20 4C 93 25 24 7C 40 3F 00 +B0 13 F2 25 C2 4C 90 29 39 40 91 29 6C 53 C2 4C +9C 2A 7B 90 41 00 05 28 B0 13 02 27 B0 13 8A 27 +12 3C E2 93 9C 2A 0B 28 B0 13 78 20 6B 93 F9 2B +B0 13 6A 20 19 53 F2 53 9C 2A 7B 53 F7 3F B0 13 +6A 20 D2 43 9F 2A 38 17 10 01 7C 40 3F 00 B0 13 +F2 25 C9 4C 00 00 10 01 4C 4A B0 13 F2 25 4B 4C +48 4B 4C 4A B0 13 F2 25 4B 4C 48 9C F9 23 10 01 +B0 13 A0 20 8C 4D 00 00 B0 13 A0 20 5C 43 10 01 +92 B3 44 01 FD 2F 10 01 B0 13 A0 20 CC 4D 00 00 +F3 3F 1B 15 4A 43 D2 53 A2 2A F2 90 05 00 A2 2A +05 28 F2 40 20 00 9D 2A 4C 43 5F 3C B0 13 98 25 +3B 40 96 2A D2 93 9F 2A 07 24 C2 93 A3 2A 04 24 +2D 4B 3D 53 5C 43 4E 3C D2 93 9F 2A 4D 20 C2 43 +9F 2A 5F 42 90 29 5F 4F 92 29 7F F0 80 00 D2 92 +A1 2A 92 29 41 20 5E 42 93 29 C2 93 A3 2A 14 20 +4F 93 10 24 C2 43 A2 2A 5F 42 94 29 47 18 0F 5F +0E 5F 82 4E 94 2A 3D 43 5C 43 B0 13 FC 24 D2 43 +A3 2A 2A 3C 3D 43 25 3C 4F 93 22 24 5F 42 94 29 +47 18 0E 5E 0F 5E 2F 9B CB 23 B0 13 9A 22 5C 93 +17 20 C2 43 A2 2A 2D 4B 5C 43 B0 13 FC 24 92 53 +96 2A 2C 4B 5C 06 0F 4C 5C 0A 0F 5C 0C 5C 0C 5F +1E 42 94 2A B0 13 B6 26 C2 4C A0 2A 5A 43 04 3C +2D 4B 4C 43 B0 13 FC 24 4C 4A 1A 17 10 01 1B 15 +0B 4C 4A 4D B0 13 02 27 4E 4A 0D 4B 7C 40 7F 00 +B0 13 68 25 6A 42 07 3C 3C 40 0F 00 B0 13 E8 26 +B0 13 E8 27 7A 53 7C 40 34 00 B0 13 14 22 A2 B3 +30 0F FD 2B 92 C3 32 0F 7C 40 35 00 B0 13 14 22 +3C 40 19 00 B0 13 E8 26 B0 13 E8 27 92 B3 32 0F +0A 28 92 C3 32 0F 92 B3 30 0F FD 2B 7C 40 3B 00 +B0 13 14 22 0D 3C 7C 40 36 00 B0 13 14 22 7C B0 +70 00 F9 23 7C 40 3A 00 B0 13 14 22 4A 93 CC 23 +1A 17 10 01 3B 15 4B 4C 4C 43 7B 90 BD 00 06 24 +7B 90 31 00 38 28 7B 90 3D 00 35 2C 08 42 32 C2 +03 43 B2 C0 40 00 02 0F B0 13 06 28 7B 90 31 00 +25 28 7B 90 3D 00 22 2C B0 13 F2 25 4A 4C 7D 40 +29 00 4C 43 B0 13 72 26 C2 4B 11 0F A2 B2 30 0F +10 28 7B 90 32 00 0D 24 7B 90 39 00 0A 24 7B 90 +38 00 07 24 A2 B2 30 0F FD 2F 3F 40 C1 0C 3F 53 +FE 2F 4D 4A 4C 43 B0 13 72 26 02 3C C2 4B 11 0F +5C 42 21 0F 02 48 38 17 10 01 2A 15 5C 43 5A 42 +90 29 3A 50 FB FF 7D 40 06 00 D2 93 95 29 0B 20 +5E 42 96 29 47 18 0E 5E 5F 42 97 29 0E 5F 82 4E +92 2A 2A 83 7D 42 B0 13 BA 27 0A 93 1A 24 1C 42 +92 2A 3C 90 00 80 09 28 08 4C 09 43 08 5A 09 63 +19 93 05 28 02 20 18 93 02 28 4C 43 0A 3C 4E 4D +3E 50 90 29 4D 4A B0 13 76 23 5C 93 02 20 82 5A +92 2A B2 40 00 A5 40 01 B2 40 10 A5 44 01 28 17 +10 01 0A 12 6C 92 2D 28 7C 90 14 00 2A 2C 7D 90 +30 00 07 28 7D 90 5B 00 09 2C 4D 4D 5A 4D 35 1D +06 3C 7D 90 2D 00 02 20 6A 43 01 3C 4A 43 7C 90 +0B 00 11 28 4F 4A 43 19 4F 10 43 18 4A 5A 4A DF +7C 90 0B 00 08 20 7D 90 31 00 03 24 7D 90 4C 00 +02 20 7A 40 80 00 4C 4C 4F 4E 5E 4C 90 1D B0 13 +C8 27 3A 41 10 01 5B 15 08 4C 09 4E 5C 43 0A 48 +0B 43 0E 48 0F 43 46 4D 0A 56 0B 63 02 3C 1E 53 +0F 63 0F 9B 03 28 18 20 0E 9A 16 2C 0C 4E 58 B3 +08 20 06 4A 07 4B 36 53 37 63 0E 96 06 20 0F 97 +04 20 7D 49 B0 13 A8 20 05 3C 3D 49 B0 13 90 20 +1E 53 0F 63 5C 93 E3 27 56 17 10 01 F2 D0 03 00 +4A 02 B2 F0 3E FF 6C 01 B2 D0 0C 00 6C 01 82 43 +66 01 B2 40 44 00 68 01 32 D0 40 00 82 43 60 01 +B2 40 50 00 62 01 B2 40 6E 11 64 01 32 C0 40 00 +3F 40 22 F4 03 43 0E 43 3F 53 3E 63 FD 2F B2 F0 +F0 FF 6E 01 A2 C3 02 01 A2 B3 02 01 F8 2F 80 00 +1E 26 7E E3 5F 93 05 20 6E FC 4E DD CC 4E 00 00 +10 01 4F 93 03 20 CC FE 00 00 10 01 6F 93 09 20 +CC FE 00 00 CC FE 20 00 CC DD 00 00 CC DD 20 00 +10 01 7F 90 03 00 08 20 4F 4E 6F FC 4F DD CC 4F +00 00 CC FE 20 00 10 01 6F 92 04 20 CC FE 00 00 +CC FE 20 00 10 01 3B 15 0A 4C 0B 4D 48 4E 39 40 +98 2A 2E 43 3D 40 62 1D 0C 49 B0 13 66 27 48 93 +13 24 78 90 03 00 10 2C 0B 93 0E 20 3A 90 64 00 +0B 2C 4E 48 4D 48 3D E3 1D 53 0A 5A 0D 5A 3D 50 +A6 1D 0C 49 B0 13 66 27 0C 49 38 17 10 01 0A 12 +4A 43 7D 42 3C 40 7A 29 B0 13 8E 21 B0 13 98 25 +D2 93 9F 2A 10 20 C2 43 9F 2A D2 93 93 29 05 20 +5F 42 90 29 CF 93 92 29 02 38 4C 43 05 3C D2 42 +92 29 A1 2A 5A 43 4C 4A 3A 41 10 01 4E 4C 3C 40 +09 00 B0 13 E8 26 B0 13 E8 27 D2 42 A1 2A 83 29 +C2 4E 85 29 0F 4D 47 19 0F 10 7F F0 7F 00 C2 4F +86 29 C2 4D 87 29 7D 40 06 00 3C 40 82 29 80 00 +8E 21 3B 15 0A 4D 6C 93 05 20 7B 40 0B 00 78 40 +06 00 03 3C 7B 40 06 00 68 43 49 43 09 3C 5E 43 +0F 4A 0F 59 6D 4F 4C 4B 4C 59 B0 13 12 23 59 53 +49 98 F5 2B 38 17 10 01 0A 12 0A 42 B0 13 40 27 +6F 4D 0C 5F 82 4C 10 0F 5F 43 07 3C B0 13 DE 27 +0C 4D 0C 5F E2 4C 10 0F 5F 53 4F 9E F7 2B C2 93 +20 0F 02 4A 3A 41 10 01 B0 13 8A 27 3C 40 00 40 +B0 13 E8 26 06 3C B2 B0 00 02 32 0F 02 28 B0 13 +F0 1F 92 B3 44 03 03 2C D2 93 9F 2A F4 23 B0 13 +9A 27 80 00 02 27 21 83 82 43 32 0F 7C 40 30 00 +B0 13 14 22 81 43 00 00 02 3C 91 53 00 00 B1 90 +64 00 00 00 FA 2B B0 13 AA 27 82 43 06 0F 21 53 +10 01 0F 42 32 C2 03 43 B0 13 06 28 7C 90 2F 00 +03 28 7C 90 3E 00 03 20 7C D0 80 00 02 3C 7C D0 +C0 00 C2 4C 13 0F 5C 42 20 0F 02 4F 10 01 B2 D0 +06 00 06 0A B2 40 1D 7B 00 0A B2 40 ED 00 04 0A +F2 D0 E0 00 4A 02 F2 D0 E0 00 44 02 B2 43 0A 0A +B2 40 FF 00 0C 0A 10 01 B2 40 80 5A 5C 01 32 C2 +03 43 B0 13 CC 23 B0 13 D4 27 3C 40 33 73 B0 13 +E8 26 B0 13 E8 27 B0 13 BA 1E B2 40 04 A5 20 01 +F4 3F 21 83 0E 42 B0 13 40 27 4D 4D 0C 5D 82 4C +10 0F B0 13 DE 27 5F 42 20 0F 81 4F 00 00 02 4E +21 53 10 01 C2 43 88 29 C2 43 A0 2A 82 43 96 2A +82 43 94 2A C2 43 A2 2A C2 43 A3 2A 82 43 32 0F +10 01 7C F3 7E F3 0F 4E 0D 4C 0E 43 1C 43 0D 5D +0E 6E 0E 9F 01 28 0E 8F 0C 6C F9 2B 10 01 0A 12 +7C 90 14 00 07 2C 4C 4C 5A 4C 90 1D 4F 4D 4E 4A +B0 13 C8 27 3A 41 10 01 3C 90 00 80 02 28 3C 40 +FF 7F 82 4C 54 03 92 C3 44 03 B2 D0 24 01 40 03 +10 01 D2 43 9E 2A B0 13 AA 27 7C 40 3A 00 B0 13 +14 22 82 43 32 0F 10 01 3D 40 58 1D 5C 43 B0 13 +32 25 3D 40 5B 1D 6C 43 80 00 32 25 0A 12 21 83 +0A 4C 81 4A 00 00 0D 41 5C 43 B0 13 24 28 F9 3F +32 C2 03 43 B0 13 06 28 4C 4C 3C D0 40 00 47 18 +0C 5C 10 01 0F 4C 04 3C CF 4D 00 00 1F 53 3E 53 +0E 93 FA 23 10 01 0F 4C 04 3C FF 4D 00 00 1F 53 +3E 53 0E 93 FA 23 10 01 0F 4C 0F 5D 03 3C CC 43 +00 00 1C 53 0C 9F FB 23 10 01 82 43 32 0F E2 43 +9E 2A 7C 40 34 00 80 00 14 22 92 C3 44 03 B2 F0 +CF FF 40 03 82 43 50 03 10 01 7C 40 36 00 B0 13 +14 22 7C B0 70 00 F9 23 10 01 B2 40 00 A5 44 01 +B2 40 40 A5 40 01 10 01 4D 4A 0C 5C 1C 4C 52 29 +80 00 22 24 3D 40 7D 1E 6C 43 80 00 32 25 B2 B0 +20 00 02 0F FC 2B 10 01 92 B3 44 03 FD 2B 80 00 +9A 27 3D 40 6C 1E 5C 43 80 00 32 25 4C 4A B0 13 +CE 26 80 00 C6 25 B2 B0 10 00 02 0F FC 2B 10 01 +4D 43 4C 43 80 00 CE 26 80 00 66 27 80 00 2C 27 +80 00 1C 28 10 01 +@FFFE +30 1D +q diff --git a/chronos-ti/Control Center/readme.txt b/chronos-ti/Control Center/readme.txt new file mode 100755 index 0000000..5835bfb --- /dev/null +++ b/chronos-ti/Control Center/readme.txt @@ -0,0 +1,37 @@ +1. General notes + +The eZ430-Chronos graphical user interface and serial port driver has been developed and +tested under Ubuntu 8.10. + +The eZ430-Chronos graphical user interface is based on TCL/Tk. + +If your Linux distribution does not already include TCL/Tk, you can +install it with easily the apt-get command: + + sudo apt-get install tcl8.5 + sudo apt-get install tk8.5 + +In order to generate keyboard events and mouse clicks through the watch buttons, +the tool xdotool is called from the script. Please install it with the apt-get command: + + sudo apt-get install xdotool + + +2. Operating instructions + + - Plug in the RF Access Point into a USB port + + - Check the /dev directory. A new entry should appear after some seconds ("/dev/ttyACM0") + + - If you see that the RF Access Point gets assigned to a different device + (e.g. ttyACM1), either remove the serial device that occupy this slot (e.g. a modem), + or change the script file variable "com". + + - Make sure that the script file is executable + + > chmod u+x ./eZ430-Chronos_CC_1_2.tcl + + - Now start the script by simply executing it from a terminal window, e.g. + + > ./eZ430-Chronos_CC_1_2.tcl + \ No newline at end of file diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, BOM, 433 V1.0b.pdf b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, BOM, 433 V1.0b.pdf new file mode 100755 index 0000000..2e62f43 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, BOM, 433 V1.0b.pdf differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, BOM, 868 V1.3d.pdf b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, BOM, 868 V1.3d.pdf new file mode 100755 index 0000000..3cff5b4 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, BOM, 868 V1.3d.pdf differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, BOM, 915 V1.3d.pdf b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, BOM, 915 V1.3d.pdf new file mode 100755 index 0000000..0d581d0 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, BOM, 915 V1.3d.pdf differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Gerbers, 433 V1.0.zip b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Gerbers, 433 V1.0.zip new file mode 100755 index 0000000..34a9884 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Gerbers, 433 V1.0.zip differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Gerbers, 868, 915 V1.3d.zip b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Gerbers, 868, 915 V1.3d.zip new file mode 100755 index 0000000..099d726 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Gerbers, 868, 915 V1.3d.zip differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Schematics, 433 V1.0.pdf b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Schematics, 433 V1.0.pdf new file mode 100755 index 0000000..67a2f9a Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Schematics, 433 V1.0.pdf differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Schematics, 868, 915 V1.3.pdf b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Schematics, 868, 915 V1.3.pdf new file mode 100755 index 0000000..f8dcfc6 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Access Point/eZ430-Chronos Access Point, Schematics, 868, 915 V1.3.pdf differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Debug Interface/eZ430-Chronos Debug IF BOM V2.0.pdf b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Debug Interface/eZ430-Chronos Debug IF BOM V2.0.pdf new file mode 100755 index 0000000..6cb6862 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Debug Interface/eZ430-Chronos Debug IF BOM V2.0.pdf differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Debug Interface/eZ430-Chronos, Debug IF, Gerbers, V2.0.zip b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Debug Interface/eZ430-Chronos, Debug IF, Gerbers, V2.0.zip new file mode 100755 index 0000000..33e3e09 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Debug Interface/eZ430-Chronos, Debug IF, Gerbers, V2.0.zip differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Debug Interface/eZ430-Chronos, Debug IF, Schematic, V2.0.pdf b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Debug Interface/eZ430-Chronos, Debug IF, Schematic, V2.0.pdf new file mode 100755 index 0000000..2c9bd65 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Debug Interface/eZ430-Chronos, Debug IF, Schematic, V2.0.pdf differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, BOM 433 V1.1.pdf b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, BOM 433 V1.1.pdf new file mode 100755 index 0000000..b9f6b51 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, BOM 433 V1.1.pdf differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, BOM, 868, 915 V1.5f.pdf b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, BOM, 868, 915 V1.5f.pdf new file mode 100755 index 0000000..2ac4833 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, BOM, 868, 915 V1.5f.pdf differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Gerbers, 433 V1.1.zip b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Gerbers, 433 V1.1.zip new file mode 100755 index 0000000..a28c9c0 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Gerbers, 433 V1.1.zip differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Gerbers, 868, 915 V1.5.zip b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Gerbers, 868, 915 V1.5.zip new file mode 100755 index 0000000..c14e2b6 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Gerbers, 868, 915 V1.5.zip differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Schematics, 433 V1.1.pdf b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Schematics, 433 V1.1.pdf new file mode 100755 index 0000000..7ead91c Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Schematics, 433 V1.1.pdf differ diff --git a/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Schematics, 868, 915 V1.5.pdf b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Schematics, 868, 915 V1.5.pdf new file mode 100755 index 0000000..fbe9df9 Binary files /dev/null and b/chronos-ti/Documentation/Schematics, Layout & BOM/eZ430-Chronos Watch/eZ430-Chronos Watch, Schematics, 868, 915 V1.5.pdf differ diff --git a/chronos-ti/Documentation/slau292c.pdf b/chronos-ti/Documentation/slau292c.pdf new file mode 100755 index 0000000..6dd8ed7 Binary files /dev/null and b/chronos-ti/Documentation/slau292c.pdf differ diff --git a/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_433MHz.txt b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_433MHz.txt new file mode 100755 index 0000000..6fb7a9a --- /dev/null +++ b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_433MHz.txt @@ -0,0 +1,1937 @@ +@8000 +5A 14 31 80 1A 00 CA 0E B0 13 44 E0 0E 43 3F 40 +C8 42 B0 13 C6 BE 81 4C 12 00 81 4D 14 00 CC 0A +B0 13 9A E6 0E 43 3F 40 20 41 B0 13 C6 BE 81 4C +16 00 81 4D 18 00 36 40 11 00 37 40 32 1D 0A 43 +28 47 19 47 02 00 CC 08 CD 09 1E 41 12 00 1F 41 +14 00 B0 13 A4 D4 0C 93 0A 38 81 48 08 00 81 49 +0A 00 27 52 1A 53 16 83 EB 23 4A 4A 03 3C 4A 4A +0A 93 7E 24 3A 90 0F 00 3D 38 3A 90 0F 00 23 24 +B0 13 86 82 1E 42 72 1D 1F 42 74 1D B0 13 E0 9E +C9 0C CA 0D 1C 42 72 1D 1D 42 74 1D 1E 42 6E 1D +1F 42 70 1D B0 13 3A 82 1C 42 70 F6 1C 82 6E F6 +B0 13 4C 82 1C 42 70 F6 B0 13 60 82 81 4C 00 00 +81 4D 02 00 73 3C B0 13 24 82 C9 0C CA 0D 1C 42 +6E 1D 1D 42 70 1D 1E 41 08 00 1F 41 0A 00 B0 13 +3A 82 1C 42 6E F6 1C 82 6C F6 B0 13 4C 82 1C 42 +6C F6 E2 3F C9 0A 59 02 16 49 4E F6 5A 06 17 4A +32 1D 18 4A 34 1D B0 13 24 82 C5 0C CA 0D B0 13 +86 82 CE 07 CF 08 B0 13 E0 9E 3E 40 34 80 3F 40 +37 3A B0 13 10 82 CC 05 CD 0A B0 13 3A B7 C5 0C +CA 0D CC 07 CD 08 1E 41 08 00 1F 41 0A 00 B0 13 +90 82 CC 05 CD 0A B0 13 C6 BE C8 0C CA 0D 1C 49 +50 F6 0C 86 B0 13 74 DE CE 0C CF 0D CC 08 CD 0A +B0 13 3A B7 C9 0C CA 0D CC 06 B0 13 60 82 A6 3F +B0 13 86 82 1E 42 32 1D 1F 42 34 1D B0 13 E0 9E +C9 0C CA 0D 1C 42 36 1D 1D 42 38 1D 1E 42 32 1D +1F 42 34 1D B0 13 3A 82 1C 42 52 F6 1C 82 50 F6 +B0 13 56 82 81 4C 00 00 81 4D 02 00 2C 41 1D 41 +02 00 B0 13 6A 82 3E 40 F4 FD 3F 40 D4 3B B0 13 +10 82 1C 41 16 00 1D 41 18 00 B0 13 C6 BE 81 4C +04 00 81 4D 06 00 1C 41 04 00 1D 41 06 00 B0 13 +6A 82 2E 41 1F 41 02 00 B0 13 3A B7 81 4C 0C 00 +81 4D 0E 00 1C 41 0C 00 1D 41 0E 00 B0 13 72 D7 +81 4C 10 00 1C 41 10 00 31 50 1A 00 55 16 10 01 +B0 13 3A B7 CE 0C CF 0D 0C 43 3D 40 80 3F B0 13 +90 82 10 01 1C 41 16 00 1D 41 18 00 1E 41 0C 00 +1F 41 0E 00 B0 13 E0 9E 10 01 B0 13 90 82 CC 09 +CD 0A B0 13 C6 BE C9 0C CA 0D 10 01 B0 13 56 82 +C9 0C CA 0D 10 01 B0 13 78 82 B0 13 3A B7 10 01 +B0 13 78 82 B0 13 E6 9E 10 01 3E 40 E7 6F 3F 40 +63 3B B0 13 3A B7 10 01 B0 13 74 DE CE 0C CF 0D +CC 09 CD 0A 10 01 1C 41 16 00 1D 41 18 00 10 01 +B0 13 E0 9E CE 0C CF 0D 10 01 4A 14 31 82 B0 13 +C2 EE C8 0C CF 08 3F 50 FF 7F 81 4F 06 00 91 41 +06 00 04 00 82 43 46 1E 4A 43 49 43 4C 49 B0 13 +0C 85 1F 4C 18 00 1F 83 1D 24 1F 83 14 24 D2 B3 +D6 1E 47 24 1E 42 4E 1E 1F 42 50 1E 3E F3 3F F0 +FF 00 1F 9C 02 00 3D 20 2E 9C 3B 20 D2 C3 D6 1E +82 43 46 1E 36 3C 5A 53 B0 13 DA D2 4C 93 31 24 +C7 09 2F 3C B0 13 58 EA C6 0C CC 09 B0 13 C8 D8 +4C 93 0C 20 CC 09 CD 06 CE 08 B0 13 4C A2 1F 42 +44 1E AF 93 18 00 09 20 5A 53 07 3C 82 43 46 1E +E2 B2 D6 1E 02 20 B0 13 12 DF 1F 42 44 1E 9F 93 +18 00 0F 20 CF 01 3F 50 03 00 81 4F 00 00 CC 06 +CD 01 3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 +E4 D1 59 53 AB 27 4A 93 50 24 92 93 46 1E 18 38 +4C 47 B0 13 0C 85 CC 07 B0 13 84 B6 4C 93 10 24 +5A 83 CF 01 3F 50 03 00 81 4F 00 00 7C 42 CD 01 +3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 E4 D1 +4A 93 33 24 1F 42 42 1E 0F 88 1F 93 2C 34 E2 B2 +D6 1E 0D 20 E2 D2 D6 1E C2 93 4B 1E 04 20 B2 50 +E0 7F 42 1E 20 3C B2 50 C0 53 42 1E 1C 3C E2 C2 +D6 1E C2 93 4B 1E 03 24 3F 40 40 6C 02 3C 3F 40 +20 00 82 5F 42 1E 49 43 4C 49 B0 13 0C 85 AC 93 +18 00 07 20 CC 09 B0 13 CE E2 4C 93 02 20 5A 83 +04 24 59 53 F1 27 4A 93 0E 20 F2 F0 F9 00 D6 1E +91 91 06 00 04 00 02 24 0E 43 08 3C B0 13 C8 EF +A2 43 9A 1E 70 3C E2 D3 D6 1E 1E 43 1F 41 06 00 +0F 88 0F 93 54 38 0E 93 3C 24 E2 B2 D6 1E 16 20 +1F 41 06 00 1F 82 42 1E 3F 80 42 00 0F 93 31 38 +F2 40 07 00 98 1E C2 43 99 1E F2 D0 18 00 D6 1E +92 42 42 1E 94 1E A2 43 9A 1E 4B 3C 1F 41 06 00 +0F 88 3F 80 42 00 1F 93 1C 38 F2 40 07 00 98 1E +C2 43 99 1E F2 D0 18 00 D6 1E 1F 41 06 00 1F 82 +42 1E 3F 80 42 00 0F 93 05 34 1F 41 06 00 3F 80 +42 00 02 3C 1F 42 42 1E 82 4F 94 1E 92 43 9A 1E +28 3C D2 41 02 00 98 1E D2 41 03 00 99 1E 5F 42 +D6 1E 7F C2 7F D0 10 00 C2 4F D6 1E 92 41 06 00 +94 1E 92 41 04 00 96 1E 82 43 9A 1E 12 3C D2 91 +02 00 98 1E 09 24 D2 41 02 00 98 1E D2 41 03 00 +99 1E F2 D0 10 00 D6 1E 92 41 04 00 94 1E 92 43 +9A 1E D2 C3 D6 1E 31 52 46 16 10 01 3D 40 1C 00 +B0 13 38 EC 1C 52 D4 F6 82 4C 44 1E 10 01 4F 14 +B2 F0 EF FF 42 03 92 C3 42 03 B2 80 00 80 52 03 +B2 D0 10 00 42 03 B0 13 76 CE B2 D0 10 00 8C 1C +B0 13 3A EF 4C 93 EE 20 B0 13 2E EF 4C 93 EA 20 +E2 93 2E 1E 04 28 A2 D3 0A 1E B0 13 5C E9 E2 93 +E0 1E 11 20 5E 42 E1 1E CF 0E 5F 83 C2 4F E1 1E +4E 93 06 20 F2 40 0A 00 E1 1E B0 13 4C F0 03 3C +B2 D0 10 00 0A 1E B0 13 46 EF 4C 93 02 24 92 D3 +0A 1E B0 13 4E ED 4C 93 0D 24 92 83 24 1E 04 20 +B0 13 3C EA B0 13 62 87 F2 B0 40 00 01 02 02 24 +A2 D2 0A 1E B0 13 3C ED 4C 93 12 24 92 83 60 1E +09 20 B0 13 E0 DF B0 13 62 87 7C 40 1F 00 4D 43 +B0 13 02 E9 F2 B0 20 00 01 02 02 24 B2 D2 0A 1E +B0 13 22 EF 4C 93 02 24 B0 13 32 BE B2 B0 20 00 +08 1E 10 24 5E 42 9E 1E CF 0E 5F 83 C2 4F 9E 1E +4E 93 08 20 92 D3 0C 1E B2 D0 20 00 0C 1E F2 40 +0F 00 9E 1E 82 93 0C 1E 0F 24 92 B3 0C 1E 08 20 +A2 B2 0C 1E 09 24 A2 C2 0C 1E 92 D3 8C 1C 04 3C +92 C3 0C 1E A2 D3 0C 1E A2 B3 08 1E 0E 24 1F 42 +26 1E 1E 42 28 1E 1F 82 2A 1E 1E 72 2C 1E 03 20 +3F 90 1F 00 02 28 92 D3 08 1E D2 93 7B 1E 0E 20 +E2 92 7A 1E 03 2C D2 53 7A 1E 08 3C F2 C2 03 02 +F2 C2 05 02 C2 43 7A 1E C2 43 7B 1E E2 B3 01 02 +03 24 D2 B3 01 02 2F 20 C2 43 C2 1E E2 B2 01 02 +11 24 D2 53 78 1E F2 90 03 00 78 1E 0D 28 B2 D0 +20 00 76 1E B2 F0 7F FF 76 1E C2 43 78 1E E2 C2 +19 02 02 3C C2 43 78 1E E2 B3 01 02 11 24 D2 53 +79 1E F2 90 03 00 79 1E 47 28 B2 D0 40 00 76 1E +B2 F0 FF FE 76 1E C2 43 79 1E E2 C3 19 02 3C 3C +C2 43 79 1E 39 3C D2 53 C2 1E 5F 42 C2 1E 5F 83 +7F 90 03 00 31 28 1F 42 08 1E 2F C2 2E 42 1E C2 +08 1E 0E DF 82 4E 08 1E 92 D3 0C 1E A2 B2 08 1E +04 20 B2 D0 10 00 0C 1E 02 3C B2 D2 0C 1E C2 43 +C2 1E 1A 3C 82 93 EC 1C 04 20 F2 D0 20 00 F0 1C +02 3C 92 83 EC 1C B2 90 03 00 EA 1C 0D 20 C2 93 +EE 1C 08 20 7C 40 5A 00 3D 40 28 F5 5E 43 B0 13 +70 AF 02 3C D2 83 EE 1C B1 C0 D0 00 14 00 4B 16 +00 13 7C 40 46 00 3D 40 8C F5 5E 43 B0 13 70 AF +6C 43 4D 43 B0 13 02 E9 7C 40 03 00 4D 43 B0 13 +02 E9 10 01 4A 14 B0 13 E6 EE 82 43 08 0A 7C 40 +46 00 3D 40 5C F5 5E 43 B0 13 70 AF 7C 40 5B 00 +3D 40 62 F5 5E 43 B0 13 70 AF 7C 40 1E 00 B0 13 +AE 89 7C 40 13 00 B0 13 AE 89 7C 40 14 00 B0 13 +AE 89 7C 40 15 00 B0 13 AE 89 7C 40 16 00 B0 13 +AE 89 7C 40 17 00 B0 13 AE 89 7C 40 18 00 B0 13 +AE 89 7C 40 19 00 B0 13 AE 89 6C 43 B0 13 AE 89 +7C 40 03 00 B0 13 AE 89 4C 43 B0 13 AE 89 B2 40 +80 5A 5C 01 32 D0 D8 00 03 43 B0 13 8C EC B0 13 +44 F0 B0 13 A4 89 E2 B2 01 02 04 24 F2 B0 10 00 +01 02 09 20 B0 13 A4 89 82 43 76 1E F2 C2 03 02 +F2 C2 05 02 AE 3C 49 43 5A 43 4A 93 71 24 B0 13 +8C EC 4A 43 4F 49 0F 93 5E 24 1F 83 49 24 1F 83 +36 24 1F 83 10 24 1F 83 5F 20 A2 D2 76 1E B0 13 +5E A5 B0 13 A4 89 B0 13 32 BE 5D 43 B0 13 72 CB +B0 13 EE D4 51 3C B0 13 8A C3 28 42 06 43 07 43 +3C 40 00 20 B0 13 A0 CC B0 13 4C E3 5C 42 59 1E +CD 06 B0 13 96 89 7C 40 47 00 5E 43 B0 13 70 AF +5C 42 5B 1E CD 07 B0 13 96 89 7C 40 5D 00 5E 43 +B0 13 70 AF 18 83 E4 23 B0 13 E0 DF 2D 3C 5D 43 +B0 13 10 AB 28 42 3C 40 00 20 B0 13 A0 CC 4C 43 +B0 13 9C BD 6D 43 B0 13 10 AB 18 83 F4 23 1C 3C +5D 43 B0 13 38 A9 28 43 F2 B0 40 00 01 02 FC 27 +4C 43 B0 13 96 BA 6D 43 B0 13 38 A9 18 83 F4 23 +B0 13 3C EA 09 3C B0 13 3E EB E2 B2 01 02 04 24 +F2 B0 10 00 01 02 F9 23 3C 40 99 19 B0 13 A0 CC +E2 B2 01 02 2D 20 E2 B3 01 02 27 20 F2 B0 10 00 +01 02 1F 20 D2 B3 01 02 19 20 F2 B2 01 02 22 24 +F2 B2 01 02 FD 23 92 C3 00 0A 82 43 08 0A 3C 40 +00 40 B0 13 A0 CC B0 13 E6 EE B2 40 80 5A 5C 01 +32 D0 F8 00 03 43 92 43 5C 01 0C 3C 69 42 5A 43 +09 3C 79 40 03 00 5A 43 05 3C 69 43 5A 43 02 3C +59 43 5A 43 B2 40 2B 5A 5C 01 32 D0 D8 00 03 43 +54 3F 46 16 10 01 7E 40 03 00 4F 43 B0 13 FC B4 +CD 0C 10 01 3C 40 CC 0C B0 13 A0 CC 10 01 5D 43 +B0 13 02 E9 10 01 6A 14 31 80 10 00 C8 0F C5 0E +81 4D 02 00 C7 0C 3F 01 3A 00 71 0F 08 00 5F 41 +38 00 81 4F 04 00 16 41 36 00 91 41 32 00 0C 00 +91 41 34 00 0E 00 19 41 30 00 82 43 76 1E B0 13 +86 F0 B0 13 6A E8 5F 42 34 1E 81 4F 06 00 E2 43 +34 1E 82 43 7C 1E B0 13 E0 EB 7C 40 60 00 B0 13 +B4 EE 1A 43 54 43 B6 3C 0E 43 A2 B2 76 1E 01 24 +1E 43 3F 40 10 00 0F F6 0E 93 23 24 3A B0 00 80 +0E 7E 3E E3 87 5A 00 00 87 6E 02 00 1E 41 0E 00 +1E 97 02 00 05 38 12 20 1E 41 0C 00 2E 97 0E 2C +16 B3 03 24 CD 08 CE 09 04 3C 1D 41 0C 00 1E 41 +0E 00 87 4D 00 00 87 4E 02 00 1A 43 A2 C2 76 1E +54 43 B2 B2 76 1E 20 24 3A B0 00 80 0E 7E 3E E3 +87 8A 00 00 87 7E 02 00 87 99 02 00 04 38 11 20 +87 98 00 00 0E 2C 16 B3 05 24 1D 41 0C 00 1E 41 +0E 00 02 3C CD 08 CE 09 87 4D 00 00 87 4E 02 00 +1A 43 B2 C2 76 1E 54 43 0F 93 35 24 3E 40 1E 00 +1E 52 7C 1E 18 24 3E 80 0A 00 18 24 3E 80 0A 00 +18 24 3E 80 0A 00 26 24 3E 80 0A 00 12 24 3E 80 +0A 00 0C 24 3E 80 0A 00 06 24 1A 93 1C 24 4F 43 +5F 93 09 24 18 3C 3A 40 E8 03 05 3C 3A 40 64 00 +02 3C 3A 40 0A 00 2C 47 1D 47 02 00 3A B0 00 80 +0F 7F 3F E3 CE 0A B0 13 CC D9 87 8E 00 00 87 7F +02 00 01 3C 1A 43 44 93 2B 24 26 B2 1C 24 87 93 +02 00 11 34 6C 43 4D 43 B0 13 02 E9 7C 40 03 00 +5D 43 B0 13 02 E9 2D 47 1E 47 02 00 3D E3 3E E3 +1D 53 0E 63 0B 3C 6C 43 5D 43 B0 13 C4 8B 2D 47 +1E 47 02 00 03 3C 2D 47 1E 47 02 00 C1 45 00 00 +1C 41 04 00 1F 41 02 00 3B 01 08 00 4B 13 44 43 +B0 13 16 EF 92 B3 08 1E 09 20 92 B3 76 1E 06 20 +A2 B3 76 1E 41 27 36 B0 20 00 3E 27 6C 43 4D 43 +B0 13 C4 8B 7C 40 E0 00 B0 13 B4 EE B0 13 86 F0 +B0 13 D2 EF 1F 41 06 00 C2 4F 34 1E 31 50 10 00 +64 16 10 01 B0 13 02 E9 7C 40 03 00 4D 43 B0 13 +02 E9 10 01 0A 14 31 80 1E 00 B0 13 78 E9 B2 B0 +40 00 08 1E 05 20 91 43 0E 00 81 43 10 00 04 3C +81 43 0E 00 81 43 10 00 1A 41 0E 00 5F 42 30 1E +81 4F 12 00 81 43 14 00 5F 42 31 1E 81 4F 16 00 +81 43 18 00 5F 42 32 1E 81 4F 1A 00 81 43 1C 00 +4E 43 9F 3C 4F 4E 0F 93 07 24 1F 83 55 24 1F 83 +40 24 1F 83 2C 24 95 3C B0 13 F2 EE B0 13 D4 8D +0F 43 81 43 00 00 91 43 02 00 81 43 04 00 B1 40 +29 00 06 00 F1 40 49 00 08 00 00 18 F1 40 F6 EB +0A 00 CC 01 3C 50 0E 00 5D 43 4E 43 B0 13 B6 89 +81 93 10 00 07 20 81 93 0E 00 04 20 B2 D0 40 00 +08 1E 03 3C B2 F0 BF FF 08 1E 5E 43 6A 3C B0 13 +B0 8D F1 40 5E 00 08 00 00 18 F1 40 02 E7 0A 00 +CC 01 3C 50 1A 00 6D 43 4E 43 B0 13 B6 89 4E 43 +58 3C B0 13 B0 8D F1 40 48 00 08 00 00 18 F1 40 +02 E7 0A 00 CC 01 3C 50 16 00 6D 43 4E 43 B0 13 +B6 89 7E 40 03 00 45 3C 1C 41 12 00 1D 41 14 00 +B0 13 C8 8D 7C 40 4A 00 5E 43 B0 13 70 AF 7C 40 +1E 00 5D 43 B0 13 02 E9 1C 41 16 00 1D 41 18 00 +B0 13 C8 8D 7C 40 48 00 5E 43 B0 13 70 AF 1C 41 +1A 00 1D 41 1C 00 B0 13 C8 8D 7C 40 5E 00 5E 43 +B0 13 70 AF 7C 40 29 00 5D 43 B0 13 02 E9 0F 43 +81 43 00 00 B1 40 17 00 02 00 81 43 04 00 B1 40 +23 00 06 00 F1 40 4A 00 08 00 00 18 F1 40 E6 D6 +0A 00 CC 01 3C 50 12 00 6D 43 4E 43 B0 13 B6 89 +6E 43 92 B3 08 1E 13 20 92 B3 76 1E 5B 27 B0 13 +E6 EE D2 41 12 00 30 1E D2 41 16 00 31 1E D2 41 +1A 00 32 1E B0 13 44 F0 B0 13 D4 8D 0B 3C 0A 93 +04 20 B2 D0 40 00 08 1E 03 3C B2 F0 BF FF 08 1E +B0 13 D4 8D 82 43 76 1E 31 50 1E 00 0A 16 10 01 +0F 43 81 43 04 00 B1 40 3B 00 06 00 81 43 08 00 +B1 40 23 00 0A 00 10 01 6E 43 4F 43 B0 13 FC B4 +CD 0C 10 01 4C 43 4D 43 B0 13 02 E9 10 01 7F 14 +59 42 1B 02 B2 B0 20 00 76 1E EA 20 B2 B0 40 00 +76 1E E6 20 82 43 76 1E 5A 42 1D 02 4A F9 48 43 +B0 13 3A EF 4C 93 6D 20 7A B0 1F 00 0F 24 32 C2 +03 43 C2 43 1B 02 32 D2 3C 40 A3 00 B0 13 A0 CC +92 42 26 1E 2A 1E 92 42 28 1E 2C 1E 6A B2 44 20 +6A B3 2D 20 7A B0 10 00 22 20 5A B3 0E 20 7A B2 +77 24 F2 B2 01 02 74 24 D2 43 7B 1E C2 43 7A 1E +F2 D2 03 02 F2 D2 05 02 6B 3C D2 B3 01 02 68 24 +B2 D2 76 1E 58 43 B0 13 F0 EC 4C 93 61 24 A2 B2 +08 1E 5E 20 B0 13 DA EA B2 C2 76 1E 59 3C F2 B0 +10 00 01 02 55 24 A2 D2 76 1E 58 43 51 3C E2 B3 +01 02 0B 20 E2 B3 19 02 4B 24 A2 D3 76 1E B2 F0 +FF FE 76 1E E2 C3 19 02 43 3C A2 D3 76 1E B2 F0 +FF FE 76 1E 58 43 3C 3C E2 B2 01 02 0B 20 E2 B2 +19 02 36 24 92 D3 76 1E B2 F0 7F FF 76 1E E2 C2 +19 02 2E 3C 92 D3 76 1E B2 F0 7F FF 76 1E 58 43 +27 3C D2 53 7E 1E 5F 42 7E 1E 5F 83 7F 90 07 00 +05 28 F2 F0 0F 00 F2 1C C2 43 7E 1E 6A B2 13 20 +6A B3 0D 20 7A B0 10 00 06 20 5A B3 11 24 F2 D0 +20 00 F0 1C 0D 3C F2 D0 30 00 F2 1C 07 3C F2 D0 +20 00 F2 1C 03 3C F2 D0 10 00 F2 1C F2 D2 F0 1C +A2 B3 76 1E 03 24 B2 B2 76 1E 18 20 48 93 18 24 +E2 93 E0 1E 0A 24 B2 B0 10 00 08 1E 0A 20 5C 43 +3D 40 33 13 B0 13 12 D6 04 3C B0 13 4C F0 82 43 +76 1E 3C 40 00 20 B0 13 A0 CC 02 3C 82 43 76 1E +7A B0 20 00 02 24 B2 D2 0A 1E 7A B0 40 00 02 24 +A2 D2 0A 1E 92 B3 76 1E 03 20 A2 B3 76 1E 18 24 +3C 40 66 06 B0 13 A0 CC E2 B2 01 02 07 24 E2 D2 +19 02 92 C3 76 1E B2 D0 80 00 76 1E E2 B3 01 02 +07 24 E2 D3 19 02 A2 C3 76 1E B2 D0 00 01 76 1E +32 C2 03 43 C2 43 1D 02 C2 49 1B 02 32 D2 B1 C0 +F0 00 20 00 78 16 00 13 0A 14 31 80 1A 00 B0 13 +78 E9 5F 42 CB 1E 4C 4F 0D 43 4E 4F 81 4E 0E 00 +81 43 10 00 5E 42 CC 1E 81 4E 12 00 81 43 14 00 +91 42 CE 1E 16 00 81 43 18 00 B2 B0 40 00 08 1E +0D 20 4C 4F B0 13 BE 91 7C 40 48 00 B0 13 8E 91 +7C 40 4A 00 5E 43 B0 13 70 AF 0B 3C B0 13 BE 91 +7C 40 4A 00 B0 13 8E 91 7C 40 48 00 5E 43 B0 13 +70 AF 7C 40 1F 00 5D 43 B0 13 02 E9 4A 43 70 3C +4F 4A 0F 93 3E 24 1F 83 1F 24 1F 83 55 20 B2 B0 +40 00 08 1E 0C 20 B0 13 A2 91 B0 13 5A 91 CC 01 +3C 50 0E 00 6D 43 4E 43 B0 13 B6 89 0B 3C B0 13 +A2 91 B0 13 74 91 CC 01 3C 50 0E 00 6D 43 4E 43 +B0 13 B6 89 4A 43 38 3C B2 B0 40 00 08 1E 0C 20 +B0 13 B0 91 B0 13 74 91 CC 01 3C 50 12 00 6D 43 +4E 43 B0 13 B6 89 0B 3C B0 13 B0 91 B0 13 5A 91 +CC 01 3C 50 12 00 6D 43 4E 43 B0 13 B6 89 6A 43 +1B 3C 3F 40 D8 07 81 43 00 00 B1 40 34 08 02 00 +81 43 04 00 B1 40 22 00 06 00 F1 40 5C 00 08 00 +00 18 F1 40 02 E7 0A 00 CC 01 3C 50 16 00 6D 42 +4E 43 B0 13 B6 89 5A 43 5C 41 12 00 1D 41 16 00 +B0 13 86 C2 4F 4C 0E 43 1E 91 10 00 04 38 08 20 +1F 91 0E 00 05 2C 4F 4C 81 4F 0E 00 81 43 10 00 +92 B3 08 1E 0C 20 92 B3 76 1E 8A 27 D2 41 0E 00 +CB 1E D2 41 12 00 CC 1E 92 41 16 00 CE 1E 82 43 +76 1E 31 50 1A 00 0A 16 10 01 81 43 08 00 B1 40 +23 00 0A 00 F1 40 48 00 0C 00 00 18 F1 40 02 E7 +0E 00 10 01 81 43 08 00 B1 40 23 00 0A 00 F1 40 +4A 00 0C 00 00 18 F1 40 02 E7 0E 00 10 01 5E 43 +B0 13 70 AF 1C 41 16 00 1D 41 18 00 B0 13 BE 91 +10 01 1F 43 81 43 04 00 4C 4C 81 4C 06 00 10 01 +1F 43 81 43 04 00 B1 40 0C 00 06 00 10 01 6E 43 +4F 43 B0 13 FC B4 CD 0C 10 01 31 80 1A 00 B0 13 +78 E9 5F 42 F6 1D 81 4F 0E 00 81 43 10 00 1C 42 +FC 1D 1D 42 FE 1D 3E 40 E8 03 0F 43 B0 13 8E D0 +81 4C 16 00 81 4D 18 00 B2 B0 40 00 08 1E 12 20 +1C 42 F8 1D 0D 43 3E 40 B9 01 0F 43 B0 13 46 E7 +3E 40 C8 00 0F 43 B0 13 CC D9 81 4C 12 00 81 4D +14 00 05 3C 91 42 F8 1D 12 00 81 43 14 00 4E 43 +82 3C 4F 4E 0F 93 55 24 1F 83 39 24 1F 83 7B 20 +B2 B0 40 00 08 1E 19 20 7C 40 5E 00 3D 40 4E F5 +5E 43 B0 13 70 AF 3F 40 46 00 81 43 00 00 B1 40 +90 01 02 00 B0 13 A0 93 CC 01 3C 50 12 00 7D 40 +03 00 6E 43 B0 13 B6 89 18 3C 7C 40 5E 00 3D 40 +52 F5 5E 43 B0 13 70 AF 3F 40 1E 00 81 43 00 00 +B1 40 96 00 02 00 B0 13 A0 93 CC 01 3C 50 12 00 +7D 40 03 00 6E 43 B0 13 B6 89 4E 43 44 3C 0F 43 +81 43 00 00 91 43 02 00 81 43 04 00 B1 40 29 00 +06 00 F1 40 5C 00 08 00 00 18 F1 40 0C EC 0A 00 +CC 01 3C 50 0E 00 5D 43 4E 43 B0 13 B6 89 6E 43 +2A 3C 7C 40 10 00 5D 43 B0 13 02 E9 0F 43 81 43 +00 00 B1 40 3F 0D 02 00 B1 40 03 00 04 00 B1 40 +32 00 06 00 F1 40 5A 00 08 00 00 18 F1 40 02 E7 +0A 00 CC 01 3C 50 16 00 7D 40 06 00 7E 40 05 00 +B0 13 B6 89 7C 40 10 00 4D 43 B0 13 02 E9 6C 43 +B0 13 D2 CE 5E 43 92 B3 08 1E 2D 20 92 B3 76 1E +78 27 1C 41 16 00 1D 41 18 00 3E 40 E8 03 0F 43 +B0 13 46 E7 82 4C FC 1D 82 4D FE 1D D2 41 0E 00 +F6 1D B2 B0 40 00 08 1E 11 20 1C 41 12 00 1D 41 +14 00 3E 40 C8 00 0F 43 B0 13 46 E7 3E 40 B9 01 +0F 43 B0 13 CC D9 82 4C F8 1D 03 3C 92 41 12 00 +F8 1D A2 D2 8C 1C 82 43 76 1E 31 50 1A 00 10 01 +81 43 08 00 B1 40 22 00 0A 00 F1 40 62 00 0C 00 +00 18 F1 40 02 E7 0E 00 10 01 6A 14 31 80 20 00 +C8 0F C9 0D CA 0E 81 43 0C 00 81 43 0E 00 B0 13 +74 DE 81 4C 14 00 81 4D 16 00 CC 09 CD 0A B0 13 +44 E0 0E 43 3F 40 C8 42 B0 13 C6 BE 81 4C 18 00 +81 4D 1A 00 CC 08 B0 13 9A E6 0E 43 3F 40 20 41 +B0 13 C6 BE 81 4C 1C 00 81 4D 1E 00 1C 41 14 00 +1D 41 16 00 3E 40 F4 FD 3F 40 D4 3B B0 13 3A B7 +1E 41 1C 00 1F 41 1E 00 B0 13 E6 9E 81 4C 10 00 +81 4D 12 00 1C 41 10 00 1D 41 12 00 3E 40 E7 6F +3F 40 63 3B B0 13 3A B7 CE 0C CF 0D 1C 41 14 00 +1D 41 16 00 B0 13 C6 BE 81 4C 08 00 81 4D 0A 00 +36 40 10 00 37 40 50 F6 0A 43 2C 47 B0 13 60 95 +CE 08 CF 09 B0 13 A4 D4 0C 93 08 38 81 48 0C 00 +81 49 0E 00 27 53 1A 53 16 83 EF 23 4A 4A 5A 02 +1C 4A 70 F6 B0 13 9A E6 C6 0C C7 0D 1C 4A 50 F6 +B0 13 60 95 B0 13 84 95 C4 0C C5 0D 1C 41 08 00 +1D 41 0A 00 CE 08 CF 09 B0 13 E0 9E 3E 40 82 A8 +3F 40 7B 38 B0 13 3A B7 CE 0C CF 0D 0C 43 3D 40 +80 3F B0 13 72 95 C4 0C C5 0D 1C 4A 72 F6 B0 13 +9A E6 CE 06 CF 07 B0 13 72 95 C5 0C CA 0D CC 08 +CD 09 B0 13 84 95 CE 0C CF 0D CC 05 CD 0A B0 13 +C6 BE CE 06 CF 07 B0 13 E6 9E 81 4C 04 00 81 4D +06 00 1C 41 18 00 1D 41 1A 00 1E 41 04 00 1F 41 +06 00 B0 13 C6 BE 81 4C 00 00 81 4D 02 00 38 40 +11 00 3A 40 32 1D 39 40 72 F6 3C 49 B0 13 9A E6 +2E 41 1F 41 02 00 B0 13 3A B7 2A 52 8A 4C FC FF +8A 4D FE FF 18 83 F1 23 31 50 20 00 64 16 10 01 +B0 13 74 DE C8 0C C9 0D 1C 41 0C 00 1D 41 0E 00 +10 01 B0 13 E0 9E CE 0C CF 0D CC 04 CD 05 B0 13 +3A B7 10 01 1E 41 10 00 1F 41 12 00 B0 13 E0 9E +10 01 3C 40 79 1D 0D 43 3E 40 21 00 B0 13 72 ED +7C 40 30 00 B0 13 D8 C6 7C 40 30 00 B0 13 2C D7 +4C 93 AF 20 7C 40 31 00 B0 13 2C D7 7C 90 06 00 +A5 20 7C 40 36 00 B0 13 D8 C6 B0 13 18 97 FD 23 +B2 40 01 02 34 0F 0F 42 32 C2 03 43 B2 B0 10 00 +02 0F FC 27 B2 40 51 7E 10 0F B2 B0 10 00 02 0F +FC 27 F2 40 3D 00 11 0F B2 B0 10 00 02 0F FC 27 +F2 40 FE 00 11 0F B2 B0 20 00 02 0F FC 27 C2 43 +10 0F B2 B0 80 00 02 0F FC 27 F2 90 51 00 20 0F +72 20 B2 B0 10 00 02 0F FC 27 F2 40 3D 00 11 0F +02 4F 3B 40 92 F5 4E 43 6C 4B 4F 4E 5F 02 5D 4F +93 F5 B0 13 46 DF 2B 53 5E 53 7E 90 20 00 F4 2B +3D 40 92 F5 4E 43 6C 4D B0 13 2C D7 4F 4E 5F 02 +CF 9C 93 F5 4D 20 2D 53 5E 53 7E 90 20 00 F3 2B +7C 40 36 00 B0 13 D8 C6 B0 13 18 97 FD 23 7C 40 +0C 00 5D 42 16 1E B0 13 46 DF B0 13 A8 E8 6C 43 +B0 13 72 EA 7C 40 34 00 B0 13 D8 C6 A2 B3 30 0F +FD 27 3E 40 10 00 7C 40 34 00 B0 13 2C D7 5C F3 +5F 42 9A 1D 4F 5F 4C DF C2 4C 9A 1D 1E 83 F3 23 +F2 D0 80 00 9A 1D B0 13 F4 E1 7C 40 32 00 B0 13 +D8 C6 D2 43 78 1D B2 40 36 00 9E 1D B2 40 E2 04 +A0 1D 3C 40 79 1D 0D 43 3E 40 1F 00 B0 13 72 ED +3C 40 98 1D 0D 43 2E 43 B0 13 72 ED 32 D2 10 01 +32 C2 03 43 FF 3F 32 C2 03 43 FF 3F 32 C2 03 43 +FF 3F 32 C2 03 43 FF 3F 7C 40 3D 00 B0 13 D8 C6 +7C B0 F0 FF 10 01 1A 14 CA 0C 6D 93 3C 24 5D 93 +0E 24 6D 92 60 20 B0 13 6A 98 6D 42 B0 13 02 E9 +C2 43 2F 1E 4C 43 4D 43 B0 13 02 E9 54 3C C2 93 +2F 1E 1A 20 B2 B0 40 00 08 1E 09 20 B0 13 FA 97 +5A 93 07 20 5C 42 30 1E B0 13 CC E9 02 3C B0 13 +12 98 B0 13 44 98 C9 0C 5C 42 31 1E B0 13 20 98 +B0 13 6A 98 6D 43 E0 3F B0 13 5C 98 C9 0C 5C 42 +32 1E B0 13 20 98 7D 40 1F 00 7E 40 29 00 B0 13 +76 EF 5D 43 D1 3F 5F 42 2E 1E 4F 93 24 24 C2 93 +2F 1E 1A 20 4F 4F 2F 83 0F 24 1F 83 1C 20 B2 B0 +40 00 08 1E 07 20 B0 13 FA 97 5C 42 30 1E B0 13 +CC E9 02 3C B0 13 12 98 B0 13 44 98 CA 0C 5C 42 +31 1E B0 13 36 98 07 3C B0 13 5C 98 CA 0C 5C 42 +32 1E B0 13 36 98 19 16 10 01 5C 42 30 1E B0 13 +26 EB CF 0C CC 0A B0 13 4C 98 4C 4F B0 13 28 98 +10 01 B0 13 4C 98 5C 42 30 1E B0 13 28 98 10 01 +B0 13 28 98 CC 0A 10 01 B0 13 78 98 CC 09 5E 43 +B0 13 70 AF 10 01 B0 13 78 98 CC 0A 5E 43 B0 13 +70 AF 10 01 CC 0A B0 13 5C 98 10 01 7D 40 4A 00 +7E 40 60 00 B0 13 76 EF C9 0C 10 01 7D 40 48 00 +7E 40 5E 00 B0 13 76 EF 10 01 7D 40 1E 00 7E 40 +28 00 B0 13 76 EF 10 01 0D 43 6E 43 4F 43 B0 13 +FC B4 CD 0C 10 01 1A 14 31 80 16 00 B0 13 C2 DB +CA 0C 0A 93 03 20 3C 40 03 00 97 3C 5C 43 CD 0A +B0 13 44 B0 4C 93 04 20 CC 0A B0 13 92 F0 F3 3F +B0 13 98 F0 CD 0C C9 01 39 52 CC 09 2E 42 B0 13 +60 ED 81 49 00 00 CF 01 3F 50 0C 00 81 4F 02 00 +F1 40 09 00 04 00 E1 43 05 00 CD 01 3D 50 0E 00 +3C 40 6C 1E B0 13 20 EA D1 4A 09 00 12 00 D1 42 +75 1E 0D 00 B0 13 BE F0 C1 4C 13 00 D1 43 0C 00 +B0 13 C2 F0 C1 4C 14 00 2C 43 3D 40 03 00 CE 01 +B0 13 F0 B7 0C 93 59 20 B0 13 80 F0 C9 0C E1 43 +05 00 CF 01 3F 50 0C 00 81 4F 02 00 CF 0A 3F 50 +03 00 81 4F 00 00 79 90 03 00 06 24 59 93 02 20 +B0 13 E0 E6 B0 13 0A E8 B0 13 DE DE 79 90 03 00 +07 24 59 93 03 24 B0 13 EA E7 02 3C B0 13 0A E6 +2C 43 2D 43 CE 01 B0 13 F0 B7 0C 93 05 24 CC 0A +B0 13 92 F0 1C 43 29 3C 3F 40 7F 00 5F F1 0C 00 +5F 93 09 24 7F 90 03 00 06 24 CC 0A B0 13 92 F0 +3C 40 05 00 1A 3C EA 43 00 00 DA 41 0E 00 0A 00 +D2 4A 0B 00 77 1D F1 90 40 00 0F 00 02 20 5F 43 +02 3C 7F 40 03 00 CA 4F 01 00 D2 53 75 1E C2 93 +75 1E 02 20 D2 43 75 1E 0C 43 31 50 16 00 19 16 +10 01 3A 14 31 82 C9 0C F9 90 14 00 00 00 05 28 +B0 13 C2 F0 C9 9C 14 00 74 20 3C 40 0E 00 0C 59 +CD 01 B0 13 52 EF 91 92 6E 1E 02 00 6A 20 91 92 +6C 1E 00 00 66 20 58 49 12 00 3A 40 05 00 0A 59 +3C 40 05 00 0C 59 CD 08 B0 13 78 DC 0C 93 48 20 +C2 93 70 1E 56 24 B0 13 C2 DB C7 0C 07 93 51 24 +3C 40 03 00 0C 57 CD 0A 2E 42 B0 13 60 ED 6C 43 +CD 07 B0 13 44 B0 4C 93 03 24 D2 93 74 1E 04 20 +CC 07 B0 13 92 F0 3D 3C 5F 42 74 1E CE 0F 5E 53 +C2 4E 74 1E 4F 4F DF 47 0B 00 72 1E C7 48 0A 00 +E7 43 00 00 F9 90 40 00 13 00 02 20 5F 43 02 3C +7F 40 03 00 C7 4F 01 00 D1 47 09 00 06 00 B0 13 +BE F0 C1 4C 07 00 B0 13 02 9B B0 13 F0 9A CD 01 +B0 13 10 9B D5 27 B0 13 D8 9A 0C 93 12 24 D0 3F +B0 13 02 9B D1 4C 09 00 06 00 B0 13 BE F0 C1 4C +07 00 B0 13 F0 9A CD 01 B0 13 10 9B 02 24 B0 13 +D8 9A 31 52 37 16 10 01 3C 40 03 00 0C 59 CD 0A +2E 42 B0 13 60 ED CC 09 4D 43 B0 13 68 E1 10 01 +3E 40 07 00 5E F9 0A 00 3F 40 03 00 4F 8E 6C 43 +10 01 F1 40 81 00 08 00 D1 49 0D 00 09 00 10 01 +2D 52 6E 42 B0 13 6C C0 C9 0C 09 93 10 01 C2 43 +17 1D 5F 42 F2 1C 2F 83 99 24 1F 83 3F 24 1F 83 +23 24 1F 83 06 24 2F 83 96 20 F2 D0 20 00 F0 1C +10 01 E2 43 F2 1C 3C 40 1E 1D 4D 43 4E 4D 5E 02 +5F 4E F3 1C 47 18 0F 5F 5E 4E F4 1C 0E 5F 2C 53 +8C 4E FE FF 5D 53 7D 90 09 00 F0 2B E2 43 18 1D +F2 40 09 00 17 1D 10 01 E2 43 F2 1C 5E 42 F3 1C +47 18 0E 5E 5F 42 F4 1C 0E 5F 82 4E 1A 1D 5F 42 +F5 1C 47 18 0F 5F 5D 42 F6 1C 0F 5D 82 4F 1C 1D +D2 43 18 1D 4F 8E C2 4F 17 1D 10 01 3E 40 BF FF +1E F2 08 1E 5F 42 F3 1C 5F 03 3F F0 C0 FF 0E DF +82 4E 08 1E 3F 40 7F 00 5F F2 F3 1C C2 4F 30 1E +D2 42 F4 1C 31 1E D2 42 F5 1C 32 1E 5F 42 F6 1C +47 18 0F 5F 5E 42 F7 1C 0E 5F 82 4E CE 1E D2 42 +F8 1C CC 1E D2 42 F9 1C CB 1E D2 42 FA 1C E2 1E +D2 42 FB 1C E3 1E 5F 42 FC 1C 47 18 0F 5F 5E 42 +FD 1C 0E 5F CF 0E 1F 52 D4 1E 1F 82 D2 1E 82 4F +D4 1E 82 4E D2 1E 5F 42 FE 1C 47 18 0F 5F 5C 42 +FF 1C 0C 5F 82 4C 20 1E 1D 42 1A 1E 1E 42 1C 1E +1F 42 1E 1E B0 13 BA 93 7C 40 5A 00 3D 40 0A F5 +5E 43 B0 13 70 AF D2 43 EE 1C 10 01 F2 40 03 00 +F2 1C D2 43 17 1D 10 01 0A 14 31 82 92 B3 8C 1C +0F 20 A2 B2 8C 1C 0C 20 3F 40 0C 00 1F 52 E6 1E +6F 13 4C 93 0C 24 5C 43 6D 43 80 13 0E 1E 07 3C +5C 43 B0 13 D2 CE 5C 43 5D 43 80 13 0E 1E A2 B3 +0C 1E 1B 20 92 B3 8C 1C 12 20 B2 B2 8C 1C 0F 20 +3F 40 0C 00 1F 52 E4 1E 6F 13 4C 93 5B 24 82 93 +0C 1E 58 20 6C 43 6D 43 80 13 12 1E 53 3C 6C 43 +B0 13 D2 CE 6C 43 5D 43 F7 3F 6A 43 B2 B2 0C 1E +28 20 B2 B0 10 00 0C 1E 20 20 B2 B0 20 00 0C 1E +14 20 B2 B0 40 00 0C 1E 0C 20 B2 B0 80 00 0C 1E +1F 24 CC 01 3D 40 68 F5 2E 42 B0 13 60 ED 5A 43 +17 3C CC 01 3D 40 6E F5 F7 3F CC 01 3D 40 74 F5 +3E 40 06 00 B0 13 60 ED 0B 3C CC 01 3D 40 7C F5 +F7 3F CC 01 3D 40 84 F5 3E 40 06 00 B0 13 60 ED +CC 0A B0 13 D2 CE CC 0A 6D 42 80 13 12 1E 6A 93 +07 24 7C 40 46 00 CD 01 5E 43 B0 13 70 AF 06 3C +7C 40 5A 00 CD 01 5E 43 B0 13 70 AF 82 43 0C 1E +A2 D2 0C 1E 92 B3 8C 1C 10 24 B0 13 22 EF 6C 93 +0C 20 7C 40 17 00 B0 13 A4 9D 7C 40 18 00 B0 13 +A4 9D 7C 40 19 00 B0 13 A4 9D 82 43 8C 1C 31 52 +0A 16 10 01 7D 40 03 00 B0 13 02 E9 10 01 2A 14 +C2 93 93 1E 8C 24 5D 93 78 24 6D 93 15 24 6D 92 +8D 20 B0 13 E0 DF C2 43 58 1E 7C 40 1F 00 4D 43 +B0 13 02 E9 6C 43 4D 43 B0 13 02 E9 7C 40 03 00 +4D 43 B0 13 02 E9 7A 3C 5F 42 5E 1E 0F 93 13 24 +1F 83 0A 24 5A 42 5B 1E 7C 40 1A 00 7D 40 5A 00 +5E 43 B0 13 66 C6 10 3C 5A 42 5A 1E 7C 40 1A 00 +7D 40 59 00 F5 3F 5A 42 59 1E 7C 40 1A 00 7D 40 +58 00 5E 43 B0 13 66 C6 CC 0A B0 13 C0 D3 3D 40 +0A 00 B0 13 22 EC B0 13 9A E6 3E 40 CD CC 3F 40 +4C 3E B0 13 3A B7 C8 0C C9 0D 1C 42 5C 1E B0 13 +9A E6 3E 40 CD CC 3F 40 4C 3F B0 13 3A B7 CE 0C +CF 0D CC 08 CD 09 B0 13 E6 9E B0 13 72 D7 82 4C +5C 1E 0D 43 7E 40 03 00 4F 43 B0 13 FC B4 CD 0C +7C 40 47 00 5E 43 B0 13 70 AF CC 0A B0 13 6E EE +4C 93 08 20 6C 43 4D 43 B0 13 02 E9 7C 40 03 00 +5D 43 9F 3F 6C 43 5D 43 97 3F B0 13 3C ED 4C 93 +0B 20 82 43 5C 1E B0 13 8A C3 B2 40 10 0E 60 1E +D2 43 58 1E D2 43 5E 1E 7C 40 1F 00 E9 3F 7C 40 +47 00 3D 40 06 F5 5E 43 B0 13 70 AF 28 16 10 01 +3B 40 80 00 01 3C 0B 43 0A 14 09 14 08 14 07 14 +21 83 3F B0 80 7F 7B 24 3D B0 80 7F 05 20 0C 4E +0D 4F 8B 10 0D EB 73 3C 5D 02 08 4D 4D 10 38 F0 +00 FF 0D D8 5F 02 08 4F 4F 10 38 F0 00 FF 0F D8 +09 4C 0A 4D 3D F0 80 00 C1 4D 00 00 0B EA 0B EF +3B C0 7F FF 3A D0 80 00 3F D0 80 00 0A 9F 02 20 +09 9E 0A 24 0B 2C 0D 4F 0F 4A 0A 4D 0C 4E 0E 49 +09 4C 81 EB 00 00 02 3C 0B 93 4F 20 0C 43 08 4A +88 10 47 48 8F 10 48 8F 8F 10 0E 24 38 90 19 00 +34 2C 12 C3 4F 10 5E 00 5C 00 3C B0 00 10 02 24 +3C D0 00 20 18 83 F5 23 0B 93 0C 24 08 8C 09 7E +4A 7F 0C 48 4A 93 12 30 5C 02 09 69 4A 6A 17 83 +2C 24 F8 3F 09 5E 4A 6F 09 28 4A 10 59 00 5C 00 +3C B0 00 10 02 24 3C D0 00 20 17 53 3C B0 00 80 +07 24 09 63 4A 63 07 63 3C B0 00 60 01 20 19 C3 +17 93 13 38 37 90 FF 00 13 34 7A C0 80 00 87 10 +D1 51 00 00 00 00 57 00 0A D7 0C 49 0D 4A 21 53 +07 16 08 16 09 16 0A 16 10 01 0D 43 0C 43 F7 3F +3D 40 FF FE D1 61 00 00 00 00 5D 00 3C 43 EF 3F +6D 93 1E 24 5D 93 8A 20 C2 93 40 1E 08 20 3D 40 +3A 1E 7C 40 5A 00 5E 43 B0 13 70 AF 07 3C 3D 40 +38 1E 7C 40 5A 00 5E 43 B0 13 70 AF 7C 40 27 00 +5D 43 B0 13 02 E9 7C 40 28 00 5D 43 80 00 02 E9 +B2 B0 20 00 8C 1C 6A 24 C2 93 40 1E 38 20 5F 42 +35 1E 4F 93 63 24 4F 4F 1F 83 1E 24 1F 83 16 24 +1F 83 0E 24 1F 83 06 24 3F 80 03 00 1B 24 1F 83 +1F 24 10 01 5D 42 3A 1E 7C 40 21 00 B0 13 2E A1 +5D 42 3B 1E 7C 40 22 00 B0 13 2E A1 5D 42 3C 1E +7C 40 23 00 B0 13 2E A1 5D 42 3D 1E 7C 40 24 00 +B0 13 2E A1 5D 42 3E 1E 7C 40 25 00 B0 13 2E A1 +5D 42 3F 1E 7C 40 26 00 5E 43 80 00 66 C6 5F 42 +35 1E 1F 83 28 24 1F 83 20 24 1F 83 18 24 1F 83 +10 24 1F 83 08 24 1F 83 21 20 5D 42 38 1E 7C 40 +21 00 B0 13 2E A1 5D 42 39 1E 7C 40 22 00 B0 13 +2E A1 5D 42 3A 1E 7C 40 23 00 B0 13 2E A1 5D 42 +3B 1E 7C 40 24 00 B0 13 2E A1 5D 42 3C 1E 7C 40 +25 00 B0 13 2E A1 5D 42 3D 1E CC 3F 10 01 5E 43 +B0 13 66 C6 10 01 A2 D3 08 1E 82 93 76 1E 03 24 +A2 B2 08 1E 68 20 B2 B0 20 00 76 1E 5B 20 B2 B0 +40 00 76 1E 4B 20 82 93 76 1E 69 24 92 B3 76 1E +32 20 A2 B3 76 1E 1A 20 A2 B2 76 1E 0D 20 B2 B2 +76 1E 5D 24 1F 42 E4 1E 0F 0F 6C 43 4F 13 B2 D2 +8C 1C B2 C2 76 1E 53 3C 1F 42 E6 1E 0F 0F 5C 43 +4F 13 A2 D2 8C 1C A2 C2 76 1E 49 3C C2 43 89 1E +6C 43 6D 42 80 13 12 1E 1F 42 E4 1E 1F 4F 10 00 +82 4F E4 1E 00 18 D2 4F 08 00 12 1E B2 D2 8C 1C +A2 C3 76 1E 34 3C 5C 43 6D 42 80 13 0E 1E 1F 42 +E6 1E 1F 4F 10 00 82 4F E6 1E 00 18 D2 4F 08 00 +0E 1E A2 D2 8C 1C 92 C3 76 1E 21 3C B2 F0 BF FF +76 1E 1F 42 E4 1E 3F 0F 04 00 6C 43 4F 13 92 D3 +8C 1C 15 3C B2 F0 DF FF 76 1E 1F 42 E6 1E 3F 0F +04 00 5C 43 F3 3F E2 B3 01 02 03 24 D2 B3 01 02 +04 20 92 D3 0C 1E B2 D2 0C 1E 82 43 76 1E 82 93 +08 1E 09 24 92 B3 08 1E 06 24 92 C3 08 1E B0 13 +F2 EE 92 D3 8C 1C A2 C3 08 1E 10 01 1A 14 C9 0C +1A 42 44 1E 4D 4D 1D 5A 0C 00 0D 8E 3D 80 13 00 +0D 93 78 34 3E 40 1A 00 1E 52 44 1E 6F 4E 3F F0 +03 00 1F 83 4F 24 1F 83 2C 20 CA 43 12 00 2F 42 +6F BE 1A 20 1C 42 44 1E D2 9C 11 00 48 1E 09 2C +C2 93 4A 1E 03 20 B0 13 DE CF 09 3C 8C 43 18 00 +06 3C B0 13 1A CE 1F 42 44 1E DF 53 11 00 CC 09 +5D 43 B0 13 4C D9 4E 3C EE C2 00 00 1F 42 44 1E +8F 43 00 00 8F 43 02 00 1C 42 44 1E B0 13 DE CF +41 3C 3C 40 80 00 5C 8A 13 00 CF 0A 2D 4F 1E 4F +02 00 3F 40 00 02 B0 13 82 D5 1C 5A 0C 00 3C 50 +00 02 8A 4C 0C 00 1F 42 44 1E CF 43 0F 00 3F 40 +1A 00 1F 52 44 1E 3E 40 FC 00 6E FF 5E D3 CF 4E +00 00 20 3C 3C 40 40 00 5C 8A 13 00 2D 4A 1E 4A +02 00 3F 40 80 1C B0 13 82 D5 1F 42 44 1E 1C 5F +0A 00 3C 50 00 06 8F 4C 0C 00 1F 42 44 1E DF 43 +0F 00 3F 40 1A 00 1F 52 44 1E 6E 4F 5E C3 6E D3 +CF 4E 00 00 19 16 10 01 31 80 16 00 B0 13 78 E9 +5C 42 E2 1E 4F 4C 81 4F 0E 00 81 43 10 00 5F 42 +E3 1E 81 4F 12 00 81 43 14 00 4C 4C 0D 43 6E 43 +4F 43 B0 13 FC B4 CD 0C 7C 40 4A 00 5E 43 B0 13 +70 AF 7C 40 1E 00 5D 43 B0 13 02 E9 1C 41 12 00 +1D 41 14 00 6E 43 4F 43 B0 13 FC B4 CD 0C 7C 40 +48 00 5E 43 B0 13 70 AF 4E 43 3A 3C 4F 4E 0F 93 +1D 24 1F 83 35 20 0F 43 81 43 00 00 B1 40 3B 00 +02 00 81 43 04 00 B1 40 23 00 06 00 F1 40 48 00 +08 00 00 18 F1 40 02 E7 0A 00 CC 01 3C 50 12 00 +6D 43 4E 43 B0 13 B6 89 4E 43 1A 3C 0F 43 81 43 +00 00 B1 40 17 00 02 00 81 43 04 00 B1 40 23 00 +06 00 F1 40 4A 00 08 00 00 18 F1 40 E6 D6 0A 00 +CC 01 3C 50 0E 00 6D 43 4E 43 B0 13 B6 89 5E 43 +92 B3 08 1E 0B 20 92 B3 76 1E C0 27 D2 41 0E 00 +E2 1E D2 41 12 00 E3 1E A2 D2 8C 1C 82 43 76 1E +B2 D0 00 02 8C 1C 31 50 16 00 10 01 0A 14 31 80 +16 00 B0 13 78 E9 B2 B0 40 00 08 1E 0D 20 B0 13 +0E EB 3C B0 00 80 0F 7F 3F E3 81 4C 0E 00 81 4F +10 00 1A 42 D2 1E 44 3C 1F 42 D2 1E 3F B0 00 80 +0E 7E 3E E3 81 4F 0E 00 81 4E 10 00 CA 0F 38 3C +B2 B0 40 00 08 1E 08 20 7C 40 1D 00 7D 40 46 00 +5E 43 B0 13 66 C6 07 3C 7C 40 1D 00 7D 40 43 00 +5E 43 B0 13 66 C6 7C 40 1F 00 5D 43 B0 13 02 E9 +7C 40 0F 00 5D 43 B0 13 02 E9 3F 40 19 FC B1 43 +00 00 B1 40 E7 03 02 00 81 43 04 00 B1 40 06 00 +06 00 F1 40 49 00 08 00 00 18 F1 40 02 E7 0A 00 +CC 01 3C 50 0E 00 7D 40 03 00 5E 43 B0 13 B6 89 +92 B3 08 1E 1E 20 92 B3 76 1E C2 27 B2 B0 40 00 +08 1E 07 20 1C 41 0E 00 B0 13 2A ED 81 4C 12 00 +03 3C 91 41 0E 00 12 00 1F 41 12 00 0F 8A 81 4F +14 00 92 51 14 00 D4 1E 92 41 12 00 D2 1E A2 D2 +8C 1C 82 43 76 1E 31 50 16 00 0A 16 10 01 B2 B0 +20 00 08 1E 77 20 B0 13 3A EF 4C 93 73 20 A2 B2 +76 1E 70 24 1F 42 EE 1D 0F 93 68 20 B0 13 BA ED +B0 13 F0 DC 7C 40 0A 00 B0 13 62 F0 7C 42 B0 13 +68 F0 82 43 F2 1D 82 43 F4 1D 7C 40 05 00 B0 13 +34 F0 7C 40 0C 00 5D 42 16 1E B0 13 28 DD 92 43 +EE 1D 7C 40 17 00 6D 43 B0 13 02 E9 7C 40 18 00 +6D 43 B0 13 02 E9 7C 40 19 00 6D 43 B0 13 02 E9 +4C 43 B0 13 C2 E5 0C 93 0F 20 4C 43 1D 42 F2 1D +1E 42 F4 1D B0 13 8C DA 4C 43 B0 13 86 CF 4C 43 +B0 13 C2 E5 2C 93 25 24 4C 43 B0 13 C2 E5 1C 93 +27 20 A2 43 EE 1D 82 93 F4 1D 0A 20 82 93 F2 1D +07 20 4C 43 B0 13 A4 E2 82 4C F2 1D 82 4D F4 1D +7C 40 17 00 B0 13 56 A6 7C 40 18 00 B0 13 56 A6 +7C 40 19 00 B0 13 56 A6 7C 40 13 00 6D 43 80 00 +02 E9 3C 40 99 19 B0 13 A0 CC D1 3F 2F 93 02 20 +80 00 EE D4 10 01 7D 40 03 00 B0 13 02 E9 10 01 +1A 14 31 80 18 00 B0 13 80 F0 C9 0C B0 13 98 F0 +81 4C 10 00 CF 01 2F 52 81 4F 12 00 F1 42 14 00 +7A 40 03 00 C1 4A 15 00 CD 01 3D 50 06 00 3C 40 +8A 1E B0 13 20 EA D1 43 04 00 D1 42 92 1E 05 00 +D1 43 0A 00 B0 13 C2 F0 C1 4C 0B 00 2C 43 3D 40 +03 00 CE 01 3E 50 10 00 B0 13 F0 B7 C1 4A 15 00 +CF 01 2F 52 81 4F 12 00 CF 01 3F 50 0C 00 81 4F +10 00 79 90 03 00 06 24 59 93 02 20 B0 13 E0 E6 +B0 13 0A E8 B0 13 DE DE 3A 40 06 00 79 90 03 00 +07 24 59 93 03 24 B0 13 EA E7 02 3C B0 13 0A E6 +2C 43 2D 43 CE 01 3E 50 10 00 B0 13 F0 B7 0C 93 +1D 20 3F 40 7F 00 5F F1 04 00 5F 93 03 24 7F 90 +06 00 14 20 CC 01 CD 01 3D 50 06 00 2E 42 B0 13 +60 ED 2C 41 1D 41 02 00 B0 13 A8 ED CC 01 3C 50 +0C 00 B0 13 5E EF D2 53 92 1E 0A 43 CC 0A 31 50 +18 00 19 16 10 01 0A 14 21 83 C1 43 00 00 F2 90 +03 00 78 1D 6B 20 7C 40 3B 00 B0 13 2C D7 CE 0C +7C 40 3B 00 B0 13 2C D7 4E 9C F9 23 4E 93 61 24 +CC 01 5D 43 B0 13 A8 E0 6F 41 3F 50 03 00 4E 4E +0E 9F 38 20 F1 90 1F 00 00 00 34 2C F1 90 0B 00 +00 00 30 28 3C 40 79 1D 0D 43 3E 40 1F 00 B0 13 +72 ED E2 41 79 1D 3C 40 7A 1D 6D 41 B0 13 A8 E0 +3C 40 98 1D 6D 43 B0 13 A8 E0 F2 B0 80 FF 99 1D +14 24 92 53 AC 1D 82 63 AE 1D B0 13 08 DB 4C 93 +30 20 5C 42 98 1D B0 13 98 E1 C2 4C 98 1D F2 F0 +7F 00 99 1D B0 13 CA E7 24 3C 92 53 A8 1D 82 63 +AA 1D 1F 3C 92 53 B0 1D 82 63 B2 1D 0A 42 32 C2 +03 43 7C 40 36 00 B0 13 D8 C6 7C 40 3D 00 B0 13 +D8 C6 7C B0 F0 FF F9 23 7C 40 3A 00 B0 13 D8 C6 +7C 40 34 00 B0 13 D8 C6 02 4A 03 3C 32 C2 03 43 +FF 3F 21 53 0A 16 10 01 C2 93 40 1E 20 20 D2 53 +3F 1E D2 53 41 1E 5F 42 41 1E 5F 83 7F 90 12 00 +04 28 F2 42 35 1E C2 43 41 1E F2 90 3A 00 3F 1E +0A 20 F2 40 30 00 3F 1E D2 53 3E 1E D2 43 37 1E +F2 40 07 00 35 1E F2 90 3A 00 3E 1E 51 20 D2 43 +35 1E D2 43 36 1E 3F 40 30 00 C2 4F 3E 1E D2 53 +3D 1E F2 90 3A 00 3D 1E 43 20 D2 53 35 1E C2 4F +3D 1E D2 53 3C 1E F2 90 36 00 3C 1E 39 20 D2 53 +35 1E C2 4F 3C 1E D2 53 3B 1E F2 90 3A 00 3B 1E +2F 20 D2 53 35 1E C2 4F 3B 1E D2 53 3A 1E 5E 42 +3A 1E 7E 90 32 00 1F 24 7E 90 36 00 21 20 D2 53 +35 1E C2 4F 3A 1E D2 53 39 1E F2 90 3A 00 39 1E +17 20 D2 53 35 1E C2 4F 39 1E D2 53 38 1E F2 90 +32 00 38 1E 0D 20 B0 13 4A E8 D2 43 34 1E 5D 43 +B0 13 10 A0 05 3C D2 43 40 1E 5D 43 B0 13 10 A0 +B2 D0 20 00 8C 1C 10 01 4D 4D 1D 93 19 24 2D 93 +2A 24 2D 92 54 20 82 43 18 1E B0 13 3C EA 7C 40 +0B 00 4D 43 B0 13 02 E9 7C 40 09 00 4D 43 B0 13 +02 E9 6C 43 4D 43 B0 13 1A AA 4D 43 80 00 02 E9 +92 43 18 1E B0 13 4C DA B2 B0 40 00 08 1E 06 20 +7C 40 09 00 5D 43 B0 13 02 E9 05 3C 7C 40 0B 00 +5D 43 B0 13 02 E9 82 93 24 1E 29 24 B2 B0 40 00 +08 1E 19 20 1C 42 20 1E B0 13 B0 E9 3C 90 10 27 +0D 34 0C 93 0D 34 3C E3 1C 53 B0 13 02 AA 4D 43 +B0 13 1A AA 5D 43 B0 13 02 E9 0B 3C 3C 40 0F 27 +B0 13 F0 A9 06 3C 1C 42 20 1E 0C 93 EC 3B B0 13 +F0 A9 7C 40 46 00 CD 0B 5E 43 80 00 70 AF 10 01 +B0 13 02 AA 5D 43 B0 13 1A AA 4D 43 B0 13 02 E9 +10 01 3C B0 00 80 0D 7D 3D E3 6E 42 7F 40 03 00 +B0 13 FC B4 CB 0C 6C 43 10 01 B0 13 02 E9 7C 40 +03 00 10 01 3A 14 31 80 12 00 B0 13 78 E9 B2 B0 +40 00 08 1E 12 20 7C 40 09 00 5D 43 B0 13 02 E9 +1C 42 20 1E B0 13 B0 E9 B0 13 FE AA 37 40 0C FE +38 43 39 40 0F 27 0A 43 30 3C 7C 40 0B 00 5D 43 +B0 13 02 E9 1E 42 20 1E 3E B0 00 80 0F 7F 3F E3 +81 4E 0E 00 81 4F 10 00 37 40 9C FF 38 43 39 40 +A0 0F 0A 43 1A 3C CF 07 CE 08 81 4E 00 00 81 49 +02 00 81 4A 04 00 B1 40 16 00 06 00 F1 40 46 00 +08 00 00 18 F1 40 02 E7 0A 00 CC 01 3C 50 0E 00 +6D 42 7E 40 03 00 B0 13 B6 89 92 B3 08 1E 19 20 +92 B3 76 1E E0 27 B2 B0 40 00 08 1E 06 20 1C 41 +0E 00 B0 13 94 E9 B0 13 FE AA 1C 41 0E 00 1D 42 +1A 1E 1E 42 1C 1E 1F 42 1E 1E B0 13 BA 93 A2 D2 +8C 1C 82 43 76 1E 31 50 12 00 37 16 10 01 3C B0 +00 80 0F 7F 3F E3 81 4C 12 00 81 4F 14 00 10 01 +4D 4D 1D 93 14 24 2D 93 34 24 2D 92 63 20 82 43 +D0 1E 6C 43 4D 43 B0 13 E6 AB 7C 40 0F 00 4D 43 +B0 13 02 E9 7C 40 1F 00 4D 43 80 00 02 E9 92 43 +D0 1E 7C 40 1F 00 5D 43 B0 13 02 E9 7C 40 0F 00 +5D 43 B0 13 02 E9 B2 B0 40 00 08 1E 08 20 7C 40 +1D 00 7D 40 46 00 5E 43 B0 13 66 C6 07 3C 7C 40 +1D 00 7D 40 43 00 5E 43 B0 13 66 C6 4C 43 B0 13 +9C BD B2 B0 40 00 08 1E 04 20 B0 13 0E EB CB 0C +02 3C 1B 42 D2 1E 0B 93 05 38 6C 43 5D 43 B0 13 +E6 AB 0B 3C 3B E3 1B 53 6C 43 4D 43 B0 13 02 E9 +7C 40 03 00 5D 43 B0 13 02 E9 3B 90 E8 03 02 38 +3B 40 E7 03 CC 0B 3C B0 00 80 0D 7D 3D E3 7E 40 +03 00 5F 43 B0 13 FC B4 CD 0C 7C 40 49 00 5E 43 +80 00 70 AF 10 01 B0 13 02 E9 7C 40 03 00 4D 43 +B0 13 02 E9 10 01 5F 42 F2 1C 2F 83 03 24 1F 83 +2C 24 10 01 D2 93 18 1D 16 24 E2 93 18 1D 5D 20 +CF 0C 5F 02 1E 4F 1E 1D CF 0E 8F 10 C2 4F F3 1C +C2 4E F4 1C 4C 4C 3E 40 F5 1C 7F 40 03 00 B0 13 +CC AC FD 2B 10 01 1F 42 1A 1D 0F 5C CE 0F 8E 10 +C2 4E F3 1C C2 4F F4 1C 4C 4C 3E 40 F5 1C 7F 40 +03 00 B0 13 CC AC FD 2B 10 01 1F 42 08 1E 7F F0 +C0 00 4F 5F 3E 40 7F 00 5E F2 30 1E 4E DF C2 4E +F3 1C D2 42 31 1E F4 1C D2 42 32 1E F5 1C 1E 42 +CE 1E CF 0E 8F 10 C2 4F F6 1C C2 4E F7 1C D2 42 +CC 1E F8 1C D2 42 CB 1E F9 1C D2 42 E2 1E FA 1C +D2 42 E3 1E FB 1C 1E 42 D2 1E CF 0E 8F 10 8F 11 +C2 4F FC 1C C2 4E FD 1C 1E 42 20 1E CF 0E 8F 10 +8F 11 C2 4F FE 1C C2 4E FF 1C 10 01 1E 53 CE 4C +FF FF 5F 53 7F 90 13 00 10 01 0A 14 CA 0D 6A 92 +1F 24 B2 B0 40 00 08 1E 10 20 5C 42 00 1E B0 13 +9A E6 3E 40 12 14 3F 40 1F 3F B0 13 3A B7 B0 13 +72 D7 4C 4C B0 13 96 AD 04 3C 5C 42 00 1E B0 13 +96 AD 7C 40 47 00 5E 43 B0 13 70 AF 5A 93 1D 24 +6A 92 37 20 7C 40 20 00 4D 43 B0 13 02 E9 7C 40 +0A 00 4D 43 B0 13 A6 AD 4D 43 B0 13 A6 AD 4D 43 +B0 13 02 E9 7C 40 0C 00 4D 43 B0 13 02 E9 7C 40 +0E 00 4D 43 B0 13 02 E9 1C 3C 7C 40 20 00 B0 13 +B0 AD B2 B0 40 00 08 1E 09 20 7C 40 0B 00 B0 13 +B0 AD 7C 40 0C 00 B0 13 B0 AD 07 3C 7C 40 0A 00 +5D 43 B0 13 A6 AD B0 13 B0 AD 7C 40 0E 00 B0 13 +B0 AD 0A 16 10 01 0D 43 7E 40 03 00 5F 43 B0 13 +FC B4 CD 0C 10 01 B0 13 02 E9 7C 40 0B 00 10 01 +5D 43 B0 13 02 E9 10 01 0A 14 CA 0D 6A 92 3A 24 +B2 B0 40 00 08 1E 18 20 1C 42 02 1E 1D 42 04 1E +B0 13 44 E0 3E 40 83 86 3F 40 7E 3D B0 13 3A B7 +B0 13 58 D4 3D 90 1E 00 04 28 11 20 3C 90 80 84 +0E 2C B0 13 84 AE 17 3C 1C 42 02 1E 1D 42 04 1E +3D 90 1E 00 09 28 03 20 3C 90 80 84 05 28 3C 40 +3F 0D 3D 40 03 00 ED 3F 3E 40 0A 00 0F 43 B0 13 +8E D0 B0 13 84 AE 7C 40 5A 00 5E 43 B0 13 70 AF +5A 93 12 24 6A 92 24 20 7C 40 11 00 4D 43 B0 13 +02 E9 7C 40 12 00 4D 43 B0 13 02 E9 7C 40 29 00 +4D 43 B0 13 02 E9 14 3C B2 B0 40 00 08 1E 06 20 +7C 40 12 00 5D 43 B0 13 02 E9 05 3C 7C 40 11 00 +5D 43 B0 13 02 E9 7C 40 29 00 5D 43 B0 13 02 E9 +0A 16 10 01 7E 40 06 00 7F 40 03 00 B0 13 FC B4 +CD 0C 10 01 6A 14 31 80 06 00 C6 0C 09 43 3A 40 +00 1C 7F 40 03 00 81 4F 00 00 2F 46 1F 93 06 24 +0F 93 0B 20 58 46 02 00 C7 09 10 3C 5C 46 02 00 +B0 13 F2 E3 C7 0C 07 93 02 20 0C 43 4D 3C 58 47 +09 00 3F 40 03 00 0F 57 81 4F 02 00 24 43 0F 42 +32 C2 03 43 1E 43 6E 9A 39 20 EA 42 00 00 02 4F +3F 40 0B 00 0F 5A 6F 4F 3F F0 3F 00 4E 48 0F 9E +2A 20 25 46 15 93 0E 20 78 90 3F 00 06 20 3F 40 +03 00 0F 57 81 4F 04 00 05 3C 3F 40 07 00 0F 5A +81 4F 04 00 1C 41 04 00 1D 41 02 00 2E 42 B0 13 +2E E6 4C 4C 05 93 02 24 0C 93 0D 20 5F 4A 01 00 +2E 41 4F 9E 08 2C 09 93 02 24 D9 43 00 00 81 4F +00 00 C9 0A 04 3C DA 43 00 00 01 3C 02 4F 3A 50 +23 00 14 83 BC 23 CC 09 31 50 06 00 64 16 10 01 +4A 14 C9 0E 4C 4C 3C 80 46 00 53 24 1C 83 4C 24 +1C 83 46 24 1C 83 41 24 1C 83 3B 24 3C 80 10 00 +3C 90 09 00 55 2C 5C 06 00 18 50 4C 9E AF FC AF +00 00 F6 AF 00 00 F2 AF 00 00 E8 AF 00 00 E0 AF +00 00 DC AF 00 00 D4 AF 00 00 CC AF 00 00 C2 AF +00 00 7A 40 03 00 78 40 22 00 2E 3C 6A 43 78 40 +21 00 2A 3C 6A 43 78 40 23 00 26 3C 6A 42 F7 3F +6A 43 78 40 25 00 20 3C 7A 40 03 00 78 40 24 00 +1B 3C 6A 42 F0 3F 7A 40 05 00 E5 3F 7A 40 06 00 +E6 3F 6A 43 78 40 1A 00 0F 3C 7A 40 03 00 FA 3F +6A 43 78 40 1C 00 08 3C 7A 40 03 00 78 40 1B 00 +03 3C 6A 42 78 40 1A 00 C7 0D 4A 4A 06 43 CC 08 +4C 56 7D 47 CE 09 B0 13 66 C6 16 53 1A 83 F7 23 +46 16 10 01 4A 14 21 83 C8 0D C7 0C 39 40 B9 1D +CC 01 0D 43 1E 43 B0 13 72 ED 46 43 09 98 25 24 +2F 43 6F 99 22 20 5A 49 09 00 7A 90 3E 00 1D 2C +57 93 13 24 3C 40 03 00 0C 59 3D 40 03 00 0D 58 +2E 42 B0 13 2E E6 0C 93 10 20 4F 4A CA 01 3A 50 +E0 FF 0A 5F DA 43 00 00 08 3C C2 9A B6 1D 05 2C +4A 4A CF 01 0F 8A DF 43 3D 00 39 50 0C 00 56 53 +D5 27 CE 01 0F 43 4C 43 CE 93 00 00 04 24 1E 53 +5C 53 FA 27 09 3C 67 93 04 20 7C 50 20 00 4F 4C +03 3C 3F 40 3D 00 4F 8C 67 93 0B 24 5E 42 B7 1D +0F 9E 12 38 5E 42 B6 1D 0F 9E 0F 20 D2 83 B6 1D +0C 3C 5E 42 B6 1D 0E 9F 07 38 5E 42 B7 1D 0E 9F +04 34 C2 4F B7 1D 01 3C 0F 43 C8 4F 09 00 CC 0F +21 53 46 16 10 01 0A 14 CA 0C 5C 43 B0 13 D2 CE +5C 43 6D 42 80 13 0E 1E 5C 43 5D 43 B0 13 26 97 +1A 93 02 20 5F 43 01 3C 6F 43 C2 4F F2 1C C2 43 +F3 1C C2 43 F4 1C C2 43 F5 1C 7C 40 17 00 6D 43 +B0 13 02 E9 7C 40 18 00 6D 43 B0 13 02 E9 7C 40 +19 00 6D 43 B0 13 02 E9 3C 40 00 20 B0 13 A0 CC +B0 13 BA ED 82 4A EA 1C B2 40 10 0E EC 1C B0 13 +A2 B8 4C 93 06 24 1A 93 02 20 B0 13 8A C3 B0 13 +0C DA 82 43 EA 1C B0 13 E0 DF B0 13 0E EE 3C 40 +00 20 B0 13 A0 CC C2 43 1D 02 82 43 76 1E 7C 40 +17 00 6D 42 B0 13 02 E9 7C 40 18 00 6D 42 B0 13 +02 E9 7C 40 19 00 6D 42 B0 13 02 E9 5C 43 B0 13 +D2 CE 5C 43 6D 42 B0 13 26 97 92 D3 8C 1C 0A 16 +10 01 0A 14 CA 0C 5D 93 05 24 6D 92 34 20 C2 43 +CA 1E 31 3C C2 93 CA 1E 1A 20 5C 42 CB 1E B0 13 +7A B2 03 20 B0 13 5A B2 02 3C B0 13 6A B2 5C 42 +CC 1E B0 13 7A B2 03 20 B0 13 6A B2 02 3C B0 13 +5A B2 B0 13 8E B2 5D 43 B0 13 02 E9 14 3C 1C 42 +CE 1E 0D 43 6E 42 4F 43 B0 13 FC B4 CF 0C CC 0A +7D 40 46 00 7E 40 5C 00 B0 13 9E B2 B0 13 8E B2 +4D 43 B0 13 02 E9 0A 16 10 01 CC 0A 7D 40 48 00 +7E 40 5E 00 B0 13 9E B2 10 01 CC 0A 7D 40 4A 00 +7E 40 60 00 B0 13 9E B2 10 01 0D 43 6E 43 4F 43 +B0 13 FC B4 CF 0C B2 B0 40 00 08 1E 10 01 CC 0A +7D 40 1F 00 7E 40 29 00 B0 13 76 EF 10 01 B0 13 +76 EF CD 0F 5E 43 B0 13 70 AF 10 01 1A 14 CA 0D +C9 0C D2 93 78 1D 58 24 B0 13 F4 E1 1D 43 6D 59 +CC 09 B0 13 7A DF 49 43 4A 93 37 24 5A 93 32 20 +6A 42 16 3C 7C 40 36 00 B0 13 D8 C6 7C 40 3D 00 +B0 13 D8 C6 7C B0 F0 FF F9 23 7C 40 3A 00 B0 13 +D8 C6 4A 93 02 20 59 43 2B 3C B0 13 A6 EA 5A 83 +7C 40 34 00 B0 13 D8 C6 A2 B3 30 0F FD 27 92 C3 +32 0F 7C 40 35 00 B0 13 D8 C6 3C 40 19 00 B0 13 +8C EA 92 B3 32 0F D6 27 92 C3 32 0F 92 B3 30 0F +FD 27 0E 3C 32 C2 03 43 FF 3F 7C 40 35 00 B0 13 +D8 C6 B2 B0 00 02 32 0F FC 27 B2 F0 FF FD 32 0F +7C 40 3B 00 B0 13 D8 C6 F2 90 03 00 78 1D 02 20 +B0 13 B4 EB CC 09 03 3C 32 C2 03 43 FF 3F 19 16 +10 01 B2 40 23 5A 5C 01 B0 13 92 E4 F2 40 A5 00 +21 01 F2 D0 80 00 20 01 C2 43 21 01 F2 D0 03 00 +4A 02 92 C3 6C 01 B2 D0 0C 00 6C 01 82 43 66 01 +B2 40 44 00 68 01 32 D0 40 00 82 43 60 01 B2 40 +50 00 62 01 B2 40 6E 11 64 01 32 C0 40 00 1E 14 +3D 40 41 D1 0E 43 1D 83 0E 73 FD 23 0D 93 FB 23 +1D 16 00 3C B2 F0 F0 FF 6E 01 A2 C3 02 01 A2 B3 +02 01 F8 23 32 C2 03 43 B2 40 52 2D C0 01 A2 43 +C2 01 F2 40 0E 00 D7 01 F2 F0 7F 00 03 02 F2 D0 +80 00 05 02 F2 40 11 00 CD 01 F2 40 12 00 CE 01 +F2 40 13 00 CF 01 82 43 C0 01 32 D2 B0 13 12 E0 +B0 13 3E EE B0 13 C6 E1 B0 13 A0 E3 B0 13 04 E5 +B0 13 64 EC 80 00 04 C5 1A 14 CA 0C 5D 93 14 24 +6D 92 47 20 4C 43 4D 43 B0 13 02 E9 C2 93 E0 1E +06 20 7C 40 16 00 6D 42 B0 13 02 E9 3A 3C 7C 40 +16 00 7D 40 03 00 F8 3F B2 B0 40 00 08 1E 10 20 +5C 42 E2 1E B0 13 26 EB CF 0C CC 0A B0 13 EC B4 +4C 4F B0 13 D6 B4 5C 42 E2 1E B0 13 CC E9 06 3C +B0 13 EC B4 5C 42 E2 1E B0 13 D6 B4 CC 0A 7D 40 +48 00 7E 40 5E 00 B0 13 76 EF C9 0C 5C 42 E3 1E +B0 13 D6 B4 CC 0A 7D 40 1E 00 7E 40 28 00 B0 13 +76 EF 5D 43 B0 13 02 E9 7C 40 16 00 6D 43 B0 13 +02 E9 19 16 10 01 0D 43 6E 43 4F 43 B0 13 FC B4 +CD 0C CC 09 5E 43 B0 13 70 AF 10 01 7D 40 4A 00 +7E 40 60 00 B0 13 76 EF C9 0C 10 01 4A 14 C7 0F +C6 0E C9 0C CA 0D C8 06 3C 40 E2 1C 3D 40 12 F5 +3E 40 07 00 B0 13 60 ED 48 93 4E 24 78 92 4C 2C +0A 93 1E 20 39 90 B5 00 1B 2C 78 90 03 00 0D 2C +CD 09 59 02 0D 59 4F 48 0D 8F 3D 50 DB F0 4E 48 +3C 40 E2 1C B0 13 60 ED 22 3C 4C 46 3C 50 DF 1C +CD 09 59 02 0D 59 3D 50 D8 F0 3E 40 03 00 F2 3F +CC 09 CD 0A 3E 40 0A 00 0F 43 B0 13 8E D0 7E 50 +30 00 4F 46 CF 4E E1 1C CC 09 CD 0A 3E 40 0A 00 +0F 43 B0 13 8E D0 C9 0C CA 0D 56 83 E9 23 3F 40 +E2 1C 4D 43 08 3C 47 93 04 24 FF 40 20 00 00 00 +57 83 1F 53 5D 53 3E 40 30 00 6E 9F 05 20 4E 48 +1E 83 4C 4D 0C 9E EF 3B 3C 40 E2 1C 46 16 10 01 +31 80 0E 00 CE 01 3D 40 00 18 4F 43 1E 53 FE 4D +FF FF 5F 53 7F 90 0D 00 F9 2B F1 93 00 00 39 24 +5F 41 01 00 C2 4F 16 1E 3F 90 15 00 05 38 3F 90 +EC 00 02 34 C2 43 16 1E 5F 41 02 00 47 18 0F 5F +5E 41 03 00 0E 5F 82 4E D4 1E 5F 41 04 00 47 18 +0F 5F 5E 41 05 00 0E 5F 82 4E A2 1E D2 41 06 00 +12 1D D2 41 07 00 13 1D D2 41 08 00 14 1D D2 41 +09 00 15 1D F1 93 0C 00 08 24 5F 41 0A 00 47 18 +0F 5F 5E 41 0B 00 0E 5F 01 3C 0E 43 82 4E 22 1E +16 3C E2 42 16 1E B2 40 06 FF D4 1E B2 40 F6 FF +A2 1E F2 40 79 00 12 1D F2 40 56 00 13 1D F2 40 +34 00 14 1D F2 40 12 00 15 1D 82 43 22 1E 31 50 +0E 00 10 01 0A 14 CA 0C 1F 42 44 1E 8F 93 02 00 +10 20 8F 93 00 00 0D 20 C2 93 49 1E 0A 24 5E 42 +49 1E 3E 50 64 00 5D 42 DA 1E 0D 9E 02 34 4C 43 +42 3C BF 40 00 70 08 00 5C 42 51 1E 1D 42 4E 1E +1E 42 50 1E 3D F3 3E F0 FF 00 3F 40 00 08 B0 13 +82 D5 1C 52 D8 1E 1F 42 44 1E 8F 4C 0A 00 1F 42 +44 1E 9F 42 D8 1E 0C 00 1F 42 44 1E CF 43 14 00 +1F 42 44 1E CF 43 15 00 1F 42 44 1E 8F 93 02 00 +05 20 8F 93 00 00 02 20 EF D2 1A 00 1D 42 44 1E +1E 42 4E 1E 1F 42 50 1E 3E F3 3F F0 FF 00 8D 4E +00 00 8D 4F 02 00 1F 42 44 1E 9F 43 18 00 CC 0A +B0 13 F6 C0 5C 43 0A 16 10 01 3A 14 07 4F 07 ED +0A 4F 5A 02 8A 10 4A 4A 0A 93 49 24 7F D0 80 00 +0B 4D 5B 02 8B 10 4B 4B 0B 93 3F 24 7D D0 80 00 +0B 5A 3B 80 7F 00 08 43 09 43 0E 93 09 24 1A 43 +5E 00 02 28 08 5C 09 6D 59 00 58 00 5A 02 F8 2B +0E 43 1A 43 5F 00 02 28 08 5C 09 6D 59 00 58 00 +5E 00 3E B0 00 10 02 24 3E D0 00 20 4A 5A F2 23 +49 93 02 34 1B 53 03 3C 0E 6E 08 68 49 69 3E B0 +00 80 07 24 08 63 49 63 0B 63 3E B0 00 60 01 20 +18 C3 1B 93 0C 38 3B 90 FF 00 0C 34 49 59 8B 10 +09 DB 57 02 59 00 0D 49 0C 48 37 16 10 01 0C 43 +0D 43 FB 3F 3D 40 FF FE 3C 43 57 02 5D 00 F5 3F +CF 0D CD 0E CE 0C C2 93 D1 1D 06 20 B0 13 DC EC +4C 93 02 20 2C 43 10 01 2E 83 2C 24 1E 83 43 24 +2E 83 20 24 1E 83 3B 24 3E 80 03 00 34 24 1E 83 +30 20 0E 43 8D 93 00 00 09 20 0F 93 2A 20 1C 4D +02 00 1D 4D 04 00 B0 13 A8 ED 31 3C 1C 43 2C 9D +20 20 0F 93 1E 20 1C 4D 02 00 1D 4D 04 00 B0 13 +96 ED 25 3C 3F B0 FE FF 14 20 CC 0F B0 13 04 EA +CE 0C 1D 3C 3F 90 03 00 07 24 2F 93 0A 20 CC 0D +B0 13 38 E1 CE 0C 13 3C CC 0D B0 13 36 D2 CE 0C +0E 3C 2E 43 0C 3C B0 13 B6 F0 CE 0C 08 3C B0 13 +BA F0 CE 0C 04 3C CC 0F B0 13 2C CF CE 0C CC 0E +10 01 0A 14 31 80 06 00 B0 13 EE ED 2E 42 CF 01 +1F 53 3D 40 12 1D 1F 53 FF 4D FF FF 1E 83 FB 23 +3C 40 05 00 0D 43 CE 01 1E 53 B0 13 F0 B7 D2 43 +F0 1C 4A 43 B0 13 20 E2 0C 93 08 24 B0 13 38 B9 +1A 2C F2 B0 20 00 F0 1C F5 27 1F 3C E1 43 00 00 +3C 40 03 00 3D 40 0A 00 CE 01 B0 13 F0 B7 4A 43 +B0 13 AA F0 0C 93 04 20 E2 43 F0 1C 5C 43 10 3C +B0 13 38 B9 06 28 C2 43 D1 1D E2 42 F0 1C 4C 43 +07 3C F2 B0 20 00 F0 1C EB 27 C2 43 D1 1D 4C 43 +31 50 06 00 0A 16 10 01 3C 40 E8 03 B0 13 FE ED +B2 40 2B 5A 5C 01 CF 0A 1A 43 4A 5F 7F 90 0B 00 +10 01 92 93 EA 1C 1C 24 C2 93 31 1D 0B 20 F2 B0 +F0 FF F2 1C 04 20 32 D0 D8 00 03 43 34 3C F2 40 +05 00 31 1D D2 83 31 1D 04 20 F2 F0 0F 00 F2 1C +2A 3C 3C 40 D7 03 B0 13 A0 CC F2 D2 F0 1C 23 3C +3C 40 A3 00 B0 13 A0 CC B2 B2 0A 1E 1C 24 F2 B0 +20 00 01 02 18 24 B2 C2 0A 1E B0 13 4C E3 D2 53 +31 1D 5F 42 31 1D 5F 83 6F 93 0D 28 C2 43 31 1D +D2 42 59 1E F3 1C D2 42 5A 1E F4 1C D2 42 5B 1E +F5 1C F2 D2 F0 1C B2 B0 10 00 8C 1C 0A 24 5C 43 +6D 43 B0 13 26 97 B2 F0 EF FF 8C 1C B2 40 2B 5A +5C 01 10 01 1A 14 21 82 39 40 CB 00 3C 40 00 40 +B0 13 A0 CC 3C 40 03 00 3D 40 05 00 0E 43 B0 13 +F0 B7 D1 43 02 00 C1 49 03 00 CC 01 2C 53 6D 43 +B0 13 40 CA 3C 40 03 00 3D 42 0E 43 B0 13 F0 B7 +3C 40 0A 00 B0 13 FE ED CC 01 B0 13 CA D5 0C 93 +18 20 C1 93 00 00 F8 27 B0 13 1E 9B 4A 43 5A 92 +17 1D F2 2F 3C 40 0A 00 B0 13 FE ED 4C 4A B0 13 +F6 AB 3C 40 F2 1C 7D 40 13 00 B0 13 40 CA 5A 53 +EE 3F 3C 40 03 00 2D 42 0E 43 B0 13 F0 B7 B2 40 +2B 5A 5C 01 F2 B0 20 00 F0 1C B8 27 C2 43 D1 1D +21 52 19 16 10 01 1A 14 21 82 CA 0C F2 B0 40 00 +01 02 3C 24 B0 13 0C D4 82 4C 1E 1E B0 13 D8 CB +81 4C 00 00 81 4D 02 00 4A 93 03 20 B0 13 22 BB +27 3C 2C 41 1D 41 02 00 B0 13 44 E0 3E 40 CD CC +3F 40 4C 3E B0 13 3A B7 C9 0C CA 0D 1C 42 1A 1E +1D 42 1C 1E B0 13 44 E0 3E 40 CD CC 3F 40 4C 3F +B0 13 3A B7 CE 0C CF 0D CC 09 CD 0A B0 13 E6 9E +B0 13 58 D4 81 4C 00 00 81 4D 02 00 B0 13 22 BB +1E 42 1E 1E B0 13 00 80 82 4C 20 1E 21 52 19 16 +10 01 1C 41 04 00 1D 41 06 00 82 4C 1A 1E 82 4D +1C 1E 10 01 5C 43 B0 13 D2 CE 5C 43 6D 42 80 13 +0E 1E B0 13 E0 DF B0 13 4C DA B0 13 3C EA 4C 43 +B0 13 9C BD 7C 40 17 00 6D 43 B0 13 02 E9 7C 40 +18 00 6D 43 B0 13 02 E9 7C 40 19 00 6D 43 B0 13 +02 E9 3C 40 00 20 B0 13 A0 CC B0 13 BA ED B2 40 +03 00 EA 1C B2 40 10 0E EC 1C B0 13 A2 B8 4C 93 +02 24 B0 13 F4 B9 82 43 EA 1C B0 13 0E EE 3C 40 +00 20 B0 13 A0 CC C2 43 1D 02 82 43 76 1E 7C 40 +17 00 6D 42 B0 13 02 E9 7C 40 18 00 6D 42 B0 13 +02 E9 7C 40 19 00 6D 42 B0 13 02 E9 92 D3 8C 1C +10 01 5A 14 C6 0F C7 0E C5 0D C9 0C 18 41 1C 00 +C7 43 00 00 B0 13 94 AE CA 0C 0A 93 02 20 2C 42 +3C 3C 1F 43 2F 99 02 24 09 43 09 3C 5C 49 02 00 +B0 13 F2 E3 C9 0C 09 93 02 20 2C 43 2E 3C 5E 4A +02 00 7E 80 0B 00 C7 4E 00 00 3D 40 0E 00 0D 5A +4E 4E CC 05 B0 13 60 ED 09 93 06 24 D9 4A 21 00 +07 00 D9 4A 22 00 08 00 06 93 07 24 3D 40 07 00 +0D 5A CC 06 2E 42 B0 13 60 ED 08 93 06 24 3F 40 +07 00 5F FA 0C 00 C8 4F 00 00 5D 4A 01 00 5C 43 +B0 13 4C E2 CA 43 00 00 0C 43 55 16 10 01 4F 43 +4C 93 2D 24 5C 93 20 24 6C 93 13 24 7C 90 03 00 +2A 20 A2 D2 22 03 A2 C2 24 03 B2 C2 22 03 B0 13 +CE F0 B0 13 FC BC 1F 42 20 03 6F F2 B2 C2 22 03 +1A 3C A2 D2 24 03 B0 13 EA BC B0 13 FC BC A2 D2 +22 03 B0 13 CE F0 0F 3C A2 D2 24 03 B2 C2 22 03 +A2 D2 22 03 B0 13 CE F0 B0 13 E0 BC 04 3C A2 D2 +24 03 B0 13 E0 BC 4C 43 4F 93 01 20 5C 43 10 01 +B0 13 FC BC B0 13 EA BC 10 01 A2 C2 22 03 B0 13 +CE F0 B2 C2 22 03 B0 13 CE F0 10 01 B2 D2 22 03 +B0 13 CE F0 10 01 1A 14 CB 0C 7B 90 BD 00 07 24 +4C 43 7B 90 31 00 40 28 7B 90 3D 00 3D 2C 0A 42 +32 C2 03 43 B2 F0 BF FF 02 0F B2 B0 10 00 02 0F +FC 27 7B 90 3D 00 26 2C 4C 43 B0 13 CA EB C9 0C +4C 43 7D 40 29 00 B0 13 28 DD C2 4B 11 0F A2 B2 +30 0F 13 24 7B 90 32 00 10 24 7B 90 39 00 0D 24 +7B 90 38 00 0A 24 A2 B2 30 0F FD 23 0D 14 3D 40 +BF 0C 1D 83 FE 23 0D 16 03 43 4C 43 CD 09 B0 13 +28 DD 03 3C F2 40 BD 00 11 0F 5C 42 21 0F B2 B0 +40 00 02 0F FC 27 02 4A 19 16 10 01 0A 14 21 82 +CA 0C 0C 43 3D 40 00 08 3E 40 0A 00 B0 13 70 C9 +0D 43 3E 40 07 0D 0F 43 B0 13 46 E7 3C 80 B9 65 +3D 70 5E 00 3E 40 00 08 0F 43 B0 13 CC D9 81 4C +00 00 81 4D 02 00 1E 42 D4 1E 3E B0 00 80 0F 7F +3F E3 81 5E 00 00 81 6F 02 00 5A 93 1A 20 1E 42 +D2 1E 3E B0 00 80 0F 7F 3F E3 1F 91 02 00 0D 38 +02 20 2E 91 0A 28 81 9F 02 00 04 38 0C 20 81 9E +00 00 09 2C 92 83 D2 1E 06 3C 1E 53 82 4E D2 1E +02 3C A2 41 D2 1E B2 D0 40 00 8C 1C 21 52 0A 16 +10 01 4C 43 B0 13 C2 E5 0C 93 42 24 1C 83 42 20 +B0 13 5C F0 4C 4C C2 4C FA 1D B0 13 AA E7 C2 4C +00 1E B0 13 8A E7 0D 43 82 4C 02 1E 82 4D 04 1E +5C 42 FA 1D 7C 90 41 00 28 28 1D 42 F8 1D 0D 93 +24 24 4C 4C 3C 80 3C 00 B0 13 38 EC CF 0C 44 19 +0F 10 D2 93 F6 1D 03 20 46 19 0C 10 0F 8C CD 0F +0E 43 1D 52 FC 1D 1E 62 FE 1D 3E 90 EB 0B 04 28 +08 20 3D 90 01 C2 05 2C 82 5F FC 1D 82 63 FE 1D +04 3C 82 43 FC 1D 82 43 FE 1D 92 43 F0 1D 10 01 +80 00 EE D4 10 01 3A 14 07 4F 07 ED 0A 4F 5A 02 +8A 10 4A 4A 0A 93 38 24 7F D0 80 00 0B 4D 5B 02 +8B 10 4B 4B 0B 93 2B 24 7D D0 80 00 0B 8A 3B 50 +7F 00 3A 40 18 00 08 43 09 43 0C 8E 0D 7F 03 2C +0C 5E 0D 6F 12 C3 08 68 09 69 5C 02 0D 6D 1A 83 +F4 23 49 93 03 30 1A 53 1B 83 EF 3F 0C 7E 0D 7F +08 63 49 63 0B 63 1B 93 0C 38 3B 90 FF 00 0C 34 +49 59 8B 10 09 DB 57 02 59 00 0D 49 0C 48 37 16 +10 01 0C 43 0D 43 FB 3F 3C 40 FF FE 3D 43 57 02 +5D 00 F5 3F 2A 14 21 83 C9 0C 3F 40 0B 00 0F 59 +68 4F 3A 40 3F 00 4A F8 3C 40 07 00 0C 59 1D 42 +64 1E 2E 42 B0 13 2E E6 0C 93 2D 24 78 B0 40 00 +2A 20 4A 93 10 24 7A 90 07 00 0D 2C 4A 4A 5A 06 +00 18 5F 4A 90 F6 2C 43 0C 59 4F 13 1C 93 1B 20 +D9 43 00 00 1A 3C 7A 90 3F 00 03 24 7A 90 20 00 +12 28 2C 43 0C 59 CD 01 B0 13 E0 BF 4C 93 0B 24 +D9 43 00 00 00 18 C2 93 68 1E 07 24 6C 41 80 13 +68 1E 4C 93 02 24 C9 43 00 00 21 53 28 16 10 01 +4A 14 C7 0D C8 0C 39 40 B9 1D 3A 40 3F 00 5A F8 +09 00 26 43 2F 43 6F 99 32 20 5A 99 09 00 2F 20 +7A 90 3F 00 0B 24 3C 40 03 00 0C 59 3D 40 05 00 +0D 58 2E 42 B0 13 2E E6 0C 93 21 20 D7 49 0B 00 +00 00 57 43 7A 90 3F 00 16 24 3F 40 0A 00 0F 58 +6F 4F 7F B0 80 FF 0A 20 7F B2 0D 24 D9 98 0B 00 +02 00 02 20 C9 43 02 00 47 43 05 3C 5D 49 0A 00 +CC 08 B0 13 88 C4 B0 13 CE EE CC 07 05 3C 39 50 +0C 00 16 83 C7 23 4C 43 46 16 10 01 4A 14 C9 0F +C7 0E C6 0D CA 0C 6C 43 B0 13 7C C5 C8 0C 08 93 +02 20 0C 43 36 3C CF 07 7F 50 0B 00 C8 4F 02 00 +3E 40 0B 00 0E 58 3F 40 80 00 6F FE 4F DA CE 4F +00 00 D8 42 62 1E 0D 00 D2 53 62 1E FD 27 F8 F0 +BF 00 0C 00 5F 48 0C 00 7F F0 F8 00 4F D9 C8 4F +0C 00 F8 F0 7F 00 0C 00 F8 C2 0C 00 FE F0 7F 00 +00 00 3C 40 0E 00 0C 58 4E 47 CD 06 B0 13 60 ED +3C 40 07 00 0C 58 1D 42 64 1E 2E 42 B0 13 60 ED +CC 08 46 16 10 01 1F 42 44 1E CF 43 11 00 1F 42 +44 1E DF 42 51 1E 13 00 1F 42 44 1E 5E 42 D8 1E +5E 8F 0C 00 CF 4E 16 00 1F 42 44 1E 5E 4F 16 00 +8E 11 8F 5E 0A 00 1F 42 44 1E DF 5F 16 00 15 00 +1F 42 44 1E DF 42 DA 1E 12 00 1F 42 44 1E FF 92 +12 00 02 2C FF 42 12 00 1F 42 44 1E 9F 42 52 1E +04 00 9F 42 54 1E 06 00 1F 42 44 1E DF 42 56 1E +0E 00 1F 42 44 1E EF B2 1A 00 03 20 4D 43 B0 13 +4C D9 B0 13 1A CE D2 C3 D6 1E 10 01 1E 42 44 1E +5F 4E 15 00 8F 11 3F 90 40 00 10 34 3F 90 C1 FF +19 34 FE 50 40 00 15 00 1F 42 44 1E 9F 83 08 00 +1F 42 44 1E 5F 4F 15 00 8F 11 0C 3C FE 80 40 00 +15 00 1F 42 44 1E 9F 53 08 00 1F 42 44 1E 5F 4F +15 00 8F 11 1E 42 44 1E CE 5F 14 00 1E 42 44 1E +5F 4E 14 00 8F 11 3F 90 40 00 0B 34 3F 90 C1 FF +0F 34 FE 50 40 00 14 00 1F 42 44 1E 9F 83 0A 00 +10 01 FE 80 40 00 14 00 1F 42 44 1E 9F 53 0A 00 +10 01 4F 14 1F 42 6E 03 2F 83 36 24 2F 83 27 24 +2F 83 03 24 2F 83 1A 24 31 3C B2 F0 EF FF 48 03 +92 C3 48 03 82 93 50 03 02 20 0F 43 05 3C 1F 42 +50 03 1F 92 50 03 FB 23 1F 52 C0 1E 82 4F 58 03 +B2 D0 10 00 48 03 80 13 BC 1E 18 3C B2 F0 EF FF +4A 03 92 C3 4A 03 B2 D0 80 00 08 1E 0F 3C B2 F0 +EF FF 46 03 92 C3 46 03 B0 13 B4 DC B2 D0 10 00 +46 03 B0 13 48 A8 02 3C B0 13 00 DC B1 C0 D0 00 +14 00 4B 16 00 13 0A 14 CA 0D 4C 4C 3C 90 07 00 +0E 34 3C 90 06 00 2F 24 1C 83 30 24 1C 83 14 24 +1C 83 2C 24 1C 83 27 24 1C 83 28 24 2A 3C 3C 80 +07 00 2C 93 23 28 2C 83 1E 24 1C 83 1F 24 1C 83 +1A 24 1C 83 1B 24 1D 3C 3A B0 03 00 0E 20 CC 0A +3D 40 64 00 B0 13 22 EC 0E 93 0A 20 CC 0A 3D 40 +90 01 B0 13 22 EC 0E 93 03 24 7C 40 1C 00 0A 3C +7C 40 1D 00 07 3C 7C 40 1E 00 04 3C 7C 40 1F 00 +01 3C 4C 43 0A 16 10 01 3C 40 B5 1D 0D 43 3E 40 +1C 00 B0 13 72 ED E2 43 B5 1D F2 40 3D 00 B6 1D +F2 40 20 00 B7 1D D2 43 B8 1D B0 13 76 E5 B0 13 +2A E8 B0 13 E8 E9 B0 13 E6 EF B0 13 1A E4 B0 13 +DC EF B0 13 08 E1 3F 40 B9 1D CF 43 00 00 3F 50 +0C 00 CF 43 00 00 C2 93 C5 1D 15 20 E2 43 C5 1D +F2 40 03 00 C6 1D 7F 40 3F 00 C2 4F CE 1D C2 4F +CF 1D F2 43 D0 1D B0 13 98 F0 CD 0C 3C 40 C8 1D +2E 42 B0 13 60 ED 0C 43 10 01 F2 D0 A9 00 C1 05 +F2 D0 80 00 C0 05 F2 40 1E 00 C6 05 C2 43 C7 05 +D2 C3 C0 05 F2 F0 DF 00 19 02 F2 F0 DF 00 05 02 +F2 F0 DF 00 04 02 F2 D0 20 00 06 02 F2 D0 E0 00 +0A 02 A2 D3 22 03 92 D3 22 03 3C 40 47 01 B0 13 +A0 CC F2 F0 DF 00 1D 02 F2 D0 20 00 1B 02 6C 42 +6D 43 B0 13 0C CB 6C 42 7D 40 0A 00 B0 13 0C CB +6C 42 6D 42 B0 13 0C CB 3C 40 A3 00 B0 13 A0 CC +6C 43 7D 40 82 00 80 00 0C CB 7C 40 36 00 B0 13 +06 BD F2 B0 10 00 D6 1E 27 24 7C 40 0A 00 5D 42 +98 1E B0 13 28 DD F2 90 7F 00 99 1E 07 38 7C 40 +0C 00 7D 40 0C 00 B0 13 28 DD 06 3C 7C 40 0C 00 +5D 42 99 1E B0 13 28 DD F2 B2 D6 1E 07 20 7C 40 +12 00 7D 40 11 00 B0 13 28 DD 06 3C 7C 40 12 00 +7D 40 15 00 B0 13 28 DD 7C 40 34 00 B0 13 06 BD +B2 F0 FE FD 32 0F B2 F0 FE FD 32 0F B2 D0 01 02 +36 0F A2 43 C4 1E 10 01 1A 14 31 80 22 00 C9 0D +5A 4C 0B 00 3F 40 CF 00 5F F1 0A 00 5F D2 66 1E +7F F0 BF 00 C1 4F 0A 00 3D 40 05 00 0D 5C CC 01 +1C 53 2E 42 B0 13 60 ED CC 01 3C 50 05 00 1D 42 +64 1E 2E 42 B0 13 60 ED 3D 40 C0 00 5D F1 09 00 +4D D9 F1 40 0B 00 00 00 C1 4A 0B 00 3F 40 70 00 +5F F1 0A 00 7F D0 0B 00 C1 4F 0A 00 7D F0 3F 00 +C1 4D 09 00 CC 01 4D 43 B0 13 AC B2 31 50 22 00 +19 16 10 01 21 82 F2 F0 BF 00 05 02 F2 F0 BF 00 +19 02 B2 D0 0C 00 22 03 B2 D0 0C 00 24 03 C2 43 +76 1D 3C 40 CC 0C B0 13 A0 CC 7C 40 06 00 5D 43 +B0 13 36 D0 C1 4C 00 00 3C 40 CC 0C B0 13 A0 CC +7C 40 07 00 4D 43 B0 13 4A C7 C1 4C 01 00 D1 B3 +01 00 12 20 C1 93 01 00 0F 24 7C 40 7F 00 4D 43 +B0 13 4A C7 C1 4C 02 00 D1 93 02 00 03 24 C2 43 +76 1D 02 3C D2 43 76 1D 21 52 10 01 2A 14 5C 93 +03 20 3F 40 00 1C 02 3C 3F 40 46 1C 2D 43 08 43 +CB 08 4E 43 79 40 03 00 CF 93 00 00 06 20 6C 93 +02 20 CC 0F 24 3C CB 0F 0C 3C 5C 93 0A 20 5E 53 +2A 42 6A 9F 06 24 5A 4F 01 00 4A 99 02 2C C8 0F +C9 0A 3F 50 23 00 1D 83 E7 23 0B 93 0C 20 08 93 +02 20 0C 43 0C 3C CB 08 5D 4B 01 00 B0 13 4C E2 +EB 43 01 00 03 3C 5E 53 CB 4E 01 00 CC 0B 28 16 +10 01 3C 40 10 00 3D 40 00 0A 3E 40 0B 00 B0 13 +70 C9 5C 06 3D 40 29 00 B0 13 22 EC 1F 42 A2 1E +0F 5C 3F 90 69 01 03 2C 1C 42 A0 1E 03 3C 1C 42 +A0 1E CF 0C 5C 06 0C 5F 5C 02 3D 40 0A 00 B0 13 +22 EC 82 4C A0 1E 3C 90 F0 00 08 28 B2 F0 DF FF +08 1E 7C 42 4D 43 B0 13 02 E9 07 3C B2 D0 20 00 +08 1E 7C 42 5D 43 B0 13 02 E9 B2 D2 8C 1C B2 D0 +80 00 8C 1C 10 01 1A 14 CF 0E CA 0C 7A 90 1A 00 +31 28 7A 90 2A 00 2E 2C 4E 4A 5E 02 1C 4E 8E 1C +4E 4A 5E 4E FE F5 7D 90 30 00 05 2C 7D 90 2D 00 +05 20 6B 43 08 3C 7D 90 5B 00 02 28 4B 43 03 3C +4B 4D 5B 4B A2 F5 7A 90 21 00 11 28 C9 0B 43 18 +49 59 43 19 4B 10 4B D9 7A 90 21 00 08 20 7D 90 +31 00 03 24 7D 90 4C 00 02 20 7B 40 80 00 CD 0B +B0 13 BC CD 19 16 10 01 0A 14 CE 0C 0B 42 32 C2 +03 43 B2 F0 BF FF 02 0F B2 B0 10 00 02 0F FC 27 +7E 90 31 00 23 28 7E 90 3D 00 20 2C 4C 43 B0 13 +2C D7 CA 0C 4C 43 7D 40 29 00 B0 13 46 DF C2 4E +11 0F A2 B2 30 0F 0D 24 7E 90 32 00 0A 24 7E 90 +38 00 07 24 A2 B2 30 0F FD 23 3C 40 F8 02 B0 13 +8C EA 4C 43 CD 0A B0 13 46 DF 02 3C C2 4E 11 0F +5C 42 21 0F 02 4B 0A 16 10 01 0A 14 CB 0D CA 0C +4C 43 B0 13 6E BC 7C 40 22 00 B0 13 AC C7 0C 24 +CC 0A B0 13 AC C7 08 24 5C 43 B0 13 6E BC 7C 40 +23 00 B0 13 AC C7 02 20 0C 43 16 3C 5B 93 05 24 +4C 43 B0 13 88 D2 4D 4C 0B 3C 5C 43 B0 13 88 D2 +4C 4C 4D 4C 8D 10 4C 43 B0 13 88 D2 4C 4C 0D DC +6C 43 B0 13 6E BC CC 0D 0A 16 10 01 B0 13 0A D9 +7C 40 03 00 B0 13 6E BC 4C 93 10 01 7C 40 36 00 +B0 13 06 BD 4C 43 3D 40 28 F6 7E 40 27 00 B0 13 +FC D7 7C 40 2C 00 7D 40 88 00 B0 13 28 DD 7C 40 +2D 00 7D 40 31 00 B0 13 28 DD 7C 40 2E 00 7D 40 +09 00 B0 13 28 DD 7C 40 36 00 B0 13 06 BD 7C 40 +33 00 B0 13 06 BD 7C 40 3D 00 B0 13 06 BD 7C B0 +70 00 F9 23 7C 40 36 00 B0 13 06 BD 82 43 C4 1E +B2 D0 01 02 34 0F 82 43 32 0F 10 01 B2 40 0A F3 +E6 1E B2 40 88 F3 E4 1E 00 18 D2 42 12 F3 0E 1E +00 18 D2 42 90 F3 12 1E 82 43 76 1E 82 43 08 1E +82 43 0A 1E 82 43 8C 1C 82 43 0C 1E 92 D3 8C 1C +B2 D0 40 00 08 1E B0 13 C0 B5 B0 13 76 E6 B0 13 +04 ED B0 13 6E EB B0 13 FA EF B0 13 4A E8 B0 13 +8C D9 B0 13 A6 EE B0 13 D0 DD B0 13 04 F0 B0 13 +0E F0 B0 13 CC ED 80 00 F2 C5 4C 4C C2 93 93 1E +02 20 4C 43 10 01 41 18 4C 5C 4C 4C F2 F0 DF 00 +06 02 A2 C3 22 03 5F 42 CC 05 C2 4C CE 05 3F 40 +E8 03 D2 B3 DD 05 03 20 1F 83 FB 23 18 3C 0F 93 +16 24 5F 42 CC 05 C2 43 CE 05 3F 40 E8 03 D2 B3 +DD 05 03 20 1F 83 FB 23 0A 3C 0F 93 08 24 5C 42 +CC 05 A2 D3 22 03 F2 D0 20 00 06 02 10 01 C2 43 +93 1E 4C 43 10 01 0A 14 CA 0D CB 0C 7B 93 02 24 +CF 0B 02 3C 4B 43 4F 43 4E 4B 4F 4F 0F 8E 1F 53 +4C 4B 3D 40 1C 00 B0 13 38 EC 1C 52 D4 F6 4A 93 +09 24 8C 43 00 00 8C 43 02 00 CC 43 1A 00 FC 40 +7F 00 10 00 8C 43 18 00 FC F0 FC 00 1A 00 8C 43 +04 00 8C 43 06 00 CC 43 0E 00 CC 43 12 00 CC 43 +0F 00 CC 43 11 00 5B 53 1F 83 DA 23 0A 16 10 01 +1A 14 C9 0D 3A 40 81 00 0A 5C 82 DA B0 01 CF 09 +3F 50 10 00 82 4F 00 07 B2 40 00 02 02 07 7E 50 +10 00 C2 4E 10 07 92 43 0C 07 2C 43 B0 13 A0 CC +A2 D3 00 07 C2 43 EA 1E 92 D3 00 07 3C 40 05 00 +B0 13 A0 CC C2 93 EA 1E FD 27 39 D0 03 00 82 C9 +00 07 B2 F0 EF FF 00 07 82 CA B0 01 82 43 0C 07 +1C 42 E8 1E 19 16 10 01 1A 14 21 82 CA 0C 3C 40 +05 00 0C 5A 5D 4A 0E 00 B0 13 3C DC 0C 93 02 20 +3F 42 03 3C B0 13 92 F0 0F 43 F1 40 82 00 00 00 +D1 4A 0D 00 01 00 C1 4F 02 00 6C 43 CD 01 7E 40 +03 00 7F 40 03 00 B0 13 6C C0 C9 0C 09 93 0D 24 +3C 40 03 00 0C 59 3D 40 05 00 0D 5A 2E 42 B0 13 +60 ED CC 09 4D 43 B0 13 68 E1 21 52 19 16 10 01 +2A 14 C8 0D C9 0C 5C 42 77 1D B0 13 F2 E3 CA 0C +B0 13 80 F0 0A 93 24 24 CC 0A 5D 43 B0 13 50 E5 +0C 93 1F 20 09 93 1D 24 5C 4A 0A 00 5F 4A 01 00 +CD 09 CE 08 B0 13 6C C0 C9 0C 09 93 0E 24 3C 40 +03 00 0C 59 3D 40 03 00 0D 5A 2E 42 B0 13 60 ED +CC 09 5D 43 B0 13 68 E1 04 3C 3C 40 03 00 01 3C +2C 43 28 16 10 01 0E 42 32 C2 03 43 4C 93 2C 24 +4F 4C 3F 50 00 7E B2 B0 10 00 02 0F FC 27 82 4F +10 0F B2 B0 10 00 02 0F FC 27 F2 40 3D 00 11 0F +B2 B0 10 00 02 0F FC 27 F2 40 FE 00 11 0F B2 B0 +20 00 02 0F FC 27 C2 43 10 0F B2 B0 80 00 02 0F +FC 27 5D 42 20 0F B2 B0 10 00 02 0F FC 27 F2 40 +3D 00 11 0F 4D 9C D7 23 02 4E 10 01 4C 4C C2 93 +93 1E 2E 24 41 18 4C 5C 6C D3 F2 F0 DF 00 06 02 +A2 C3 22 03 5F 42 CC 05 C2 4C CE 05 3F 40 E8 03 +D2 B3 DD 05 03 20 1F 83 FB 23 18 3C 0F 93 16 24 +5F 42 CC 05 C2 4D CE 05 3F 40 E8 03 D2 B3 DD 05 +03 20 1F 83 FB 23 0A 3C 0F 93 08 24 5F 42 CC 05 +A2 D3 22 03 F2 D0 20 00 06 02 10 01 C2 43 93 1E +10 01 0A 14 CA 0D 6A 92 1A 24 B0 13 22 EF 4C 93 +08 20 7C 40 47 00 3D 40 40 F5 5E 43 B0 13 70 AF +0E 3C 5C 42 FA 1D 0D 43 7E 40 03 00 6F 43 B0 13 +FC B4 CD 0C 7C 40 47 00 5E 43 B0 13 70 AF B0 13 +22 EF 4C 93 0F 20 5A 93 08 24 6A 92 0B 20 7C 40 +13 00 4D 43 B0 13 02 E9 05 3C 7C 40 13 00 5D 43 +B0 13 02 E9 0A 16 10 01 21 82 81 43 00 00 81 43 +02 00 7C 40 7F 00 4D 43 B0 13 4A C7 81 4C 00 00 +81 43 02 00 2C 41 1F 41 02 00 47 18 0C 5C 0D 43 +3C F0 00 07 0D F3 B0 13 62 DB 81 4C 00 00 81 4D +02 00 7C 40 80 00 5D 43 B0 13 4A C7 81 DC 00 00 +12 C3 11 10 02 00 11 10 00 00 12 C3 11 10 02 00 +11 10 00 00 2C 41 1D 41 02 00 21 52 10 01 1F 42 +38 0F 1E 42 0E 0F 0E 93 14 20 0F 93 28 24 3F 90 +14 00 0C 20 B2 B0 00 02 36 0F 03 20 32 C2 03 43 +FF 3F B2 F0 FF FD 32 0F 80 00 56 A7 32 C2 03 43 +FF 3F 2E 93 11 20 1F 42 0C 0F 2F 93 0A 24 2F 92 +08 24 3F 90 06 00 05 24 3F 92 03 24 32 C2 03 43 +FF 3F 32 C2 03 43 FF 3F 32 C2 03 43 FF 3F 10 01 +B2 B0 30 00 40 03 2B 24 B2 F0 EF FF 4A 03 B2 F0 +7F FF 08 1E 82 93 50 03 02 20 0F 43 05 3C 1F 42 +50 03 1F 92 50 03 FB 23 0F 5C 82 4F 5A 03 92 C3 +4A 03 B2 D0 10 00 4A 03 B0 13 54 F0 B2 40 2B 5A +5C 01 B0 13 F0 EC 4C 93 03 24 6D 43 B0 13 10 A0 +32 C2 03 43 B2 B0 80 00 08 1E EE 27 32 D2 10 01 +B2 F0 FE FD 36 0F B2 F0 FE FD 32 0F B2 F0 FE FD +32 0F 92 43 C4 1E 7C 40 32 00 B0 13 CA EB C2 4C +C6 1E 7C 43 3D 40 4E 1E 7E 40 0A 00 B0 13 B8 D7 +7C 43 B0 13 CA EB C2 4C DA 1E 7C B0 80 FF 04 20 +F2 80 80 00 DA 1E 03 3C F2 F0 7F 00 DA 1E 1F 42 +C8 1E 3F 80 10 00 82 4F D8 1E 80 00 CA DA 5D 93 +10 24 6D 93 08 24 6D 92 19 20 82 43 9C 1E 7C 42 +4D 43 80 00 02 E9 B0 13 9E CD B2 F0 7F FF 8C 1C +10 01 7C 42 5D 43 B0 13 02 E9 92 43 9C 1E B0 13 +9E CD 7C 40 29 00 5D 43 80 00 02 E9 10 01 1C 42 +A0 1E 0D 43 7E 40 03 00 4F 43 B0 13 FC B4 CD 0C +7C 40 5D 00 5E 43 B0 13 70 AF 10 01 5F 93 20 24 +4F 93 1B 24 6F 93 12 24 7F 90 03 00 05 24 6F 92 +1C 20 B0 13 0C CE 10 01 4E 4E 3E E3 CF 0E 6F FC +4D DF CC 4D 00 00 CC FE 20 00 10 01 B0 13 0C CE +CC DD 00 00 CC DD 20 00 10 01 CC CE 00 00 10 01 +6F 4C 4F CE 4D DF CC 4D 00 00 10 01 4E 4E 3E E3 +CC FE 00 00 CC FE 20 00 10 01 0A 14 1F 42 44 1E +DF 53 13 00 B0 13 7C C1 1F 42 44 1E 1E 4F 08 00 +1E 5F 0A 00 8F 4E 0C 00 1F 42 44 1E 9F 4F 0C 00 +0A 00 1A 42 44 1E CF 0A 5C 4F 13 00 2D 4F 1E 4F +02 00 3F 40 00 08 B0 13 82 D5 8A 8C 0C 00 1F 42 +44 1E FF 40 07 00 0F 00 1F 42 44 1E FF F0 FC 00 +1A 00 0A 16 10 01 92 53 26 1E 82 63 28 1E 1F 43 +5F 52 32 1E 3F 90 3C 00 1F 20 C2 43 32 1E 1F 43 +5F 52 31 1E 3F 90 3C 00 12 20 C2 43 31 1E 1F 43 +5F 52 30 1E F2 40 03 00 2E 1E 3F 90 18 00 03 24 +C2 4F 30 1E 10 01 C2 43 30 1E 80 00 28 D3 C2 4F +31 1E E2 43 2E 1E 10 01 C2 4F 32 1E D2 43 2E 1E +10 01 0A 14 CA 0C 7D 40 46 00 7E 40 5A 00 B0 13 +76 EF 0D 43 4E 43 B0 13 70 AF 5A 93 0D 24 7C 40 +29 00 B0 13 24 CF 7C 40 27 00 B0 13 24 CF 7C 40 +28 00 B0 13 24 CF 0C 3C 7C 40 1F 00 B0 13 24 CF +7C 40 20 00 B0 13 24 CF 7C 40 1E 00 B0 13 24 CF +0A 16 10 01 4D 43 B0 13 02 E9 10 01 0A 14 0A 43 +2C 92 22 24 3C 90 05 00 1C 24 3C 92 17 24 3C 90 +0A 00 12 20 2F 4D 0F 93 0A 24 1F 83 06 24 1F 83 +02 24 2C 43 16 3C 6C 43 03 3C 5C 43 01 3C 4C 43 +B0 13 72 EA 0C 43 0D 3C 2A 43 0A 3C B0 13 0A E8 +07 3C B0 13 E0 E6 04 3C B0 13 EA E7 B0 13 0A E6 +CC 0A 0A 16 10 01 1A 14 C9 0C 79 93 02 24 CA 09 +02 3C 49 43 4A 43 4F 49 4A 4A 0A 8F 1A 53 CC 09 +B0 13 C2 E5 0C 93 09 20 4C 49 3D 40 1C 00 B0 13 +38 EC 1C 52 D4 F6 B0 13 DE CF 59 53 1A 83 EF 23 +E2 B3 D6 1E 0A 24 B0 13 BE EF 4C 93 06 20 D2 C3 +D6 1E B0 13 DE ED B0 13 74 F0 19 16 10 01 AC 43 +18 00 FC F0 FC 00 1A 00 CC 43 12 00 5F 42 4A 1E +C2 93 4B 1E 03 20 CC 4F 13 00 08 3C 5E 42 4A 1E +12 C3 4E 10 4E 11 4F 8E CC 4F 13 00 E2 B3 D6 1E +11 20 F2 D0 06 00 D6 1E B0 13 C2 EE 82 4C 42 1E +C2 93 4B 1E 04 20 B2 50 E0 7F 42 1E 10 01 B2 50 +C0 53 42 1E 10 01 0A 14 21 83 CA 0D CB 0C 4C 43 +B0 13 6E BC 7C 40 22 00 B0 13 72 D0 0E 24 CC 0B +B0 13 72 D0 0A 24 CC 0A B0 13 80 D0 C1 4C 00 00 +6C 43 B0 13 6E BC 5C 43 01 3C 4C 43 21 53 0A 16 +10 01 B0 13 80 D0 C1 4C 04 00 C1 93 04 00 10 01 +B0 13 0A D9 7C 40 03 00 B0 13 6E BC 10 01 0A 14 +09 14 09 43 0A 43 1B 43 0F 93 04 24 09 4D 0D 4C +0C 43 0D 3C 5C 02 0D 6D 09 69 09 8E 04 28 1C D3 +5B 02 F8 2B 03 3C 09 5E 5B 02 F4 2B 1B 43 5C 02 +0D 6D 09 69 0A 6A 09 8E 0A 7F 04 28 1C D3 5B 02 +F6 2B 04 3C 09 5E 0A 6F 5B 02 F1 2B 0E 49 0F 4A +09 16 0A 16 10 01 0A 14 7C 40 23 00 B0 13 CA EB +CA 0C 7A D0 20 00 CD 0A 7C 40 23 00 B0 13 28 DD +7C 40 C6 00 B0 13 A6 CA 7C 40 33 00 B0 13 06 BD +7C 40 3D 00 B0 13 06 BD 7C B0 70 00 F9 23 3D 40 +DF 00 4D FA 7C 40 23 00 B0 13 28 DD 7C 40 36 00 +B0 13 06 BD 82 43 C4 1E 0A 16 10 01 0A 14 CA 0D +6A 92 17 24 1C 42 FC 1D 1D 42 FE 1D 3E 40 E8 03 +0F 43 B0 13 8E D0 7E 40 06 00 7F 40 05 00 B0 13 +FC B4 CD 0C 7C 40 5A 00 5E 43 B0 13 70 AF 5A 93 +08 24 6A 92 0B 20 7C 40 10 00 4D 43 B0 13 02 E9 +05 3C 7C 40 10 00 5D 43 B0 13 02 E9 0A 16 10 01 +B2 B0 20 00 08 1E 25 20 B0 13 22 EF 4C 93 21 20 +B0 13 3A EF 4C 93 1D 20 D2 53 89 1E E2 93 89 1E +18 20 4C 43 4D 43 B0 13 02 E9 5C 43 B0 13 D2 CE +7C 40 5A 00 3D 40 20 F5 5E 43 B0 13 70 AF 7C 40 +46 00 3D 40 56 F5 5E 43 B0 13 70 AF 3F 40 00 10 +C0 0F 10 01 2A 14 1A 41 10 00 49 4C 1B 42 44 1E +1B 4B 0C 00 0B 89 3B 80 32 00 28 4D C9 0B 09 88 +09 93 02 38 28 9E 15 20 8D 4B 00 00 1D 42 44 1E +4C 4C 1C 5D 0C 00 3C 50 10 00 8E 4C 00 00 1E 42 +44 1E DF 4E 0F 00 00 00 1F 42 44 1E DA 4F 10 00 +00 00 28 16 10 01 1A 14 CA 0C 5C 4A 05 00 CF 0C +3F 80 03 00 06 24 2F 83 2F 93 03 28 7F 40 03 00 +01 3C 5F 43 4C 4C 1D 4A 02 00 5E 4A 04 00 B0 13 +6C C0 C9 0C 09 93 0C 24 3C 40 03 00 0C 59 2D 4A +2E 42 B0 13 60 ED CC 09 5D 43 B0 13 68 E1 02 3C +3C 40 03 00 19 16 10 01 A2 D2 22 03 A2 C2 24 03 +3E 42 4F 43 B2 C2 22 03 B0 13 CC D2 4F 5F A2 B2 +20 03 01 24 5F D3 1E 83 F5 23 A2 D2 24 03 B2 C2 +22 03 5C 93 03 24 A2 D2 22 03 02 3C A2 C2 22 03 +B0 13 CC D2 B2 C2 22 03 CC 0F 10 01 B0 13 CE F0 +B2 D2 22 03 B0 13 CE F0 10 01 D2 B3 D6 1E 1E 24 +A2 93 46 1E 1B 24 1F 42 44 1E 2E 4F 1F 4F 02 00 +0F 93 09 20 0E 93 07 20 82 93 46 1E 0F 20 92 43 +46 1E 5C 43 10 01 1C 42 4E 1E 1D 42 50 1E 3C F3 +3D F0 FF 00 0D 9F 02 20 0C 9E 02 24 4C 43 10 01 +A2 43 46 1E 5C 43 10 01 2A 14 19 43 59 52 CB 1E +18 42 CE 1E 5A 42 CC 1E 4C 4A CD 08 B0 13 86 C2 +4C 4C 0C 99 11 34 5A 53 3A 90 0D 00 05 34 C2 4A +CC 1E D2 43 CB 1E 0A 3C D2 43 CB 1E D2 43 CC 1E +18 53 82 48 CE 1E 02 3C C2 49 CB 1E 92 D3 8C 1C +28 16 10 01 F2 B0 10 00 01 02 10 20 D2 B3 01 02 +06 24 C2 93 7F 1E 19 20 B2 D2 76 1E 0C 3C 82 43 +7C 1E F2 40 0A 00 7F 1E 80 00 9E F0 C2 93 7F 1E +0C 20 A2 D2 76 1E 92 53 7C 1E 92 42 26 1E 2A 1E +92 42 28 1E 2C 1E 80 00 A4 F0 D2 83 7F 1E 10 01 +2A 14 4A 4C 4C 4A B0 13 6E EE 4C 93 02 20 7A E3 +5A 53 3A B0 00 80 0B 7B 3B E3 38 40 AC F6 09 43 +0F 43 1C 43 0D 43 CE 0F B0 13 1E EE 0C FA 0D FB +CE 0F B0 13 2E EE 3D 48 B0 13 38 EC 09 5C 1F 53 +3F 90 07 00 EE 3B CC 09 28 16 10 01 21 83 81 43 +00 00 7C 40 81 00 5D 43 B0 13 4A C7 81 4C 00 00 +B1 B0 00 20 00 00 02 20 4E 43 08 3C B1 D0 00 C0 +00 00 B1 E3 00 00 91 53 00 00 5E 43 2C 41 5C 03 +CF 0C 4E 93 04 24 3C 40 AC 0A 0C 8F 03 3C 3C 40 +AC 0A 0C 5F 21 53 10 01 0B 4D 0E 4B 0D 93 1F 30 +3B F0 80 7F 1C 24 5B 02 8B 10 7E D0 80 00 3B 80 +7F 00 15 30 3B 90 20 00 0F 34 3B 80 17 00 05 30 +1B 83 08 30 5C 02 0E 6E FB 3F 5E 01 5C 00 1B 53 +01 24 FB 3F 0D 4E 10 01 3C 43 3D 43 10 01 0C 43 +0D 43 10 01 0B 4D 0B EF 0A 30 0D 93 12 30 0D 9F +02 24 19 34 16 3C 0C 9E 18 24 13 28 14 3C 3D B0 +80 7F 04 20 3F B0 80 7F 01 20 0F 24 0D 9F 0B 34 +08 3C 0F 9D 02 24 07 34 04 3C 0E 9C EC 27 01 28 +02 3C 3C 43 10 01 1C 43 10 01 0C 43 10 01 82 43 +EE 1D 4C 43 B0 13 6E F0 B0 13 0E EE C2 43 FA 1D +C2 43 00 1E 82 43 02 1E 82 43 04 1E 92 D3 8C 1C +7C 40 13 00 6D 42 B0 13 02 E9 7C 40 17 00 6D 42 +B0 13 02 E9 7C 40 18 00 6D 42 B0 13 02 E9 7C 40 +19 00 6D 42 80 00 02 E9 E2 93 AA 1E 13 24 B0 13 +78 EC C2 93 AA 1E 1C 24 82 43 90 03 B2 D0 10 00 +80 03 F2 D0 80 00 0B 02 E2 43 AA 1E 92 42 A8 1E +C0 1E 10 01 B2 F0 CF FF 80 03 F2 F0 7F 00 03 02 +F2 F0 7F 00 0B 02 D2 43 AA 1E 92 42 A6 1E C0 1E +10 01 1A 14 CB 0E CA 0D CE 0C CC 0A CD 0B B0 13 +A0 DB 4D 4C CC 0A 49 4E 5C E9 06 F4 47 18 0C 5C +4E ED 5E 4E 06 F4 0E 5C 4A 4A 47 18 0A 5A CC 0B +4C DD 0C 5A 0C EE 0F 9C 06 2C 3E 40 FF 7F 0C FE +5E 03 0F 9C FC 2B 19 16 10 01 1A 14 31 80 06 00 +C9 0C 5A 42 77 1D CC 0A B0 13 F2 E3 0C 93 02 20 +2C 43 13 3C 4D 43 B0 13 50 E5 0C 93 0E 20 91 43 +02 00 C1 4A 04 00 81 43 00 00 CC 01 2C 53 3D 40 +F2 1C CE 09 0F 43 B0 13 D2 BB 31 50 06 00 19 16 +10 01 C2 93 A4 1E 20 20 C2 4C A4 1E B2 40 8F 02 +A6 1E 82 4D A8 1E B2 40 14 01 80 03 B2 40 05 00 +92 03 B2 40 80 00 82 03 F2 D0 80 00 0B 02 00 18 +F2 40 38 D5 BC 1E 3C 40 8F 02 B0 13 F8 E2 92 42 +A8 1E C0 1E E2 43 AA 1E 10 01 F2 40 A5 00 21 01 +4E 4C 4F 4E 8F 10 0E 5F 3E 50 00 44 82 4E 24 01 +4F 4C 3F 50 00 44 82 4F 26 01 92 B3 2C 01 FD 27 +C2 4C 20 01 B2 F0 F9 FF 2C 01 A2 B3 2C 01 03 24 +A2 B2 2C 01 FD 27 82 4E 26 01 C2 43 21 01 10 01 +1A 14 3F 40 E8 F6 9F 00 FF FF 12 24 3D 40 E8 F6 +0C 3C 4F 13 2A 52 12 3C 3C 4D CA 0D CE 09 B0 13 +60 ED 0A 59 CD 0A 1D 53 1D C3 39 4D 09 93 F4 23 +3F 40 FF FF 3F 93 05 24 3A 40 FF FF 0F 0A DF 03 +E8 23 19 16 10 01 1A 14 21 83 CB 0F CA 0D C9 0C +5E 41 0E 00 B2 B0 40 00 08 1E 10 20 4C 4A B0 13 +26 EB C1 4E 00 00 4C 4C CD 0C 0E 43 CC 09 CF 0B +B0 13 02 E7 4C 4A B0 13 CC E9 05 3C C1 4E 00 00 +0E 43 B0 13 02 E7 21 53 19 16 10 01 7C 90 3C 00 +06 28 7C 90 3E 00 03 24 32 C2 03 43 FF 3F 0F 42 +32 C2 03 43 B2 B0 10 00 02 0F FC 27 7C 90 2F 00 +08 28 7C 90 3E 00 05 24 7C D0 C0 00 C2 4C 13 0F +04 3C 7C D0 80 00 C2 4C 13 0F 5C 42 22 0F 02 4F +10 01 0B 4D 0E 4B 3B F0 80 7F 1C 24 5B 02 8B 10 +7E D0 80 00 3B 80 7F 00 15 30 3B 90 10 00 10 34 +5E 01 5C 00 1E 93 01 24 FB 3F 1B 83 03 30 5C 02 +0E 6E FB 3F 0D 93 02 34 3E E3 1E 53 0C 4E 10 01 +3C 43 10 01 0C 43 10 01 0A 14 CB 0D 0A 42 32 C2 +03 43 B2 B0 10 00 02 0F FC 27 7C D0 C0 00 C2 4C +13 0F 4F 4E 1F 83 0A 24 B2 B0 80 00 02 0F FC 27 +1D 53 DD 42 22 0F FF FF 1F 83 F6 23 4D 4E 0D 5B +DD 42 20 0F FF FF 02 4A 0A 16 10 01 0B 42 32 C2 +03 43 B2 B0 10 00 02 0F FC 27 4C 4C 47 18 0C 5C +3C D0 00 40 6F 4D 0F 5C 82 4F 10 0F 6E 93 0C 28 +1D 53 4E 4E 1E 83 E2 4D 10 0F B2 B0 20 00 02 0F +FC 27 1D 53 1E 83 F7 23 5F 42 20 0F 02 4B 10 01 +92 B3 0A 1E 03 24 5C 43 B0 13 9C BD A2 B2 0A 1E +03 24 5C 43 B0 13 96 BA B2 B2 0A 1E 02 24 B0 13 +FE EE A2 B3 0A 1E 02 24 B0 13 F2 C5 B2 B0 10 00 +0A 1E 05 24 6C 43 3D 40 99 19 B0 13 12 D6 82 43 +0A 1E 10 01 1A 14 C9 0C 3D 40 0C 00 0D 59 6E 49 +7E 80 0B 00 5C 43 7F 40 03 00 B0 13 6C C0 CA 0C +0A 93 10 24 3C 40 03 00 0C 5A 3D 40 05 00 0D 59 +2E 42 B0 13 60 ED FA D0 80 00 0E 00 CC 0A 4D 43 +B0 13 68 E1 19 16 10 01 D2 B3 D6 1E 0E 24 1D 42 +4E 1E 1E 42 50 1E 3D F3 3E F0 FF 00 1F 42 44 1E +1E 9F 02 00 02 20 2D 9F 02 24 4C 43 10 01 DF 92 +51 1E 13 00 04 24 D2 C3 D6 1E 4C 43 10 01 EF C2 +1A 00 B0 13 F6 C0 5C 43 10 01 A2 D2 24 03 7F 40 +80 00 3E 42 B2 C2 22 03 CD 0C 4D FF 4D 9F 03 24 +A2 C2 22 03 02 3C A2 D2 22 03 12 C3 4F 10 B0 13 +CE F0 B2 D2 22 03 B0 13 CE F0 1E 83 EB 23 B2 C2 +22 03 A2 D2 22 03 A2 C2 24 03 10 01 4C 93 1D 20 +4C 43 B0 13 C2 E5 0C 93 04 24 1C 83 09 24 1C 83 +14 20 C2 43 DC 1E C2 43 DD 1E 82 43 DE 1E 10 01 +1F 42 D4 F6 D2 4F 0E 00 DC 1E 1E 4F 04 00 1F 4F +06 00 C2 4F DD 1E 82 4E DE 1E 10 01 82 43 18 1E +82 43 24 1E 82 43 20 1E C2 93 76 1D 16 24 B0 13 +2A E5 B0 13 4C DA B0 13 3C EA 1C 42 22 1E 0C 93 +0C 24 1C 52 20 1E 82 4C 20 1E 1D 42 1A 1E 1E 42 +1C 1E 1F 42 1E 1E 80 00 BA 93 10 01 0A 14 0A 43 +0F 93 05 34 3E E3 3F E3 1E 53 0F 63 1A D3 0D 93 +05 34 3C E3 3D E3 1C 53 0D 63 3A E3 B0 13 8E D0 +1A B3 04 24 3C E3 3D E3 1C 53 0D 63 2A B3 04 24 +3E E3 3F E3 1E 53 0F 63 0A 16 10 01 B0 13 52 B9 +F2 B2 F0 1C 14 24 3C 40 03 00 3D 40 05 00 0E 43 +B0 13 F0 B7 3C 40 F2 1C 6D 42 B0 13 40 CA 3C 40 +03 00 2D 42 0E 43 B0 13 F0 B7 F2 C2 F0 1C F2 B0 +20 00 F0 1C E3 27 C2 43 D1 1D 10 01 C2 93 76 1D +15 24 82 93 24 1E 19 20 F2 F0 BF 00 1D 02 F2 D0 +40 00 1B 02 B0 13 6A EF B2 40 10 0E 24 1E F2 B0 +40 00 01 02 FC 27 4C 43 80 00 96 BA 7C 40 47 00 +3D 40 06 F5 5E 43 80 00 70 AF 10 01 0A 14 CA 0D +CB 0E 4C 4C 3D 40 1C 00 B0 13 38 EC 1F 42 D4 F6 +0F 5C 8F 93 18 00 0F 20 8F 4A 00 00 8F 4B 02 00 +0B 93 06 20 0A 93 04 20 1C 52 D4 F6 EC C2 1A 00 +FF 40 7F 00 10 00 0A 16 10 01 0A 14 5A 42 57 1E +3C 40 4E 1E B0 13 AA DE 4C 4C 0C EA 47 18 0C 5C +8C 10 4C 4C CA 0C C2 4A 57 1E 3A 90 21 00 05 20 +D2 D3 D6 1E B0 13 74 F0 05 3C F2 F0 EF 00 D6 1E +B0 13 0A C4 0A 16 10 01 1A 14 C2 93 A2 1D 16 24 +3C 40 7A 1D 29 42 3A 40 D8 F6 3B 40 A4 1D 4E 43 +4F 43 7D 4C 7D 9B 01 20 5E 53 7D 9A 01 20 5F 53 +19 83 F7 23 6F 92 02 24 6E 92 02 20 4C 43 01 3C +5C 43 19 16 10 01 5C 02 0D 6D 5C 02 0D 6D 5C 02 +0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 +0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 +0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 +0D 6D 10 01 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 +5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 +5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 +5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 +10 01 0A 14 3F 40 B9 1D 2E 43 0C 43 2D 43 6D 9F +05 20 3F 50 0C 00 1C 53 1E 83 F8 23 6C 93 02 20 +0C 43 0C 3C 4C 4C 3D 40 0C 00 B0 13 38 EC 3A 40 +B9 1D 0A 5C CC 0A B0 13 98 DD CC 0A 0A 16 10 01 +92 C3 44 03 82 93 9A 1E 0E 24 B0 13 9A 82 92 93 +9A 1E 03 24 B0 13 AE DF 02 3C B0 13 0A C4 1C 42 +94 1E 80 00 E4 E8 F2 C2 D6 1E B0 13 0A C4 1C 42 +96 1E B0 13 E4 E8 92 43 9A 1E 10 01 3A 14 C8 0D +C7 0C 3A 40 B9 1D 29 43 2F 43 6F 9A 0E 20 3D 40 +03 00 0D 5A CC 07 2E 42 B0 13 2E E6 0C 93 05 20 +58 9A 0A 00 02 20 CC 0A 05 3C 3A 50 0C 00 19 83 +EB 23 0C 43 37 16 10 01 3A 14 C8 0D C7 0C 3A 40 +B9 1D 49 43 2F 43 6F 9A 0E 20 3C 40 03 00 0C 5A +CD 07 2E 42 B0 13 2E E6 0C 93 05 20 CA 98 0A 00 +02 20 CC 0A 05 3C 3A 50 0C 00 59 53 EB 27 0C 43 +37 16 10 01 C2 93 40 1E 14 20 3F 40 47 01 1F 52 +56 03 C2 93 36 1E 08 20 C2 93 37 1E 0E 24 3F 80 +03 00 C2 43 37 1E 09 3C 3F 80 05 00 C2 43 36 1E +F8 3F 3F 40 00 80 1F 52 56 03 82 4F 56 03 10 01 +82 43 4C 1E B0 13 7A F0 F2 40 21 00 48 1E F2 40 +06 00 4A 1E C2 43 49 1E D2 43 4B 1E 7C 43 5D 43 +B0 13 06 C9 B0 13 BC C7 B0 13 E6 D0 7C 40 0C 00 +5D 42 16 1E 80 00 28 DD 21 83 0F 42 32 C2 03 43 +B2 B0 10 00 02 0F FC 27 4C 4C 47 18 0C 5C 3C D0 +00 40 4D 4D 0C 5D 82 4C 10 0F B2 B0 20 00 02 0F +FC 27 5E 42 20 0F 81 4E 00 00 02 4F 21 53 10 01 +5F 14 1A 42 38 0F 4A 4A B0 13 3A EF 4C 93 10 20 +7A 90 14 00 04 24 4A 93 0D 20 03 43 0B 3C 1F 42 +EE 1D 1F 93 02 24 2F 93 05 20 B0 13 18 ED 02 3C +B0 13 3E CC 5A 16 00 13 21 83 CC 43 0A 00 EC 43 +00 00 DC 42 B8 1D 0B 00 D2 53 B8 1D 02 3C D2 53 +B8 1D C2 93 B8 1D FB 27 F2 93 B8 1D F8 27 5C 42 +B8 1D CD 01 B0 13 CA E3 4C 93 F1 23 21 53 10 01 +82 43 EE 1D 82 43 F2 1D 82 43 F4 1D 82 43 F0 1D +C2 43 FA 1D C2 43 00 1E 82 43 02 1E 82 43 04 1E +82 43 FC 1D 82 43 FE 1D C2 43 F6 1D B2 40 4B 00 +F8 1D C2 43 06 1E 10 01 B0 13 72 B3 B0 13 2C C8 +B0 13 84 87 B0 13 16 EF 82 93 76 1E 03 20 82 93 +08 1E 02 24 B0 13 36 A1 82 93 0A 1E 02 24 B0 13 +40 D8 82 93 8C 1C EE 27 B0 13 68 9C EB 3F 0A 14 +CA 0C 5D 42 EE 1E B0 13 D8 E0 4C 93 0E 24 B0 13 +84 ED CD 0C 1C 43 0C 5A 2E 42 B0 13 2E E6 0C 93 +02 20 0C 43 05 3C 2C 43 03 3C B0 13 CE EE 1C 43 +0A 16 10 01 0E 4C 0D 4C 0D 93 16 24 03 34 3D E3 +1D 53 0F 30 3B 40 8F 00 1B 83 5D 02 FD 2B 4C 4D +8C 10 8D 10 4D 4D 8B 10 0D DB 5E 02 5D 00 5C 00 +10 01 3D 40 00 C7 0C 43 10 01 0A 14 3A 40 09 00 +0F 43 6D 4C 3B 42 4E 4D 0E EF 3E 90 80 00 04 38 +4F 5F 7F E0 97 00 02 3C 4F 5F 4F 4F 4D 5D 1B 83 +F2 23 1C 53 1A 83 ED 23 CC 0F 0A 16 10 01 1D 42 +9E 1D 0F 42 32 C2 03 43 D2 43 9C 1D 02 4F 0D 93 +07 24 B0 13 C6 E8 C2 93 9B 1D 02 20 1D 83 F9 23 +0F 42 32 C2 03 43 C2 43 9B 1D C2 43 9C 1D 02 4F +10 01 B0 13 2C F0 1F 42 44 1E FF 90 7F 00 10 00 +0A 24 2C 93 05 34 3C 93 0D 34 DF 83 10 00 10 01 +DF 53 10 00 10 01 CF 4C 10 00 1F 42 44 1E FF 50 +0C 00 10 00 10 01 7C 90 2F 00 06 28 7C 90 3E 00 +03 24 32 C2 03 43 FF 3F 0F 42 32 C2 03 43 B2 B0 +10 00 02 0F FC 27 C2 4C 11 0F B2 B0 20 00 02 0F +FC 27 C2 4D 10 0F 02 4F 10 01 4D 93 03 20 32 C2 +03 43 FF 3F 0F 42 32 C2 03 43 B2 B0 10 00 02 0F +FC 27 F2 40 7F 00 11 0F 4D 4D B2 B0 20 00 02 0F +FC 27 F2 4C 10 0F 1D 83 F8 23 02 4F 10 01 B2 F0 +FE FD 36 0F B2 F0 FE FD 32 0F 7C 40 36 00 B0 13 +06 BD 7C 40 3A 00 B0 13 06 BD 7C 40 36 00 B0 13 +06 BD 7C 40 32 00 B0 13 06 BD 82 43 C4 1E 10 01 +F2 F0 DF 00 1B 02 92 C3 22 03 F2 F0 DF 00 03 02 +F2 F0 1F 00 02 02 F2 F0 1F 00 0A 02 A2 C3 22 03 +F2 D0 20 00 05 02 F2 D0 E0 00 04 02 A2 D3 24 03 +10 01 21 83 7C 40 30 00 B0 13 06 BD 81 43 00 00 +02 3C 91 53 00 00 B1 90 64 00 00 00 FA 2B 7C 40 +36 00 B0 13 06 BD 7C B0 70 00 F9 23 82 43 06 0F +21 53 10 01 0C 93 02 20 0D 93 14 24 3B 40 9F 00 +1B 83 5C 02 0D 6D FC 2B 12 C3 5D 00 5C 00 3E 40 +06 00 5D 01 5C 00 1E 83 FC 37 8B 10 0D DB 12 C3 +5D 00 5C 00 10 01 A2 B2 76 1E 15 24 5F 42 E0 1E +4F 93 0A 24 5F 93 0F 20 C2 43 E0 1E 92 D3 0C 1E +B2 D0 80 00 0C 1E 10 01 D2 43 E0 1E 92 D3 0C 1E +B2 D0 40 00 0C 1E 10 01 4D 93 03 20 32 C2 03 43 +FF 3F 0F 42 32 C2 03 43 4D 4D B2 B0 10 00 02 0F +FC 27 F2 40 BF 00 13 0F 1C 53 DC 42 22 0F FF FF +1D 83 F3 23 02 4F 10 01 CF 0C FF B0 80 FF 0C 00 +02 20 6C 43 10 01 CF 9D 0D 00 0C 20 B0 13 84 ED +CD 0C 1C 43 0C 5F 2E 42 B0 13 2E E6 0C 93 02 20 +4C 43 10 01 5C 43 10 01 82 93 6E 1E 09 20 82 93 +6C 1E 06 20 B2 40 04 03 6C 1E B2 40 02 01 6E 1E +B0 13 9E EB C2 4C 75 1E 4C 93 FA 27 3C 40 72 1E +0D 43 1E 43 80 00 72 ED 31 80 06 00 81 43 02 00 +D1 4C 05 00 04 00 CF 0C 3F 50 06 00 81 4F 00 00 +1D 4C 02 00 2E 42 0E 5C 2F 4C CC 01 2C 53 B0 13 +D2 BB 31 50 06 00 10 01 0A 14 CA 0C 3F 40 CF 00 +5F FA 0C 00 5F D2 66 1E CA 4F 0C 00 2C 43 0C 5A +B0 13 AC B2 4C 93 02 20 0C 43 02 3C 3C 40 09 00 +CA 43 00 00 0A 16 10 01 7C 90 80 00 09 28 4C 4C +3C 80 00 01 2D 43 B0 13 78 E2 3C 80 4A 00 04 3C +4C 4C 5C 03 3C 80 4A 00 3C 90 80 FF 02 34 3C 40 +80 FF 8C 11 10 01 92 C3 22 03 F2 F0 DF 00 03 02 +F2 F0 1F 00 02 02 A2 C3 22 03 F2 D0 20 00 05 02 +F2 D0 E0 00 04 02 A2 D3 24 03 92 D3 24 03 D2 43 +93 1E 10 01 B2 F0 FF FD 36 0F 7C 40 36 00 B0 13 +D8 C6 7C 40 3D 00 B0 13 D8 C6 7C B0 F0 FF F9 23 +7C 40 3A 00 B0 13 D8 C6 B2 F0 FF FD 32 0F 10 01 +C2 93 D1 1D 0E 20 B0 13 92 95 B0 13 08 C3 0C 93 +0C 20 B0 13 E0 E6 B0 13 84 ED B0 13 E6 E5 B0 13 +8A E8 D2 43 D1 1D 80 00 60 A6 10 01 5C 93 13 20 +0C 42 32 C2 03 43 2E 43 3F 40 00 1C CF 93 00 00 +05 24 5D 9F 01 00 02 2C DF 83 01 00 3F 50 23 00 +1E 83 F4 23 02 4C 10 01 0B 43 0D 93 03 34 3D E3 +1D 53 1B D3 0C 93 03 34 3C E3 1C 53 3B E3 B0 13 +22 EC 1B B3 02 24 3C E3 1C 53 2B B3 02 24 3E E3 +1E 53 10 01 4C 4C 3D 40 1C 00 B0 13 38 EC CF 0C +1F 52 D4 F6 EF B2 1A 00 03 24 0F 43 0D 43 05 3C +1C 52 D4 F6 2F 4C 1D 4C 02 00 CC 0F 10 01 C2 93 +4A 1E 09 24 1F 42 44 1E DF 83 13 00 1F 42 44 1E +CF 93 13 00 02 24 5C 43 10 01 8F 43 18 00 5D 43 +B0 13 4C D9 4C 43 10 01 82 4C C0 1E 82 93 50 03 +02 20 0F 43 05 3C 1F 42 50 03 1F 92 50 03 FB 23 +0F 5C 82 4F 58 03 92 C3 48 03 B2 D0 10 00 48 03 +10 01 31 40 FC 2B 00 18 F2 40 D2 F0 AC 1E 00 18 +F2 40 D2 F0 B0 1E B0 13 AE F0 0C 93 02 24 B0 13 +A0 D6 0C 43 B0 13 08 DE B0 13 B2 F0 92 B3 22 03 +11 24 7C 40 06 00 B0 13 9A C8 C2 4C 59 1E 7C 40 +07 00 B0 13 9A C8 C2 4C 5A 1E 7C 42 B0 13 9A C8 +C2 4C 5B 1E 10 01 5D 93 12 20 C2 93 89 1E 0A 24 +E2 93 89 1E 0C 2C 7C 40 5A 00 3D 40 1A F5 5E 43 +80 00 70 AF 7C 40 5A 00 3D 40 20 F5 F8 3F 10 01 +B2 D0 06 00 06 0A B2 40 1D 7B 00 0A B2 40 ED 00 +04 0A F2 D0 E0 00 4A 02 F2 D0 E0 00 44 02 B2 43 +0A 0A B2 40 FF 00 0C 0A 10 01 3F 40 B9 1D 0E 43 +2B 43 6B 9F 07 20 CF 9C 0B 00 04 20 CD 4E 00 00 +5C 43 10 01 3F 50 0C 00 1E 53 2E 93 F1 3B 4C 43 +10 01 21 83 CD 01 B0 13 CA E3 4C 93 0B 24 6C 41 +3D 40 0C 00 B0 13 38 EC EC 93 B9 1D 03 20 3C 50 +B9 1D 01 3C 0C 43 21 53 10 01 82 93 8C 1E 09 20 +82 93 8A 1E 06 20 B2 40 08 07 8A 1E B2 40 06 05 +8C 1E 00 18 C2 43 8E 1E B0 13 9E EB C2 4C 92 1E +10 01 B2 B0 20 00 08 1E 0F 20 B0 13 22 EF 4C 93 +0B 20 F2 C2 03 02 F2 C2 05 02 F2 C2 1B 02 2C 43 +B0 13 16 B1 F2 D2 1B 02 10 01 B2 B0 20 00 08 1E +0F 20 B0 13 22 EF 4C 93 0B 20 F2 C2 03 02 F2 C2 +05 02 F2 C2 1B 02 1C 43 B0 13 16 B1 F2 D2 1B 02 +10 01 3C 40 03 00 5C F2 20 01 7C 90 03 00 03 2C +5C 53 B0 13 5A D6 6C 92 03 28 5C 83 B0 13 B8 E4 +7C 90 03 00 EE 23 10 01 F2 40 A5 00 21 01 4E 4C +4F 4E 8F 10 0E 5F 3E 50 00 44 82 4E 26 01 92 B3 +2C 01 FD 27 C2 4C 20 01 C2 43 21 01 10 01 3F 40 +13 00 6F 9C 09 24 5F 4C 0C 00 1F 83 07 24 1F 83 +07 20 B0 13 D8 C9 04 3C DC 43 0C 00 B0 13 D2 99 +0C 43 10 01 F2 F0 E0 00 05 02 F2 F0 E0 00 03 02 +F2 D0 1F 00 07 02 F2 F0 E0 00 19 02 F2 F0 E0 00 +1D 02 F2 D0 1F 00 1B 02 10 01 1A 14 39 40 11 00 +3F 40 32 1D 3A 40 72 F6 3C 4A B0 13 9A E6 2F 52 +8F 4C FC FF 8F 4D FE FF 19 83 F6 23 19 16 10 01 +4D 93 03 24 5F 4C 0A 00 02 3C 5F 4C 09 00 4F 93 +06 24 CC 93 00 00 03 24 7F 90 20 00 02 2C 2C 43 +10 01 0C 43 10 01 3C 40 80 1E 0D 43 2E 42 B0 13 +72 ED C2 93 88 1E 09 20 3C 40 84 1E 3D 40 BA F6 +2E 42 B0 13 60 ED D2 43 88 1E 10 01 B2 B0 20 00 +08 1E 0E 20 B0 13 22 EF 4C 93 0A 20 F2 C2 03 02 +F2 C2 05 02 F2 C2 1B 02 B0 13 34 BB F2 D2 1B 02 +10 01 4C 4C 3D 40 1C 00 B0 13 38 EC CF 0C 1F 52 +D4 F6 EF B2 1A 00 02 24 2C 43 10 01 1C 52 D4 F6 +1C 4C 18 00 10 01 CE 0C 6D 4E 5D 92 D8 F6 0C 24 +7C 40 09 00 B0 13 46 DF 2D 42 3F 40 A4 1D 1F 53 +FF 4E FF FF 1D 83 FB 23 10 01 0A 14 0A 42 32 C2 +03 43 D2 93 78 1D 08 24 B0 13 EA E7 7C 40 32 00 +B0 13 D8 C6 D2 43 78 1D 02 4A 0A 16 10 01 0E 93 +02 20 0C 43 10 01 1D 83 1C 83 1D 53 6B 4D 1C 53 +6F 4C 4F 9B 02 20 1E 83 F8 23 4B 4B 4C 4F 0C 8B +10 01 0A 14 CA 0C 5D 42 17 1E B0 13 D8 E0 4C 93 +04 20 B0 13 CE EE 1C 43 04 3C CC 0A B0 13 0A EF +0C 43 0A 16 10 01 82 43 26 1E 82 43 28 1E E2 42 +30 1E F2 40 1E 00 31 1E C2 43 32 1E C2 43 2F 1E +82 43 2A 1E 82 43 2C 1E 10 01 0D 4C 0D 93 0E 24 +3B 40 8F 00 1B 83 5D 02 FD 2B 4C 4D 8C 10 8D 10 +4D 4D 8B 10 0D DB 12 C3 5D 00 5C 00 10 01 82 43 +90 03 B2 40 C0 00 92 03 B2 D0 10 00 80 03 92 B3 +82 03 FD 27 B2 F0 EF FF 80 03 92 C3 82 03 10 01 +D2 93 78 1D 0D 20 7C 40 36 00 B0 13 D8 C6 7C 40 +3D 00 B0 13 D8 C6 7C B0 F0 FF F9 23 E2 43 78 1D +10 01 0A 14 CB 0E CA 0C CE 0F CC 0D CD 0B 5F 41 +08 00 B0 13 FC B4 CD 0C CC 0A 6E 43 B0 13 70 AF +0A 16 10 01 0A 14 CA 0C 5D 42 75 1E B0 13 D8 E0 +4C 93 04 20 B0 13 CE EE 1C 43 03 3C CC 0A B0 13 +DE E4 0A 16 10 01 02 12 32 C2 03 43 82 4C D0 04 +82 4D D2 04 82 4E E0 04 82 4F E2 04 1C 42 E4 04 +1D 42 E6 04 32 41 10 01 D2 43 34 1E 92 42 50 03 +56 03 B0 13 B4 DC 92 C3 46 03 B2 D0 10 00 46 03 +7C 40 14 00 5D 43 80 00 02 E9 1F 42 D4 F6 BF 90 +FF 00 02 00 05 28 06 20 BF 90 00 FF 00 00 02 2C +0C 43 10 01 1C 42 DE 1E 10 01 1F 42 D4 F6 BF 90 +FF 00 02 00 05 28 06 20 BF 90 00 FF 00 00 02 2C +4C 43 10 01 5C 42 DD 1E 10 01 0A 14 5C 43 B0 13 +7C C5 CA 0C 0A 93 07 24 2C 43 0C 5A B0 13 DA EE +CC 0A B0 13 54 BF 0A 16 10 01 D2 93 78 1D 09 24 +F2 90 03 00 78 1D 08 20 B0 13 F4 E1 E2 43 78 1D +10 01 32 C2 03 43 FF 3F 10 01 D2 93 78 1D 09 24 +F2 90 03 00 78 1D 08 24 F2 40 03 00 78 1D 80 00 +B4 EB 32 C2 03 43 FF 3F 10 01 C2 43 66 1E 00 18 +C2 43 68 1E B0 13 84 ED 82 4C 64 1E B0 13 9E EB +C2 4C 62 1E 4C 93 FA 27 10 01 3C 40 38 1E 3D 40 +44 F5 3E 42 B0 13 60 ED C2 43 37 1E C2 43 36 1E +C2 43 34 1E C2 43 40 1E 10 01 B2 F0 CF FF 80 03 +F2 F0 7F 00 03 02 F2 F0 7F 00 0B 02 B2 F0 EF FF +82 03 B0 13 3C F0 80 00 FA EF D2 92 D8 F6 A4 1D +08 24 D2 43 A2 1D 7C 40 07 00 7D 40 07 00 80 00 +46 DF 32 C2 03 43 FF 3F B0 13 F4 E1 7C 40 0A 00 +5D 42 DC F6 B0 13 46 DF F2 90 03 00 78 1D 02 20 +80 00 B4 EB 10 01 3F 40 3E 00 0E 42 32 C2 03 43 +B0 13 BE E6 02 4E C2 93 9B 1D 03 20 1F 83 3F 93 +F4 23 10 01 CF 0C 82 4F 54 03 92 C3 44 03 B0 13 +C2 EE 2F 83 0F 8C 3F 90 00 80 02 28 92 D3 44 03 +10 01 CF 0D 7C 90 2A 00 0A 2C 4E 4C 5D 4E FE F5 +4C 4C 5C 02 1C 4C 8E 1C CE 0D 80 00 BC CD 10 01 +0C 9D 02 2C 80 00 60 ED 0C 5E 0D 5E 0E 93 06 24 +1D 83 1C 83 EC 4D 00 00 1E 83 FA 23 10 01 CD 0C +C2 93 88 1E 02 24 4C 43 10 01 3C 40 84 1E 2E 42 +B0 13 60 ED D2 43 88 1E 5C 43 10 01 D2 93 E0 1E +0A 20 D2 92 E3 1E 31 1E 06 20 D2 92 E2 1E 30 1E +02 20 E2 43 E0 1E 10 01 5C 43 B0 13 D2 CE 6C 43 +B0 13 D2 CE 5C 43 6D 42 80 13 0E 1E 6C 43 6D 42 +20 00 12 1E 3C B0 00 80 0D 7D 3D E3 3E 40 3D 00 +0F 43 B0 13 46 E7 3E 40 C8 00 0F 43 80 00 CC D9 +3C B0 00 80 0D 7D 3D E3 3E 40 52 00 0F 43 B0 13 +46 E7 3E 40 19 00 0F 43 80 00 CC D9 B0 13 8A EE +4C 93 08 20 4C 43 4D 43 B0 13 02 E9 5C 43 5D 43 +80 00 02 E9 4C 43 FB 3F 3C 40 00 1C 0D 43 3E 40 +46 00 B0 13 72 ED 3C 40 46 1C 0D 43 3E 40 46 00 +80 00 72 ED 0A 14 CF 0C CC 0D 2A 43 0F 93 05 20 +B0 13 3E E9 4C 93 01 24 0A 43 CC 0A 0A 16 10 01 +21 82 CF 0C CC 0D A1 4F 00 00 91 4F 02 00 02 00 +CD 01 2E 42 B0 13 20 E9 21 52 10 01 C2 93 76 1D +0A 24 B0 13 F0 EF F2 F0 BF 00 1B 02 F2 F0 BF 00 +1D 02 82 43 24 1E 10 01 1F 42 44 1E 5C 4F 11 00 +6C 93 02 2C 3C 42 10 01 5C 53 4C 5C 4C 5C 4C 4C +10 01 7C 90 03 00 07 2C 4C 4C 5D 4C E0 F6 7C 40 +3E 00 80 00 46 DF 32 C2 03 43 FF 3F 0C 93 0A 24 +5C 0F 1C 53 0F 42 32 C2 03 43 B0 13 BE E6 02 4F +1C 83 F8 23 10 01 B0 13 9E EB 7C F0 0F 00 5C 53 +4E 4C 1C 42 A0 1D B0 13 8C EA 1E 83 FA 23 10 01 +B2 90 06 00 0E 07 08 20 92 42 20 07 E8 1E D2 43 +EA 1E B1 C0 D0 00 00 00 00 13 B2 F0 EF FF 46 03 +C2 43 34 1E 7C 40 14 00 4D 43 B0 13 02 E9 5D 43 +80 00 10 A0 6D 42 B0 13 7C EE 4F 43 C2 93 06 1E +01 20 5F 43 C2 4F 06 1E 5D 43 80 00 7C EE 1C 42 +D2 1E CF 0C 5F 0A 0C 5F 3D 40 05 00 B0 13 78 E2 +3C 50 40 01 10 01 4C 93 06 24 7C 90 0D 00 06 28 +7C 80 0C 00 10 01 3F 40 0C 00 4C 5F 10 01 3D 40 +FF 00 3E 40 0C 00 3F 40 20 0A 1F 53 CF 4D FF FF +1E 83 FB 23 10 01 5D 42 92 1E B0 13 D8 E0 4C 93 +02 24 0C 43 10 01 B0 13 CE EE 1C 43 10 01 F2 40 +06 00 E2 1E F2 40 1E 00 E3 1E F2 40 0A 00 E1 1E +C2 43 E0 1E 10 01 D2 53 5E 1E F2 90 03 00 5E 1E +02 28 C2 43 5E 1E 82 43 5C 1E 80 00 4C E3 5C 42 +9A 1D 3D 40 6D 00 B0 13 38 EC 7C 50 43 00 C2 4C +9A 1D 10 01 B2 F0 FF FD 32 0F 7C 40 34 00 B0 13 +D8 C6 B2 D0 00 02 36 0F 10 01 0F 42 32 C2 03 43 +7C D0 C0 00 C2 4C 13 0F 5C 42 22 0F 02 4F 10 01 +B2 D0 10 00 08 1E 00 18 F2 40 74 D3 BC 1E 3C 40 +99 19 80 00 F8 E2 0E 93 08 20 2D 93 06 2C 5D 06 +3D 50 C4 F6 6E 43 80 00 70 AF 10 01 0E 93 08 20 +2D 93 06 2C 5D 06 3D 50 CC F6 6E 43 80 00 70 AF +10 01 0E 43 0F 4C 1C 43 5F 02 0E 6E 0E 9D 01 28 +0E 8D 0C 6C F9 2B 10 01 02 12 32 C2 03 43 82 4C +C0 04 82 4D C8 04 1C 42 CA 04 32 41 10 01 B2 B2 +76 1E 07 24 C2 93 34 1E 02 20 80 00 68 E7 80 00 +DA EA 10 01 B2 40 FF 7F 52 03 B2 D0 10 00 42 03 +B2 D0 24 01 40 03 10 01 5F 42 A4 1E 5F 83 D2 83 +A4 1E 0F 93 02 20 80 00 6A E8 10 01 3E 40 0C 00 +3F 40 20 0A 1F 53 CF 43 FF FF 1E 83 FB 23 10 01 +5D 93 07 20 7C 40 5A 00 3D 40 30 F5 5E 43 80 00 +70 AF 10 01 5D 93 07 20 7C 40 5A 00 3D 40 38 F5 +5E 43 80 00 70 AF 10 01 5D 93 07 20 7C 40 5A 00 +3D 40 28 F5 5E 43 80 00 70 AF 10 01 3C 80 05 00 +05 24 3C 80 05 00 02 24 4C 43 10 01 5C 43 10 01 +4C 43 D2 93 34 1E 05 20 B2 90 F8 F2 E4 1E 01 20 +5C 43 10 01 B2 40 D9 07 CE 1E F2 42 CC 1E D2 43 +CB 1E C2 43 CA 1E 10 01 1F 42 50 03 82 4F C8 1E +1F 92 50 03 F9 23 80 00 00 CD CF 0C 5F 06 0C 5F +3C 80 40 06 3D 40 09 00 80 00 78 E2 4C 43 D2 93 +58 1E 04 20 82 93 60 1E 01 24 5C 43 10 01 4C 43 +92 93 18 1E 04 20 82 93 24 1E 01 24 5C 43 10 01 +CF 0C 0E 93 05 24 1F 53 FF 4D FF FF 1E 83 FB 23 +10 01 0E 93 06 24 4D 4D 1C 53 CC 4D FF FF 1E 83 +FB 23 10 01 C2 93 88 1E 03 24 3C 40 84 1E 10 01 +3C 40 BA F6 10 01 0D 93 02 20 0C 93 04 24 82 4C +8A 1E 82 4D 8C 1E 10 01 0D 93 02 20 0C 93 04 24 +82 4C 6C 1E 82 4D 6E 1E 10 01 B0 13 12 E0 B2 F0 +EF FF 32 0F B2 D0 10 00 36 0F 10 01 82 43 9C 1E +F2 40 0F 00 9E 1E B2 40 2C 01 A0 1E 10 01 A2 43 +9A 1E 92 C3 44 03 B2 D0 10 00 44 03 10 01 A2 D2 +80 03 82 43 80 03 B2 D0 00 02 80 03 10 01 CE 0C +3C 40 E8 03 B0 13 8C EA 1E 83 FA 23 10 01 82 43 +32 0F 82 43 36 0F B0 13 12 E0 80 00 3E EE 3E F0 +1F 00 04 24 5C 02 0D 6D 1E 83 FC 23 10 01 3E F0 +1F 00 04 24 5D 03 5C 00 1E 83 FC 23 10 01 7C 40 +36 00 B0 13 06 BD 7C 40 39 00 80 00 06 BD 4F 43 +C2 93 CA 1E 01 20 5F 43 C2 4F CA 1E 10 01 4F 43 +C2 93 2F 1E 01 20 5F 43 C2 4F 2F 1E 10 01 4F 43 +7C B0 80 FF 01 20 5F 43 CC 0F 10 01 C2 93 06 1E +02 20 80 00 3C D1 80 00 B8 AD 4F 43 7C 90 0C 00 +01 2C 5F 43 CC 0F 10 01 B0 13 DA EA B0 13 4A E8 +5D 43 80 00 10 A0 D2 43 5E 1E 82 43 60 1E C2 43 +58 1E 10 01 B2 F0 1F FF 04 0A 4C 4C 82 DC 04 0A +10 01 1C 42 50 03 1C 92 50 03 FB 23 10 01 C2 93 +9C 1D 02 24 D2 43 9B 1D 10 01 3D 40 79 1D 3E 40 +21 00 80 00 60 ED B2 F0 DF FF 40 03 82 43 50 03 +10 01 5C 43 B0 13 D2 CE 6C 43 80 00 D2 CE B0 13 +4C E3 B2 D0 00 04 8C 1C 10 01 DC 93 0C 00 02 20 +80 00 84 D8 10 01 B0 13 54 F0 B2 40 2B 5A 5C 01 +10 01 4C 43 A2 93 EE 1D 01 20 5C 43 10 01 4C 43 +92 93 EE 1D 01 20 5C 43 10 01 4C 43 82 93 EA 1C +01 24 5C 43 10 01 4C 43 92 93 D0 1E 01 20 5C 43 +10 01 CF 0C CC 0D CD 0F 2E 42 80 00 20 E9 CD 0C +3C 40 80 1E 2E 42 80 00 60 ED 7C 40 03 00 7D 40 +0B 00 80 00 36 D0 5C 93 02 20 CC 0D 10 01 CC 0E +10 01 1C 42 8C 1C 49 19 0C 10 5C F3 10 01 1C 42 +8C 1C 48 19 0C 10 5C F3 10 01 1C 42 8C 1C 46 19 +0C 10 5C F3 10 01 1C 42 8C 1C 44 19 0C 10 5C F3 +10 01 1C 42 8C 1C 45 19 0C 10 5C F3 10 01 1C 42 +44 03 7C F0 10 00 10 01 B2 F0 EF FF 44 03 80 00 +AE DF B2 F0 EF FF 08 1E 80 00 3C F0 B0 13 9E EB +C2 4C EE 1E 10 01 B0 13 9E EB C2 4C 17 1E 10 01 +7C 40 03 00 4D 43 80 00 36 D0 C2 43 A4 1E C2 43 +AA 1E 10 01 82 43 EA 1C E2 42 16 1D 10 01 82 43 +D0 1E 4C 43 80 00 9C BD 1C 42 8C 1C 8C 10 5C F3 +10 01 1C 42 8C 1C 5C 0F 5C F3 10 01 5C 42 C6 1E +8C 11 10 01 4C 5C C2 4C 49 1E 10 01 B2 F0 EF FF +48 03 10 01 B2 D0 20 00 40 03 10 01 D2 43 E0 1E +80 00 6A E8 32 D0 D8 00 03 43 10 01 5C 42 DC 1E +10 01 C2 4C 48 1E 10 01 C2 4C 4A 1E 10 01 4D 43 +80 00 06 C9 92 D3 44 03 10 01 92 C3 44 03 10 01 +5C 42 78 1D 10 01 A2 D2 06 0A 10 01 82 43 76 1E +10 01 CC 43 00 00 10 01 3C 40 D8 F6 10 01 92 D3 +04 0A 10 01 92 C3 04 0A 10 01 80 00 86 98 1C 43 +10 01 03 43 FF 3F 2C 43 10 01 2C 43 10 01 4C 43 +10 01 6C 43 10 01 0C 43 10 01 0C 43 10 01 03 43 +10 01 10 01 10 01 10 01 30 30 30 30 30 31 30 30 +32 30 30 33 30 30 34 30 30 35 30 30 36 30 30 37 +30 30 38 30 30 39 30 31 30 30 31 31 30 31 32 30 +31 33 30 31 34 30 31 35 30 31 36 30 31 37 30 31 +38 30 31 39 30 32 30 30 32 31 30 32 32 30 32 33 +30 32 34 30 32 35 30 32 36 30 32 37 30 32 38 30 +32 39 30 33 30 30 33 31 30 33 32 30 33 33 30 33 +34 30 33 35 30 33 36 30 33 37 30 33 38 30 33 39 +30 34 30 30 34 31 30 34 32 30 34 33 30 34 34 30 +34 35 30 34 36 30 34 37 30 34 38 30 34 39 30 35 +30 30 35 31 30 35 32 30 35 33 30 35 34 30 35 35 +30 35 36 30 35 37 30 35 38 30 35 39 30 36 30 30 +36 31 30 36 32 30 36 33 30 36 34 30 36 35 30 36 +36 30 36 37 30 36 38 30 36 39 30 37 30 30 37 31 +30 37 32 30 37 33 30 37 34 30 37 35 30 37 36 30 +37 37 30 37 38 30 37 39 30 38 30 30 38 31 30 38 +32 30 38 33 30 38 34 30 38 35 30 38 36 30 38 37 +30 38 38 30 38 39 30 39 30 30 39 31 30 39 32 30 +39 33 30 39 34 30 39 35 30 39 36 30 39 37 30 39 +38 30 39 39 31 30 30 31 30 31 31 30 32 31 30 33 +31 30 34 31 30 35 31 30 36 31 30 37 31 30 38 31 +30 39 31 31 30 31 31 31 31 31 32 31 31 33 31 31 +34 31 31 35 31 31 36 31 31 37 31 31 38 31 31 39 +31 32 30 31 32 31 31 32 32 31 32 33 31 32 34 31 +32 35 31 32 36 31 32 37 31 32 38 31 32 39 31 33 +30 31 33 31 31 33 32 31 33 33 31 33 34 31 33 35 +31 33 36 31 33 37 31 33 38 31 33 39 31 34 30 31 +34 31 31 34 32 31 34 33 31 34 34 31 34 35 31 34 +36 31 34 37 31 34 38 31 34 39 31 35 30 31 35 31 +31 35 32 31 35 33 31 35 34 31 35 35 31 35 36 31 +35 37 31 35 38 31 35 39 31 36 30 31 36 31 31 36 +32 31 36 33 31 36 34 31 36 35 31 36 36 31 36 37 +31 36 38 31 36 39 31 37 30 31 37 31 31 37 32 31 +37 33 31 37 34 31 37 35 31 37 36 31 37 37 31 37 +38 31 37 39 31 38 30 00 4E EC 00 00 98 EE 00 00 +10 A0 00 00 A6 EF 00 00 9A F3 5E EE 00 00 D4 8B +00 00 26 97 00 00 22 F0 00 00 1C F3 76 E0 00 00 +58 A3 00 00 38 B4 00 00 8E EF 00 00 2E F3 D4 F0 +00 00 5C A4 00 00 10 AB 00 00 B2 EF 00 00 40 F3 +D6 F0 00 00 24 AA 00 00 38 A9 00 00 22 F0 00 00 +52 F3 5E A5 00 00 8C F0 00 00 72 CB 00 00 22 F0 +00 00 64 F3 D4 F0 00 00 D4 F0 00 00 DA AC 00 00 +22 F0 00 00 76 F3 86 EB 00 00 D4 F0 00 00 AE 9D +00 00 82 EF 00 00 0A F3 4E EE 00 00 D8 8F 00 00 +E2 B1 00 00 18 F0 00 00 F8 F2 D4 F0 00 00 D4 F0 +00 00 5E CD 00 00 9A EF 00 00 AC F3 6A E4 00 00 +D4 F0 00 00 B4 EC 00 00 22 F0 00 00 BE F3 42 E4 +00 00 D4 F0 00 00 A0 EC 00 00 22 F0 00 00 D0 F3 +9C E5 00 00 D4 F0 00 00 C8 EC 00 00 22 F0 00 00 +E2 F3 F4 EA 00 00 CA 91 00 00 7C EE 00 00 22 F0 +00 00 F4 F3 90 D1 00 00 D4 F0 00 00 76 E3 00 00 +22 F0 00 00 88 F3 01 80 40 20 10 08 84 42 21 90 +48 A4 52 29 14 0A 85 C2 61 B0 58 AC D6 6B 35 9A +CD 66 33 99 4C A6 53 A9 54 2A 95 CA E5 F2 79 3C +9E CF 67 B3 D9 6C B6 5B 2D 16 0B 05 82 41 A0 50 +28 94 4A A5 D2 69 34 1A 8D 46 23 91 C8 E4 72 39 +1C 8E C7 E3 F1 F8 FC FE FF 7F 3F 1F 0F 07 83 C1 +E0 70 38 9C CE E7 F3 F9 7C BE DF 6F 37 9B 4D 26 +13 89 44 22 11 88 C4 62 31 98 CC E6 73 B9 5C AE +D7 EB 75 BA DD 6E B7 DB 6D 36 1B 0D 06 03 81 C0 +60 30 18 8C C6 63 B1 D8 EC F6 7B 3D 1E 8F 47 A3 +D1 E8 F4 7A BD 5E AF 57 AB 55 AA D5 EA F5 FA FD +7E BF 5F 2F 17 8B 45 A2 51 A8 D4 6A B5 DA ED 76 +3B 1D 0E 87 C3 E1 F0 78 BC DE EF 77 BB 5D 2E 97 +CB 65 B2 59 2C 96 4B 25 92 49 24 12 09 04 02 01 +80 40 20 10 08 84 42 21 90 48 A4 52 29 14 0A 85 +C2 61 B0 58 AC D6 6B 35 9A CD 66 33 99 4C A6 53 +A9 54 2A 95 CA E5 45 52 52 00 20 20 44 4F 4E 45 +00 00 30 30 30 30 30 30 30 00 20 43 4F 4E 46 00 +20 52 46 42 53 4C 00 00 20 20 53 59 4E 43 00 00 +20 20 20 50 50 54 00 00 20 20 20 41 43 43 00 00 +2D 2D 2D 00 30 30 30 30 30 30 30 30 00 00 4C 42 +00 00 4B 47 00 00 20 52 41 4D 00 00 30 34 33 30 +00 00 43 43 34 33 30 00 20 4F 46 46 00 00 20 20 +4F 4E 00 00 4C 4F 42 41 54 54 00 00 20 20 4F 50 +45 4E 00 00 20 20 4C 4F 3F 54 00 00 2D 2D 2D 2D +00 00 02 1B 01 1E 17 3C 18 10 06 1E 08 05 03 47 +0B 08 0C 00 0D 10 0E B0 0F 71 10 7B 11 83 12 13 +13 22 14 F8 15 42 19 1D 1A 1C 1B C7 1C 00 1D B2 +21 B6 22 10 23 EA 24 2A 25 00 26 1F 2C 81 2D 35 +2E 09 F5 60 B6 F2 63 D3 D7 70 F7 F3 00 00 00 00 +00 86 00 77 C7 95 E6 97 17 F3 67 05 F0 87 85 75 +46 C6 37 F5 06 D3 87 C4 C4 02 67 E3 B6 00 03 01 +04 08 10 80 80 80 80 20 40 02 01 80 04 02 10 20 +40 08 08 80 08 08 08 08 F7 F7 F7 F7 20 40 04 80 +7F 7F 7F 7F 7F 10 01 80 2F 1E 1B 07 37 B2 0A 04 +00 00 00 0C 00 10 AA 56 4D 3B 15 11 F8 57 07 0C +10 1D 1C C7 10 B0 FF FF F9 B6 10 EA 2A 00 1F 00 +67 FF 00 00 6F 00 1C 02 DD 03 B1 05 9D 07 A2 09 +C4 0B 07 0E 6E 10 01 13 C6 15 C8 18 11 1C B5 1F +CC 23 07 04 F5 03 E8 03 B6 03 84 03 52 03 20 03 +EE 02 BC 02 8A 02 58 02 26 02 F4 01 C2 01 90 01 +5E 01 2C 01 52 E6 00 00 24 E7 00 00 56 EB 00 00 +CA F0 00 00 C6 F0 00 00 3E DE 00 00 12 00 24 00 +47 00 8F 00 1E 01 3B 02 76 04 79 56 34 12 02 01 +01 01 00 00 32 34 48 00 31 32 48 00 4D 41 4C 45 +46 45 4D 41 D2 1D D2 1D FF FF FF FF 00 32 50 6E +0F 27 8D 00 02 00 00 +@f6e8 +01 00 C2 1E 00 00 01 00 7E 1E 00 00 01 00 7F 1E +0A 00 54 00 8E 1C 20 0A 20 0A 20 0A 20 0A 24 0A +2A 0A 29 0A 27 0A 26 0A 24 0A 24 0A 26 0A 26 0A +24 0A 26 0A 24 0A 26 0A 26 0A 26 0A 21 0A 22 0A +20 0A 23 0A 24 0A 25 0A 26 0A 21 0A 22 0A 23 0A +25 0A 20 0A 20 0A 24 0A 2B 0A 2B 0A 2A 0A 29 0A +28 0A 27 0A 20 0A 24 0A 28 0A 02 00 E4 1E 00 00 +01 00 41 1E 00 00 01 00 31 1D 00 00 02 00 E6 1E +00 00 01 00 D1 1D 00 00 01 00 78 1D 00 00 01 00 +9A 1D 00 00 01 00 9B 1D 00 00 01 00 9C 1D 00 00 +02 00 9E 1D 00 00 02 00 A0 1D 00 00 01 00 A2 1D +00 00 01 00 A4 1D FF 00 04 00 A8 1D 00 00 00 00 +04 00 AC 1D 00 00 00 00 04 00 B0 1D 00 00 00 00 +01 00 88 1E 00 00 01 00 62 1E 00 00 02 00 64 1E +00 00 01 00 66 1E 00 00 04 00 68 1E 00 00 00 00 +01 00 B4 1D 01 00 01 00 17 1E 00 00 02 00 EC 1E +00 00 01 00 EE 1E 00 00 04 00 6C 1E 00 00 00 00 +01 00 70 1E 00 00 01 00 74 1E 00 00 01 00 75 1E +00 00 04 00 8A 1E 00 00 00 00 04 00 8E 1E 00 00 +00 00 01 00 92 1E 00 00 01 00 48 1E 00 00 01 00 +49 1E 00 00 01 00 4A 1E 00 00 01 00 4B 1E 00 00 +02 00 94 1E 00 00 02 00 96 1E 00 00 01 00 98 1E +00 00 01 00 99 1E 00 00 01 00 C6 1E 00 00 02 00 +C8 1E 00 00 02 00 D8 1E 00 00 01 00 DA 1E 00 00 +00 00 +@ffe0 +DE 8D +@ffea +60 DD 02 C2 1E 85 C0 EA +@fffe +22 E3 +q diff --git a/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_868MHz.txt b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_868MHz.txt new file mode 100755 index 0000000..ece2264 --- /dev/null +++ b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_868MHz.txt @@ -0,0 +1,1937 @@ +@8000 +5A 14 31 80 1A 00 CA 0E B0 13 44 E0 0E 43 3F 40 +C8 42 B0 13 C6 BE 81 4C 12 00 81 4D 14 00 CC 0A +B0 13 9A E6 0E 43 3F 40 20 41 B0 13 C6 BE 81 4C +16 00 81 4D 18 00 36 40 11 00 37 40 32 1D 0A 43 +28 47 19 47 02 00 CC 08 CD 09 1E 41 12 00 1F 41 +14 00 B0 13 A4 D4 0C 93 0A 38 81 48 08 00 81 49 +0A 00 27 52 1A 53 16 83 EB 23 4A 4A 03 3C 4A 4A +0A 93 7E 24 3A 90 0F 00 3D 38 3A 90 0F 00 23 24 +B0 13 86 82 1E 42 72 1D 1F 42 74 1D B0 13 E0 9E +C9 0C CA 0D 1C 42 72 1D 1D 42 74 1D 1E 42 6E 1D +1F 42 70 1D B0 13 3A 82 1C 42 70 F6 1C 82 6E F6 +B0 13 4C 82 1C 42 70 F6 B0 13 60 82 81 4C 00 00 +81 4D 02 00 73 3C B0 13 24 82 C9 0C CA 0D 1C 42 +6E 1D 1D 42 70 1D 1E 41 08 00 1F 41 0A 00 B0 13 +3A 82 1C 42 6E F6 1C 82 6C F6 B0 13 4C 82 1C 42 +6C F6 E2 3F C9 0A 59 02 16 49 4E F6 5A 06 17 4A +32 1D 18 4A 34 1D B0 13 24 82 C5 0C CA 0D B0 13 +86 82 CE 07 CF 08 B0 13 E0 9E 3E 40 34 80 3F 40 +37 3A B0 13 10 82 CC 05 CD 0A B0 13 3A B7 C5 0C +CA 0D CC 07 CD 08 1E 41 08 00 1F 41 0A 00 B0 13 +90 82 CC 05 CD 0A B0 13 C6 BE C8 0C CA 0D 1C 49 +50 F6 0C 86 B0 13 74 DE CE 0C CF 0D CC 08 CD 0A +B0 13 3A B7 C9 0C CA 0D CC 06 B0 13 60 82 A6 3F +B0 13 86 82 1E 42 32 1D 1F 42 34 1D B0 13 E0 9E +C9 0C CA 0D 1C 42 36 1D 1D 42 38 1D 1E 42 32 1D +1F 42 34 1D B0 13 3A 82 1C 42 52 F6 1C 82 50 F6 +B0 13 56 82 81 4C 00 00 81 4D 02 00 2C 41 1D 41 +02 00 B0 13 6A 82 3E 40 F4 FD 3F 40 D4 3B B0 13 +10 82 1C 41 16 00 1D 41 18 00 B0 13 C6 BE 81 4C +04 00 81 4D 06 00 1C 41 04 00 1D 41 06 00 B0 13 +6A 82 2E 41 1F 41 02 00 B0 13 3A B7 81 4C 0C 00 +81 4D 0E 00 1C 41 0C 00 1D 41 0E 00 B0 13 72 D7 +81 4C 10 00 1C 41 10 00 31 50 1A 00 55 16 10 01 +B0 13 3A B7 CE 0C CF 0D 0C 43 3D 40 80 3F B0 13 +90 82 10 01 1C 41 16 00 1D 41 18 00 1E 41 0C 00 +1F 41 0E 00 B0 13 E0 9E 10 01 B0 13 90 82 CC 09 +CD 0A B0 13 C6 BE C9 0C CA 0D 10 01 B0 13 56 82 +C9 0C CA 0D 10 01 B0 13 78 82 B0 13 3A B7 10 01 +B0 13 78 82 B0 13 E6 9E 10 01 3E 40 E7 6F 3F 40 +63 3B B0 13 3A B7 10 01 B0 13 74 DE CE 0C CF 0D +CC 09 CD 0A 10 01 1C 41 16 00 1D 41 18 00 10 01 +B0 13 E0 9E CE 0C CF 0D 10 01 4A 14 31 82 B0 13 +C2 EE C8 0C CF 08 3F 50 FF 7F 81 4F 06 00 91 41 +06 00 04 00 82 43 46 1E 4A 43 49 43 4C 49 B0 13 +0C 85 1F 4C 18 00 1F 83 1D 24 1F 83 14 24 D2 B3 +D6 1E 47 24 1E 42 4E 1E 1F 42 50 1E 3E F3 3F F0 +FF 00 1F 9C 02 00 3D 20 2E 9C 3B 20 D2 C3 D6 1E +82 43 46 1E 36 3C 5A 53 B0 13 DA D2 4C 93 31 24 +C7 09 2F 3C B0 13 58 EA C6 0C CC 09 B0 13 C8 D8 +4C 93 0C 20 CC 09 CD 06 CE 08 B0 13 4C A2 1F 42 +44 1E AF 93 18 00 09 20 5A 53 07 3C 82 43 46 1E +E2 B2 D6 1E 02 20 B0 13 12 DF 1F 42 44 1E 9F 93 +18 00 0F 20 CF 01 3F 50 03 00 81 4F 00 00 CC 06 +CD 01 3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 +E4 D1 59 53 AB 27 4A 93 50 24 92 93 46 1E 18 38 +4C 47 B0 13 0C 85 CC 07 B0 13 84 B6 4C 93 10 24 +5A 83 CF 01 3F 50 03 00 81 4F 00 00 7C 42 CD 01 +3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 E4 D1 +4A 93 33 24 1F 42 42 1E 0F 88 1F 93 2C 34 E2 B2 +D6 1E 0D 20 E2 D2 D6 1E C2 93 4B 1E 04 20 B2 50 +E0 7F 42 1E 20 3C B2 50 C0 53 42 1E 1C 3C E2 C2 +D6 1E C2 93 4B 1E 03 24 3F 40 40 6C 02 3C 3F 40 +20 00 82 5F 42 1E 49 43 4C 49 B0 13 0C 85 AC 93 +18 00 07 20 CC 09 B0 13 CE E2 4C 93 02 20 5A 83 +04 24 59 53 F1 27 4A 93 0E 20 F2 F0 F9 00 D6 1E +91 91 06 00 04 00 02 24 0E 43 08 3C B0 13 C8 EF +A2 43 9A 1E 70 3C E2 D3 D6 1E 1E 43 1F 41 06 00 +0F 88 0F 93 54 38 0E 93 3C 24 E2 B2 D6 1E 16 20 +1F 41 06 00 1F 82 42 1E 3F 80 42 00 0F 93 31 38 +F2 40 07 00 98 1E C2 43 99 1E F2 D0 18 00 D6 1E +92 42 42 1E 94 1E A2 43 9A 1E 4B 3C 1F 41 06 00 +0F 88 3F 80 42 00 1F 93 1C 38 F2 40 07 00 98 1E +C2 43 99 1E F2 D0 18 00 D6 1E 1F 41 06 00 1F 82 +42 1E 3F 80 42 00 0F 93 05 34 1F 41 06 00 3F 80 +42 00 02 3C 1F 42 42 1E 82 4F 94 1E 92 43 9A 1E +28 3C D2 41 02 00 98 1E D2 41 03 00 99 1E 5F 42 +D6 1E 7F C2 7F D0 10 00 C2 4F D6 1E 92 41 06 00 +94 1E 92 41 04 00 96 1E 82 43 9A 1E 12 3C D2 91 +02 00 98 1E 09 24 D2 41 02 00 98 1E D2 41 03 00 +99 1E F2 D0 10 00 D6 1E 92 41 04 00 94 1E 92 43 +9A 1E D2 C3 D6 1E 31 52 46 16 10 01 3D 40 1C 00 +B0 13 38 EC 1C 52 D4 F6 82 4C 44 1E 10 01 4F 14 +B2 F0 EF FF 42 03 92 C3 42 03 B2 80 00 80 52 03 +B2 D0 10 00 42 03 B0 13 76 CE B2 D0 10 00 8C 1C +B0 13 3A EF 4C 93 EE 20 B0 13 2E EF 4C 93 EA 20 +E2 93 2E 1E 04 28 A2 D3 0A 1E B0 13 5C E9 E2 93 +E0 1E 11 20 5E 42 E1 1E CF 0E 5F 83 C2 4F E1 1E +4E 93 06 20 F2 40 0A 00 E1 1E B0 13 4C F0 03 3C +B2 D0 10 00 0A 1E B0 13 46 EF 4C 93 02 24 92 D3 +0A 1E B0 13 4E ED 4C 93 0D 24 92 83 24 1E 04 20 +B0 13 3C EA B0 13 62 87 F2 B0 40 00 01 02 02 24 +A2 D2 0A 1E B0 13 3C ED 4C 93 12 24 92 83 60 1E +09 20 B0 13 E0 DF B0 13 62 87 7C 40 1F 00 4D 43 +B0 13 02 E9 F2 B0 20 00 01 02 02 24 B2 D2 0A 1E +B0 13 22 EF 4C 93 02 24 B0 13 32 BE B2 B0 20 00 +08 1E 10 24 5E 42 9E 1E CF 0E 5F 83 C2 4F 9E 1E +4E 93 08 20 92 D3 0C 1E B2 D0 20 00 0C 1E F2 40 +0F 00 9E 1E 82 93 0C 1E 0F 24 92 B3 0C 1E 08 20 +A2 B2 0C 1E 09 24 A2 C2 0C 1E 92 D3 8C 1C 04 3C +92 C3 0C 1E A2 D3 0C 1E A2 B3 08 1E 0E 24 1F 42 +26 1E 1E 42 28 1E 1F 82 2A 1E 1E 72 2C 1E 03 20 +3F 90 1F 00 02 28 92 D3 08 1E D2 93 7B 1E 0E 20 +E2 92 7A 1E 03 2C D2 53 7A 1E 08 3C F2 C2 03 02 +F2 C2 05 02 C2 43 7A 1E C2 43 7B 1E E2 B3 01 02 +03 24 D2 B3 01 02 2F 20 C2 43 C2 1E E2 B2 01 02 +11 24 D2 53 78 1E F2 90 03 00 78 1E 0D 28 B2 D0 +20 00 76 1E B2 F0 7F FF 76 1E C2 43 78 1E E2 C2 +19 02 02 3C C2 43 78 1E E2 B3 01 02 11 24 D2 53 +79 1E F2 90 03 00 79 1E 47 28 B2 D0 40 00 76 1E +B2 F0 FF FE 76 1E C2 43 79 1E E2 C3 19 02 3C 3C +C2 43 79 1E 39 3C D2 53 C2 1E 5F 42 C2 1E 5F 83 +7F 90 03 00 31 28 1F 42 08 1E 2F C2 2E 42 1E C2 +08 1E 0E DF 82 4E 08 1E 92 D3 0C 1E A2 B2 08 1E +04 20 B2 D0 10 00 0C 1E 02 3C B2 D2 0C 1E C2 43 +C2 1E 1A 3C 82 93 EC 1C 04 20 F2 D0 20 00 F0 1C +02 3C 92 83 EC 1C B2 90 03 00 EA 1C 0D 20 C2 93 +EE 1C 08 20 7C 40 5A 00 3D 40 28 F5 5E 43 B0 13 +70 AF 02 3C D2 83 EE 1C B1 C0 D0 00 14 00 4B 16 +00 13 7C 40 46 00 3D 40 8C F5 5E 43 B0 13 70 AF +6C 43 4D 43 B0 13 02 E9 7C 40 03 00 4D 43 B0 13 +02 E9 10 01 4A 14 B0 13 E6 EE 82 43 08 0A 7C 40 +46 00 3D 40 5C F5 5E 43 B0 13 70 AF 7C 40 5B 00 +3D 40 62 F5 5E 43 B0 13 70 AF 7C 40 1E 00 B0 13 +AE 89 7C 40 13 00 B0 13 AE 89 7C 40 14 00 B0 13 +AE 89 7C 40 15 00 B0 13 AE 89 7C 40 16 00 B0 13 +AE 89 7C 40 17 00 B0 13 AE 89 7C 40 18 00 B0 13 +AE 89 7C 40 19 00 B0 13 AE 89 6C 43 B0 13 AE 89 +7C 40 03 00 B0 13 AE 89 4C 43 B0 13 AE 89 B2 40 +80 5A 5C 01 32 D0 D8 00 03 43 B0 13 8C EC B0 13 +44 F0 B0 13 A4 89 E2 B2 01 02 04 24 F2 B0 10 00 +01 02 09 20 B0 13 A4 89 82 43 76 1E F2 C2 03 02 +F2 C2 05 02 AE 3C 49 43 5A 43 4A 93 71 24 B0 13 +8C EC 4A 43 4F 49 0F 93 5E 24 1F 83 49 24 1F 83 +36 24 1F 83 10 24 1F 83 5F 20 A2 D2 76 1E B0 13 +5E A5 B0 13 A4 89 B0 13 32 BE 5D 43 B0 13 72 CB +B0 13 EE D4 51 3C B0 13 8A C3 28 42 06 43 07 43 +3C 40 00 20 B0 13 A0 CC B0 13 4C E3 5C 42 59 1E +CD 06 B0 13 96 89 7C 40 47 00 5E 43 B0 13 70 AF +5C 42 5B 1E CD 07 B0 13 96 89 7C 40 5D 00 5E 43 +B0 13 70 AF 18 83 E4 23 B0 13 E0 DF 2D 3C 5D 43 +B0 13 10 AB 28 42 3C 40 00 20 B0 13 A0 CC 4C 43 +B0 13 9C BD 6D 43 B0 13 10 AB 18 83 F4 23 1C 3C +5D 43 B0 13 38 A9 28 43 F2 B0 40 00 01 02 FC 27 +4C 43 B0 13 96 BA 6D 43 B0 13 38 A9 18 83 F4 23 +B0 13 3C EA 09 3C B0 13 3E EB E2 B2 01 02 04 24 +F2 B0 10 00 01 02 F9 23 3C 40 99 19 B0 13 A0 CC +E2 B2 01 02 2D 20 E2 B3 01 02 27 20 F2 B0 10 00 +01 02 1F 20 D2 B3 01 02 19 20 F2 B2 01 02 22 24 +F2 B2 01 02 FD 23 92 C3 00 0A 82 43 08 0A 3C 40 +00 40 B0 13 A0 CC B0 13 E6 EE B2 40 80 5A 5C 01 +32 D0 F8 00 03 43 92 43 5C 01 0C 3C 69 42 5A 43 +09 3C 79 40 03 00 5A 43 05 3C 69 43 5A 43 02 3C +59 43 5A 43 B2 40 2B 5A 5C 01 32 D0 D8 00 03 43 +54 3F 46 16 10 01 7E 40 03 00 4F 43 B0 13 FC B4 +CD 0C 10 01 3C 40 CC 0C B0 13 A0 CC 10 01 5D 43 +B0 13 02 E9 10 01 6A 14 31 80 10 00 C8 0F C5 0E +81 4D 02 00 C7 0C 3F 01 3A 00 71 0F 08 00 5F 41 +38 00 81 4F 04 00 16 41 36 00 91 41 32 00 0C 00 +91 41 34 00 0E 00 19 41 30 00 82 43 76 1E B0 13 +86 F0 B0 13 6A E8 5F 42 34 1E 81 4F 06 00 E2 43 +34 1E 82 43 7C 1E B0 13 E0 EB 7C 40 60 00 B0 13 +B4 EE 1A 43 54 43 B6 3C 0E 43 A2 B2 76 1E 01 24 +1E 43 3F 40 10 00 0F F6 0E 93 23 24 3A B0 00 80 +0E 7E 3E E3 87 5A 00 00 87 6E 02 00 1E 41 0E 00 +1E 97 02 00 05 38 12 20 1E 41 0C 00 2E 97 0E 2C +16 B3 03 24 CD 08 CE 09 04 3C 1D 41 0C 00 1E 41 +0E 00 87 4D 00 00 87 4E 02 00 1A 43 A2 C2 76 1E +54 43 B2 B2 76 1E 20 24 3A B0 00 80 0E 7E 3E E3 +87 8A 00 00 87 7E 02 00 87 99 02 00 04 38 11 20 +87 98 00 00 0E 2C 16 B3 05 24 1D 41 0C 00 1E 41 +0E 00 02 3C CD 08 CE 09 87 4D 00 00 87 4E 02 00 +1A 43 B2 C2 76 1E 54 43 0F 93 35 24 3E 40 1E 00 +1E 52 7C 1E 18 24 3E 80 0A 00 18 24 3E 80 0A 00 +18 24 3E 80 0A 00 26 24 3E 80 0A 00 12 24 3E 80 +0A 00 0C 24 3E 80 0A 00 06 24 1A 93 1C 24 4F 43 +5F 93 09 24 18 3C 3A 40 E8 03 05 3C 3A 40 64 00 +02 3C 3A 40 0A 00 2C 47 1D 47 02 00 3A B0 00 80 +0F 7F 3F E3 CE 0A B0 13 CC D9 87 8E 00 00 87 7F +02 00 01 3C 1A 43 44 93 2B 24 26 B2 1C 24 87 93 +02 00 11 34 6C 43 4D 43 B0 13 02 E9 7C 40 03 00 +5D 43 B0 13 02 E9 2D 47 1E 47 02 00 3D E3 3E E3 +1D 53 0E 63 0B 3C 6C 43 5D 43 B0 13 C4 8B 2D 47 +1E 47 02 00 03 3C 2D 47 1E 47 02 00 C1 45 00 00 +1C 41 04 00 1F 41 02 00 3B 01 08 00 4B 13 44 43 +B0 13 16 EF 92 B3 08 1E 09 20 92 B3 76 1E 06 20 +A2 B3 76 1E 41 27 36 B0 20 00 3E 27 6C 43 4D 43 +B0 13 C4 8B 7C 40 E0 00 B0 13 B4 EE B0 13 86 F0 +B0 13 D2 EF 1F 41 06 00 C2 4F 34 1E 31 50 10 00 +64 16 10 01 B0 13 02 E9 7C 40 03 00 4D 43 B0 13 +02 E9 10 01 0A 14 31 80 1E 00 B0 13 78 E9 B2 B0 +40 00 08 1E 05 20 91 43 0E 00 81 43 10 00 04 3C +81 43 0E 00 81 43 10 00 1A 41 0E 00 5F 42 30 1E +81 4F 12 00 81 43 14 00 5F 42 31 1E 81 4F 16 00 +81 43 18 00 5F 42 32 1E 81 4F 1A 00 81 43 1C 00 +4E 43 9F 3C 4F 4E 0F 93 07 24 1F 83 55 24 1F 83 +40 24 1F 83 2C 24 95 3C B0 13 F2 EE B0 13 D4 8D +0F 43 81 43 00 00 91 43 02 00 81 43 04 00 B1 40 +29 00 06 00 F1 40 49 00 08 00 00 18 F1 40 F6 EB +0A 00 CC 01 3C 50 0E 00 5D 43 4E 43 B0 13 B6 89 +81 93 10 00 07 20 81 93 0E 00 04 20 B2 D0 40 00 +08 1E 03 3C B2 F0 BF FF 08 1E 5E 43 6A 3C B0 13 +B0 8D F1 40 5E 00 08 00 00 18 F1 40 02 E7 0A 00 +CC 01 3C 50 1A 00 6D 43 4E 43 B0 13 B6 89 4E 43 +58 3C B0 13 B0 8D F1 40 48 00 08 00 00 18 F1 40 +02 E7 0A 00 CC 01 3C 50 16 00 6D 43 4E 43 B0 13 +B6 89 7E 40 03 00 45 3C 1C 41 12 00 1D 41 14 00 +B0 13 C8 8D 7C 40 4A 00 5E 43 B0 13 70 AF 7C 40 +1E 00 5D 43 B0 13 02 E9 1C 41 16 00 1D 41 18 00 +B0 13 C8 8D 7C 40 48 00 5E 43 B0 13 70 AF 1C 41 +1A 00 1D 41 1C 00 B0 13 C8 8D 7C 40 5E 00 5E 43 +B0 13 70 AF 7C 40 29 00 5D 43 B0 13 02 E9 0F 43 +81 43 00 00 B1 40 17 00 02 00 81 43 04 00 B1 40 +23 00 06 00 F1 40 4A 00 08 00 00 18 F1 40 E6 D6 +0A 00 CC 01 3C 50 12 00 6D 43 4E 43 B0 13 B6 89 +6E 43 92 B3 08 1E 13 20 92 B3 76 1E 5B 27 B0 13 +E6 EE D2 41 12 00 30 1E D2 41 16 00 31 1E D2 41 +1A 00 32 1E B0 13 44 F0 B0 13 D4 8D 0B 3C 0A 93 +04 20 B2 D0 40 00 08 1E 03 3C B2 F0 BF FF 08 1E +B0 13 D4 8D 82 43 76 1E 31 50 1E 00 0A 16 10 01 +0F 43 81 43 04 00 B1 40 3B 00 06 00 81 43 08 00 +B1 40 23 00 0A 00 10 01 6E 43 4F 43 B0 13 FC B4 +CD 0C 10 01 4C 43 4D 43 B0 13 02 E9 10 01 7F 14 +59 42 1B 02 B2 B0 20 00 76 1E EA 20 B2 B0 40 00 +76 1E E6 20 82 43 76 1E 5A 42 1D 02 4A F9 48 43 +B0 13 3A EF 4C 93 6D 20 7A B0 1F 00 0F 24 32 C2 +03 43 C2 43 1B 02 32 D2 3C 40 A3 00 B0 13 A0 CC +92 42 26 1E 2A 1E 92 42 28 1E 2C 1E 6A B2 44 20 +6A B3 2D 20 7A B0 10 00 22 20 5A B3 0E 20 7A B2 +77 24 F2 B2 01 02 74 24 D2 43 7B 1E C2 43 7A 1E +F2 D2 03 02 F2 D2 05 02 6B 3C D2 B3 01 02 68 24 +B2 D2 76 1E 58 43 B0 13 F0 EC 4C 93 61 24 A2 B2 +08 1E 5E 20 B0 13 DA EA B2 C2 76 1E 59 3C F2 B0 +10 00 01 02 55 24 A2 D2 76 1E 58 43 51 3C E2 B3 +01 02 0B 20 E2 B3 19 02 4B 24 A2 D3 76 1E B2 F0 +FF FE 76 1E E2 C3 19 02 43 3C A2 D3 76 1E B2 F0 +FF FE 76 1E 58 43 3C 3C E2 B2 01 02 0B 20 E2 B2 +19 02 36 24 92 D3 76 1E B2 F0 7F FF 76 1E E2 C2 +19 02 2E 3C 92 D3 76 1E B2 F0 7F FF 76 1E 58 43 +27 3C D2 53 7E 1E 5F 42 7E 1E 5F 83 7F 90 07 00 +05 28 F2 F0 0F 00 F2 1C C2 43 7E 1E 6A B2 13 20 +6A B3 0D 20 7A B0 10 00 06 20 5A B3 11 24 F2 D0 +20 00 F0 1C 0D 3C F2 D0 30 00 F2 1C 07 3C F2 D0 +20 00 F2 1C 03 3C F2 D0 10 00 F2 1C F2 D2 F0 1C +A2 B3 76 1E 03 24 B2 B2 76 1E 18 20 48 93 18 24 +E2 93 E0 1E 0A 24 B2 B0 10 00 08 1E 0A 20 5C 43 +3D 40 33 13 B0 13 12 D6 04 3C B0 13 4C F0 82 43 +76 1E 3C 40 00 20 B0 13 A0 CC 02 3C 82 43 76 1E +7A B0 20 00 02 24 B2 D2 0A 1E 7A B0 40 00 02 24 +A2 D2 0A 1E 92 B3 76 1E 03 20 A2 B3 76 1E 18 24 +3C 40 66 06 B0 13 A0 CC E2 B2 01 02 07 24 E2 D2 +19 02 92 C3 76 1E B2 D0 80 00 76 1E E2 B3 01 02 +07 24 E2 D3 19 02 A2 C3 76 1E B2 D0 00 01 76 1E +32 C2 03 43 C2 43 1D 02 C2 49 1B 02 32 D2 B1 C0 +F0 00 20 00 78 16 00 13 0A 14 31 80 1A 00 B0 13 +78 E9 5F 42 CB 1E 4C 4F 0D 43 4E 4F 81 4E 0E 00 +81 43 10 00 5E 42 CC 1E 81 4E 12 00 81 43 14 00 +91 42 CE 1E 16 00 81 43 18 00 B2 B0 40 00 08 1E +0D 20 4C 4F B0 13 BE 91 7C 40 48 00 B0 13 8E 91 +7C 40 4A 00 5E 43 B0 13 70 AF 0B 3C B0 13 BE 91 +7C 40 4A 00 B0 13 8E 91 7C 40 48 00 5E 43 B0 13 +70 AF 7C 40 1F 00 5D 43 B0 13 02 E9 4A 43 70 3C +4F 4A 0F 93 3E 24 1F 83 1F 24 1F 83 55 20 B2 B0 +40 00 08 1E 0C 20 B0 13 A2 91 B0 13 5A 91 CC 01 +3C 50 0E 00 6D 43 4E 43 B0 13 B6 89 0B 3C B0 13 +A2 91 B0 13 74 91 CC 01 3C 50 0E 00 6D 43 4E 43 +B0 13 B6 89 4A 43 38 3C B2 B0 40 00 08 1E 0C 20 +B0 13 B0 91 B0 13 74 91 CC 01 3C 50 12 00 6D 43 +4E 43 B0 13 B6 89 0B 3C B0 13 B0 91 B0 13 5A 91 +CC 01 3C 50 12 00 6D 43 4E 43 B0 13 B6 89 6A 43 +1B 3C 3F 40 D8 07 81 43 00 00 B1 40 34 08 02 00 +81 43 04 00 B1 40 22 00 06 00 F1 40 5C 00 08 00 +00 18 F1 40 02 E7 0A 00 CC 01 3C 50 16 00 6D 42 +4E 43 B0 13 B6 89 5A 43 5C 41 12 00 1D 41 16 00 +B0 13 86 C2 4F 4C 0E 43 1E 91 10 00 04 38 08 20 +1F 91 0E 00 05 2C 4F 4C 81 4F 0E 00 81 43 10 00 +92 B3 08 1E 0C 20 92 B3 76 1E 8A 27 D2 41 0E 00 +CB 1E D2 41 12 00 CC 1E 92 41 16 00 CE 1E 82 43 +76 1E 31 50 1A 00 0A 16 10 01 81 43 08 00 B1 40 +23 00 0A 00 F1 40 48 00 0C 00 00 18 F1 40 02 E7 +0E 00 10 01 81 43 08 00 B1 40 23 00 0A 00 F1 40 +4A 00 0C 00 00 18 F1 40 02 E7 0E 00 10 01 5E 43 +B0 13 70 AF 1C 41 16 00 1D 41 18 00 B0 13 BE 91 +10 01 1F 43 81 43 04 00 4C 4C 81 4C 06 00 10 01 +1F 43 81 43 04 00 B1 40 0C 00 06 00 10 01 6E 43 +4F 43 B0 13 FC B4 CD 0C 10 01 31 80 1A 00 B0 13 +78 E9 5F 42 F6 1D 81 4F 0E 00 81 43 10 00 1C 42 +FC 1D 1D 42 FE 1D 3E 40 E8 03 0F 43 B0 13 8E D0 +81 4C 16 00 81 4D 18 00 B2 B0 40 00 08 1E 12 20 +1C 42 F8 1D 0D 43 3E 40 B9 01 0F 43 B0 13 46 E7 +3E 40 C8 00 0F 43 B0 13 CC D9 81 4C 12 00 81 4D +14 00 05 3C 91 42 F8 1D 12 00 81 43 14 00 4E 43 +82 3C 4F 4E 0F 93 55 24 1F 83 39 24 1F 83 7B 20 +B2 B0 40 00 08 1E 19 20 7C 40 5E 00 3D 40 4E F5 +5E 43 B0 13 70 AF 3F 40 46 00 81 43 00 00 B1 40 +90 01 02 00 B0 13 A0 93 CC 01 3C 50 12 00 7D 40 +03 00 6E 43 B0 13 B6 89 18 3C 7C 40 5E 00 3D 40 +52 F5 5E 43 B0 13 70 AF 3F 40 1E 00 81 43 00 00 +B1 40 96 00 02 00 B0 13 A0 93 CC 01 3C 50 12 00 +7D 40 03 00 6E 43 B0 13 B6 89 4E 43 44 3C 0F 43 +81 43 00 00 91 43 02 00 81 43 04 00 B1 40 29 00 +06 00 F1 40 5C 00 08 00 00 18 F1 40 0C EC 0A 00 +CC 01 3C 50 0E 00 5D 43 4E 43 B0 13 B6 89 6E 43 +2A 3C 7C 40 10 00 5D 43 B0 13 02 E9 0F 43 81 43 +00 00 B1 40 3F 0D 02 00 B1 40 03 00 04 00 B1 40 +32 00 06 00 F1 40 5A 00 08 00 00 18 F1 40 02 E7 +0A 00 CC 01 3C 50 16 00 7D 40 06 00 7E 40 05 00 +B0 13 B6 89 7C 40 10 00 4D 43 B0 13 02 E9 6C 43 +B0 13 D2 CE 5E 43 92 B3 08 1E 2D 20 92 B3 76 1E +78 27 1C 41 16 00 1D 41 18 00 3E 40 E8 03 0F 43 +B0 13 46 E7 82 4C FC 1D 82 4D FE 1D D2 41 0E 00 +F6 1D B2 B0 40 00 08 1E 11 20 1C 41 12 00 1D 41 +14 00 3E 40 C8 00 0F 43 B0 13 46 E7 3E 40 B9 01 +0F 43 B0 13 CC D9 82 4C F8 1D 03 3C 92 41 12 00 +F8 1D A2 D2 8C 1C 82 43 76 1E 31 50 1A 00 10 01 +81 43 08 00 B1 40 22 00 0A 00 F1 40 62 00 0C 00 +00 18 F1 40 02 E7 0E 00 10 01 6A 14 31 80 20 00 +C8 0F C9 0D CA 0E 81 43 0C 00 81 43 0E 00 B0 13 +74 DE 81 4C 14 00 81 4D 16 00 CC 09 CD 0A B0 13 +44 E0 0E 43 3F 40 C8 42 B0 13 C6 BE 81 4C 18 00 +81 4D 1A 00 CC 08 B0 13 9A E6 0E 43 3F 40 20 41 +B0 13 C6 BE 81 4C 1C 00 81 4D 1E 00 1C 41 14 00 +1D 41 16 00 3E 40 F4 FD 3F 40 D4 3B B0 13 3A B7 +1E 41 1C 00 1F 41 1E 00 B0 13 E6 9E 81 4C 10 00 +81 4D 12 00 1C 41 10 00 1D 41 12 00 3E 40 E7 6F +3F 40 63 3B B0 13 3A B7 CE 0C CF 0D 1C 41 14 00 +1D 41 16 00 B0 13 C6 BE 81 4C 08 00 81 4D 0A 00 +36 40 10 00 37 40 50 F6 0A 43 2C 47 B0 13 60 95 +CE 08 CF 09 B0 13 A4 D4 0C 93 08 38 81 48 0C 00 +81 49 0E 00 27 53 1A 53 16 83 EF 23 4A 4A 5A 02 +1C 4A 70 F6 B0 13 9A E6 C6 0C C7 0D 1C 4A 50 F6 +B0 13 60 95 B0 13 84 95 C4 0C C5 0D 1C 41 08 00 +1D 41 0A 00 CE 08 CF 09 B0 13 E0 9E 3E 40 82 A8 +3F 40 7B 38 B0 13 3A B7 CE 0C CF 0D 0C 43 3D 40 +80 3F B0 13 72 95 C4 0C C5 0D 1C 4A 72 F6 B0 13 +9A E6 CE 06 CF 07 B0 13 72 95 C5 0C CA 0D CC 08 +CD 09 B0 13 84 95 CE 0C CF 0D CC 05 CD 0A B0 13 +C6 BE CE 06 CF 07 B0 13 E6 9E 81 4C 04 00 81 4D +06 00 1C 41 18 00 1D 41 1A 00 1E 41 04 00 1F 41 +06 00 B0 13 C6 BE 81 4C 00 00 81 4D 02 00 38 40 +11 00 3A 40 32 1D 39 40 72 F6 3C 49 B0 13 9A E6 +2E 41 1F 41 02 00 B0 13 3A B7 2A 52 8A 4C FC FF +8A 4D FE FF 18 83 F1 23 31 50 20 00 64 16 10 01 +B0 13 74 DE C8 0C C9 0D 1C 41 0C 00 1D 41 0E 00 +10 01 B0 13 E0 9E CE 0C CF 0D CC 04 CD 05 B0 13 +3A B7 10 01 1E 41 10 00 1F 41 12 00 B0 13 E0 9E +10 01 3C 40 79 1D 0D 43 3E 40 21 00 B0 13 72 ED +7C 40 30 00 B0 13 D8 C6 7C 40 30 00 B0 13 2C D7 +4C 93 AF 20 7C 40 31 00 B0 13 2C D7 7C 90 06 00 +A5 20 7C 40 36 00 B0 13 D8 C6 B0 13 18 97 FD 23 +B2 40 01 02 34 0F 0F 42 32 C2 03 43 B2 B0 10 00 +02 0F FC 27 B2 40 51 7E 10 0F B2 B0 10 00 02 0F +FC 27 F2 40 3D 00 11 0F B2 B0 10 00 02 0F FC 27 +F2 40 FE 00 11 0F B2 B0 20 00 02 0F FC 27 C2 43 +10 0F B2 B0 80 00 02 0F FC 27 F2 90 51 00 20 0F +72 20 B2 B0 10 00 02 0F FC 27 F2 40 3D 00 11 0F +02 4F 3B 40 92 F5 4E 43 6C 4B 4F 4E 5F 02 5D 4F +93 F5 B0 13 46 DF 2B 53 5E 53 7E 90 20 00 F4 2B +3D 40 92 F5 4E 43 6C 4D B0 13 2C D7 4F 4E 5F 02 +CF 9C 93 F5 4D 20 2D 53 5E 53 7E 90 20 00 F3 2B +7C 40 36 00 B0 13 D8 C6 B0 13 18 97 FD 23 7C 40 +0C 00 5D 42 16 1E B0 13 46 DF B0 13 A8 E8 6C 43 +B0 13 72 EA 7C 40 34 00 B0 13 D8 C6 A2 B3 30 0F +FD 27 3E 40 10 00 7C 40 34 00 B0 13 2C D7 5C F3 +5F 42 9A 1D 4F 5F 4C DF C2 4C 9A 1D 1E 83 F3 23 +F2 D0 80 00 9A 1D B0 13 F4 E1 7C 40 32 00 B0 13 +D8 C6 D2 43 78 1D B2 40 36 00 9E 1D B2 40 E2 04 +A0 1D 3C 40 79 1D 0D 43 3E 40 1F 00 B0 13 72 ED +3C 40 98 1D 0D 43 2E 43 B0 13 72 ED 32 D2 10 01 +32 C2 03 43 FF 3F 32 C2 03 43 FF 3F 32 C2 03 43 +FF 3F 32 C2 03 43 FF 3F 7C 40 3D 00 B0 13 D8 C6 +7C B0 F0 FF 10 01 1A 14 CA 0C 6D 93 3C 24 5D 93 +0E 24 6D 92 60 20 B0 13 6A 98 6D 42 B0 13 02 E9 +C2 43 2F 1E 4C 43 4D 43 B0 13 02 E9 54 3C C2 93 +2F 1E 1A 20 B2 B0 40 00 08 1E 09 20 B0 13 FA 97 +5A 93 07 20 5C 42 30 1E B0 13 CC E9 02 3C B0 13 +12 98 B0 13 44 98 C9 0C 5C 42 31 1E B0 13 20 98 +B0 13 6A 98 6D 43 E0 3F B0 13 5C 98 C9 0C 5C 42 +32 1E B0 13 20 98 7D 40 1F 00 7E 40 29 00 B0 13 +76 EF 5D 43 D1 3F 5F 42 2E 1E 4F 93 24 24 C2 93 +2F 1E 1A 20 4F 4F 2F 83 0F 24 1F 83 1C 20 B2 B0 +40 00 08 1E 07 20 B0 13 FA 97 5C 42 30 1E B0 13 +CC E9 02 3C B0 13 12 98 B0 13 44 98 CA 0C 5C 42 +31 1E B0 13 36 98 07 3C B0 13 5C 98 CA 0C 5C 42 +32 1E B0 13 36 98 19 16 10 01 5C 42 30 1E B0 13 +26 EB CF 0C CC 0A B0 13 4C 98 4C 4F B0 13 28 98 +10 01 B0 13 4C 98 5C 42 30 1E B0 13 28 98 10 01 +B0 13 28 98 CC 0A 10 01 B0 13 78 98 CC 09 5E 43 +B0 13 70 AF 10 01 B0 13 78 98 CC 0A 5E 43 B0 13 +70 AF 10 01 CC 0A B0 13 5C 98 10 01 7D 40 4A 00 +7E 40 60 00 B0 13 76 EF C9 0C 10 01 7D 40 48 00 +7E 40 5E 00 B0 13 76 EF 10 01 7D 40 1E 00 7E 40 +28 00 B0 13 76 EF 10 01 0D 43 6E 43 4F 43 B0 13 +FC B4 CD 0C 10 01 1A 14 31 80 16 00 B0 13 C2 DB +CA 0C 0A 93 03 20 3C 40 03 00 97 3C 5C 43 CD 0A +B0 13 44 B0 4C 93 04 20 CC 0A B0 13 92 F0 F3 3F +B0 13 98 F0 CD 0C C9 01 39 52 CC 09 2E 42 B0 13 +60 ED 81 49 00 00 CF 01 3F 50 0C 00 81 4F 02 00 +F1 40 09 00 04 00 E1 43 05 00 CD 01 3D 50 0E 00 +3C 40 6C 1E B0 13 20 EA D1 4A 09 00 12 00 D1 42 +75 1E 0D 00 B0 13 BE F0 C1 4C 13 00 D1 43 0C 00 +B0 13 C2 F0 C1 4C 14 00 2C 43 3D 40 03 00 CE 01 +B0 13 F0 B7 0C 93 59 20 B0 13 80 F0 C9 0C E1 43 +05 00 CF 01 3F 50 0C 00 81 4F 02 00 CF 0A 3F 50 +03 00 81 4F 00 00 79 90 03 00 06 24 59 93 02 20 +B0 13 E0 E6 B0 13 0A E8 B0 13 DE DE 79 90 03 00 +07 24 59 93 03 24 B0 13 EA E7 02 3C B0 13 0A E6 +2C 43 2D 43 CE 01 B0 13 F0 B7 0C 93 05 24 CC 0A +B0 13 92 F0 1C 43 29 3C 3F 40 7F 00 5F F1 0C 00 +5F 93 09 24 7F 90 03 00 06 24 CC 0A B0 13 92 F0 +3C 40 05 00 1A 3C EA 43 00 00 DA 41 0E 00 0A 00 +D2 4A 0B 00 77 1D F1 90 40 00 0F 00 02 20 5F 43 +02 3C 7F 40 03 00 CA 4F 01 00 D2 53 75 1E C2 93 +75 1E 02 20 D2 43 75 1E 0C 43 31 50 16 00 19 16 +10 01 3A 14 31 82 C9 0C F9 90 14 00 00 00 05 28 +B0 13 C2 F0 C9 9C 14 00 74 20 3C 40 0E 00 0C 59 +CD 01 B0 13 52 EF 91 92 6E 1E 02 00 6A 20 91 92 +6C 1E 00 00 66 20 58 49 12 00 3A 40 05 00 0A 59 +3C 40 05 00 0C 59 CD 08 B0 13 78 DC 0C 93 48 20 +C2 93 70 1E 56 24 B0 13 C2 DB C7 0C 07 93 51 24 +3C 40 03 00 0C 57 CD 0A 2E 42 B0 13 60 ED 6C 43 +CD 07 B0 13 44 B0 4C 93 03 24 D2 93 74 1E 04 20 +CC 07 B0 13 92 F0 3D 3C 5F 42 74 1E CE 0F 5E 53 +C2 4E 74 1E 4F 4F DF 47 0B 00 72 1E C7 48 0A 00 +E7 43 00 00 F9 90 40 00 13 00 02 20 5F 43 02 3C +7F 40 03 00 C7 4F 01 00 D1 47 09 00 06 00 B0 13 +BE F0 C1 4C 07 00 B0 13 02 9B B0 13 F0 9A CD 01 +B0 13 10 9B D5 27 B0 13 D8 9A 0C 93 12 24 D0 3F +B0 13 02 9B D1 4C 09 00 06 00 B0 13 BE F0 C1 4C +07 00 B0 13 F0 9A CD 01 B0 13 10 9B 02 24 B0 13 +D8 9A 31 52 37 16 10 01 3C 40 03 00 0C 59 CD 0A +2E 42 B0 13 60 ED CC 09 4D 43 B0 13 68 E1 10 01 +3E 40 07 00 5E F9 0A 00 3F 40 03 00 4F 8E 6C 43 +10 01 F1 40 81 00 08 00 D1 49 0D 00 09 00 10 01 +2D 52 6E 42 B0 13 6C C0 C9 0C 09 93 10 01 C2 43 +17 1D 5F 42 F2 1C 2F 83 99 24 1F 83 3F 24 1F 83 +23 24 1F 83 06 24 2F 83 96 20 F2 D0 20 00 F0 1C +10 01 E2 43 F2 1C 3C 40 1E 1D 4D 43 4E 4D 5E 02 +5F 4E F3 1C 47 18 0F 5F 5E 4E F4 1C 0E 5F 2C 53 +8C 4E FE FF 5D 53 7D 90 09 00 F0 2B E2 43 18 1D +F2 40 09 00 17 1D 10 01 E2 43 F2 1C 5E 42 F3 1C +47 18 0E 5E 5F 42 F4 1C 0E 5F 82 4E 1A 1D 5F 42 +F5 1C 47 18 0F 5F 5D 42 F6 1C 0F 5D 82 4F 1C 1D +D2 43 18 1D 4F 8E C2 4F 17 1D 10 01 3E 40 BF FF +1E F2 08 1E 5F 42 F3 1C 5F 03 3F F0 C0 FF 0E DF +82 4E 08 1E 3F 40 7F 00 5F F2 F3 1C C2 4F 30 1E +D2 42 F4 1C 31 1E D2 42 F5 1C 32 1E 5F 42 F6 1C +47 18 0F 5F 5E 42 F7 1C 0E 5F 82 4E CE 1E D2 42 +F8 1C CC 1E D2 42 F9 1C CB 1E D2 42 FA 1C E2 1E +D2 42 FB 1C E3 1E 5F 42 FC 1C 47 18 0F 5F 5E 42 +FD 1C 0E 5F CF 0E 1F 52 D4 1E 1F 82 D2 1E 82 4F +D4 1E 82 4E D2 1E 5F 42 FE 1C 47 18 0F 5F 5C 42 +FF 1C 0C 5F 82 4C 20 1E 1D 42 1A 1E 1E 42 1C 1E +1F 42 1E 1E B0 13 BA 93 7C 40 5A 00 3D 40 0A F5 +5E 43 B0 13 70 AF D2 43 EE 1C 10 01 F2 40 03 00 +F2 1C D2 43 17 1D 10 01 0A 14 31 82 92 B3 8C 1C +0F 20 A2 B2 8C 1C 0C 20 3F 40 0C 00 1F 52 E6 1E +6F 13 4C 93 0C 24 5C 43 6D 43 80 13 0E 1E 07 3C +5C 43 B0 13 D2 CE 5C 43 5D 43 80 13 0E 1E A2 B3 +0C 1E 1B 20 92 B3 8C 1C 12 20 B2 B2 8C 1C 0F 20 +3F 40 0C 00 1F 52 E4 1E 6F 13 4C 93 5B 24 82 93 +0C 1E 58 20 6C 43 6D 43 80 13 12 1E 53 3C 6C 43 +B0 13 D2 CE 6C 43 5D 43 F7 3F 6A 43 B2 B2 0C 1E +28 20 B2 B0 10 00 0C 1E 20 20 B2 B0 20 00 0C 1E +14 20 B2 B0 40 00 0C 1E 0C 20 B2 B0 80 00 0C 1E +1F 24 CC 01 3D 40 68 F5 2E 42 B0 13 60 ED 5A 43 +17 3C CC 01 3D 40 6E F5 F7 3F CC 01 3D 40 74 F5 +3E 40 06 00 B0 13 60 ED 0B 3C CC 01 3D 40 7C F5 +F7 3F CC 01 3D 40 84 F5 3E 40 06 00 B0 13 60 ED +CC 0A B0 13 D2 CE CC 0A 6D 42 80 13 12 1E 6A 93 +07 24 7C 40 46 00 CD 01 5E 43 B0 13 70 AF 06 3C +7C 40 5A 00 CD 01 5E 43 B0 13 70 AF 82 43 0C 1E +A2 D2 0C 1E 92 B3 8C 1C 10 24 B0 13 22 EF 6C 93 +0C 20 7C 40 17 00 B0 13 A4 9D 7C 40 18 00 B0 13 +A4 9D 7C 40 19 00 B0 13 A4 9D 82 43 8C 1C 31 52 +0A 16 10 01 7D 40 03 00 B0 13 02 E9 10 01 2A 14 +C2 93 93 1E 8C 24 5D 93 78 24 6D 93 15 24 6D 92 +8D 20 B0 13 E0 DF C2 43 58 1E 7C 40 1F 00 4D 43 +B0 13 02 E9 6C 43 4D 43 B0 13 02 E9 7C 40 03 00 +4D 43 B0 13 02 E9 7A 3C 5F 42 5E 1E 0F 93 13 24 +1F 83 0A 24 5A 42 5B 1E 7C 40 1A 00 7D 40 5A 00 +5E 43 B0 13 66 C6 10 3C 5A 42 5A 1E 7C 40 1A 00 +7D 40 59 00 F5 3F 5A 42 59 1E 7C 40 1A 00 7D 40 +58 00 5E 43 B0 13 66 C6 CC 0A B0 13 C0 D3 3D 40 +0A 00 B0 13 22 EC B0 13 9A E6 3E 40 CD CC 3F 40 +4C 3E B0 13 3A B7 C8 0C C9 0D 1C 42 5C 1E B0 13 +9A E6 3E 40 CD CC 3F 40 4C 3F B0 13 3A B7 CE 0C +CF 0D CC 08 CD 09 B0 13 E6 9E B0 13 72 D7 82 4C +5C 1E 0D 43 7E 40 03 00 4F 43 B0 13 FC B4 CD 0C +7C 40 47 00 5E 43 B0 13 70 AF CC 0A B0 13 6E EE +4C 93 08 20 6C 43 4D 43 B0 13 02 E9 7C 40 03 00 +5D 43 9F 3F 6C 43 5D 43 97 3F B0 13 3C ED 4C 93 +0B 20 82 43 5C 1E B0 13 8A C3 B2 40 10 0E 60 1E +D2 43 58 1E D2 43 5E 1E 7C 40 1F 00 E9 3F 7C 40 +47 00 3D 40 06 F5 5E 43 B0 13 70 AF 28 16 10 01 +3B 40 80 00 01 3C 0B 43 0A 14 09 14 08 14 07 14 +21 83 3F B0 80 7F 7B 24 3D B0 80 7F 05 20 0C 4E +0D 4F 8B 10 0D EB 73 3C 5D 02 08 4D 4D 10 38 F0 +00 FF 0D D8 5F 02 08 4F 4F 10 38 F0 00 FF 0F D8 +09 4C 0A 4D 3D F0 80 00 C1 4D 00 00 0B EA 0B EF +3B C0 7F FF 3A D0 80 00 3F D0 80 00 0A 9F 02 20 +09 9E 0A 24 0B 2C 0D 4F 0F 4A 0A 4D 0C 4E 0E 49 +09 4C 81 EB 00 00 02 3C 0B 93 4F 20 0C 43 08 4A +88 10 47 48 8F 10 48 8F 8F 10 0E 24 38 90 19 00 +34 2C 12 C3 4F 10 5E 00 5C 00 3C B0 00 10 02 24 +3C D0 00 20 18 83 F5 23 0B 93 0C 24 08 8C 09 7E +4A 7F 0C 48 4A 93 12 30 5C 02 09 69 4A 6A 17 83 +2C 24 F8 3F 09 5E 4A 6F 09 28 4A 10 59 00 5C 00 +3C B0 00 10 02 24 3C D0 00 20 17 53 3C B0 00 80 +07 24 09 63 4A 63 07 63 3C B0 00 60 01 20 19 C3 +17 93 13 38 37 90 FF 00 13 34 7A C0 80 00 87 10 +D1 51 00 00 00 00 57 00 0A D7 0C 49 0D 4A 21 53 +07 16 08 16 09 16 0A 16 10 01 0D 43 0C 43 F7 3F +3D 40 FF FE D1 61 00 00 00 00 5D 00 3C 43 EF 3F +6D 93 1E 24 5D 93 8A 20 C2 93 40 1E 08 20 3D 40 +3A 1E 7C 40 5A 00 5E 43 B0 13 70 AF 07 3C 3D 40 +38 1E 7C 40 5A 00 5E 43 B0 13 70 AF 7C 40 27 00 +5D 43 B0 13 02 E9 7C 40 28 00 5D 43 80 00 02 E9 +B2 B0 20 00 8C 1C 6A 24 C2 93 40 1E 38 20 5F 42 +35 1E 4F 93 63 24 4F 4F 1F 83 1E 24 1F 83 16 24 +1F 83 0E 24 1F 83 06 24 3F 80 03 00 1B 24 1F 83 +1F 24 10 01 5D 42 3A 1E 7C 40 21 00 B0 13 2E A1 +5D 42 3B 1E 7C 40 22 00 B0 13 2E A1 5D 42 3C 1E +7C 40 23 00 B0 13 2E A1 5D 42 3D 1E 7C 40 24 00 +B0 13 2E A1 5D 42 3E 1E 7C 40 25 00 B0 13 2E A1 +5D 42 3F 1E 7C 40 26 00 5E 43 80 00 66 C6 5F 42 +35 1E 1F 83 28 24 1F 83 20 24 1F 83 18 24 1F 83 +10 24 1F 83 08 24 1F 83 21 20 5D 42 38 1E 7C 40 +21 00 B0 13 2E A1 5D 42 39 1E 7C 40 22 00 B0 13 +2E A1 5D 42 3A 1E 7C 40 23 00 B0 13 2E A1 5D 42 +3B 1E 7C 40 24 00 B0 13 2E A1 5D 42 3C 1E 7C 40 +25 00 B0 13 2E A1 5D 42 3D 1E CC 3F 10 01 5E 43 +B0 13 66 C6 10 01 A2 D3 08 1E 82 93 76 1E 03 24 +A2 B2 08 1E 68 20 B2 B0 20 00 76 1E 5B 20 B2 B0 +40 00 76 1E 4B 20 82 93 76 1E 69 24 92 B3 76 1E +32 20 A2 B3 76 1E 1A 20 A2 B2 76 1E 0D 20 B2 B2 +76 1E 5D 24 1F 42 E4 1E 0F 0F 6C 43 4F 13 B2 D2 +8C 1C B2 C2 76 1E 53 3C 1F 42 E6 1E 0F 0F 5C 43 +4F 13 A2 D2 8C 1C A2 C2 76 1E 49 3C C2 43 89 1E +6C 43 6D 42 80 13 12 1E 1F 42 E4 1E 1F 4F 10 00 +82 4F E4 1E 00 18 D2 4F 08 00 12 1E B2 D2 8C 1C +A2 C3 76 1E 34 3C 5C 43 6D 42 80 13 0E 1E 1F 42 +E6 1E 1F 4F 10 00 82 4F E6 1E 00 18 D2 4F 08 00 +0E 1E A2 D2 8C 1C 92 C3 76 1E 21 3C B2 F0 BF FF +76 1E 1F 42 E4 1E 3F 0F 04 00 6C 43 4F 13 92 D3 +8C 1C 15 3C B2 F0 DF FF 76 1E 1F 42 E6 1E 3F 0F +04 00 5C 43 F3 3F E2 B3 01 02 03 24 D2 B3 01 02 +04 20 92 D3 0C 1E B2 D2 0C 1E 82 43 76 1E 82 93 +08 1E 09 24 92 B3 08 1E 06 24 92 C3 08 1E B0 13 +F2 EE 92 D3 8C 1C A2 C3 08 1E 10 01 1A 14 C9 0C +1A 42 44 1E 4D 4D 1D 5A 0C 00 0D 8E 3D 80 13 00 +0D 93 78 34 3E 40 1A 00 1E 52 44 1E 6F 4E 3F F0 +03 00 1F 83 4F 24 1F 83 2C 20 CA 43 12 00 2F 42 +6F BE 1A 20 1C 42 44 1E D2 9C 11 00 48 1E 09 2C +C2 93 4A 1E 03 20 B0 13 DE CF 09 3C 8C 43 18 00 +06 3C B0 13 1A CE 1F 42 44 1E DF 53 11 00 CC 09 +5D 43 B0 13 4C D9 4E 3C EE C2 00 00 1F 42 44 1E +8F 43 00 00 8F 43 02 00 1C 42 44 1E B0 13 DE CF +41 3C 3C 40 80 00 5C 8A 13 00 CF 0A 2D 4F 1E 4F +02 00 3F 40 00 02 B0 13 82 D5 1C 5A 0C 00 3C 50 +00 02 8A 4C 0C 00 1F 42 44 1E CF 43 0F 00 3F 40 +1A 00 1F 52 44 1E 3E 40 FC 00 6E FF 5E D3 CF 4E +00 00 20 3C 3C 40 40 00 5C 8A 13 00 2D 4A 1E 4A +02 00 3F 40 80 1C B0 13 82 D5 1F 42 44 1E 1C 5F +0A 00 3C 50 00 06 8F 4C 0C 00 1F 42 44 1E DF 43 +0F 00 3F 40 1A 00 1F 52 44 1E 6E 4F 5E C3 6E D3 +CF 4E 00 00 19 16 10 01 31 80 16 00 B0 13 78 E9 +5C 42 E2 1E 4F 4C 81 4F 0E 00 81 43 10 00 5F 42 +E3 1E 81 4F 12 00 81 43 14 00 4C 4C 0D 43 6E 43 +4F 43 B0 13 FC B4 CD 0C 7C 40 4A 00 5E 43 B0 13 +70 AF 7C 40 1E 00 5D 43 B0 13 02 E9 1C 41 12 00 +1D 41 14 00 6E 43 4F 43 B0 13 FC B4 CD 0C 7C 40 +48 00 5E 43 B0 13 70 AF 4E 43 3A 3C 4F 4E 0F 93 +1D 24 1F 83 35 20 0F 43 81 43 00 00 B1 40 3B 00 +02 00 81 43 04 00 B1 40 23 00 06 00 F1 40 48 00 +08 00 00 18 F1 40 02 E7 0A 00 CC 01 3C 50 12 00 +6D 43 4E 43 B0 13 B6 89 4E 43 1A 3C 0F 43 81 43 +00 00 B1 40 17 00 02 00 81 43 04 00 B1 40 23 00 +06 00 F1 40 4A 00 08 00 00 18 F1 40 E6 D6 0A 00 +CC 01 3C 50 0E 00 6D 43 4E 43 B0 13 B6 89 5E 43 +92 B3 08 1E 0B 20 92 B3 76 1E C0 27 D2 41 0E 00 +E2 1E D2 41 12 00 E3 1E A2 D2 8C 1C 82 43 76 1E +B2 D0 00 02 8C 1C 31 50 16 00 10 01 0A 14 31 80 +16 00 B0 13 78 E9 B2 B0 40 00 08 1E 0D 20 B0 13 +0E EB 3C B0 00 80 0F 7F 3F E3 81 4C 0E 00 81 4F +10 00 1A 42 D2 1E 44 3C 1F 42 D2 1E 3F B0 00 80 +0E 7E 3E E3 81 4F 0E 00 81 4E 10 00 CA 0F 38 3C +B2 B0 40 00 08 1E 08 20 7C 40 1D 00 7D 40 46 00 +5E 43 B0 13 66 C6 07 3C 7C 40 1D 00 7D 40 43 00 +5E 43 B0 13 66 C6 7C 40 1F 00 5D 43 B0 13 02 E9 +7C 40 0F 00 5D 43 B0 13 02 E9 3F 40 19 FC B1 43 +00 00 B1 40 E7 03 02 00 81 43 04 00 B1 40 06 00 +06 00 F1 40 49 00 08 00 00 18 F1 40 02 E7 0A 00 +CC 01 3C 50 0E 00 7D 40 03 00 5E 43 B0 13 B6 89 +92 B3 08 1E 1E 20 92 B3 76 1E C2 27 B2 B0 40 00 +08 1E 07 20 1C 41 0E 00 B0 13 2A ED 81 4C 12 00 +03 3C 91 41 0E 00 12 00 1F 41 12 00 0F 8A 81 4F +14 00 92 51 14 00 D4 1E 92 41 12 00 D2 1E A2 D2 +8C 1C 82 43 76 1E 31 50 16 00 0A 16 10 01 B2 B0 +20 00 08 1E 77 20 B0 13 3A EF 4C 93 73 20 A2 B2 +76 1E 70 24 1F 42 EE 1D 0F 93 68 20 B0 13 BA ED +B0 13 F0 DC 7C 40 0A 00 B0 13 62 F0 7C 42 B0 13 +68 F0 82 43 F2 1D 82 43 F4 1D 7C 40 05 00 B0 13 +34 F0 7C 40 0C 00 5D 42 16 1E B0 13 28 DD 92 43 +EE 1D 7C 40 17 00 6D 43 B0 13 02 E9 7C 40 18 00 +6D 43 B0 13 02 E9 7C 40 19 00 6D 43 B0 13 02 E9 +4C 43 B0 13 C2 E5 0C 93 0F 20 4C 43 1D 42 F2 1D +1E 42 F4 1D B0 13 8C DA 4C 43 B0 13 86 CF 4C 43 +B0 13 C2 E5 2C 93 25 24 4C 43 B0 13 C2 E5 1C 93 +27 20 A2 43 EE 1D 82 93 F4 1D 0A 20 82 93 F2 1D +07 20 4C 43 B0 13 A4 E2 82 4C F2 1D 82 4D F4 1D +7C 40 17 00 B0 13 56 A6 7C 40 18 00 B0 13 56 A6 +7C 40 19 00 B0 13 56 A6 7C 40 13 00 6D 43 80 00 +02 E9 3C 40 99 19 B0 13 A0 CC D1 3F 2F 93 02 20 +80 00 EE D4 10 01 7D 40 03 00 B0 13 02 E9 10 01 +1A 14 31 80 18 00 B0 13 80 F0 C9 0C B0 13 98 F0 +81 4C 10 00 CF 01 2F 52 81 4F 12 00 F1 42 14 00 +7A 40 03 00 C1 4A 15 00 CD 01 3D 50 06 00 3C 40 +8A 1E B0 13 20 EA D1 43 04 00 D1 42 92 1E 05 00 +D1 43 0A 00 B0 13 C2 F0 C1 4C 0B 00 2C 43 3D 40 +03 00 CE 01 3E 50 10 00 B0 13 F0 B7 C1 4A 15 00 +CF 01 2F 52 81 4F 12 00 CF 01 3F 50 0C 00 81 4F +10 00 79 90 03 00 06 24 59 93 02 20 B0 13 E0 E6 +B0 13 0A E8 B0 13 DE DE 3A 40 06 00 79 90 03 00 +07 24 59 93 03 24 B0 13 EA E7 02 3C B0 13 0A E6 +2C 43 2D 43 CE 01 3E 50 10 00 B0 13 F0 B7 0C 93 +1D 20 3F 40 7F 00 5F F1 04 00 5F 93 03 24 7F 90 +06 00 14 20 CC 01 CD 01 3D 50 06 00 2E 42 B0 13 +60 ED 2C 41 1D 41 02 00 B0 13 A8 ED CC 01 3C 50 +0C 00 B0 13 5E EF D2 53 92 1E 0A 43 CC 0A 31 50 +18 00 19 16 10 01 0A 14 21 83 C1 43 00 00 F2 90 +03 00 78 1D 6B 20 7C 40 3B 00 B0 13 2C D7 CE 0C +7C 40 3B 00 B0 13 2C D7 4E 9C F9 23 4E 93 61 24 +CC 01 5D 43 B0 13 A8 E0 6F 41 3F 50 03 00 4E 4E +0E 9F 38 20 F1 90 1F 00 00 00 34 2C F1 90 0B 00 +00 00 30 28 3C 40 79 1D 0D 43 3E 40 1F 00 B0 13 +72 ED E2 41 79 1D 3C 40 7A 1D 6D 41 B0 13 A8 E0 +3C 40 98 1D 6D 43 B0 13 A8 E0 F2 B0 80 FF 99 1D +14 24 92 53 AC 1D 82 63 AE 1D B0 13 08 DB 4C 93 +30 20 5C 42 98 1D B0 13 98 E1 C2 4C 98 1D F2 F0 +7F 00 99 1D B0 13 CA E7 24 3C 92 53 A8 1D 82 63 +AA 1D 1F 3C 92 53 B0 1D 82 63 B2 1D 0A 42 32 C2 +03 43 7C 40 36 00 B0 13 D8 C6 7C 40 3D 00 B0 13 +D8 C6 7C B0 F0 FF F9 23 7C 40 3A 00 B0 13 D8 C6 +7C 40 34 00 B0 13 D8 C6 02 4A 03 3C 32 C2 03 43 +FF 3F 21 53 0A 16 10 01 C2 93 40 1E 20 20 D2 53 +3F 1E D2 53 41 1E 5F 42 41 1E 5F 83 7F 90 12 00 +04 28 F2 42 35 1E C2 43 41 1E F2 90 3A 00 3F 1E +0A 20 F2 40 30 00 3F 1E D2 53 3E 1E D2 43 37 1E +F2 40 07 00 35 1E F2 90 3A 00 3E 1E 51 20 D2 43 +35 1E D2 43 36 1E 3F 40 30 00 C2 4F 3E 1E D2 53 +3D 1E F2 90 3A 00 3D 1E 43 20 D2 53 35 1E C2 4F +3D 1E D2 53 3C 1E F2 90 36 00 3C 1E 39 20 D2 53 +35 1E C2 4F 3C 1E D2 53 3B 1E F2 90 3A 00 3B 1E +2F 20 D2 53 35 1E C2 4F 3B 1E D2 53 3A 1E 5E 42 +3A 1E 7E 90 32 00 1F 24 7E 90 36 00 21 20 D2 53 +35 1E C2 4F 3A 1E D2 53 39 1E F2 90 3A 00 39 1E +17 20 D2 53 35 1E C2 4F 39 1E D2 53 38 1E F2 90 +32 00 38 1E 0D 20 B0 13 4A E8 D2 43 34 1E 5D 43 +B0 13 10 A0 05 3C D2 43 40 1E 5D 43 B0 13 10 A0 +B2 D0 20 00 8C 1C 10 01 4D 4D 1D 93 19 24 2D 93 +2A 24 2D 92 54 20 82 43 18 1E B0 13 3C EA 7C 40 +0B 00 4D 43 B0 13 02 E9 7C 40 09 00 4D 43 B0 13 +02 E9 6C 43 4D 43 B0 13 1A AA 4D 43 80 00 02 E9 +92 43 18 1E B0 13 4C DA B2 B0 40 00 08 1E 06 20 +7C 40 09 00 5D 43 B0 13 02 E9 05 3C 7C 40 0B 00 +5D 43 B0 13 02 E9 82 93 24 1E 29 24 B2 B0 40 00 +08 1E 19 20 1C 42 20 1E B0 13 B0 E9 3C 90 10 27 +0D 34 0C 93 0D 34 3C E3 1C 53 B0 13 02 AA 4D 43 +B0 13 1A AA 5D 43 B0 13 02 E9 0B 3C 3C 40 0F 27 +B0 13 F0 A9 06 3C 1C 42 20 1E 0C 93 EC 3B B0 13 +F0 A9 7C 40 46 00 CD 0B 5E 43 80 00 70 AF 10 01 +B0 13 02 AA 5D 43 B0 13 1A AA 4D 43 B0 13 02 E9 +10 01 3C B0 00 80 0D 7D 3D E3 6E 42 7F 40 03 00 +B0 13 FC B4 CB 0C 6C 43 10 01 B0 13 02 E9 7C 40 +03 00 10 01 3A 14 31 80 12 00 B0 13 78 E9 B2 B0 +40 00 08 1E 12 20 7C 40 09 00 5D 43 B0 13 02 E9 +1C 42 20 1E B0 13 B0 E9 B0 13 FE AA 37 40 0C FE +38 43 39 40 0F 27 0A 43 30 3C 7C 40 0B 00 5D 43 +B0 13 02 E9 1E 42 20 1E 3E B0 00 80 0F 7F 3F E3 +81 4E 0E 00 81 4F 10 00 37 40 9C FF 38 43 39 40 +A0 0F 0A 43 1A 3C CF 07 CE 08 81 4E 00 00 81 49 +02 00 81 4A 04 00 B1 40 16 00 06 00 F1 40 46 00 +08 00 00 18 F1 40 02 E7 0A 00 CC 01 3C 50 0E 00 +6D 42 7E 40 03 00 B0 13 B6 89 92 B3 08 1E 19 20 +92 B3 76 1E E0 27 B2 B0 40 00 08 1E 06 20 1C 41 +0E 00 B0 13 94 E9 B0 13 FE AA 1C 41 0E 00 1D 42 +1A 1E 1E 42 1C 1E 1F 42 1E 1E B0 13 BA 93 A2 D2 +8C 1C 82 43 76 1E 31 50 12 00 37 16 10 01 3C B0 +00 80 0F 7F 3F E3 81 4C 12 00 81 4F 14 00 10 01 +4D 4D 1D 93 14 24 2D 93 34 24 2D 92 63 20 82 43 +D0 1E 6C 43 4D 43 B0 13 E6 AB 7C 40 0F 00 4D 43 +B0 13 02 E9 7C 40 1F 00 4D 43 80 00 02 E9 92 43 +D0 1E 7C 40 1F 00 5D 43 B0 13 02 E9 7C 40 0F 00 +5D 43 B0 13 02 E9 B2 B0 40 00 08 1E 08 20 7C 40 +1D 00 7D 40 46 00 5E 43 B0 13 66 C6 07 3C 7C 40 +1D 00 7D 40 43 00 5E 43 B0 13 66 C6 4C 43 B0 13 +9C BD B2 B0 40 00 08 1E 04 20 B0 13 0E EB CB 0C +02 3C 1B 42 D2 1E 0B 93 05 38 6C 43 5D 43 B0 13 +E6 AB 0B 3C 3B E3 1B 53 6C 43 4D 43 B0 13 02 E9 +7C 40 03 00 5D 43 B0 13 02 E9 3B 90 E8 03 02 38 +3B 40 E7 03 CC 0B 3C B0 00 80 0D 7D 3D E3 7E 40 +03 00 5F 43 B0 13 FC B4 CD 0C 7C 40 49 00 5E 43 +80 00 70 AF 10 01 B0 13 02 E9 7C 40 03 00 4D 43 +B0 13 02 E9 10 01 5F 42 F2 1C 2F 83 03 24 1F 83 +2C 24 10 01 D2 93 18 1D 16 24 E2 93 18 1D 5D 20 +CF 0C 5F 02 1E 4F 1E 1D CF 0E 8F 10 C2 4F F3 1C +C2 4E F4 1C 4C 4C 3E 40 F5 1C 7F 40 03 00 B0 13 +CC AC FD 2B 10 01 1F 42 1A 1D 0F 5C CE 0F 8E 10 +C2 4E F3 1C C2 4F F4 1C 4C 4C 3E 40 F5 1C 7F 40 +03 00 B0 13 CC AC FD 2B 10 01 1F 42 08 1E 7F F0 +C0 00 4F 5F 3E 40 7F 00 5E F2 30 1E 4E DF C2 4E +F3 1C D2 42 31 1E F4 1C D2 42 32 1E F5 1C 1E 42 +CE 1E CF 0E 8F 10 C2 4F F6 1C C2 4E F7 1C D2 42 +CC 1E F8 1C D2 42 CB 1E F9 1C D2 42 E2 1E FA 1C +D2 42 E3 1E FB 1C 1E 42 D2 1E CF 0E 8F 10 8F 11 +C2 4F FC 1C C2 4E FD 1C 1E 42 20 1E CF 0E 8F 10 +8F 11 C2 4F FE 1C C2 4E FF 1C 10 01 1E 53 CE 4C +FF FF 5F 53 7F 90 13 00 10 01 0A 14 CA 0D 6A 92 +1F 24 B2 B0 40 00 08 1E 10 20 5C 42 00 1E B0 13 +9A E6 3E 40 12 14 3F 40 1F 3F B0 13 3A B7 B0 13 +72 D7 4C 4C B0 13 96 AD 04 3C 5C 42 00 1E B0 13 +96 AD 7C 40 47 00 5E 43 B0 13 70 AF 5A 93 1D 24 +6A 92 37 20 7C 40 20 00 4D 43 B0 13 02 E9 7C 40 +0A 00 4D 43 B0 13 A6 AD 4D 43 B0 13 A6 AD 4D 43 +B0 13 02 E9 7C 40 0C 00 4D 43 B0 13 02 E9 7C 40 +0E 00 4D 43 B0 13 02 E9 1C 3C 7C 40 20 00 B0 13 +B0 AD B2 B0 40 00 08 1E 09 20 7C 40 0B 00 B0 13 +B0 AD 7C 40 0C 00 B0 13 B0 AD 07 3C 7C 40 0A 00 +5D 43 B0 13 A6 AD B0 13 B0 AD 7C 40 0E 00 B0 13 +B0 AD 0A 16 10 01 0D 43 7E 40 03 00 5F 43 B0 13 +FC B4 CD 0C 10 01 B0 13 02 E9 7C 40 0B 00 10 01 +5D 43 B0 13 02 E9 10 01 0A 14 CA 0D 6A 92 3A 24 +B2 B0 40 00 08 1E 18 20 1C 42 02 1E 1D 42 04 1E +B0 13 44 E0 3E 40 83 86 3F 40 7E 3D B0 13 3A B7 +B0 13 58 D4 3D 90 1E 00 04 28 11 20 3C 90 80 84 +0E 2C B0 13 84 AE 17 3C 1C 42 02 1E 1D 42 04 1E +3D 90 1E 00 09 28 03 20 3C 90 80 84 05 28 3C 40 +3F 0D 3D 40 03 00 ED 3F 3E 40 0A 00 0F 43 B0 13 +8E D0 B0 13 84 AE 7C 40 5A 00 5E 43 B0 13 70 AF +5A 93 12 24 6A 92 24 20 7C 40 11 00 4D 43 B0 13 +02 E9 7C 40 12 00 4D 43 B0 13 02 E9 7C 40 29 00 +4D 43 B0 13 02 E9 14 3C B2 B0 40 00 08 1E 06 20 +7C 40 12 00 5D 43 B0 13 02 E9 05 3C 7C 40 11 00 +5D 43 B0 13 02 E9 7C 40 29 00 5D 43 B0 13 02 E9 +0A 16 10 01 7E 40 06 00 7F 40 03 00 B0 13 FC B4 +CD 0C 10 01 6A 14 31 80 06 00 C6 0C 09 43 3A 40 +00 1C 7F 40 03 00 81 4F 00 00 2F 46 1F 93 06 24 +0F 93 0B 20 58 46 02 00 C7 09 10 3C 5C 46 02 00 +B0 13 F2 E3 C7 0C 07 93 02 20 0C 43 4D 3C 58 47 +09 00 3F 40 03 00 0F 57 81 4F 02 00 24 43 0F 42 +32 C2 03 43 1E 43 6E 9A 39 20 EA 42 00 00 02 4F +3F 40 0B 00 0F 5A 6F 4F 3F F0 3F 00 4E 48 0F 9E +2A 20 25 46 15 93 0E 20 78 90 3F 00 06 20 3F 40 +03 00 0F 57 81 4F 04 00 05 3C 3F 40 07 00 0F 5A +81 4F 04 00 1C 41 04 00 1D 41 02 00 2E 42 B0 13 +2E E6 4C 4C 05 93 02 24 0C 93 0D 20 5F 4A 01 00 +2E 41 4F 9E 08 2C 09 93 02 24 D9 43 00 00 81 4F +00 00 C9 0A 04 3C DA 43 00 00 01 3C 02 4F 3A 50 +23 00 14 83 BC 23 CC 09 31 50 06 00 64 16 10 01 +4A 14 C9 0E 4C 4C 3C 80 46 00 53 24 1C 83 4C 24 +1C 83 46 24 1C 83 41 24 1C 83 3B 24 3C 80 10 00 +3C 90 09 00 55 2C 5C 06 00 18 50 4C 9E AF FC AF +00 00 F6 AF 00 00 F2 AF 00 00 E8 AF 00 00 E0 AF +00 00 DC AF 00 00 D4 AF 00 00 CC AF 00 00 C2 AF +00 00 7A 40 03 00 78 40 22 00 2E 3C 6A 43 78 40 +21 00 2A 3C 6A 43 78 40 23 00 26 3C 6A 42 F7 3F +6A 43 78 40 25 00 20 3C 7A 40 03 00 78 40 24 00 +1B 3C 6A 42 F0 3F 7A 40 05 00 E5 3F 7A 40 06 00 +E6 3F 6A 43 78 40 1A 00 0F 3C 7A 40 03 00 FA 3F +6A 43 78 40 1C 00 08 3C 7A 40 03 00 78 40 1B 00 +03 3C 6A 42 78 40 1A 00 C7 0D 4A 4A 06 43 CC 08 +4C 56 7D 47 CE 09 B0 13 66 C6 16 53 1A 83 F7 23 +46 16 10 01 4A 14 21 83 C8 0D C7 0C 39 40 B9 1D +CC 01 0D 43 1E 43 B0 13 72 ED 46 43 09 98 25 24 +2F 43 6F 99 22 20 5A 49 09 00 7A 90 3E 00 1D 2C +57 93 13 24 3C 40 03 00 0C 59 3D 40 03 00 0D 58 +2E 42 B0 13 2E E6 0C 93 10 20 4F 4A CA 01 3A 50 +E0 FF 0A 5F DA 43 00 00 08 3C C2 9A B6 1D 05 2C +4A 4A CF 01 0F 8A DF 43 3D 00 39 50 0C 00 56 53 +D5 27 CE 01 0F 43 4C 43 CE 93 00 00 04 24 1E 53 +5C 53 FA 27 09 3C 67 93 04 20 7C 50 20 00 4F 4C +03 3C 3F 40 3D 00 4F 8C 67 93 0B 24 5E 42 B7 1D +0F 9E 12 38 5E 42 B6 1D 0F 9E 0F 20 D2 83 B6 1D +0C 3C 5E 42 B6 1D 0E 9F 07 38 5E 42 B7 1D 0E 9F +04 34 C2 4F B7 1D 01 3C 0F 43 C8 4F 09 00 CC 0F +21 53 46 16 10 01 0A 14 CA 0C 5C 43 B0 13 D2 CE +5C 43 6D 42 80 13 0E 1E 5C 43 5D 43 B0 13 26 97 +1A 93 02 20 5F 43 01 3C 6F 43 C2 4F F2 1C C2 43 +F3 1C C2 43 F4 1C C2 43 F5 1C 7C 40 17 00 6D 43 +B0 13 02 E9 7C 40 18 00 6D 43 B0 13 02 E9 7C 40 +19 00 6D 43 B0 13 02 E9 3C 40 00 20 B0 13 A0 CC +B0 13 BA ED 82 4A EA 1C B2 40 10 0E EC 1C B0 13 +A2 B8 4C 93 06 24 1A 93 02 20 B0 13 8A C3 B0 13 +0C DA 82 43 EA 1C B0 13 E0 DF B0 13 0E EE 3C 40 +00 20 B0 13 A0 CC C2 43 1D 02 82 43 76 1E 7C 40 +17 00 6D 42 B0 13 02 E9 7C 40 18 00 6D 42 B0 13 +02 E9 7C 40 19 00 6D 42 B0 13 02 E9 5C 43 B0 13 +D2 CE 5C 43 6D 42 B0 13 26 97 92 D3 8C 1C 0A 16 +10 01 0A 14 CA 0C 5D 93 05 24 6D 92 34 20 C2 43 +CA 1E 31 3C C2 93 CA 1E 1A 20 5C 42 CB 1E B0 13 +7A B2 03 20 B0 13 5A B2 02 3C B0 13 6A B2 5C 42 +CC 1E B0 13 7A B2 03 20 B0 13 6A B2 02 3C B0 13 +5A B2 B0 13 8E B2 5D 43 B0 13 02 E9 14 3C 1C 42 +CE 1E 0D 43 6E 42 4F 43 B0 13 FC B4 CF 0C CC 0A +7D 40 46 00 7E 40 5C 00 B0 13 9E B2 B0 13 8E B2 +4D 43 B0 13 02 E9 0A 16 10 01 CC 0A 7D 40 48 00 +7E 40 5E 00 B0 13 9E B2 10 01 CC 0A 7D 40 4A 00 +7E 40 60 00 B0 13 9E B2 10 01 0D 43 6E 43 4F 43 +B0 13 FC B4 CF 0C B2 B0 40 00 08 1E 10 01 CC 0A +7D 40 1F 00 7E 40 29 00 B0 13 76 EF 10 01 B0 13 +76 EF CD 0F 5E 43 B0 13 70 AF 10 01 1A 14 CA 0D +C9 0C D2 93 78 1D 58 24 B0 13 F4 E1 1D 43 6D 59 +CC 09 B0 13 7A DF 49 43 4A 93 37 24 5A 93 32 20 +6A 42 16 3C 7C 40 36 00 B0 13 D8 C6 7C 40 3D 00 +B0 13 D8 C6 7C B0 F0 FF F9 23 7C 40 3A 00 B0 13 +D8 C6 4A 93 02 20 59 43 2B 3C B0 13 A6 EA 5A 83 +7C 40 34 00 B0 13 D8 C6 A2 B3 30 0F FD 27 92 C3 +32 0F 7C 40 35 00 B0 13 D8 C6 3C 40 19 00 B0 13 +8C EA 92 B3 32 0F D6 27 92 C3 32 0F 92 B3 30 0F +FD 27 0E 3C 32 C2 03 43 FF 3F 7C 40 35 00 B0 13 +D8 C6 B2 B0 00 02 32 0F FC 27 B2 F0 FF FD 32 0F +7C 40 3B 00 B0 13 D8 C6 F2 90 03 00 78 1D 02 20 +B0 13 B4 EB CC 09 03 3C 32 C2 03 43 FF 3F 19 16 +10 01 B2 40 23 5A 5C 01 B0 13 92 E4 F2 40 A5 00 +21 01 F2 D0 80 00 20 01 C2 43 21 01 F2 D0 03 00 +4A 02 92 C3 6C 01 B2 D0 0C 00 6C 01 82 43 66 01 +B2 40 44 00 68 01 32 D0 40 00 82 43 60 01 B2 40 +50 00 62 01 B2 40 6E 11 64 01 32 C0 40 00 1E 14 +3D 40 41 D1 0E 43 1D 83 0E 73 FD 23 0D 93 FB 23 +1D 16 00 3C B2 F0 F0 FF 6E 01 A2 C3 02 01 A2 B3 +02 01 F8 23 32 C2 03 43 B2 40 52 2D C0 01 A2 43 +C2 01 F2 40 0E 00 D7 01 F2 F0 7F 00 03 02 F2 D0 +80 00 05 02 F2 40 11 00 CD 01 F2 40 12 00 CE 01 +F2 40 13 00 CF 01 82 43 C0 01 32 D2 B0 13 12 E0 +B0 13 3E EE B0 13 C6 E1 B0 13 A0 E3 B0 13 04 E5 +B0 13 64 EC 80 00 04 C5 1A 14 CA 0C 5D 93 14 24 +6D 92 47 20 4C 43 4D 43 B0 13 02 E9 C2 93 E0 1E +06 20 7C 40 16 00 6D 42 B0 13 02 E9 3A 3C 7C 40 +16 00 7D 40 03 00 F8 3F B2 B0 40 00 08 1E 10 20 +5C 42 E2 1E B0 13 26 EB CF 0C CC 0A B0 13 EC B4 +4C 4F B0 13 D6 B4 5C 42 E2 1E B0 13 CC E9 06 3C +B0 13 EC B4 5C 42 E2 1E B0 13 D6 B4 CC 0A 7D 40 +48 00 7E 40 5E 00 B0 13 76 EF C9 0C 5C 42 E3 1E +B0 13 D6 B4 CC 0A 7D 40 1E 00 7E 40 28 00 B0 13 +76 EF 5D 43 B0 13 02 E9 7C 40 16 00 6D 43 B0 13 +02 E9 19 16 10 01 0D 43 6E 43 4F 43 B0 13 FC B4 +CD 0C CC 09 5E 43 B0 13 70 AF 10 01 7D 40 4A 00 +7E 40 60 00 B0 13 76 EF C9 0C 10 01 4A 14 C7 0F +C6 0E C9 0C CA 0D C8 06 3C 40 E2 1C 3D 40 12 F5 +3E 40 07 00 B0 13 60 ED 48 93 4E 24 78 92 4C 2C +0A 93 1E 20 39 90 B5 00 1B 2C 78 90 03 00 0D 2C +CD 09 59 02 0D 59 4F 48 0D 8F 3D 50 DB F0 4E 48 +3C 40 E2 1C B0 13 60 ED 22 3C 4C 46 3C 50 DF 1C +CD 09 59 02 0D 59 3D 50 D8 F0 3E 40 03 00 F2 3F +CC 09 CD 0A 3E 40 0A 00 0F 43 B0 13 8E D0 7E 50 +30 00 4F 46 CF 4E E1 1C CC 09 CD 0A 3E 40 0A 00 +0F 43 B0 13 8E D0 C9 0C CA 0D 56 83 E9 23 3F 40 +E2 1C 4D 43 08 3C 47 93 04 24 FF 40 20 00 00 00 +57 83 1F 53 5D 53 3E 40 30 00 6E 9F 05 20 4E 48 +1E 83 4C 4D 0C 9E EF 3B 3C 40 E2 1C 46 16 10 01 +31 80 0E 00 CE 01 3D 40 00 18 4F 43 1E 53 FE 4D +FF FF 5F 53 7F 90 0D 00 F9 2B F1 93 00 00 39 24 +5F 41 01 00 C2 4F 16 1E 3F 90 15 00 05 38 3F 90 +EC 00 02 34 C2 43 16 1E 5F 41 02 00 47 18 0F 5F +5E 41 03 00 0E 5F 82 4E D4 1E 5F 41 04 00 47 18 +0F 5F 5E 41 05 00 0E 5F 82 4E A2 1E D2 41 06 00 +12 1D D2 41 07 00 13 1D D2 41 08 00 14 1D D2 41 +09 00 15 1D F1 93 0C 00 08 24 5F 41 0A 00 47 18 +0F 5F 5E 41 0B 00 0E 5F 01 3C 0E 43 82 4E 22 1E +16 3C E2 42 16 1E B2 40 06 FF D4 1E B2 40 F6 FF +A2 1E F2 40 79 00 12 1D F2 40 56 00 13 1D F2 40 +34 00 14 1D F2 40 12 00 15 1D 82 43 22 1E 31 50 +0E 00 10 01 0A 14 CA 0C 1F 42 44 1E 8F 93 02 00 +10 20 8F 93 00 00 0D 20 C2 93 49 1E 0A 24 5E 42 +49 1E 3E 50 64 00 5D 42 DA 1E 0D 9E 02 34 4C 43 +42 3C BF 40 00 70 08 00 5C 42 51 1E 1D 42 4E 1E +1E 42 50 1E 3D F3 3E F0 FF 00 3F 40 00 08 B0 13 +82 D5 1C 52 D8 1E 1F 42 44 1E 8F 4C 0A 00 1F 42 +44 1E 9F 42 D8 1E 0C 00 1F 42 44 1E CF 43 14 00 +1F 42 44 1E CF 43 15 00 1F 42 44 1E 8F 93 02 00 +05 20 8F 93 00 00 02 20 EF D2 1A 00 1D 42 44 1E +1E 42 4E 1E 1F 42 50 1E 3E F3 3F F0 FF 00 8D 4E +00 00 8D 4F 02 00 1F 42 44 1E 9F 43 18 00 CC 0A +B0 13 F6 C0 5C 43 0A 16 10 01 3A 14 07 4F 07 ED +0A 4F 5A 02 8A 10 4A 4A 0A 93 49 24 7F D0 80 00 +0B 4D 5B 02 8B 10 4B 4B 0B 93 3F 24 7D D0 80 00 +0B 5A 3B 80 7F 00 08 43 09 43 0E 93 09 24 1A 43 +5E 00 02 28 08 5C 09 6D 59 00 58 00 5A 02 F8 2B +0E 43 1A 43 5F 00 02 28 08 5C 09 6D 59 00 58 00 +5E 00 3E B0 00 10 02 24 3E D0 00 20 4A 5A F2 23 +49 93 02 34 1B 53 03 3C 0E 6E 08 68 49 69 3E B0 +00 80 07 24 08 63 49 63 0B 63 3E B0 00 60 01 20 +18 C3 1B 93 0C 38 3B 90 FF 00 0C 34 49 59 8B 10 +09 DB 57 02 59 00 0D 49 0C 48 37 16 10 01 0C 43 +0D 43 FB 3F 3D 40 FF FE 3C 43 57 02 5D 00 F5 3F +CF 0D CD 0E CE 0C C2 93 D1 1D 06 20 B0 13 DC EC +4C 93 02 20 2C 43 10 01 2E 83 2C 24 1E 83 43 24 +2E 83 20 24 1E 83 3B 24 3E 80 03 00 34 24 1E 83 +30 20 0E 43 8D 93 00 00 09 20 0F 93 2A 20 1C 4D +02 00 1D 4D 04 00 B0 13 A8 ED 31 3C 1C 43 2C 9D +20 20 0F 93 1E 20 1C 4D 02 00 1D 4D 04 00 B0 13 +96 ED 25 3C 3F B0 FE FF 14 20 CC 0F B0 13 04 EA +CE 0C 1D 3C 3F 90 03 00 07 24 2F 93 0A 20 CC 0D +B0 13 38 E1 CE 0C 13 3C CC 0D B0 13 36 D2 CE 0C +0E 3C 2E 43 0C 3C B0 13 B6 F0 CE 0C 08 3C B0 13 +BA F0 CE 0C 04 3C CC 0F B0 13 2C CF CE 0C CC 0E +10 01 0A 14 31 80 06 00 B0 13 EE ED 2E 42 CF 01 +1F 53 3D 40 12 1D 1F 53 FF 4D FF FF 1E 83 FB 23 +3C 40 05 00 0D 43 CE 01 1E 53 B0 13 F0 B7 D2 43 +F0 1C 4A 43 B0 13 20 E2 0C 93 08 24 B0 13 38 B9 +1A 2C F2 B0 20 00 F0 1C F5 27 1F 3C E1 43 00 00 +3C 40 03 00 3D 40 0A 00 CE 01 B0 13 F0 B7 4A 43 +B0 13 AA F0 0C 93 04 20 E2 43 F0 1C 5C 43 10 3C +B0 13 38 B9 06 28 C2 43 D1 1D E2 42 F0 1C 4C 43 +07 3C F2 B0 20 00 F0 1C EB 27 C2 43 D1 1D 4C 43 +31 50 06 00 0A 16 10 01 3C 40 E8 03 B0 13 FE ED +B2 40 2B 5A 5C 01 CF 0A 1A 43 4A 5F 7F 90 0B 00 +10 01 92 93 EA 1C 1C 24 C2 93 31 1D 0B 20 F2 B0 +F0 FF F2 1C 04 20 32 D0 D8 00 03 43 34 3C F2 40 +05 00 31 1D D2 83 31 1D 04 20 F2 F0 0F 00 F2 1C +2A 3C 3C 40 D7 03 B0 13 A0 CC F2 D2 F0 1C 23 3C +3C 40 A3 00 B0 13 A0 CC B2 B2 0A 1E 1C 24 F2 B0 +20 00 01 02 18 24 B2 C2 0A 1E B0 13 4C E3 D2 53 +31 1D 5F 42 31 1D 5F 83 6F 93 0D 28 C2 43 31 1D +D2 42 59 1E F3 1C D2 42 5A 1E F4 1C D2 42 5B 1E +F5 1C F2 D2 F0 1C B2 B0 10 00 8C 1C 0A 24 5C 43 +6D 43 B0 13 26 97 B2 F0 EF FF 8C 1C B2 40 2B 5A +5C 01 10 01 1A 14 21 82 39 40 CB 00 3C 40 00 40 +B0 13 A0 CC 3C 40 03 00 3D 40 05 00 0E 43 B0 13 +F0 B7 D1 43 02 00 C1 49 03 00 CC 01 2C 53 6D 43 +B0 13 40 CA 3C 40 03 00 3D 42 0E 43 B0 13 F0 B7 +3C 40 0A 00 B0 13 FE ED CC 01 B0 13 CA D5 0C 93 +18 20 C1 93 00 00 F8 27 B0 13 1E 9B 4A 43 5A 92 +17 1D F2 2F 3C 40 0A 00 B0 13 FE ED 4C 4A B0 13 +F6 AB 3C 40 F2 1C 7D 40 13 00 B0 13 40 CA 5A 53 +EE 3F 3C 40 03 00 2D 42 0E 43 B0 13 F0 B7 B2 40 +2B 5A 5C 01 F2 B0 20 00 F0 1C B8 27 C2 43 D1 1D +21 52 19 16 10 01 1A 14 21 82 CA 0C F2 B0 40 00 +01 02 3C 24 B0 13 0C D4 82 4C 1E 1E B0 13 D8 CB +81 4C 00 00 81 4D 02 00 4A 93 03 20 B0 13 22 BB +27 3C 2C 41 1D 41 02 00 B0 13 44 E0 3E 40 CD CC +3F 40 4C 3E B0 13 3A B7 C9 0C CA 0D 1C 42 1A 1E +1D 42 1C 1E B0 13 44 E0 3E 40 CD CC 3F 40 4C 3F +B0 13 3A B7 CE 0C CF 0D CC 09 CD 0A B0 13 E6 9E +B0 13 58 D4 81 4C 00 00 81 4D 02 00 B0 13 22 BB +1E 42 1E 1E B0 13 00 80 82 4C 20 1E 21 52 19 16 +10 01 1C 41 04 00 1D 41 06 00 82 4C 1A 1E 82 4D +1C 1E 10 01 5C 43 B0 13 D2 CE 5C 43 6D 42 80 13 +0E 1E B0 13 E0 DF B0 13 4C DA B0 13 3C EA 4C 43 +B0 13 9C BD 7C 40 17 00 6D 43 B0 13 02 E9 7C 40 +18 00 6D 43 B0 13 02 E9 7C 40 19 00 6D 43 B0 13 +02 E9 3C 40 00 20 B0 13 A0 CC B0 13 BA ED B2 40 +03 00 EA 1C B2 40 10 0E EC 1C B0 13 A2 B8 4C 93 +02 24 B0 13 F4 B9 82 43 EA 1C B0 13 0E EE 3C 40 +00 20 B0 13 A0 CC C2 43 1D 02 82 43 76 1E 7C 40 +17 00 6D 42 B0 13 02 E9 7C 40 18 00 6D 42 B0 13 +02 E9 7C 40 19 00 6D 42 B0 13 02 E9 92 D3 8C 1C +10 01 5A 14 C6 0F C7 0E C5 0D C9 0C 18 41 1C 00 +C7 43 00 00 B0 13 94 AE CA 0C 0A 93 02 20 2C 42 +3C 3C 1F 43 2F 99 02 24 09 43 09 3C 5C 49 02 00 +B0 13 F2 E3 C9 0C 09 93 02 20 2C 43 2E 3C 5E 4A +02 00 7E 80 0B 00 C7 4E 00 00 3D 40 0E 00 0D 5A +4E 4E CC 05 B0 13 60 ED 09 93 06 24 D9 4A 21 00 +07 00 D9 4A 22 00 08 00 06 93 07 24 3D 40 07 00 +0D 5A CC 06 2E 42 B0 13 60 ED 08 93 06 24 3F 40 +07 00 5F FA 0C 00 C8 4F 00 00 5D 4A 01 00 5C 43 +B0 13 4C E2 CA 43 00 00 0C 43 55 16 10 01 4F 43 +4C 93 2D 24 5C 93 20 24 6C 93 13 24 7C 90 03 00 +2A 20 A2 D2 22 03 A2 C2 24 03 B2 C2 22 03 B0 13 +CE F0 B0 13 FC BC 1F 42 20 03 6F F2 B2 C2 22 03 +1A 3C A2 D2 24 03 B0 13 EA BC B0 13 FC BC A2 D2 +22 03 B0 13 CE F0 0F 3C A2 D2 24 03 B2 C2 22 03 +A2 D2 22 03 B0 13 CE F0 B0 13 E0 BC 04 3C A2 D2 +24 03 B0 13 E0 BC 4C 43 4F 93 01 20 5C 43 10 01 +B0 13 FC BC B0 13 EA BC 10 01 A2 C2 22 03 B0 13 +CE F0 B2 C2 22 03 B0 13 CE F0 10 01 B2 D2 22 03 +B0 13 CE F0 10 01 1A 14 CB 0C 7B 90 BD 00 07 24 +4C 43 7B 90 31 00 40 28 7B 90 3D 00 3D 2C 0A 42 +32 C2 03 43 B2 F0 BF FF 02 0F B2 B0 10 00 02 0F +FC 27 7B 90 3D 00 26 2C 4C 43 B0 13 CA EB C9 0C +4C 43 7D 40 29 00 B0 13 28 DD C2 4B 11 0F A2 B2 +30 0F 13 24 7B 90 32 00 10 24 7B 90 39 00 0D 24 +7B 90 38 00 0A 24 A2 B2 30 0F FD 23 0D 14 3D 40 +BF 0C 1D 83 FE 23 0D 16 03 43 4C 43 CD 09 B0 13 +28 DD 03 3C F2 40 BD 00 11 0F 5C 42 21 0F B2 B0 +40 00 02 0F FC 27 02 4A 19 16 10 01 0A 14 21 82 +CA 0C 0C 43 3D 40 00 08 3E 40 0A 00 B0 13 70 C9 +0D 43 3E 40 07 0D 0F 43 B0 13 46 E7 3C 80 B9 65 +3D 70 5E 00 3E 40 00 08 0F 43 B0 13 CC D9 81 4C +00 00 81 4D 02 00 1E 42 D4 1E 3E B0 00 80 0F 7F +3F E3 81 5E 00 00 81 6F 02 00 5A 93 1A 20 1E 42 +D2 1E 3E B0 00 80 0F 7F 3F E3 1F 91 02 00 0D 38 +02 20 2E 91 0A 28 81 9F 02 00 04 38 0C 20 81 9E +00 00 09 2C 92 83 D2 1E 06 3C 1E 53 82 4E D2 1E +02 3C A2 41 D2 1E B2 D0 40 00 8C 1C 21 52 0A 16 +10 01 4C 43 B0 13 C2 E5 0C 93 42 24 1C 83 42 20 +B0 13 5C F0 4C 4C C2 4C FA 1D B0 13 AA E7 C2 4C +00 1E B0 13 8A E7 0D 43 82 4C 02 1E 82 4D 04 1E +5C 42 FA 1D 7C 90 41 00 28 28 1D 42 F8 1D 0D 93 +24 24 4C 4C 3C 80 3C 00 B0 13 38 EC CF 0C 44 19 +0F 10 D2 93 F6 1D 03 20 46 19 0C 10 0F 8C CD 0F +0E 43 1D 52 FC 1D 1E 62 FE 1D 3E 90 EB 0B 04 28 +08 20 3D 90 01 C2 05 2C 82 5F FC 1D 82 63 FE 1D +04 3C 82 43 FC 1D 82 43 FE 1D 92 43 F0 1D 10 01 +80 00 EE D4 10 01 3A 14 07 4F 07 ED 0A 4F 5A 02 +8A 10 4A 4A 0A 93 38 24 7F D0 80 00 0B 4D 5B 02 +8B 10 4B 4B 0B 93 2B 24 7D D0 80 00 0B 8A 3B 50 +7F 00 3A 40 18 00 08 43 09 43 0C 8E 0D 7F 03 2C +0C 5E 0D 6F 12 C3 08 68 09 69 5C 02 0D 6D 1A 83 +F4 23 49 93 03 30 1A 53 1B 83 EF 3F 0C 7E 0D 7F +08 63 49 63 0B 63 1B 93 0C 38 3B 90 FF 00 0C 34 +49 59 8B 10 09 DB 57 02 59 00 0D 49 0C 48 37 16 +10 01 0C 43 0D 43 FB 3F 3C 40 FF FE 3D 43 57 02 +5D 00 F5 3F 2A 14 21 83 C9 0C 3F 40 0B 00 0F 59 +68 4F 3A 40 3F 00 4A F8 3C 40 07 00 0C 59 1D 42 +64 1E 2E 42 B0 13 2E E6 0C 93 2D 24 78 B0 40 00 +2A 20 4A 93 10 24 7A 90 07 00 0D 2C 4A 4A 5A 06 +00 18 5F 4A 90 F6 2C 43 0C 59 4F 13 1C 93 1B 20 +D9 43 00 00 1A 3C 7A 90 3F 00 03 24 7A 90 20 00 +12 28 2C 43 0C 59 CD 01 B0 13 E0 BF 4C 93 0B 24 +D9 43 00 00 00 18 C2 93 68 1E 07 24 6C 41 80 13 +68 1E 4C 93 02 24 C9 43 00 00 21 53 28 16 10 01 +4A 14 C7 0D C8 0C 39 40 B9 1D 3A 40 3F 00 5A F8 +09 00 26 43 2F 43 6F 99 32 20 5A 99 09 00 2F 20 +7A 90 3F 00 0B 24 3C 40 03 00 0C 59 3D 40 05 00 +0D 58 2E 42 B0 13 2E E6 0C 93 21 20 D7 49 0B 00 +00 00 57 43 7A 90 3F 00 16 24 3F 40 0A 00 0F 58 +6F 4F 7F B0 80 FF 0A 20 7F B2 0D 24 D9 98 0B 00 +02 00 02 20 C9 43 02 00 47 43 05 3C 5D 49 0A 00 +CC 08 B0 13 88 C4 B0 13 CE EE CC 07 05 3C 39 50 +0C 00 16 83 C7 23 4C 43 46 16 10 01 4A 14 C9 0F +C7 0E C6 0D CA 0C 6C 43 B0 13 7C C5 C8 0C 08 93 +02 20 0C 43 36 3C CF 07 7F 50 0B 00 C8 4F 02 00 +3E 40 0B 00 0E 58 3F 40 80 00 6F FE 4F DA CE 4F +00 00 D8 42 62 1E 0D 00 D2 53 62 1E FD 27 F8 F0 +BF 00 0C 00 5F 48 0C 00 7F F0 F8 00 4F D9 C8 4F +0C 00 F8 F0 7F 00 0C 00 F8 C2 0C 00 FE F0 7F 00 +00 00 3C 40 0E 00 0C 58 4E 47 CD 06 B0 13 60 ED +3C 40 07 00 0C 58 1D 42 64 1E 2E 42 B0 13 60 ED +CC 08 46 16 10 01 1F 42 44 1E CF 43 11 00 1F 42 +44 1E DF 42 51 1E 13 00 1F 42 44 1E 5E 42 D8 1E +5E 8F 0C 00 CF 4E 16 00 1F 42 44 1E 5E 4F 16 00 +8E 11 8F 5E 0A 00 1F 42 44 1E DF 5F 16 00 15 00 +1F 42 44 1E DF 42 DA 1E 12 00 1F 42 44 1E FF 92 +12 00 02 2C FF 42 12 00 1F 42 44 1E 9F 42 52 1E +04 00 9F 42 54 1E 06 00 1F 42 44 1E DF 42 56 1E +0E 00 1F 42 44 1E EF B2 1A 00 03 20 4D 43 B0 13 +4C D9 B0 13 1A CE D2 C3 D6 1E 10 01 1E 42 44 1E +5F 4E 15 00 8F 11 3F 90 40 00 10 34 3F 90 C1 FF +19 34 FE 50 40 00 15 00 1F 42 44 1E 9F 83 08 00 +1F 42 44 1E 5F 4F 15 00 8F 11 0C 3C FE 80 40 00 +15 00 1F 42 44 1E 9F 53 08 00 1F 42 44 1E 5F 4F +15 00 8F 11 1E 42 44 1E CE 5F 14 00 1E 42 44 1E +5F 4E 14 00 8F 11 3F 90 40 00 0B 34 3F 90 C1 FF +0F 34 FE 50 40 00 14 00 1F 42 44 1E 9F 83 0A 00 +10 01 FE 80 40 00 14 00 1F 42 44 1E 9F 53 0A 00 +10 01 4F 14 1F 42 6E 03 2F 83 36 24 2F 83 27 24 +2F 83 03 24 2F 83 1A 24 31 3C B2 F0 EF FF 48 03 +92 C3 48 03 82 93 50 03 02 20 0F 43 05 3C 1F 42 +50 03 1F 92 50 03 FB 23 1F 52 C0 1E 82 4F 58 03 +B2 D0 10 00 48 03 80 13 BC 1E 18 3C B2 F0 EF FF +4A 03 92 C3 4A 03 B2 D0 80 00 08 1E 0F 3C B2 F0 +EF FF 46 03 92 C3 46 03 B0 13 B4 DC B2 D0 10 00 +46 03 B0 13 48 A8 02 3C B0 13 00 DC B1 C0 D0 00 +14 00 4B 16 00 13 0A 14 CA 0D 4C 4C 3C 90 07 00 +0E 34 3C 90 06 00 2F 24 1C 83 30 24 1C 83 14 24 +1C 83 2C 24 1C 83 27 24 1C 83 28 24 2A 3C 3C 80 +07 00 2C 93 23 28 2C 83 1E 24 1C 83 1F 24 1C 83 +1A 24 1C 83 1B 24 1D 3C 3A B0 03 00 0E 20 CC 0A +3D 40 64 00 B0 13 22 EC 0E 93 0A 20 CC 0A 3D 40 +90 01 B0 13 22 EC 0E 93 03 24 7C 40 1C 00 0A 3C +7C 40 1D 00 07 3C 7C 40 1E 00 04 3C 7C 40 1F 00 +01 3C 4C 43 0A 16 10 01 3C 40 B5 1D 0D 43 3E 40 +1C 00 B0 13 72 ED E2 43 B5 1D F2 40 3D 00 B6 1D +F2 40 20 00 B7 1D D2 43 B8 1D B0 13 76 E5 B0 13 +2A E8 B0 13 E8 E9 B0 13 E6 EF B0 13 1A E4 B0 13 +DC EF B0 13 08 E1 3F 40 B9 1D CF 43 00 00 3F 50 +0C 00 CF 43 00 00 C2 93 C5 1D 15 20 E2 43 C5 1D +F2 40 03 00 C6 1D 7F 40 3F 00 C2 4F CE 1D C2 4F +CF 1D F2 43 D0 1D B0 13 98 F0 CD 0C 3C 40 C8 1D +2E 42 B0 13 60 ED 0C 43 10 01 F2 D0 A9 00 C1 05 +F2 D0 80 00 C0 05 F2 40 1E 00 C6 05 C2 43 C7 05 +D2 C3 C0 05 F2 F0 DF 00 19 02 F2 F0 DF 00 05 02 +F2 F0 DF 00 04 02 F2 D0 20 00 06 02 F2 D0 E0 00 +0A 02 A2 D3 22 03 92 D3 22 03 3C 40 47 01 B0 13 +A0 CC F2 F0 DF 00 1D 02 F2 D0 20 00 1B 02 6C 42 +6D 43 B0 13 0C CB 6C 42 7D 40 0A 00 B0 13 0C CB +6C 42 6D 42 B0 13 0C CB 3C 40 A3 00 B0 13 A0 CC +6C 43 7D 40 82 00 80 00 0C CB 7C 40 36 00 B0 13 +06 BD F2 B0 10 00 D6 1E 27 24 7C 40 0A 00 5D 42 +98 1E B0 13 28 DD F2 90 7F 00 99 1E 07 38 7C 40 +0C 00 7D 40 0C 00 B0 13 28 DD 06 3C 7C 40 0C 00 +5D 42 99 1E B0 13 28 DD F2 B2 D6 1E 07 20 7C 40 +12 00 7D 40 11 00 B0 13 28 DD 06 3C 7C 40 12 00 +7D 40 15 00 B0 13 28 DD 7C 40 34 00 B0 13 06 BD +B2 F0 FE FD 32 0F B2 F0 FE FD 32 0F B2 D0 01 02 +36 0F A2 43 C4 1E 10 01 1A 14 31 80 22 00 C9 0D +5A 4C 0B 00 3F 40 CF 00 5F F1 0A 00 5F D2 66 1E +7F F0 BF 00 C1 4F 0A 00 3D 40 05 00 0D 5C CC 01 +1C 53 2E 42 B0 13 60 ED CC 01 3C 50 05 00 1D 42 +64 1E 2E 42 B0 13 60 ED 3D 40 C0 00 5D F1 09 00 +4D D9 F1 40 0B 00 00 00 C1 4A 0B 00 3F 40 70 00 +5F F1 0A 00 7F D0 0B 00 C1 4F 0A 00 7D F0 3F 00 +C1 4D 09 00 CC 01 4D 43 B0 13 AC B2 31 50 22 00 +19 16 10 01 21 82 F2 F0 BF 00 05 02 F2 F0 BF 00 +19 02 B2 D0 0C 00 22 03 B2 D0 0C 00 24 03 C2 43 +76 1D 3C 40 CC 0C B0 13 A0 CC 7C 40 06 00 5D 43 +B0 13 36 D0 C1 4C 00 00 3C 40 CC 0C B0 13 A0 CC +7C 40 07 00 4D 43 B0 13 4A C7 C1 4C 01 00 D1 B3 +01 00 12 20 C1 93 01 00 0F 24 7C 40 7F 00 4D 43 +B0 13 4A C7 C1 4C 02 00 D1 93 02 00 03 24 C2 43 +76 1D 02 3C D2 43 76 1D 21 52 10 01 2A 14 5C 93 +03 20 3F 40 00 1C 02 3C 3F 40 46 1C 2D 43 08 43 +CB 08 4E 43 79 40 03 00 CF 93 00 00 06 20 6C 93 +02 20 CC 0F 24 3C CB 0F 0C 3C 5C 93 0A 20 5E 53 +2A 42 6A 9F 06 24 5A 4F 01 00 4A 99 02 2C C8 0F +C9 0A 3F 50 23 00 1D 83 E7 23 0B 93 0C 20 08 93 +02 20 0C 43 0C 3C CB 08 5D 4B 01 00 B0 13 4C E2 +EB 43 01 00 03 3C 5E 53 CB 4E 01 00 CC 0B 28 16 +10 01 3C 40 10 00 3D 40 00 0A 3E 40 0B 00 B0 13 +70 C9 5C 06 3D 40 29 00 B0 13 22 EC 1F 42 A2 1E +0F 5C 3F 90 69 01 03 2C 1C 42 A0 1E 03 3C 1C 42 +A0 1E CF 0C 5C 06 0C 5F 5C 02 3D 40 0A 00 B0 13 +22 EC 82 4C A0 1E 3C 90 F0 00 08 28 B2 F0 DF FF +08 1E 7C 42 4D 43 B0 13 02 E9 07 3C B2 D0 20 00 +08 1E 7C 42 5D 43 B0 13 02 E9 B2 D2 8C 1C B2 D0 +80 00 8C 1C 10 01 1A 14 CF 0E CA 0C 7A 90 1A 00 +31 28 7A 90 2A 00 2E 2C 4E 4A 5E 02 1C 4E 8E 1C +4E 4A 5E 4E FE F5 7D 90 30 00 05 2C 7D 90 2D 00 +05 20 6B 43 08 3C 7D 90 5B 00 02 28 4B 43 03 3C +4B 4D 5B 4B A2 F5 7A 90 21 00 11 28 C9 0B 43 18 +49 59 43 19 4B 10 4B D9 7A 90 21 00 08 20 7D 90 +31 00 03 24 7D 90 4C 00 02 20 7B 40 80 00 CD 0B +B0 13 BC CD 19 16 10 01 0A 14 CE 0C 0B 42 32 C2 +03 43 B2 F0 BF FF 02 0F B2 B0 10 00 02 0F FC 27 +7E 90 31 00 23 28 7E 90 3D 00 20 2C 4C 43 B0 13 +2C D7 CA 0C 4C 43 7D 40 29 00 B0 13 46 DF C2 4E +11 0F A2 B2 30 0F 0D 24 7E 90 32 00 0A 24 7E 90 +38 00 07 24 A2 B2 30 0F FD 23 3C 40 F8 02 B0 13 +8C EA 4C 43 CD 0A B0 13 46 DF 02 3C C2 4E 11 0F +5C 42 21 0F 02 4B 0A 16 10 01 0A 14 CB 0D CA 0C +4C 43 B0 13 6E BC 7C 40 22 00 B0 13 AC C7 0C 24 +CC 0A B0 13 AC C7 08 24 5C 43 B0 13 6E BC 7C 40 +23 00 B0 13 AC C7 02 20 0C 43 16 3C 5B 93 05 24 +4C 43 B0 13 88 D2 4D 4C 0B 3C 5C 43 B0 13 88 D2 +4C 4C 4D 4C 8D 10 4C 43 B0 13 88 D2 4C 4C 0D DC +6C 43 B0 13 6E BC CC 0D 0A 16 10 01 B0 13 0A D9 +7C 40 03 00 B0 13 6E BC 4C 93 10 01 7C 40 36 00 +B0 13 06 BD 4C 43 3D 40 28 F6 7E 40 27 00 B0 13 +FC D7 7C 40 2C 00 7D 40 88 00 B0 13 28 DD 7C 40 +2D 00 7D 40 31 00 B0 13 28 DD 7C 40 2E 00 7D 40 +09 00 B0 13 28 DD 7C 40 36 00 B0 13 06 BD 7C 40 +33 00 B0 13 06 BD 7C 40 3D 00 B0 13 06 BD 7C B0 +70 00 F9 23 7C 40 36 00 B0 13 06 BD 82 43 C4 1E +B2 D0 01 02 34 0F 82 43 32 0F 10 01 B2 40 0A F3 +E6 1E B2 40 88 F3 E4 1E 00 18 D2 42 12 F3 0E 1E +00 18 D2 42 90 F3 12 1E 82 43 76 1E 82 43 08 1E +82 43 0A 1E 82 43 8C 1C 82 43 0C 1E 92 D3 8C 1C +B2 D0 40 00 08 1E B0 13 C0 B5 B0 13 76 E6 B0 13 +04 ED B0 13 6E EB B0 13 FA EF B0 13 4A E8 B0 13 +8C D9 B0 13 A6 EE B0 13 D0 DD B0 13 04 F0 B0 13 +0E F0 B0 13 CC ED 80 00 F2 C5 4C 4C C2 93 93 1E +02 20 4C 43 10 01 41 18 4C 5C 4C 4C F2 F0 DF 00 +06 02 A2 C3 22 03 5F 42 CC 05 C2 4C CE 05 3F 40 +E8 03 D2 B3 DD 05 03 20 1F 83 FB 23 18 3C 0F 93 +16 24 5F 42 CC 05 C2 43 CE 05 3F 40 E8 03 D2 B3 +DD 05 03 20 1F 83 FB 23 0A 3C 0F 93 08 24 5C 42 +CC 05 A2 D3 22 03 F2 D0 20 00 06 02 10 01 C2 43 +93 1E 4C 43 10 01 0A 14 CA 0D CB 0C 7B 93 02 24 +CF 0B 02 3C 4B 43 4F 43 4E 4B 4F 4F 0F 8E 1F 53 +4C 4B 3D 40 1C 00 B0 13 38 EC 1C 52 D4 F6 4A 93 +09 24 8C 43 00 00 8C 43 02 00 CC 43 1A 00 FC 40 +7F 00 10 00 8C 43 18 00 FC F0 FC 00 1A 00 8C 43 +04 00 8C 43 06 00 CC 43 0E 00 CC 43 12 00 CC 43 +0F 00 CC 43 11 00 5B 53 1F 83 DA 23 0A 16 10 01 +1A 14 C9 0D 3A 40 81 00 0A 5C 82 DA B0 01 CF 09 +3F 50 10 00 82 4F 00 07 B2 40 00 02 02 07 7E 50 +10 00 C2 4E 10 07 92 43 0C 07 2C 43 B0 13 A0 CC +A2 D3 00 07 C2 43 EA 1E 92 D3 00 07 3C 40 05 00 +B0 13 A0 CC C2 93 EA 1E FD 27 39 D0 03 00 82 C9 +00 07 B2 F0 EF FF 00 07 82 CA B0 01 82 43 0C 07 +1C 42 E8 1E 19 16 10 01 1A 14 21 82 CA 0C 3C 40 +05 00 0C 5A 5D 4A 0E 00 B0 13 3C DC 0C 93 02 20 +3F 42 03 3C B0 13 92 F0 0F 43 F1 40 82 00 00 00 +D1 4A 0D 00 01 00 C1 4F 02 00 6C 43 CD 01 7E 40 +03 00 7F 40 03 00 B0 13 6C C0 C9 0C 09 93 0D 24 +3C 40 03 00 0C 59 3D 40 05 00 0D 5A 2E 42 B0 13 +60 ED CC 09 4D 43 B0 13 68 E1 21 52 19 16 10 01 +2A 14 C8 0D C9 0C 5C 42 77 1D B0 13 F2 E3 CA 0C +B0 13 80 F0 0A 93 24 24 CC 0A 5D 43 B0 13 50 E5 +0C 93 1F 20 09 93 1D 24 5C 4A 0A 00 5F 4A 01 00 +CD 09 CE 08 B0 13 6C C0 C9 0C 09 93 0E 24 3C 40 +03 00 0C 59 3D 40 03 00 0D 5A 2E 42 B0 13 60 ED +CC 09 5D 43 B0 13 68 E1 04 3C 3C 40 03 00 01 3C +2C 43 28 16 10 01 0E 42 32 C2 03 43 4C 93 2C 24 +4F 4C 3F 50 00 7E B2 B0 10 00 02 0F FC 27 82 4F +10 0F B2 B0 10 00 02 0F FC 27 F2 40 3D 00 11 0F +B2 B0 10 00 02 0F FC 27 F2 40 FE 00 11 0F B2 B0 +20 00 02 0F FC 27 C2 43 10 0F B2 B0 80 00 02 0F +FC 27 5D 42 20 0F B2 B0 10 00 02 0F FC 27 F2 40 +3D 00 11 0F 4D 9C D7 23 02 4E 10 01 4C 4C C2 93 +93 1E 2E 24 41 18 4C 5C 6C D3 F2 F0 DF 00 06 02 +A2 C3 22 03 5F 42 CC 05 C2 4C CE 05 3F 40 E8 03 +D2 B3 DD 05 03 20 1F 83 FB 23 18 3C 0F 93 16 24 +5F 42 CC 05 C2 4D CE 05 3F 40 E8 03 D2 B3 DD 05 +03 20 1F 83 FB 23 0A 3C 0F 93 08 24 5F 42 CC 05 +A2 D3 22 03 F2 D0 20 00 06 02 10 01 C2 43 93 1E +10 01 0A 14 CA 0D 6A 92 1A 24 B0 13 22 EF 4C 93 +08 20 7C 40 47 00 3D 40 40 F5 5E 43 B0 13 70 AF +0E 3C 5C 42 FA 1D 0D 43 7E 40 03 00 6F 43 B0 13 +FC B4 CD 0C 7C 40 47 00 5E 43 B0 13 70 AF B0 13 +22 EF 4C 93 0F 20 5A 93 08 24 6A 92 0B 20 7C 40 +13 00 4D 43 B0 13 02 E9 05 3C 7C 40 13 00 5D 43 +B0 13 02 E9 0A 16 10 01 21 82 81 43 00 00 81 43 +02 00 7C 40 7F 00 4D 43 B0 13 4A C7 81 4C 00 00 +81 43 02 00 2C 41 1F 41 02 00 47 18 0C 5C 0D 43 +3C F0 00 07 0D F3 B0 13 62 DB 81 4C 00 00 81 4D +02 00 7C 40 80 00 5D 43 B0 13 4A C7 81 DC 00 00 +12 C3 11 10 02 00 11 10 00 00 12 C3 11 10 02 00 +11 10 00 00 2C 41 1D 41 02 00 21 52 10 01 1F 42 +38 0F 1E 42 0E 0F 0E 93 14 20 0F 93 28 24 3F 90 +14 00 0C 20 B2 B0 00 02 36 0F 03 20 32 C2 03 43 +FF 3F B2 F0 FF FD 32 0F 80 00 56 A7 32 C2 03 43 +FF 3F 2E 93 11 20 1F 42 0C 0F 2F 93 0A 24 2F 92 +08 24 3F 90 06 00 05 24 3F 92 03 24 32 C2 03 43 +FF 3F 32 C2 03 43 FF 3F 32 C2 03 43 FF 3F 10 01 +B2 B0 30 00 40 03 2B 24 B2 F0 EF FF 4A 03 B2 F0 +7F FF 08 1E 82 93 50 03 02 20 0F 43 05 3C 1F 42 +50 03 1F 92 50 03 FB 23 0F 5C 82 4F 5A 03 92 C3 +4A 03 B2 D0 10 00 4A 03 B0 13 54 F0 B2 40 2B 5A +5C 01 B0 13 F0 EC 4C 93 03 24 6D 43 B0 13 10 A0 +32 C2 03 43 B2 B0 80 00 08 1E EE 27 32 D2 10 01 +B2 F0 FE FD 36 0F B2 F0 FE FD 32 0F B2 F0 FE FD +32 0F 92 43 C4 1E 7C 40 32 00 B0 13 CA EB C2 4C +C6 1E 7C 43 3D 40 4E 1E 7E 40 0A 00 B0 13 B8 D7 +7C 43 B0 13 CA EB C2 4C DA 1E 7C B0 80 FF 04 20 +F2 80 80 00 DA 1E 03 3C F2 F0 7F 00 DA 1E 1F 42 +C8 1E 3F 80 10 00 82 4F D8 1E 80 00 CA DA 5D 93 +10 24 6D 93 08 24 6D 92 19 20 82 43 9C 1E 7C 42 +4D 43 80 00 02 E9 B0 13 9E CD B2 F0 7F FF 8C 1C +10 01 7C 42 5D 43 B0 13 02 E9 92 43 9C 1E B0 13 +9E CD 7C 40 29 00 5D 43 80 00 02 E9 10 01 1C 42 +A0 1E 0D 43 7E 40 03 00 4F 43 B0 13 FC B4 CD 0C +7C 40 5D 00 5E 43 B0 13 70 AF 10 01 5F 93 20 24 +4F 93 1B 24 6F 93 12 24 7F 90 03 00 05 24 6F 92 +1C 20 B0 13 0C CE 10 01 4E 4E 3E E3 CF 0E 6F FC +4D DF CC 4D 00 00 CC FE 20 00 10 01 B0 13 0C CE +CC DD 00 00 CC DD 20 00 10 01 CC CE 00 00 10 01 +6F 4C 4F CE 4D DF CC 4D 00 00 10 01 4E 4E 3E E3 +CC FE 00 00 CC FE 20 00 10 01 0A 14 1F 42 44 1E +DF 53 13 00 B0 13 7C C1 1F 42 44 1E 1E 4F 08 00 +1E 5F 0A 00 8F 4E 0C 00 1F 42 44 1E 9F 4F 0C 00 +0A 00 1A 42 44 1E CF 0A 5C 4F 13 00 2D 4F 1E 4F +02 00 3F 40 00 08 B0 13 82 D5 8A 8C 0C 00 1F 42 +44 1E FF 40 07 00 0F 00 1F 42 44 1E FF F0 FC 00 +1A 00 0A 16 10 01 92 53 26 1E 82 63 28 1E 1F 43 +5F 52 32 1E 3F 90 3C 00 1F 20 C2 43 32 1E 1F 43 +5F 52 31 1E 3F 90 3C 00 12 20 C2 43 31 1E 1F 43 +5F 52 30 1E F2 40 03 00 2E 1E 3F 90 18 00 03 24 +C2 4F 30 1E 10 01 C2 43 30 1E 80 00 28 D3 C2 4F +31 1E E2 43 2E 1E 10 01 C2 4F 32 1E D2 43 2E 1E +10 01 0A 14 CA 0C 7D 40 46 00 7E 40 5A 00 B0 13 +76 EF 0D 43 4E 43 B0 13 70 AF 5A 93 0D 24 7C 40 +29 00 B0 13 24 CF 7C 40 27 00 B0 13 24 CF 7C 40 +28 00 B0 13 24 CF 0C 3C 7C 40 1F 00 B0 13 24 CF +7C 40 20 00 B0 13 24 CF 7C 40 1E 00 B0 13 24 CF +0A 16 10 01 4D 43 B0 13 02 E9 10 01 0A 14 0A 43 +2C 92 22 24 3C 90 05 00 1C 24 3C 92 17 24 3C 90 +0A 00 12 20 2F 4D 0F 93 0A 24 1F 83 06 24 1F 83 +02 24 2C 43 16 3C 6C 43 03 3C 5C 43 01 3C 4C 43 +B0 13 72 EA 0C 43 0D 3C 2A 43 0A 3C B0 13 0A E8 +07 3C B0 13 E0 E6 04 3C B0 13 EA E7 B0 13 0A E6 +CC 0A 0A 16 10 01 1A 14 C9 0C 79 93 02 24 CA 09 +02 3C 49 43 4A 43 4F 49 4A 4A 0A 8F 1A 53 CC 09 +B0 13 C2 E5 0C 93 09 20 4C 49 3D 40 1C 00 B0 13 +38 EC 1C 52 D4 F6 B0 13 DE CF 59 53 1A 83 EF 23 +E2 B3 D6 1E 0A 24 B0 13 BE EF 4C 93 06 20 D2 C3 +D6 1E B0 13 DE ED B0 13 74 F0 19 16 10 01 AC 43 +18 00 FC F0 FC 00 1A 00 CC 43 12 00 5F 42 4A 1E +C2 93 4B 1E 03 20 CC 4F 13 00 08 3C 5E 42 4A 1E +12 C3 4E 10 4E 11 4F 8E CC 4F 13 00 E2 B3 D6 1E +11 20 F2 D0 06 00 D6 1E B0 13 C2 EE 82 4C 42 1E +C2 93 4B 1E 04 20 B2 50 E0 7F 42 1E 10 01 B2 50 +C0 53 42 1E 10 01 0A 14 21 83 CA 0D CB 0C 4C 43 +B0 13 6E BC 7C 40 22 00 B0 13 72 D0 0E 24 CC 0B +B0 13 72 D0 0A 24 CC 0A B0 13 80 D0 C1 4C 00 00 +6C 43 B0 13 6E BC 5C 43 01 3C 4C 43 21 53 0A 16 +10 01 B0 13 80 D0 C1 4C 04 00 C1 93 04 00 10 01 +B0 13 0A D9 7C 40 03 00 B0 13 6E BC 10 01 0A 14 +09 14 09 43 0A 43 1B 43 0F 93 04 24 09 4D 0D 4C +0C 43 0D 3C 5C 02 0D 6D 09 69 09 8E 04 28 1C D3 +5B 02 F8 2B 03 3C 09 5E 5B 02 F4 2B 1B 43 5C 02 +0D 6D 09 69 0A 6A 09 8E 0A 7F 04 28 1C D3 5B 02 +F6 2B 04 3C 09 5E 0A 6F 5B 02 F1 2B 0E 49 0F 4A +09 16 0A 16 10 01 0A 14 7C 40 23 00 B0 13 CA EB +CA 0C 7A D0 20 00 CD 0A 7C 40 23 00 B0 13 28 DD +7C 40 C6 00 B0 13 A6 CA 7C 40 33 00 B0 13 06 BD +7C 40 3D 00 B0 13 06 BD 7C B0 70 00 F9 23 3D 40 +DF 00 4D FA 7C 40 23 00 B0 13 28 DD 7C 40 36 00 +B0 13 06 BD 82 43 C4 1E 0A 16 10 01 0A 14 CA 0D +6A 92 17 24 1C 42 FC 1D 1D 42 FE 1D 3E 40 E8 03 +0F 43 B0 13 8E D0 7E 40 06 00 7F 40 05 00 B0 13 +FC B4 CD 0C 7C 40 5A 00 5E 43 B0 13 70 AF 5A 93 +08 24 6A 92 0B 20 7C 40 10 00 4D 43 B0 13 02 E9 +05 3C 7C 40 10 00 5D 43 B0 13 02 E9 0A 16 10 01 +B2 B0 20 00 08 1E 25 20 B0 13 22 EF 4C 93 21 20 +B0 13 3A EF 4C 93 1D 20 D2 53 89 1E E2 93 89 1E +18 20 4C 43 4D 43 B0 13 02 E9 5C 43 B0 13 D2 CE +7C 40 5A 00 3D 40 20 F5 5E 43 B0 13 70 AF 7C 40 +46 00 3D 40 56 F5 5E 43 B0 13 70 AF 3F 40 00 10 +C0 0F 10 01 2A 14 1A 41 10 00 49 4C 1B 42 44 1E +1B 4B 0C 00 0B 89 3B 80 32 00 28 4D C9 0B 09 88 +09 93 02 38 28 9E 15 20 8D 4B 00 00 1D 42 44 1E +4C 4C 1C 5D 0C 00 3C 50 10 00 8E 4C 00 00 1E 42 +44 1E DF 4E 0F 00 00 00 1F 42 44 1E DA 4F 10 00 +00 00 28 16 10 01 1A 14 CA 0C 5C 4A 05 00 CF 0C +3F 80 03 00 06 24 2F 83 2F 93 03 28 7F 40 03 00 +01 3C 5F 43 4C 4C 1D 4A 02 00 5E 4A 04 00 B0 13 +6C C0 C9 0C 09 93 0C 24 3C 40 03 00 0C 59 2D 4A +2E 42 B0 13 60 ED CC 09 5D 43 B0 13 68 E1 02 3C +3C 40 03 00 19 16 10 01 A2 D2 22 03 A2 C2 24 03 +3E 42 4F 43 B2 C2 22 03 B0 13 CC D2 4F 5F A2 B2 +20 03 01 24 5F D3 1E 83 F5 23 A2 D2 24 03 B2 C2 +22 03 5C 93 03 24 A2 D2 22 03 02 3C A2 C2 22 03 +B0 13 CC D2 B2 C2 22 03 CC 0F 10 01 B0 13 CE F0 +B2 D2 22 03 B0 13 CE F0 10 01 D2 B3 D6 1E 1E 24 +A2 93 46 1E 1B 24 1F 42 44 1E 2E 4F 1F 4F 02 00 +0F 93 09 20 0E 93 07 20 82 93 46 1E 0F 20 92 43 +46 1E 5C 43 10 01 1C 42 4E 1E 1D 42 50 1E 3C F3 +3D F0 FF 00 0D 9F 02 20 0C 9E 02 24 4C 43 10 01 +A2 43 46 1E 5C 43 10 01 2A 14 19 43 59 52 CB 1E +18 42 CE 1E 5A 42 CC 1E 4C 4A CD 08 B0 13 86 C2 +4C 4C 0C 99 11 34 5A 53 3A 90 0D 00 05 34 C2 4A +CC 1E D2 43 CB 1E 0A 3C D2 43 CB 1E D2 43 CC 1E +18 53 82 48 CE 1E 02 3C C2 49 CB 1E 92 D3 8C 1C +28 16 10 01 F2 B0 10 00 01 02 10 20 D2 B3 01 02 +06 24 C2 93 7F 1E 19 20 B2 D2 76 1E 0C 3C 82 43 +7C 1E F2 40 0A 00 7F 1E 80 00 9E F0 C2 93 7F 1E +0C 20 A2 D2 76 1E 92 53 7C 1E 92 42 26 1E 2A 1E +92 42 28 1E 2C 1E 80 00 A4 F0 D2 83 7F 1E 10 01 +2A 14 4A 4C 4C 4A B0 13 6E EE 4C 93 02 20 7A E3 +5A 53 3A B0 00 80 0B 7B 3B E3 38 40 AC F6 09 43 +0F 43 1C 43 0D 43 CE 0F B0 13 1E EE 0C FA 0D FB +CE 0F B0 13 2E EE 3D 48 B0 13 38 EC 09 5C 1F 53 +3F 90 07 00 EE 3B CC 09 28 16 10 01 21 83 81 43 +00 00 7C 40 81 00 5D 43 B0 13 4A C7 81 4C 00 00 +B1 B0 00 20 00 00 02 20 4E 43 08 3C B1 D0 00 C0 +00 00 B1 E3 00 00 91 53 00 00 5E 43 2C 41 5C 03 +CF 0C 4E 93 04 24 3C 40 AC 0A 0C 8F 03 3C 3C 40 +AC 0A 0C 5F 21 53 10 01 0B 4D 0E 4B 0D 93 1F 30 +3B F0 80 7F 1C 24 5B 02 8B 10 7E D0 80 00 3B 80 +7F 00 15 30 3B 90 20 00 0F 34 3B 80 17 00 05 30 +1B 83 08 30 5C 02 0E 6E FB 3F 5E 01 5C 00 1B 53 +01 24 FB 3F 0D 4E 10 01 3C 43 3D 43 10 01 0C 43 +0D 43 10 01 0B 4D 0B EF 0A 30 0D 93 12 30 0D 9F +02 24 19 34 16 3C 0C 9E 18 24 13 28 14 3C 3D B0 +80 7F 04 20 3F B0 80 7F 01 20 0F 24 0D 9F 0B 34 +08 3C 0F 9D 02 24 07 34 04 3C 0E 9C EC 27 01 28 +02 3C 3C 43 10 01 1C 43 10 01 0C 43 10 01 82 43 +EE 1D 4C 43 B0 13 6E F0 B0 13 0E EE C2 43 FA 1D +C2 43 00 1E 82 43 02 1E 82 43 04 1E 92 D3 8C 1C +7C 40 13 00 6D 42 B0 13 02 E9 7C 40 17 00 6D 42 +B0 13 02 E9 7C 40 18 00 6D 42 B0 13 02 E9 7C 40 +19 00 6D 42 80 00 02 E9 E2 93 AA 1E 13 24 B0 13 +78 EC C2 93 AA 1E 1C 24 82 43 90 03 B2 D0 10 00 +80 03 F2 D0 80 00 0B 02 E2 43 AA 1E 92 42 A8 1E +C0 1E 10 01 B2 F0 CF FF 80 03 F2 F0 7F 00 03 02 +F2 F0 7F 00 0B 02 D2 43 AA 1E 92 42 A6 1E C0 1E +10 01 1A 14 CB 0E CA 0D CE 0C CC 0A CD 0B B0 13 +A0 DB 4D 4C CC 0A 49 4E 5C E9 06 F4 47 18 0C 5C +4E ED 5E 4E 06 F4 0E 5C 4A 4A 47 18 0A 5A CC 0B +4C DD 0C 5A 0C EE 0F 9C 06 2C 3E 40 FF 7F 0C FE +5E 03 0F 9C FC 2B 19 16 10 01 1A 14 31 80 06 00 +C9 0C 5A 42 77 1D CC 0A B0 13 F2 E3 0C 93 02 20 +2C 43 13 3C 4D 43 B0 13 50 E5 0C 93 0E 20 91 43 +02 00 C1 4A 04 00 81 43 00 00 CC 01 2C 53 3D 40 +F2 1C CE 09 0F 43 B0 13 D2 BB 31 50 06 00 19 16 +10 01 C2 93 A4 1E 20 20 C2 4C A4 1E B2 40 8F 02 +A6 1E 82 4D A8 1E B2 40 14 01 80 03 B2 40 05 00 +92 03 B2 40 80 00 82 03 F2 D0 80 00 0B 02 00 18 +F2 40 38 D5 BC 1E 3C 40 8F 02 B0 13 F8 E2 92 42 +A8 1E C0 1E E2 43 AA 1E 10 01 F2 40 A5 00 21 01 +4E 4C 4F 4E 8F 10 0E 5F 3E 50 00 44 82 4E 24 01 +4F 4C 3F 50 00 44 82 4F 26 01 92 B3 2C 01 FD 27 +C2 4C 20 01 B2 F0 F9 FF 2C 01 A2 B3 2C 01 03 24 +A2 B2 2C 01 FD 27 82 4E 26 01 C2 43 21 01 10 01 +1A 14 3F 40 E8 F6 9F 00 FF FF 12 24 3D 40 E8 F6 +0C 3C 4F 13 2A 52 12 3C 3C 4D CA 0D CE 09 B0 13 +60 ED 0A 59 CD 0A 1D 53 1D C3 39 4D 09 93 F4 23 +3F 40 FF FF 3F 93 05 24 3A 40 FF FF 0F 0A DF 03 +E8 23 19 16 10 01 1A 14 21 83 CB 0F CA 0D C9 0C +5E 41 0E 00 B2 B0 40 00 08 1E 10 20 4C 4A B0 13 +26 EB C1 4E 00 00 4C 4C CD 0C 0E 43 CC 09 CF 0B +B0 13 02 E7 4C 4A B0 13 CC E9 05 3C C1 4E 00 00 +0E 43 B0 13 02 E7 21 53 19 16 10 01 7C 90 3C 00 +06 28 7C 90 3E 00 03 24 32 C2 03 43 FF 3F 0F 42 +32 C2 03 43 B2 B0 10 00 02 0F FC 27 7C 90 2F 00 +08 28 7C 90 3E 00 05 24 7C D0 C0 00 C2 4C 13 0F +04 3C 7C D0 80 00 C2 4C 13 0F 5C 42 22 0F 02 4F +10 01 0B 4D 0E 4B 3B F0 80 7F 1C 24 5B 02 8B 10 +7E D0 80 00 3B 80 7F 00 15 30 3B 90 10 00 10 34 +5E 01 5C 00 1E 93 01 24 FB 3F 1B 83 03 30 5C 02 +0E 6E FB 3F 0D 93 02 34 3E E3 1E 53 0C 4E 10 01 +3C 43 10 01 0C 43 10 01 0A 14 CB 0D 0A 42 32 C2 +03 43 B2 B0 10 00 02 0F FC 27 7C D0 C0 00 C2 4C +13 0F 4F 4E 1F 83 0A 24 B2 B0 80 00 02 0F FC 27 +1D 53 DD 42 22 0F FF FF 1F 83 F6 23 4D 4E 0D 5B +DD 42 20 0F FF FF 02 4A 0A 16 10 01 0B 42 32 C2 +03 43 B2 B0 10 00 02 0F FC 27 4C 4C 47 18 0C 5C +3C D0 00 40 6F 4D 0F 5C 82 4F 10 0F 6E 93 0C 28 +1D 53 4E 4E 1E 83 E2 4D 10 0F B2 B0 20 00 02 0F +FC 27 1D 53 1E 83 F7 23 5F 42 20 0F 02 4B 10 01 +92 B3 0A 1E 03 24 5C 43 B0 13 9C BD A2 B2 0A 1E +03 24 5C 43 B0 13 96 BA B2 B2 0A 1E 02 24 B0 13 +FE EE A2 B3 0A 1E 02 24 B0 13 F2 C5 B2 B0 10 00 +0A 1E 05 24 6C 43 3D 40 99 19 B0 13 12 D6 82 43 +0A 1E 10 01 1A 14 C9 0C 3D 40 0C 00 0D 59 6E 49 +7E 80 0B 00 5C 43 7F 40 03 00 B0 13 6C C0 CA 0C +0A 93 10 24 3C 40 03 00 0C 5A 3D 40 05 00 0D 59 +2E 42 B0 13 60 ED FA D0 80 00 0E 00 CC 0A 4D 43 +B0 13 68 E1 19 16 10 01 D2 B3 D6 1E 0E 24 1D 42 +4E 1E 1E 42 50 1E 3D F3 3E F0 FF 00 1F 42 44 1E +1E 9F 02 00 02 20 2D 9F 02 24 4C 43 10 01 DF 92 +51 1E 13 00 04 24 D2 C3 D6 1E 4C 43 10 01 EF C2 +1A 00 B0 13 F6 C0 5C 43 10 01 A2 D2 24 03 7F 40 +80 00 3E 42 B2 C2 22 03 CD 0C 4D FF 4D 9F 03 24 +A2 C2 22 03 02 3C A2 D2 22 03 12 C3 4F 10 B0 13 +CE F0 B2 D2 22 03 B0 13 CE F0 1E 83 EB 23 B2 C2 +22 03 A2 D2 22 03 A2 C2 24 03 10 01 4C 93 1D 20 +4C 43 B0 13 C2 E5 0C 93 04 24 1C 83 09 24 1C 83 +14 20 C2 43 DC 1E C2 43 DD 1E 82 43 DE 1E 10 01 +1F 42 D4 F6 D2 4F 0E 00 DC 1E 1E 4F 04 00 1F 4F +06 00 C2 4F DD 1E 82 4E DE 1E 10 01 82 43 18 1E +82 43 24 1E 82 43 20 1E C2 93 76 1D 16 24 B0 13 +2A E5 B0 13 4C DA B0 13 3C EA 1C 42 22 1E 0C 93 +0C 24 1C 52 20 1E 82 4C 20 1E 1D 42 1A 1E 1E 42 +1C 1E 1F 42 1E 1E 80 00 BA 93 10 01 0A 14 0A 43 +0F 93 05 34 3E E3 3F E3 1E 53 0F 63 1A D3 0D 93 +05 34 3C E3 3D E3 1C 53 0D 63 3A E3 B0 13 8E D0 +1A B3 04 24 3C E3 3D E3 1C 53 0D 63 2A B3 04 24 +3E E3 3F E3 1E 53 0F 63 0A 16 10 01 B0 13 52 B9 +F2 B2 F0 1C 14 24 3C 40 03 00 3D 40 05 00 0E 43 +B0 13 F0 B7 3C 40 F2 1C 6D 42 B0 13 40 CA 3C 40 +03 00 2D 42 0E 43 B0 13 F0 B7 F2 C2 F0 1C F2 B0 +20 00 F0 1C E3 27 C2 43 D1 1D 10 01 C2 93 76 1D +15 24 82 93 24 1E 19 20 F2 F0 BF 00 1D 02 F2 D0 +40 00 1B 02 B0 13 6A EF B2 40 10 0E 24 1E F2 B0 +40 00 01 02 FC 27 4C 43 80 00 96 BA 7C 40 47 00 +3D 40 06 F5 5E 43 80 00 70 AF 10 01 0A 14 CA 0D +CB 0E 4C 4C 3D 40 1C 00 B0 13 38 EC 1F 42 D4 F6 +0F 5C 8F 93 18 00 0F 20 8F 4A 00 00 8F 4B 02 00 +0B 93 06 20 0A 93 04 20 1C 52 D4 F6 EC C2 1A 00 +FF 40 7F 00 10 00 0A 16 10 01 0A 14 5A 42 57 1E +3C 40 4E 1E B0 13 AA DE 4C 4C 0C EA 47 18 0C 5C +8C 10 4C 4C CA 0C C2 4A 57 1E 3A 90 21 00 05 20 +D2 D3 D6 1E B0 13 74 F0 05 3C F2 F0 EF 00 D6 1E +B0 13 0A C4 0A 16 10 01 1A 14 C2 93 A2 1D 16 24 +3C 40 7A 1D 29 42 3A 40 D8 F6 3B 40 A4 1D 4E 43 +4F 43 7D 4C 7D 9B 01 20 5E 53 7D 9A 01 20 5F 53 +19 83 F7 23 6F 92 02 24 6E 92 02 20 4C 43 01 3C +5C 43 19 16 10 01 5C 02 0D 6D 5C 02 0D 6D 5C 02 +0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 +0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 +0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 +0D 6D 10 01 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 +5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 +5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 +5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 +10 01 0A 14 3F 40 B9 1D 2E 43 0C 43 2D 43 6D 9F +05 20 3F 50 0C 00 1C 53 1E 83 F8 23 6C 93 02 20 +0C 43 0C 3C 4C 4C 3D 40 0C 00 B0 13 38 EC 3A 40 +B9 1D 0A 5C CC 0A B0 13 98 DD CC 0A 0A 16 10 01 +92 C3 44 03 82 93 9A 1E 0E 24 B0 13 9A 82 92 93 +9A 1E 03 24 B0 13 AE DF 02 3C B0 13 0A C4 1C 42 +94 1E 80 00 E4 E8 F2 C2 D6 1E B0 13 0A C4 1C 42 +96 1E B0 13 E4 E8 92 43 9A 1E 10 01 3A 14 C8 0D +C7 0C 3A 40 B9 1D 29 43 2F 43 6F 9A 0E 20 3D 40 +03 00 0D 5A CC 07 2E 42 B0 13 2E E6 0C 93 05 20 +58 9A 0A 00 02 20 CC 0A 05 3C 3A 50 0C 00 19 83 +EB 23 0C 43 37 16 10 01 3A 14 C8 0D C7 0C 3A 40 +B9 1D 49 43 2F 43 6F 9A 0E 20 3C 40 03 00 0C 5A +CD 07 2E 42 B0 13 2E E6 0C 93 05 20 CA 98 0A 00 +02 20 CC 0A 05 3C 3A 50 0C 00 59 53 EB 27 0C 43 +37 16 10 01 C2 93 40 1E 14 20 3F 40 47 01 1F 52 +56 03 C2 93 36 1E 08 20 C2 93 37 1E 0E 24 3F 80 +03 00 C2 43 37 1E 09 3C 3F 80 05 00 C2 43 36 1E +F8 3F 3F 40 00 80 1F 52 56 03 82 4F 56 03 10 01 +82 43 4C 1E B0 13 7A F0 F2 40 21 00 48 1E F2 40 +06 00 4A 1E C2 43 49 1E D2 43 4B 1E 7C 43 5D 43 +B0 13 06 C9 B0 13 BC C7 B0 13 E6 D0 7C 40 0C 00 +5D 42 16 1E 80 00 28 DD 21 83 0F 42 32 C2 03 43 +B2 B0 10 00 02 0F FC 27 4C 4C 47 18 0C 5C 3C D0 +00 40 4D 4D 0C 5D 82 4C 10 0F B2 B0 20 00 02 0F +FC 27 5E 42 20 0F 81 4E 00 00 02 4F 21 53 10 01 +5F 14 1A 42 38 0F 4A 4A B0 13 3A EF 4C 93 10 20 +7A 90 14 00 04 24 4A 93 0D 20 03 43 0B 3C 1F 42 +EE 1D 1F 93 02 24 2F 93 05 20 B0 13 18 ED 02 3C +B0 13 3E CC 5A 16 00 13 21 83 CC 43 0A 00 EC 43 +00 00 DC 42 B8 1D 0B 00 D2 53 B8 1D 02 3C D2 53 +B8 1D C2 93 B8 1D FB 27 F2 93 B8 1D F8 27 5C 42 +B8 1D CD 01 B0 13 CA E3 4C 93 F1 23 21 53 10 01 +82 43 EE 1D 82 43 F2 1D 82 43 F4 1D 82 43 F0 1D +C2 43 FA 1D C2 43 00 1E 82 43 02 1E 82 43 04 1E +82 43 FC 1D 82 43 FE 1D C2 43 F6 1D B2 40 4B 00 +F8 1D C2 43 06 1E 10 01 B0 13 72 B3 B0 13 2C C8 +B0 13 84 87 B0 13 16 EF 82 93 76 1E 03 20 82 93 +08 1E 02 24 B0 13 36 A1 82 93 0A 1E 02 24 B0 13 +40 D8 82 93 8C 1C EE 27 B0 13 68 9C EB 3F 0A 14 +CA 0C 5D 42 EE 1E B0 13 D8 E0 4C 93 0E 24 B0 13 +84 ED CD 0C 1C 43 0C 5A 2E 42 B0 13 2E E6 0C 93 +02 20 0C 43 05 3C 2C 43 03 3C B0 13 CE EE 1C 43 +0A 16 10 01 0E 4C 0D 4C 0D 93 16 24 03 34 3D E3 +1D 53 0F 30 3B 40 8F 00 1B 83 5D 02 FD 2B 4C 4D +8C 10 8D 10 4D 4D 8B 10 0D DB 5E 02 5D 00 5C 00 +10 01 3D 40 00 C7 0C 43 10 01 0A 14 3A 40 09 00 +0F 43 6D 4C 3B 42 4E 4D 0E EF 3E 90 80 00 04 38 +4F 5F 7F E0 97 00 02 3C 4F 5F 4F 4F 4D 5D 1B 83 +F2 23 1C 53 1A 83 ED 23 CC 0F 0A 16 10 01 1D 42 +9E 1D 0F 42 32 C2 03 43 D2 43 9C 1D 02 4F 0D 93 +07 24 B0 13 C6 E8 C2 93 9B 1D 02 20 1D 83 F9 23 +0F 42 32 C2 03 43 C2 43 9B 1D C2 43 9C 1D 02 4F +10 01 B0 13 2C F0 1F 42 44 1E FF 90 7F 00 10 00 +0A 24 2C 93 05 34 3C 93 0D 34 DF 83 10 00 10 01 +DF 53 10 00 10 01 CF 4C 10 00 1F 42 44 1E FF 50 +0C 00 10 00 10 01 7C 90 2F 00 06 28 7C 90 3E 00 +03 24 32 C2 03 43 FF 3F 0F 42 32 C2 03 43 B2 B0 +10 00 02 0F FC 27 C2 4C 11 0F B2 B0 20 00 02 0F +FC 27 C2 4D 10 0F 02 4F 10 01 4D 93 03 20 32 C2 +03 43 FF 3F 0F 42 32 C2 03 43 B2 B0 10 00 02 0F +FC 27 F2 40 7F 00 11 0F 4D 4D B2 B0 20 00 02 0F +FC 27 F2 4C 10 0F 1D 83 F8 23 02 4F 10 01 B2 F0 +FE FD 36 0F B2 F0 FE FD 32 0F 7C 40 36 00 B0 13 +06 BD 7C 40 3A 00 B0 13 06 BD 7C 40 36 00 B0 13 +06 BD 7C 40 32 00 B0 13 06 BD 82 43 C4 1E 10 01 +F2 F0 DF 00 1B 02 92 C3 22 03 F2 F0 DF 00 03 02 +F2 F0 1F 00 02 02 F2 F0 1F 00 0A 02 A2 C3 22 03 +F2 D0 20 00 05 02 F2 D0 E0 00 04 02 A2 D3 24 03 +10 01 21 83 7C 40 30 00 B0 13 06 BD 81 43 00 00 +02 3C 91 53 00 00 B1 90 64 00 00 00 FA 2B 7C 40 +36 00 B0 13 06 BD 7C B0 70 00 F9 23 82 43 06 0F +21 53 10 01 0C 93 02 20 0D 93 14 24 3B 40 9F 00 +1B 83 5C 02 0D 6D FC 2B 12 C3 5D 00 5C 00 3E 40 +06 00 5D 01 5C 00 1E 83 FC 37 8B 10 0D DB 12 C3 +5D 00 5C 00 10 01 A2 B2 76 1E 15 24 5F 42 E0 1E +4F 93 0A 24 5F 93 0F 20 C2 43 E0 1E 92 D3 0C 1E +B2 D0 80 00 0C 1E 10 01 D2 43 E0 1E 92 D3 0C 1E +B2 D0 40 00 0C 1E 10 01 4D 93 03 20 32 C2 03 43 +FF 3F 0F 42 32 C2 03 43 4D 4D B2 B0 10 00 02 0F +FC 27 F2 40 BF 00 13 0F 1C 53 DC 42 22 0F FF FF +1D 83 F3 23 02 4F 10 01 CF 0C FF B0 80 FF 0C 00 +02 20 6C 43 10 01 CF 9D 0D 00 0C 20 B0 13 84 ED +CD 0C 1C 43 0C 5F 2E 42 B0 13 2E E6 0C 93 02 20 +4C 43 10 01 5C 43 10 01 82 93 6E 1E 09 20 82 93 +6C 1E 06 20 B2 40 04 03 6C 1E B2 40 02 01 6E 1E +B0 13 9E EB C2 4C 75 1E 4C 93 FA 27 3C 40 72 1E +0D 43 1E 43 80 00 72 ED 31 80 06 00 81 43 02 00 +D1 4C 05 00 04 00 CF 0C 3F 50 06 00 81 4F 00 00 +1D 4C 02 00 2E 42 0E 5C 2F 4C CC 01 2C 53 B0 13 +D2 BB 31 50 06 00 10 01 0A 14 CA 0C 3F 40 CF 00 +5F FA 0C 00 5F D2 66 1E CA 4F 0C 00 2C 43 0C 5A +B0 13 AC B2 4C 93 02 20 0C 43 02 3C 3C 40 09 00 +CA 43 00 00 0A 16 10 01 7C 90 80 00 09 28 4C 4C +3C 80 00 01 2D 43 B0 13 78 E2 3C 80 4A 00 04 3C +4C 4C 5C 03 3C 80 4A 00 3C 90 80 FF 02 34 3C 40 +80 FF 8C 11 10 01 92 C3 22 03 F2 F0 DF 00 03 02 +F2 F0 1F 00 02 02 A2 C3 22 03 F2 D0 20 00 05 02 +F2 D0 E0 00 04 02 A2 D3 24 03 92 D3 24 03 D2 43 +93 1E 10 01 B2 F0 FF FD 36 0F 7C 40 36 00 B0 13 +D8 C6 7C 40 3D 00 B0 13 D8 C6 7C B0 F0 FF F9 23 +7C 40 3A 00 B0 13 D8 C6 B2 F0 FF FD 32 0F 10 01 +C2 93 D1 1D 0E 20 B0 13 92 95 B0 13 08 C3 0C 93 +0C 20 B0 13 E0 E6 B0 13 84 ED B0 13 E6 E5 B0 13 +8A E8 D2 43 D1 1D 80 00 60 A6 10 01 5C 93 13 20 +0C 42 32 C2 03 43 2E 43 3F 40 00 1C CF 93 00 00 +05 24 5D 9F 01 00 02 2C DF 83 01 00 3F 50 23 00 +1E 83 F4 23 02 4C 10 01 0B 43 0D 93 03 34 3D E3 +1D 53 1B D3 0C 93 03 34 3C E3 1C 53 3B E3 B0 13 +22 EC 1B B3 02 24 3C E3 1C 53 2B B3 02 24 3E E3 +1E 53 10 01 4C 4C 3D 40 1C 00 B0 13 38 EC CF 0C +1F 52 D4 F6 EF B2 1A 00 03 24 0F 43 0D 43 05 3C +1C 52 D4 F6 2F 4C 1D 4C 02 00 CC 0F 10 01 C2 93 +4A 1E 09 24 1F 42 44 1E DF 83 13 00 1F 42 44 1E +CF 93 13 00 02 24 5C 43 10 01 8F 43 18 00 5D 43 +B0 13 4C D9 4C 43 10 01 82 4C C0 1E 82 93 50 03 +02 20 0F 43 05 3C 1F 42 50 03 1F 92 50 03 FB 23 +0F 5C 82 4F 58 03 92 C3 48 03 B2 D0 10 00 48 03 +10 01 31 40 FC 2B 00 18 F2 40 D2 F0 AC 1E 00 18 +F2 40 D2 F0 B0 1E B0 13 AE F0 0C 93 02 24 B0 13 +A0 D6 0C 43 B0 13 08 DE B0 13 B2 F0 92 B3 22 03 +11 24 7C 40 06 00 B0 13 9A C8 C2 4C 59 1E 7C 40 +07 00 B0 13 9A C8 C2 4C 5A 1E 7C 42 B0 13 9A C8 +C2 4C 5B 1E 10 01 5D 93 12 20 C2 93 89 1E 0A 24 +E2 93 89 1E 0C 2C 7C 40 5A 00 3D 40 1A F5 5E 43 +80 00 70 AF 7C 40 5A 00 3D 40 20 F5 F8 3F 10 01 +B2 D0 06 00 06 0A B2 40 1D 7B 00 0A B2 40 ED 00 +04 0A F2 D0 E0 00 4A 02 F2 D0 E0 00 44 02 B2 43 +0A 0A B2 40 FF 00 0C 0A 10 01 3F 40 B9 1D 0E 43 +2B 43 6B 9F 07 20 CF 9C 0B 00 04 20 CD 4E 00 00 +5C 43 10 01 3F 50 0C 00 1E 53 2E 93 F1 3B 4C 43 +10 01 21 83 CD 01 B0 13 CA E3 4C 93 0B 24 6C 41 +3D 40 0C 00 B0 13 38 EC EC 93 B9 1D 03 20 3C 50 +B9 1D 01 3C 0C 43 21 53 10 01 82 93 8C 1E 09 20 +82 93 8A 1E 06 20 B2 40 08 07 8A 1E B2 40 06 05 +8C 1E 00 18 C2 43 8E 1E B0 13 9E EB C2 4C 92 1E +10 01 B2 B0 20 00 08 1E 0F 20 B0 13 22 EF 4C 93 +0B 20 F2 C2 03 02 F2 C2 05 02 F2 C2 1B 02 2C 43 +B0 13 16 B1 F2 D2 1B 02 10 01 B2 B0 20 00 08 1E +0F 20 B0 13 22 EF 4C 93 0B 20 F2 C2 03 02 F2 C2 +05 02 F2 C2 1B 02 1C 43 B0 13 16 B1 F2 D2 1B 02 +10 01 3C 40 03 00 5C F2 20 01 7C 90 03 00 03 2C +5C 53 B0 13 5A D6 6C 92 03 28 5C 83 B0 13 B8 E4 +7C 90 03 00 EE 23 10 01 F2 40 A5 00 21 01 4E 4C +4F 4E 8F 10 0E 5F 3E 50 00 44 82 4E 26 01 92 B3 +2C 01 FD 27 C2 4C 20 01 C2 43 21 01 10 01 3F 40 +13 00 6F 9C 09 24 5F 4C 0C 00 1F 83 07 24 1F 83 +07 20 B0 13 D8 C9 04 3C DC 43 0C 00 B0 13 D2 99 +0C 43 10 01 F2 F0 E0 00 05 02 F2 F0 E0 00 03 02 +F2 D0 1F 00 07 02 F2 F0 E0 00 19 02 F2 F0 E0 00 +1D 02 F2 D0 1F 00 1B 02 10 01 1A 14 39 40 11 00 +3F 40 32 1D 3A 40 72 F6 3C 4A B0 13 9A E6 2F 52 +8F 4C FC FF 8F 4D FE FF 19 83 F6 23 19 16 10 01 +4D 93 03 24 5F 4C 0A 00 02 3C 5F 4C 09 00 4F 93 +06 24 CC 93 00 00 03 24 7F 90 20 00 02 2C 2C 43 +10 01 0C 43 10 01 3C 40 80 1E 0D 43 2E 42 B0 13 +72 ED C2 93 88 1E 09 20 3C 40 84 1E 3D 40 BA F6 +2E 42 B0 13 60 ED D2 43 88 1E 10 01 B2 B0 20 00 +08 1E 0E 20 B0 13 22 EF 4C 93 0A 20 F2 C2 03 02 +F2 C2 05 02 F2 C2 1B 02 B0 13 34 BB F2 D2 1B 02 +10 01 4C 4C 3D 40 1C 00 B0 13 38 EC CF 0C 1F 52 +D4 F6 EF B2 1A 00 02 24 2C 43 10 01 1C 52 D4 F6 +1C 4C 18 00 10 01 CE 0C 6D 4E 5D 92 D8 F6 0C 24 +7C 40 09 00 B0 13 46 DF 2D 42 3F 40 A4 1D 1F 53 +FF 4E FF FF 1D 83 FB 23 10 01 0A 14 0A 42 32 C2 +03 43 D2 93 78 1D 08 24 B0 13 EA E7 7C 40 32 00 +B0 13 D8 C6 D2 43 78 1D 02 4A 0A 16 10 01 0E 93 +02 20 0C 43 10 01 1D 83 1C 83 1D 53 6B 4D 1C 53 +6F 4C 4F 9B 02 20 1E 83 F8 23 4B 4B 4C 4F 0C 8B +10 01 0A 14 CA 0C 5D 42 17 1E B0 13 D8 E0 4C 93 +04 20 B0 13 CE EE 1C 43 04 3C CC 0A B0 13 0A EF +0C 43 0A 16 10 01 82 43 26 1E 82 43 28 1E E2 42 +30 1E F2 40 1E 00 31 1E C2 43 32 1E C2 43 2F 1E +82 43 2A 1E 82 43 2C 1E 10 01 0D 4C 0D 93 0E 24 +3B 40 8F 00 1B 83 5D 02 FD 2B 4C 4D 8C 10 8D 10 +4D 4D 8B 10 0D DB 12 C3 5D 00 5C 00 10 01 82 43 +90 03 B2 40 C0 00 92 03 B2 D0 10 00 80 03 92 B3 +82 03 FD 27 B2 F0 EF FF 80 03 92 C3 82 03 10 01 +D2 93 78 1D 0D 20 7C 40 36 00 B0 13 D8 C6 7C 40 +3D 00 B0 13 D8 C6 7C B0 F0 FF F9 23 E2 43 78 1D +10 01 0A 14 CB 0E CA 0C CE 0F CC 0D CD 0B 5F 41 +08 00 B0 13 FC B4 CD 0C CC 0A 6E 43 B0 13 70 AF +0A 16 10 01 0A 14 CA 0C 5D 42 75 1E B0 13 D8 E0 +4C 93 04 20 B0 13 CE EE 1C 43 03 3C CC 0A B0 13 +DE E4 0A 16 10 01 02 12 32 C2 03 43 82 4C D0 04 +82 4D D2 04 82 4E E0 04 82 4F E2 04 1C 42 E4 04 +1D 42 E6 04 32 41 10 01 D2 43 34 1E 92 42 50 03 +56 03 B0 13 B4 DC 92 C3 46 03 B2 D0 10 00 46 03 +7C 40 14 00 5D 43 80 00 02 E9 1F 42 D4 F6 BF 90 +FF 00 02 00 05 28 06 20 BF 90 00 FF 00 00 02 2C +0C 43 10 01 1C 42 DE 1E 10 01 1F 42 D4 F6 BF 90 +FF 00 02 00 05 28 06 20 BF 90 00 FF 00 00 02 2C +4C 43 10 01 5C 42 DD 1E 10 01 0A 14 5C 43 B0 13 +7C C5 CA 0C 0A 93 07 24 2C 43 0C 5A B0 13 DA EE +CC 0A B0 13 54 BF 0A 16 10 01 D2 93 78 1D 09 24 +F2 90 03 00 78 1D 08 20 B0 13 F4 E1 E2 43 78 1D +10 01 32 C2 03 43 FF 3F 10 01 D2 93 78 1D 09 24 +F2 90 03 00 78 1D 08 24 F2 40 03 00 78 1D 80 00 +B4 EB 32 C2 03 43 FF 3F 10 01 C2 43 66 1E 00 18 +C2 43 68 1E B0 13 84 ED 82 4C 64 1E B0 13 9E EB +C2 4C 62 1E 4C 93 FA 27 10 01 3C 40 38 1E 3D 40 +44 F5 3E 42 B0 13 60 ED C2 43 37 1E C2 43 36 1E +C2 43 34 1E C2 43 40 1E 10 01 B2 F0 CF FF 80 03 +F2 F0 7F 00 03 02 F2 F0 7F 00 0B 02 B2 F0 EF FF +82 03 B0 13 3C F0 80 00 FA EF D2 92 D8 F6 A4 1D +08 24 D2 43 A2 1D 7C 40 07 00 7D 40 07 00 80 00 +46 DF 32 C2 03 43 FF 3F B0 13 F4 E1 7C 40 0A 00 +5D 42 DC F6 B0 13 46 DF F2 90 03 00 78 1D 02 20 +80 00 B4 EB 10 01 3F 40 3E 00 0E 42 32 C2 03 43 +B0 13 BE E6 02 4E C2 93 9B 1D 03 20 1F 83 3F 93 +F4 23 10 01 CF 0C 82 4F 54 03 92 C3 44 03 B0 13 +C2 EE 2F 83 0F 8C 3F 90 00 80 02 28 92 D3 44 03 +10 01 CF 0D 7C 90 2A 00 0A 2C 4E 4C 5D 4E FE F5 +4C 4C 5C 02 1C 4C 8E 1C CE 0D 80 00 BC CD 10 01 +0C 9D 02 2C 80 00 60 ED 0C 5E 0D 5E 0E 93 06 24 +1D 83 1C 83 EC 4D 00 00 1E 83 FA 23 10 01 CD 0C +C2 93 88 1E 02 24 4C 43 10 01 3C 40 84 1E 2E 42 +B0 13 60 ED D2 43 88 1E 5C 43 10 01 D2 93 E0 1E +0A 20 D2 92 E3 1E 31 1E 06 20 D2 92 E2 1E 30 1E +02 20 E2 43 E0 1E 10 01 5C 43 B0 13 D2 CE 6C 43 +B0 13 D2 CE 5C 43 6D 42 80 13 0E 1E 6C 43 6D 42 +20 00 12 1E 3C B0 00 80 0D 7D 3D E3 3E 40 3D 00 +0F 43 B0 13 46 E7 3E 40 C8 00 0F 43 80 00 CC D9 +3C B0 00 80 0D 7D 3D E3 3E 40 52 00 0F 43 B0 13 +46 E7 3E 40 19 00 0F 43 80 00 CC D9 B0 13 8A EE +4C 93 08 20 4C 43 4D 43 B0 13 02 E9 5C 43 5D 43 +80 00 02 E9 4C 43 FB 3F 3C 40 00 1C 0D 43 3E 40 +46 00 B0 13 72 ED 3C 40 46 1C 0D 43 3E 40 46 00 +80 00 72 ED 0A 14 CF 0C CC 0D 2A 43 0F 93 05 20 +B0 13 3E E9 4C 93 01 24 0A 43 CC 0A 0A 16 10 01 +21 82 CF 0C CC 0D A1 4F 00 00 91 4F 02 00 02 00 +CD 01 2E 42 B0 13 20 E9 21 52 10 01 C2 93 76 1D +0A 24 B0 13 F0 EF F2 F0 BF 00 1B 02 F2 F0 BF 00 +1D 02 82 43 24 1E 10 01 1F 42 44 1E 5C 4F 11 00 +6C 93 02 2C 3C 42 10 01 5C 53 4C 5C 4C 5C 4C 4C +10 01 7C 90 03 00 07 2C 4C 4C 5D 4C E0 F6 7C 40 +3E 00 80 00 46 DF 32 C2 03 43 FF 3F 0C 93 0A 24 +5C 0F 1C 53 0F 42 32 C2 03 43 B0 13 BE E6 02 4F +1C 83 F8 23 10 01 B0 13 9E EB 7C F0 0F 00 5C 53 +4E 4C 1C 42 A0 1D B0 13 8C EA 1E 83 FA 23 10 01 +B2 90 06 00 0E 07 08 20 92 42 20 07 E8 1E D2 43 +EA 1E B1 C0 D0 00 00 00 00 13 B2 F0 EF FF 46 03 +C2 43 34 1E 7C 40 14 00 4D 43 B0 13 02 E9 5D 43 +80 00 10 A0 6D 42 B0 13 7C EE 4F 43 C2 93 06 1E +01 20 5F 43 C2 4F 06 1E 5D 43 80 00 7C EE 1C 42 +D2 1E CF 0C 5F 0A 0C 5F 3D 40 05 00 B0 13 78 E2 +3C 50 40 01 10 01 4C 93 06 24 7C 90 0D 00 06 28 +7C 80 0C 00 10 01 3F 40 0C 00 4C 5F 10 01 3D 40 +FF 00 3E 40 0C 00 3F 40 20 0A 1F 53 CF 4D FF FF +1E 83 FB 23 10 01 5D 42 92 1E B0 13 D8 E0 4C 93 +02 24 0C 43 10 01 B0 13 CE EE 1C 43 10 01 F2 40 +06 00 E2 1E F2 40 1E 00 E3 1E F2 40 0A 00 E1 1E +C2 43 E0 1E 10 01 D2 53 5E 1E F2 90 03 00 5E 1E +02 28 C2 43 5E 1E 82 43 5C 1E 80 00 4C E3 5C 42 +9A 1D 3D 40 6D 00 B0 13 38 EC 7C 50 43 00 C2 4C +9A 1D 10 01 B2 F0 FF FD 32 0F 7C 40 34 00 B0 13 +D8 C6 B2 D0 00 02 36 0F 10 01 0F 42 32 C2 03 43 +7C D0 C0 00 C2 4C 13 0F 5C 42 22 0F 02 4F 10 01 +B2 D0 10 00 08 1E 00 18 F2 40 74 D3 BC 1E 3C 40 +99 19 80 00 F8 E2 0E 93 08 20 2D 93 06 2C 5D 06 +3D 50 C4 F6 6E 43 80 00 70 AF 10 01 0E 93 08 20 +2D 93 06 2C 5D 06 3D 50 CC F6 6E 43 80 00 70 AF +10 01 0E 43 0F 4C 1C 43 5F 02 0E 6E 0E 9D 01 28 +0E 8D 0C 6C F9 2B 10 01 02 12 32 C2 03 43 82 4C +C0 04 82 4D C8 04 1C 42 CA 04 32 41 10 01 B2 B2 +76 1E 07 24 C2 93 34 1E 02 20 80 00 68 E7 80 00 +DA EA 10 01 B2 40 FF 7F 52 03 B2 D0 10 00 42 03 +B2 D0 24 01 40 03 10 01 5F 42 A4 1E 5F 83 D2 83 +A4 1E 0F 93 02 20 80 00 6A E8 10 01 3E 40 0C 00 +3F 40 20 0A 1F 53 CF 43 FF FF 1E 83 FB 23 10 01 +5D 93 07 20 7C 40 5A 00 3D 40 30 F5 5E 43 80 00 +70 AF 10 01 5D 93 07 20 7C 40 5A 00 3D 40 38 F5 +5E 43 80 00 70 AF 10 01 5D 93 07 20 7C 40 5A 00 +3D 40 28 F5 5E 43 80 00 70 AF 10 01 3C 80 05 00 +05 24 3C 80 05 00 02 24 4C 43 10 01 5C 43 10 01 +4C 43 D2 93 34 1E 05 20 B2 90 F8 F2 E4 1E 01 20 +5C 43 10 01 B2 40 D9 07 CE 1E F2 42 CC 1E D2 43 +CB 1E C2 43 CA 1E 10 01 1F 42 50 03 82 4F C8 1E +1F 92 50 03 F9 23 80 00 00 CD CF 0C 5F 06 0C 5F +3C 80 40 06 3D 40 09 00 80 00 78 E2 4C 43 D2 93 +58 1E 04 20 82 93 60 1E 01 24 5C 43 10 01 4C 43 +92 93 18 1E 04 20 82 93 24 1E 01 24 5C 43 10 01 +CF 0C 0E 93 05 24 1F 53 FF 4D FF FF 1E 83 FB 23 +10 01 0E 93 06 24 4D 4D 1C 53 CC 4D FF FF 1E 83 +FB 23 10 01 C2 93 88 1E 03 24 3C 40 84 1E 10 01 +3C 40 BA F6 10 01 0D 93 02 20 0C 93 04 24 82 4C +8A 1E 82 4D 8C 1E 10 01 0D 93 02 20 0C 93 04 24 +82 4C 6C 1E 82 4D 6E 1E 10 01 B0 13 12 E0 B2 F0 +EF FF 32 0F B2 D0 10 00 36 0F 10 01 82 43 9C 1E +F2 40 0F 00 9E 1E B2 40 2C 01 A0 1E 10 01 A2 43 +9A 1E 92 C3 44 03 B2 D0 10 00 44 03 10 01 A2 D2 +80 03 82 43 80 03 B2 D0 00 02 80 03 10 01 CE 0C +3C 40 E8 03 B0 13 8C EA 1E 83 FA 23 10 01 82 43 +32 0F 82 43 36 0F B0 13 12 E0 80 00 3E EE 3E F0 +1F 00 04 24 5C 02 0D 6D 1E 83 FC 23 10 01 3E F0 +1F 00 04 24 5D 03 5C 00 1E 83 FC 23 10 01 7C 40 +36 00 B0 13 06 BD 7C 40 39 00 80 00 06 BD 4F 43 +C2 93 CA 1E 01 20 5F 43 C2 4F CA 1E 10 01 4F 43 +C2 93 2F 1E 01 20 5F 43 C2 4F 2F 1E 10 01 4F 43 +7C B0 80 FF 01 20 5F 43 CC 0F 10 01 C2 93 06 1E +02 20 80 00 3C D1 80 00 B8 AD 4F 43 7C 90 0C 00 +01 2C 5F 43 CC 0F 10 01 B0 13 DA EA B0 13 4A E8 +5D 43 80 00 10 A0 D2 43 5E 1E 82 43 60 1E C2 43 +58 1E 10 01 B2 F0 1F FF 04 0A 4C 4C 82 DC 04 0A +10 01 1C 42 50 03 1C 92 50 03 FB 23 10 01 C2 93 +9C 1D 02 24 D2 43 9B 1D 10 01 3D 40 79 1D 3E 40 +21 00 80 00 60 ED B2 F0 DF FF 40 03 82 43 50 03 +10 01 5C 43 B0 13 D2 CE 6C 43 80 00 D2 CE B0 13 +4C E3 B2 D0 00 04 8C 1C 10 01 DC 93 0C 00 02 20 +80 00 84 D8 10 01 B0 13 54 F0 B2 40 2B 5A 5C 01 +10 01 4C 43 A2 93 EE 1D 01 20 5C 43 10 01 4C 43 +92 93 EE 1D 01 20 5C 43 10 01 4C 43 82 93 EA 1C +01 24 5C 43 10 01 4C 43 92 93 D0 1E 01 20 5C 43 +10 01 CF 0C CC 0D CD 0F 2E 42 80 00 20 E9 CD 0C +3C 40 80 1E 2E 42 80 00 60 ED 7C 40 03 00 7D 40 +0B 00 80 00 36 D0 5C 93 02 20 CC 0D 10 01 CC 0E +10 01 1C 42 8C 1C 49 19 0C 10 5C F3 10 01 1C 42 +8C 1C 48 19 0C 10 5C F3 10 01 1C 42 8C 1C 46 19 +0C 10 5C F3 10 01 1C 42 8C 1C 44 19 0C 10 5C F3 +10 01 1C 42 8C 1C 45 19 0C 10 5C F3 10 01 1C 42 +44 03 7C F0 10 00 10 01 B2 F0 EF FF 44 03 80 00 +AE DF B2 F0 EF FF 08 1E 80 00 3C F0 B0 13 9E EB +C2 4C EE 1E 10 01 B0 13 9E EB C2 4C 17 1E 10 01 +7C 40 03 00 4D 43 80 00 36 D0 C2 43 A4 1E C2 43 +AA 1E 10 01 82 43 EA 1C E2 42 16 1D 10 01 82 43 +D0 1E 4C 43 80 00 9C BD 1C 42 8C 1C 8C 10 5C F3 +10 01 1C 42 8C 1C 5C 0F 5C F3 10 01 5C 42 C6 1E +8C 11 10 01 4C 5C C2 4C 49 1E 10 01 B2 F0 EF FF +48 03 10 01 B2 D0 20 00 40 03 10 01 D2 43 E0 1E +80 00 6A E8 32 D0 D8 00 03 43 10 01 5C 42 DC 1E +10 01 C2 4C 48 1E 10 01 C2 4C 4A 1E 10 01 4D 43 +80 00 06 C9 92 D3 44 03 10 01 92 C3 44 03 10 01 +5C 42 78 1D 10 01 A2 D2 06 0A 10 01 82 43 76 1E +10 01 CC 43 00 00 10 01 3C 40 D8 F6 10 01 92 D3 +04 0A 10 01 92 C3 04 0A 10 01 80 00 86 98 1C 43 +10 01 03 43 FF 3F 2C 43 10 01 2C 43 10 01 4C 43 +10 01 6C 43 10 01 0C 43 10 01 0C 43 10 01 03 43 +10 01 10 01 10 01 10 01 30 30 30 30 30 31 30 30 +32 30 30 33 30 30 34 30 30 35 30 30 36 30 30 37 +30 30 38 30 30 39 30 31 30 30 31 31 30 31 32 30 +31 33 30 31 34 30 31 35 30 31 36 30 31 37 30 31 +38 30 31 39 30 32 30 30 32 31 30 32 32 30 32 33 +30 32 34 30 32 35 30 32 36 30 32 37 30 32 38 30 +32 39 30 33 30 30 33 31 30 33 32 30 33 33 30 33 +34 30 33 35 30 33 36 30 33 37 30 33 38 30 33 39 +30 34 30 30 34 31 30 34 32 30 34 33 30 34 34 30 +34 35 30 34 36 30 34 37 30 34 38 30 34 39 30 35 +30 30 35 31 30 35 32 30 35 33 30 35 34 30 35 35 +30 35 36 30 35 37 30 35 38 30 35 39 30 36 30 30 +36 31 30 36 32 30 36 33 30 36 34 30 36 35 30 36 +36 30 36 37 30 36 38 30 36 39 30 37 30 30 37 31 +30 37 32 30 37 33 30 37 34 30 37 35 30 37 36 30 +37 37 30 37 38 30 37 39 30 38 30 30 38 31 30 38 +32 30 38 33 30 38 34 30 38 35 30 38 36 30 38 37 +30 38 38 30 38 39 30 39 30 30 39 31 30 39 32 30 +39 33 30 39 34 30 39 35 30 39 36 30 39 37 30 39 +38 30 39 39 31 30 30 31 30 31 31 30 32 31 30 33 +31 30 34 31 30 35 31 30 36 31 30 37 31 30 38 31 +30 39 31 31 30 31 31 31 31 31 32 31 31 33 31 31 +34 31 31 35 31 31 36 31 31 37 31 31 38 31 31 39 +31 32 30 31 32 31 31 32 32 31 32 33 31 32 34 31 +32 35 31 32 36 31 32 37 31 32 38 31 32 39 31 33 +30 31 33 31 31 33 32 31 33 33 31 33 34 31 33 35 +31 33 36 31 33 37 31 33 38 31 33 39 31 34 30 31 +34 31 31 34 32 31 34 33 31 34 34 31 34 35 31 34 +36 31 34 37 31 34 38 31 34 39 31 35 30 31 35 31 +31 35 32 31 35 33 31 35 34 31 35 35 31 35 36 31 +35 37 31 35 38 31 35 39 31 36 30 31 36 31 31 36 +32 31 36 33 31 36 34 31 36 35 31 36 36 31 36 37 +31 36 38 31 36 39 31 37 30 31 37 31 31 37 32 31 +37 33 31 37 34 31 37 35 31 37 36 31 37 37 31 37 +38 31 37 39 31 38 30 00 4E EC 00 00 98 EE 00 00 +10 A0 00 00 A6 EF 00 00 9A F3 5E EE 00 00 D4 8B +00 00 26 97 00 00 22 F0 00 00 1C F3 76 E0 00 00 +58 A3 00 00 38 B4 00 00 8E EF 00 00 2E F3 D4 F0 +00 00 5C A4 00 00 10 AB 00 00 B2 EF 00 00 40 F3 +D6 F0 00 00 24 AA 00 00 38 A9 00 00 22 F0 00 00 +52 F3 5E A5 00 00 8C F0 00 00 72 CB 00 00 22 F0 +00 00 64 F3 D4 F0 00 00 D4 F0 00 00 DA AC 00 00 +22 F0 00 00 76 F3 86 EB 00 00 D4 F0 00 00 AE 9D +00 00 82 EF 00 00 0A F3 4E EE 00 00 D8 8F 00 00 +E2 B1 00 00 18 F0 00 00 F8 F2 D4 F0 00 00 D4 F0 +00 00 5E CD 00 00 9A EF 00 00 AC F3 6A E4 00 00 +D4 F0 00 00 B4 EC 00 00 22 F0 00 00 BE F3 42 E4 +00 00 D4 F0 00 00 A0 EC 00 00 22 F0 00 00 D0 F3 +9C E5 00 00 D4 F0 00 00 C8 EC 00 00 22 F0 00 00 +E2 F3 F4 EA 00 00 CA 91 00 00 7C EE 00 00 22 F0 +00 00 F4 F3 90 D1 00 00 D4 F0 00 00 76 E3 00 00 +22 F0 00 00 88 F3 01 80 40 20 10 08 84 42 21 90 +48 A4 52 29 14 0A 85 C2 61 B0 58 AC D6 6B 35 9A +CD 66 33 99 4C A6 53 A9 54 2A 95 CA E5 F2 79 3C +9E CF 67 B3 D9 6C B6 5B 2D 16 0B 05 82 41 A0 50 +28 94 4A A5 D2 69 34 1A 8D 46 23 91 C8 E4 72 39 +1C 8E C7 E3 F1 F8 FC FE FF 7F 3F 1F 0F 07 83 C1 +E0 70 38 9C CE E7 F3 F9 7C BE DF 6F 37 9B 4D 26 +13 89 44 22 11 88 C4 62 31 98 CC E6 73 B9 5C AE +D7 EB 75 BA DD 6E B7 DB 6D 36 1B 0D 06 03 81 C0 +60 30 18 8C C6 63 B1 D8 EC F6 7B 3D 1E 8F 47 A3 +D1 E8 F4 7A BD 5E AF 57 AB 55 AA D5 EA F5 FA FD +7E BF 5F 2F 17 8B 45 A2 51 A8 D4 6A B5 DA ED 76 +3B 1D 0E 87 C3 E1 F0 78 BC DE EF 77 BB 5D 2E 97 +CB 65 B2 59 2C 96 4B 25 92 49 24 12 09 04 02 01 +80 40 20 10 08 84 42 21 90 48 A4 52 29 14 0A 85 +C2 61 B0 58 AC D6 6B 35 9A CD 66 33 99 4C A6 53 +A9 54 2A 95 CA E5 45 52 52 00 20 20 44 4F 4E 45 +00 00 30 30 30 30 30 30 30 00 20 43 4F 4E 46 00 +20 52 46 42 53 4C 00 00 20 20 53 59 4E 43 00 00 +20 20 20 50 50 54 00 00 20 20 20 41 43 43 00 00 +2D 2D 2D 00 30 30 30 30 30 30 30 30 00 00 4C 42 +00 00 4B 47 00 00 20 52 41 4D 00 00 30 34 33 30 +00 00 43 43 34 33 30 00 20 4F 46 46 00 00 20 20 +4F 4E 00 00 4C 4F 42 41 54 54 00 00 20 20 4F 50 +45 4E 00 00 20 20 4C 4F 3F 54 00 00 2D 2D 2D 2D +00 00 02 1B 01 1E 17 3C 18 10 06 1E 08 05 03 47 +0B 08 0C 00 0D 21 0E 71 0F 7A 10 7B 11 83 12 13 +13 22 14 F8 15 42 19 1D 1A 1C 1B C7 1C 00 1D B2 +21 B6 22 10 23 EA 24 2A 25 00 26 1F 2C 81 2D 35 +2E 09 F5 60 B6 F2 63 D3 D7 70 F7 F3 00 00 00 00 +00 86 00 77 C7 95 E6 97 17 F3 67 05 F0 87 85 75 +46 C6 37 F5 06 D3 87 C4 C4 02 67 E3 B6 00 03 01 +04 08 10 80 80 80 80 20 40 02 01 80 04 02 10 20 +40 08 08 80 08 08 08 08 F7 F7 F7 F7 20 40 04 80 +7F 7F 7F 7F 7F 10 01 80 2F 1E 1B 07 37 B2 0A 04 +00 00 00 0C 00 21 64 EC 4D 3B 15 11 F8 57 07 0C +10 1D 1C C7 10 B0 FF FF F9 B6 10 EA 2A 00 1F 00 +67 FF 00 00 6F 00 1C 02 DD 03 B1 05 9D 07 A2 09 +C4 0B 07 0E 6E 10 01 13 C6 15 C8 18 11 1C B5 1F +CC 23 07 04 F5 03 E8 03 B6 03 84 03 52 03 20 03 +EE 02 BC 02 8A 02 58 02 26 02 F4 01 C2 01 90 01 +5E 01 2C 01 52 E6 00 00 24 E7 00 00 56 EB 00 00 +CA F0 00 00 C6 F0 00 00 3E DE 00 00 12 00 24 00 +47 00 8F 00 1E 01 3B 02 76 04 79 56 34 12 02 01 +01 01 00 00 32 34 48 00 31 32 48 00 4D 41 4C 45 +46 45 4D 41 D2 1D D2 1D FF FF FF FF 00 32 50 6E +0F 27 8C 00 02 00 00 +@f6e8 +01 00 C2 1E 00 00 01 00 7E 1E 00 00 01 00 7F 1E +0A 00 54 00 8E 1C 20 0A 20 0A 20 0A 20 0A 24 0A +2A 0A 29 0A 27 0A 26 0A 24 0A 24 0A 26 0A 26 0A +24 0A 26 0A 24 0A 26 0A 26 0A 26 0A 21 0A 22 0A +20 0A 23 0A 24 0A 25 0A 26 0A 21 0A 22 0A 23 0A +25 0A 20 0A 20 0A 24 0A 2B 0A 2B 0A 2A 0A 29 0A +28 0A 27 0A 20 0A 24 0A 28 0A 02 00 E4 1E 00 00 +01 00 41 1E 00 00 01 00 31 1D 00 00 02 00 E6 1E +00 00 01 00 D1 1D 00 00 01 00 78 1D 00 00 01 00 +9A 1D 00 00 01 00 9B 1D 00 00 01 00 9C 1D 00 00 +02 00 9E 1D 00 00 02 00 A0 1D 00 00 01 00 A2 1D +00 00 01 00 A4 1D FF 00 04 00 A8 1D 00 00 00 00 +04 00 AC 1D 00 00 00 00 04 00 B0 1D 00 00 00 00 +01 00 88 1E 00 00 01 00 62 1E 00 00 02 00 64 1E +00 00 01 00 66 1E 00 00 04 00 68 1E 00 00 00 00 +01 00 B4 1D 01 00 01 00 17 1E 00 00 02 00 EC 1E +00 00 01 00 EE 1E 00 00 04 00 6C 1E 00 00 00 00 +01 00 70 1E 00 00 01 00 74 1E 00 00 01 00 75 1E +00 00 04 00 8A 1E 00 00 00 00 04 00 8E 1E 00 00 +00 00 01 00 92 1E 00 00 01 00 48 1E 00 00 01 00 +49 1E 00 00 01 00 4A 1E 00 00 01 00 4B 1E 00 00 +02 00 94 1E 00 00 02 00 96 1E 00 00 01 00 98 1E +00 00 01 00 99 1E 00 00 01 00 C6 1E 00 00 02 00 +C8 1E 00 00 02 00 D8 1E 00 00 01 00 DA 1E 00 00 +00 00 +@ffe0 +DE 8D +@ffea +60 DD 02 C2 1E 85 C0 EA +@fffe +22 E3 +q diff --git a/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_915MHz.txt b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_915MHz.txt new file mode 100755 index 0000000..e839739 --- /dev/null +++ b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_915MHz.txt @@ -0,0 +1,1936 @@ +@8000 +5A 14 31 80 1A 00 CA 0E B0 13 1C E0 0E 43 3F 40 +C8 42 B0 13 D0 BE 81 4C 12 00 81 4D 14 00 CC 0A +B0 13 72 E6 0E 43 3F 40 20 41 B0 13 D0 BE 81 4C +16 00 81 4D 18 00 36 40 11 00 37 40 32 1D 0A 43 +28 47 19 47 02 00 CC 08 CD 09 1E 41 12 00 1F 41 +14 00 B0 13 84 D4 0C 93 0A 38 81 48 08 00 81 49 +0A 00 27 52 1A 53 16 83 EB 23 4A 4A 03 3C 4A 4A +0A 93 7E 24 3A 90 0F 00 3D 38 3A 90 0F 00 23 24 +B0 13 86 82 1E 42 72 1D 1F 42 74 1D B0 13 D8 9E +C9 0C CA 0D 1C 42 72 1D 1D 42 74 1D 1E 42 6E 1D +1F 42 70 1D B0 13 3A 82 1C 42 5A F6 1C 82 58 F6 +B0 13 4C 82 1C 42 5A F6 B0 13 60 82 81 4C 00 00 +81 4D 02 00 73 3C B0 13 24 82 C9 0C CA 0D 1C 42 +6E 1D 1D 42 70 1D 1E 41 08 00 1F 41 0A 00 B0 13 +3A 82 1C 42 58 F6 1C 82 56 F6 B0 13 4C 82 1C 42 +56 F6 E2 3F C9 0A 59 02 16 49 38 F6 5A 06 17 4A +32 1D 18 4A 34 1D B0 13 24 82 C5 0C CA 0D B0 13 +86 82 CE 07 CF 08 B0 13 D8 9E 3E 40 34 80 3F 40 +37 3A B0 13 10 82 CC 05 CD 0A B0 13 44 B7 C5 0C +CA 0D CC 07 CD 08 1E 41 08 00 1F 41 0A 00 B0 13 +90 82 CC 05 CD 0A B0 13 D0 BE C8 0C CA 0D 1C 49 +3A F6 0C 86 B0 13 4C DE CE 0C CF 0D CC 08 CD 0A +B0 13 44 B7 C9 0C CA 0D CC 06 B0 13 60 82 A6 3F +B0 13 86 82 1E 42 32 1D 1F 42 34 1D B0 13 D8 9E +C9 0C CA 0D 1C 42 36 1D 1D 42 38 1D 1E 42 32 1D +1F 42 34 1D B0 13 3A 82 1C 42 3C F6 1C 82 3A F6 +B0 13 56 82 81 4C 00 00 81 4D 02 00 2C 41 1D 41 +02 00 B0 13 6A 82 3E 40 F4 FD 3F 40 D4 3B B0 13 +10 82 1C 41 16 00 1D 41 18 00 B0 13 D0 BE 81 4C +04 00 81 4D 06 00 1C 41 04 00 1D 41 06 00 B0 13 +6A 82 2E 41 1F 41 02 00 B0 13 44 B7 81 4C 0C 00 +81 4D 0E 00 1C 41 0C 00 1D 41 0E 00 B0 13 50 D7 +81 4C 10 00 1C 41 10 00 31 50 1A 00 55 16 10 01 +B0 13 44 B7 CE 0C CF 0D 0C 43 3D 40 80 3F B0 13 +90 82 10 01 1C 41 16 00 1D 41 18 00 1E 41 0C 00 +1F 41 0E 00 B0 13 D8 9E 10 01 B0 13 90 82 CC 09 +CD 0A B0 13 D0 BE C9 0C CA 0D 10 01 B0 13 56 82 +C9 0C CA 0D 10 01 B0 13 78 82 B0 13 44 B7 10 01 +B0 13 78 82 B0 13 DE 9E 10 01 3E 40 E7 6F 3F 40 +63 3B B0 13 44 B7 10 01 B0 13 4C DE CE 0C CF 0D +CC 09 CD 0A 10 01 1C 41 16 00 1D 41 18 00 10 01 +B0 13 D8 9E CE 0C CF 0D 10 01 4A 14 31 82 B0 13 +AC EE C8 0C CF 08 3F 50 FF 7F 81 4F 06 00 91 41 +06 00 04 00 82 43 46 1E 4A 43 49 43 4C 49 B0 13 +04 85 1F 4C 18 00 1F 83 1D 24 1F 83 14 24 D2 B3 +D6 1E 47 24 1E 42 4E 1E 1F 42 50 1E 3E F3 3F F0 +FF 00 1F 9C 02 00 3D 20 2E 9C 3B 20 D2 C3 D6 1E +82 43 46 1E 36 3C 5A 53 B0 13 BC D2 4C 93 31 24 +C7 09 2F 3C B0 13 30 EA C6 0C CC 09 B0 13 E0 DA +4C 93 0C 20 CC 09 CD 06 CE 08 B0 13 2E A1 1F 42 +44 1E AF 93 18 00 09 20 5A 53 07 3C 82 43 46 1E +E2 B2 D6 1E 02 20 B0 13 EA DE 1F 42 44 1E 9F 93 +18 00 0F 20 CF 01 3F 50 03 00 81 4F 00 00 CC 06 +CD 01 3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 +C6 D1 59 53 AB 27 4A 93 50 24 92 93 46 1E 18 38 +4C 47 B0 13 04 85 CC 07 B0 13 8E B6 4C 93 10 24 +5A 83 CF 01 3F 50 03 00 81 4F 00 00 7C 42 CD 01 +3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 C6 D1 +4A 93 33 24 1F 42 42 1E 0F 88 1F 93 2C 34 E2 B2 +D6 1E 0D 20 E2 D2 D6 1E C2 93 4B 1E 04 20 B2 50 +E0 7F 42 1E 20 3C B2 50 C0 53 42 1E 1C 3C E2 C2 +D6 1E C2 93 4B 1E 03 24 3F 40 40 6C 02 3C 3F 40 +20 00 82 5F 42 1E 49 43 4C 49 B0 13 04 85 AC 93 +18 00 07 20 CC 09 B0 13 A6 E2 4C 93 02 20 5A 83 +04 24 59 53 F1 27 4A 93 0E 20 F2 F0 F9 00 D6 1E +91 91 06 00 04 00 02 24 0E 43 08 3C B0 13 B2 EF +A2 43 9A 1E 6C 3C E2 D3 D6 1E 1E 43 1F 41 06 00 +0F 88 0F 93 50 38 0E 93 38 24 E2 B2 D6 1E 15 20 +1F 41 06 00 1F 82 42 1E 3F 80 42 00 0F 93 2D 38 +C2 43 98 1E C2 43 99 1E F2 D0 18 00 D6 1E 92 42 +42 1E 94 1E A2 43 9A 1E 48 3C 1F 41 06 00 0F 88 +3F 80 42 00 1F 93 19 38 C2 43 98 1E C2 43 99 1E +F2 D0 18 00 D6 1E 1F 41 06 00 1F 82 42 1E 3F 80 +42 00 0F 93 05 34 1F 41 06 00 3F 80 42 00 02 3C +1F 42 42 1E 82 4F 94 1E 26 3C D2 41 02 00 98 1E +D2 41 03 00 99 1E 5F 42 D6 1E 7F C2 7F D0 10 00 +C2 4F D6 1E 92 41 06 00 94 1E 92 41 04 00 96 1E +82 43 9A 1E 12 3C D2 91 02 00 98 1E 09 24 D2 41 +02 00 98 1E D2 41 03 00 99 1E F2 D0 10 00 D6 1E +92 41 04 00 94 1E 92 43 9A 1E D2 C3 D6 1E 31 52 +46 16 10 01 3D 40 1C 00 B0 13 10 EC 1C 52 BE F6 +82 4C 44 1E 10 01 4F 14 B2 F0 EF FF 42 03 92 C3 +42 03 B2 80 00 80 52 03 B2 D0 10 00 42 03 B0 13 +04 CE B2 D0 10 00 8C 1C B0 13 24 EF 4C 93 EE 20 +B0 13 18 EF 4C 93 EA 20 E2 93 2E 1E 04 28 A2 D3 +0A 1E B0 13 34 E9 E2 93 E0 1E 11 20 5E 42 E1 1E +CF 0E 5F 83 C2 4F E1 1E 4E 93 06 20 F2 40 0A 00 +E1 1E B0 13 36 F0 03 3C B2 D0 10 00 0A 1E B0 13 +30 EF 4C 93 02 24 92 D3 0A 1E B0 13 38 ED 4C 93 +0D 24 92 83 24 1E 04 20 B0 13 14 EA B0 13 5A 87 +F2 B0 40 00 01 02 02 24 A2 D2 0A 1E B0 13 26 ED +4C 93 12 24 92 83 60 1E 09 20 B0 13 B8 DF B0 13 +5A 87 7C 40 1F 00 4D 43 B0 13 DA E8 F2 B0 20 00 +01 02 02 24 B2 D2 0A 1E B0 13 0C EF 4C 93 02 24 +B0 13 3C BE B2 B0 20 00 08 1E 10 24 5E 42 9E 1E +CF 0E 5F 83 C2 4F 9E 1E 4E 93 08 20 92 D3 0C 1E +B2 D0 20 00 0C 1E F2 40 0F 00 9E 1E 82 93 0C 1E +0F 24 92 B3 0C 1E 08 20 A2 B2 0C 1E 09 24 A2 C2 +0C 1E 92 D3 8C 1C 04 3C 92 C3 0C 1E A2 D3 0C 1E +A2 B3 08 1E 0E 24 1F 42 26 1E 1E 42 28 1E 1F 82 +2A 1E 1E 72 2C 1E 03 20 3F 90 1F 00 02 28 92 D3 +08 1E D2 93 7B 1E 0E 20 E2 92 7A 1E 03 2C D2 53 +7A 1E 08 3C F2 C2 03 02 F2 C2 05 02 C2 43 7A 1E +C2 43 7B 1E E2 B3 01 02 03 24 D2 B3 01 02 2F 20 +C2 43 C2 1E E2 B2 01 02 11 24 D2 53 78 1E F2 90 +03 00 78 1E 0D 28 B2 D0 20 00 76 1E B2 F0 7F FF +76 1E C2 43 78 1E E2 C2 19 02 02 3C C2 43 78 1E +E2 B3 01 02 11 24 D2 53 79 1E F2 90 03 00 79 1E +47 28 B2 D0 40 00 76 1E B2 F0 FF FE 76 1E C2 43 +79 1E E2 C3 19 02 3C 3C C2 43 79 1E 39 3C D2 53 +C2 1E 5F 42 C2 1E 5F 83 7F 90 03 00 31 28 1F 42 +08 1E 2F C2 2E 42 1E C2 08 1E 0E DF 82 4E 08 1E +92 D3 0C 1E A2 B2 08 1E 04 20 B2 D0 10 00 0C 1E +02 3C B2 D2 0C 1E C2 43 C2 1E 1A 3C 82 93 EC 1C +04 20 F2 D0 20 00 F0 1C 02 3C 92 83 EC 1C B2 90 +03 00 EA 1C 0D 20 C2 93 EE 1C 08 20 7C 40 5A 00 +3D 40 12 F5 5E 43 B0 13 7A AF 02 3C D2 83 EE 1C +B1 C0 D0 00 14 00 4B 16 00 13 7C 40 46 00 3D 40 +76 F5 5E 43 B0 13 7A AF 6C 43 4D 43 B0 13 DA E8 +7C 40 03 00 4D 43 B0 13 DA E8 10 01 4A 14 B0 13 +D0 EE 82 43 08 0A 7C 40 46 00 3D 40 46 F5 5E 43 +B0 13 7A AF 7C 40 5B 00 3D 40 4C F5 5E 43 B0 13 +7A AF 7C 40 1E 00 B0 13 A6 89 7C 40 13 00 B0 13 +A6 89 7C 40 14 00 B0 13 A6 89 7C 40 15 00 B0 13 +A6 89 7C 40 16 00 B0 13 A6 89 7C 40 17 00 B0 13 +A6 89 7C 40 18 00 B0 13 A6 89 7C 40 19 00 B0 13 +A6 89 6C 43 B0 13 A6 89 7C 40 03 00 B0 13 A6 89 +4C 43 B0 13 A6 89 B2 40 80 5A 5C 01 32 D0 D8 00 +03 43 B0 13 64 EC B0 13 2E F0 B0 13 9C 89 E2 B2 +01 02 04 24 F2 B0 10 00 01 02 09 20 B0 13 9C 89 +82 43 76 1E F2 C2 03 02 F2 C2 05 02 AE 3C 49 43 +5A 43 4A 93 71 24 B0 13 64 EC 4A 43 4F 49 0F 93 +5E 24 1F 83 49 24 1F 83 36 24 1F 83 10 24 1F 83 +5F 20 A2 D2 76 1E B0 13 68 A5 B0 13 9C 89 B0 13 +3C BE 5D 43 B0 13 5C CB B0 13 CE D4 51 3C B0 13 +0E C3 28 42 06 43 07 43 3C 40 00 20 B0 13 8A CC +B0 13 24 E3 5C 42 59 1E CD 06 B0 13 8E 89 7C 40 +47 00 5E 43 B0 13 7A AF 5C 42 5B 1E CD 07 B0 13 +8E 89 7C 40 5D 00 5E 43 B0 13 7A AF 18 83 E4 23 +B0 13 B8 DF 2D 3C 5D 43 B0 13 1A AB 28 42 3C 40 +00 20 B0 13 8A CC 4C 43 B0 13 A6 BD 6D 43 B0 13 +1A AB 18 83 F4 23 1C 3C 5D 43 B0 13 42 A9 28 43 +F2 B0 40 00 01 02 FC 27 4C 43 B0 13 A0 BA 6D 43 +B0 13 42 A9 18 83 F4 23 B0 13 14 EA 09 3C B0 13 +16 EB E2 B2 01 02 04 24 F2 B0 10 00 01 02 F9 23 +3C 40 99 19 B0 13 8A CC E2 B2 01 02 2D 20 E2 B3 +01 02 27 20 F2 B0 10 00 01 02 1F 20 D2 B3 01 02 +19 20 F2 B2 01 02 22 24 F2 B2 01 02 FD 23 92 C3 +00 0A 82 43 08 0A 3C 40 00 40 B0 13 8A CC B0 13 +D0 EE B2 40 80 5A 5C 01 32 D0 F8 00 03 43 92 43 +5C 01 0C 3C 69 42 5A 43 09 3C 79 40 03 00 5A 43 +05 3C 69 43 5A 43 02 3C 59 43 5A 43 B2 40 2B 5A +5C 01 32 D0 D8 00 03 43 54 3F 46 16 10 01 7E 40 +03 00 4F 43 B0 13 06 B5 CD 0C 10 01 3C 40 CC 0C +B0 13 8A CC 10 01 5D 43 B0 13 DA E8 10 01 6A 14 +31 80 10 00 C8 0F C5 0E 81 4D 02 00 C7 0C 3F 01 +3A 00 71 0F 08 00 5F 41 38 00 81 4F 04 00 16 41 +36 00 91 41 32 00 0C 00 91 41 34 00 0E 00 19 41 +30 00 82 43 76 1E B0 13 70 F0 B0 13 42 E8 5F 42 +34 1E 81 4F 06 00 E2 43 34 1E 82 43 7C 1E B0 13 +B8 EB 7C 40 60 00 B0 13 9E EE 1A 43 54 43 B6 3C +0E 43 A2 B2 76 1E 01 24 1E 43 3F 40 10 00 0F F6 +0E 93 23 24 3A B0 00 80 0E 7E 3E E3 87 5A 00 00 +87 6E 02 00 1E 41 0E 00 1E 97 02 00 05 38 12 20 +1E 41 0C 00 2E 97 0E 2C 16 B3 03 24 CD 08 CE 09 +04 3C 1D 41 0C 00 1E 41 0E 00 87 4D 00 00 87 4E +02 00 1A 43 A2 C2 76 1E 54 43 B2 B2 76 1E 20 24 +3A B0 00 80 0E 7E 3E E3 87 8A 00 00 87 7E 02 00 +87 99 02 00 04 38 11 20 87 98 00 00 0E 2C 16 B3 +05 24 1D 41 0C 00 1E 41 0E 00 02 3C CD 08 CE 09 +87 4D 00 00 87 4E 02 00 1A 43 B2 C2 76 1E 54 43 +0F 93 35 24 3E 40 1E 00 1E 52 7C 1E 18 24 3E 80 +0A 00 18 24 3E 80 0A 00 18 24 3E 80 0A 00 26 24 +3E 80 0A 00 12 24 3E 80 0A 00 0C 24 3E 80 0A 00 +06 24 1A 93 1C 24 4F 43 5F 93 09 24 18 3C 3A 40 +E8 03 05 3C 3A 40 64 00 02 3C 3A 40 0A 00 2C 47 +1D 47 02 00 3A B0 00 80 0F 7F 3F E3 CE 0A B0 13 +28 D9 87 8E 00 00 87 7F 02 00 01 3C 1A 43 44 93 +2B 24 26 B2 1C 24 87 93 02 00 11 34 6C 43 4D 43 +B0 13 DA E8 7C 40 03 00 5D 43 B0 13 DA E8 2D 47 +1E 47 02 00 3D E3 3E E3 1D 53 0E 63 0B 3C 6C 43 +5D 43 B0 13 BC 8B 2D 47 1E 47 02 00 03 3C 2D 47 +1E 47 02 00 C1 45 00 00 1C 41 04 00 1F 41 02 00 +3B 01 08 00 4B 13 44 43 B0 13 00 EF 92 B3 08 1E +09 20 92 B3 76 1E 06 20 A2 B3 76 1E 41 27 36 B0 +20 00 3E 27 6C 43 4D 43 B0 13 BC 8B 7C 40 E0 00 +B0 13 9E EE B0 13 70 F0 B0 13 BC EF 1F 41 06 00 +C2 4F 34 1E 31 50 10 00 64 16 10 01 B0 13 DA E8 +7C 40 03 00 4D 43 B0 13 DA E8 10 01 0A 14 31 80 +1E 00 B0 13 50 E9 B2 B0 40 00 08 1E 05 20 91 43 +0E 00 81 43 10 00 04 3C 81 43 0E 00 81 43 10 00 +1A 41 0E 00 5F 42 30 1E 81 4F 12 00 81 43 14 00 +5F 42 31 1E 81 4F 16 00 81 43 18 00 5F 42 32 1E +81 4F 1A 00 81 43 1C 00 4E 43 9F 3C 4F 4E 0F 93 +07 24 1F 83 55 24 1F 83 40 24 1F 83 2C 24 95 3C +B0 13 DC EE B0 13 CC 8D 0F 43 81 43 00 00 91 43 +02 00 81 43 04 00 B1 40 29 00 06 00 F1 40 49 00 +08 00 00 18 F1 40 CE EB 0A 00 CC 01 3C 50 0E 00 +5D 43 4E 43 B0 13 AE 89 81 93 10 00 07 20 81 93 +0E 00 04 20 B2 D0 40 00 08 1E 03 3C B2 F0 BF FF +08 1E 5E 43 6A 3C B0 13 A8 8D F1 40 5E 00 08 00 +00 18 F1 40 DA E6 0A 00 CC 01 3C 50 1A 00 6D 43 +4E 43 B0 13 AE 89 4E 43 58 3C B0 13 A8 8D F1 40 +48 00 08 00 00 18 F1 40 DA E6 0A 00 CC 01 3C 50 +16 00 6D 43 4E 43 B0 13 AE 89 7E 40 03 00 45 3C +1C 41 12 00 1D 41 14 00 B0 13 C0 8D 7C 40 4A 00 +5E 43 B0 13 7A AF 7C 40 1E 00 5D 43 B0 13 DA E8 +1C 41 16 00 1D 41 18 00 B0 13 C0 8D 7C 40 48 00 +5E 43 B0 13 7A AF 1C 41 1A 00 1D 41 1C 00 B0 13 +C0 8D 7C 40 5E 00 5E 43 B0 13 7A AF 7C 40 29 00 +5D 43 B0 13 DA E8 0F 43 81 43 00 00 B1 40 17 00 +02 00 81 43 04 00 B1 40 23 00 06 00 F1 40 4A 00 +08 00 00 18 F1 40 C4 D6 0A 00 CC 01 3C 50 12 00 +6D 43 4E 43 B0 13 AE 89 6E 43 92 B3 08 1E 13 20 +92 B3 76 1E 5B 27 B0 13 D0 EE D2 41 12 00 30 1E +D2 41 16 00 31 1E D2 41 1A 00 32 1E B0 13 2E F0 +B0 13 CC 8D 0B 3C 0A 93 04 20 B2 D0 40 00 08 1E +03 3C B2 F0 BF FF 08 1E B0 13 CC 8D 82 43 76 1E +31 50 1E 00 0A 16 10 01 0F 43 81 43 04 00 B1 40 +3B 00 06 00 81 43 08 00 B1 40 23 00 0A 00 10 01 +6E 43 4F 43 B0 13 06 B5 CD 0C 10 01 4C 43 4D 43 +B0 13 DA E8 10 01 7F 14 59 42 1B 02 B2 B0 20 00 +76 1E EA 20 B2 B0 40 00 76 1E E6 20 82 43 76 1E +5A 42 1D 02 4A F9 48 43 B0 13 24 EF 4C 93 6D 20 +7A B0 1F 00 0F 24 32 C2 03 43 C2 43 1B 02 32 D2 +3C 40 A3 00 B0 13 8A CC 92 42 26 1E 2A 1E 92 42 +28 1E 2C 1E 6A B2 44 20 6A B3 2D 20 7A B0 10 00 +22 20 5A B3 0E 20 7A B2 77 24 F2 B2 01 02 74 24 +D2 43 7B 1E C2 43 7A 1E F2 D2 03 02 F2 D2 05 02 +6B 3C D2 B3 01 02 68 24 B2 D2 76 1E 58 43 B0 13 +C8 EC 4C 93 61 24 A2 B2 08 1E 5E 20 B0 13 B2 EA +B2 C2 76 1E 59 3C F2 B0 10 00 01 02 55 24 A2 D2 +76 1E 58 43 51 3C E2 B3 01 02 0B 20 E2 B3 19 02 +4B 24 A2 D3 76 1E B2 F0 FF FE 76 1E E2 C3 19 02 +43 3C A2 D3 76 1E B2 F0 FF FE 76 1E 58 43 3C 3C +E2 B2 01 02 0B 20 E2 B2 19 02 36 24 92 D3 76 1E +B2 F0 7F FF 76 1E E2 C2 19 02 2E 3C 92 D3 76 1E +B2 F0 7F FF 76 1E 58 43 27 3C D2 53 7E 1E 5F 42 +7E 1E 5F 83 7F 90 07 00 05 28 F2 F0 0F 00 F2 1C +C2 43 7E 1E 6A B2 13 20 6A B3 0D 20 7A B0 10 00 +06 20 5A B3 11 24 F2 D0 20 00 F0 1C 0D 3C F2 D0 +30 00 F2 1C 07 3C F2 D0 20 00 F2 1C 03 3C F2 D0 +10 00 F2 1C F2 D2 F0 1C A2 B3 76 1E 03 24 B2 B2 +76 1E 18 20 48 93 18 24 E2 93 E0 1E 0A 24 B2 B0 +10 00 08 1E 0A 20 5C 43 3D 40 33 13 B0 13 AA D5 +04 3C B0 13 36 F0 82 43 76 1E 3C 40 00 20 B0 13 +8A CC 02 3C 82 43 76 1E 7A B0 20 00 02 24 B2 D2 +0A 1E 7A B0 40 00 02 24 A2 D2 0A 1E 92 B3 76 1E +03 20 A2 B3 76 1E 18 24 3C 40 66 06 B0 13 8A CC +E2 B2 01 02 07 24 E2 D2 19 02 92 C3 76 1E B2 D0 +80 00 76 1E E2 B3 01 02 07 24 E2 D3 19 02 A2 C3 +76 1E B2 D0 00 01 76 1E 32 C2 03 43 C2 43 1D 02 +C2 49 1B 02 32 D2 B1 C0 F0 00 20 00 78 16 00 13 +0A 14 31 80 1A 00 B0 13 50 E9 5F 42 CB 1E 4C 4F +0D 43 4E 4F 81 4E 0E 00 81 43 10 00 5E 42 CC 1E +81 4E 12 00 81 43 14 00 91 42 CE 1E 16 00 81 43 +18 00 B2 B0 40 00 08 1E 0D 20 4C 4F B0 13 B6 91 +7C 40 48 00 B0 13 86 91 7C 40 4A 00 5E 43 B0 13 +7A AF 0B 3C B0 13 B6 91 7C 40 4A 00 B0 13 86 91 +7C 40 48 00 5E 43 B0 13 7A AF 7C 40 1F 00 5D 43 +B0 13 DA E8 4A 43 70 3C 4F 4A 0F 93 3E 24 1F 83 +1F 24 1F 83 55 20 B2 B0 40 00 08 1E 0C 20 B0 13 +9A 91 B0 13 52 91 CC 01 3C 50 0E 00 6D 43 4E 43 +B0 13 AE 89 0B 3C B0 13 9A 91 B0 13 6C 91 CC 01 +3C 50 0E 00 6D 43 4E 43 B0 13 AE 89 4A 43 38 3C +B2 B0 40 00 08 1E 0C 20 B0 13 A8 91 B0 13 6C 91 +CC 01 3C 50 12 00 6D 43 4E 43 B0 13 AE 89 0B 3C +B0 13 A8 91 B0 13 52 91 CC 01 3C 50 12 00 6D 43 +4E 43 B0 13 AE 89 6A 43 1B 3C 3F 40 D8 07 81 43 +00 00 B1 40 34 08 02 00 81 43 04 00 B1 40 22 00 +06 00 F1 40 5C 00 08 00 00 18 F1 40 DA E6 0A 00 +CC 01 3C 50 16 00 6D 42 4E 43 B0 13 AE 89 5A 43 +5C 41 12 00 1D 41 16 00 B0 13 0A C2 4F 4C 0E 43 +1E 91 10 00 04 38 08 20 1F 91 0E 00 05 2C 4F 4C +81 4F 0E 00 81 43 10 00 92 B3 08 1E 0C 20 92 B3 +76 1E 8A 27 D2 41 0E 00 CB 1E D2 41 12 00 CC 1E +92 41 16 00 CE 1E 82 43 76 1E 31 50 1A 00 0A 16 +10 01 81 43 08 00 B1 40 23 00 0A 00 F1 40 48 00 +0C 00 00 18 F1 40 DA E6 0E 00 10 01 81 43 08 00 +B1 40 23 00 0A 00 F1 40 4A 00 0C 00 00 18 F1 40 +DA E6 0E 00 10 01 5E 43 B0 13 7A AF 1C 41 16 00 +1D 41 18 00 B0 13 B6 91 10 01 1F 43 81 43 04 00 +4C 4C 81 4C 06 00 10 01 1F 43 81 43 04 00 B1 40 +0C 00 06 00 10 01 6E 43 4F 43 B0 13 06 B5 CD 0C +10 01 31 80 1A 00 B0 13 50 E9 5F 42 F6 1D 81 4F +0E 00 81 43 10 00 1C 42 FC 1D 1D 42 FE 1D 3E 40 +E8 03 0F 43 B0 13 1E D0 81 4C 16 00 81 4D 18 00 +B2 B0 40 00 08 1E 12 20 1C 42 F8 1D 0D 43 3E 40 +B9 01 0F 43 B0 13 1E E7 3E 40 C8 00 0F 43 B0 13 +28 D9 81 4C 12 00 81 4D 14 00 05 3C 91 42 F8 1D +12 00 81 43 14 00 4E 43 82 3C 4F 4E 0F 93 55 24 +1F 83 39 24 1F 83 7B 20 B2 B0 40 00 08 1E 19 20 +7C 40 5E 00 3D 40 38 F5 5E 43 B0 13 7A AF 3F 40 +46 00 81 43 00 00 B1 40 90 01 02 00 B0 13 98 93 +CC 01 3C 50 12 00 7D 40 03 00 6E 43 B0 13 AE 89 +18 3C 7C 40 5E 00 3D 40 3C F5 5E 43 B0 13 7A AF +3F 40 1E 00 81 43 00 00 B1 40 96 00 02 00 B0 13 +98 93 CC 01 3C 50 12 00 7D 40 03 00 6E 43 B0 13 +AE 89 4E 43 44 3C 0F 43 81 43 00 00 91 43 02 00 +81 43 04 00 B1 40 29 00 06 00 F1 40 5C 00 08 00 +00 18 F1 40 E4 EB 0A 00 CC 01 3C 50 0E 00 5D 43 +4E 43 B0 13 AE 89 6E 43 2A 3C 7C 40 10 00 5D 43 +B0 13 DA E8 0F 43 81 43 00 00 B1 40 3F 0D 02 00 +B1 40 03 00 04 00 B1 40 32 00 06 00 F1 40 5A 00 +08 00 00 18 F1 40 DA E6 0A 00 CC 01 3C 50 16 00 +7D 40 06 00 7E 40 05 00 B0 13 AE 89 7C 40 10 00 +4D 43 B0 13 DA E8 6C 43 B0 13 BA CE 5E 43 92 B3 +08 1E 2D 20 92 B3 76 1E 78 27 1C 41 16 00 1D 41 +18 00 3E 40 E8 03 0F 43 B0 13 1E E7 82 4C FC 1D +82 4D FE 1D D2 41 0E 00 F6 1D B2 B0 40 00 08 1E +11 20 1C 41 12 00 1D 41 14 00 3E 40 C8 00 0F 43 +B0 13 1E E7 3E 40 B9 01 0F 43 B0 13 28 D9 82 4C +F8 1D 03 3C 92 41 12 00 F8 1D A2 D2 8C 1C 82 43 +76 1E 31 50 1A 00 10 01 81 43 08 00 B1 40 22 00 +0A 00 F1 40 62 00 0C 00 00 18 F1 40 DA E6 0E 00 +10 01 6A 14 31 80 20 00 C8 0F C9 0D CA 0E 81 43 +0C 00 81 43 0E 00 B0 13 4C DE 81 4C 14 00 81 4D +16 00 CC 09 CD 0A B0 13 1C E0 0E 43 3F 40 C8 42 +B0 13 D0 BE 81 4C 18 00 81 4D 1A 00 CC 08 B0 13 +72 E6 0E 43 3F 40 20 41 B0 13 D0 BE 81 4C 1C 00 +81 4D 1E 00 1C 41 14 00 1D 41 16 00 3E 40 F4 FD +3F 40 D4 3B B0 13 44 B7 1E 41 1C 00 1F 41 1E 00 +B0 13 DE 9E 81 4C 10 00 81 4D 12 00 1C 41 10 00 +1D 41 12 00 3E 40 E7 6F 3F 40 63 3B B0 13 44 B7 +CE 0C CF 0D 1C 41 14 00 1D 41 16 00 B0 13 D0 BE +81 4C 08 00 81 4D 0A 00 36 40 10 00 37 40 3A F6 +0A 43 2C 47 B0 13 58 95 CE 08 CF 09 B0 13 84 D4 +0C 93 08 38 81 48 0C 00 81 49 0E 00 27 53 1A 53 +16 83 EF 23 4A 4A 5A 02 1C 4A 5A F6 B0 13 72 E6 +C6 0C C7 0D 1C 4A 3A F6 B0 13 58 95 B0 13 7C 95 +C4 0C C5 0D 1C 41 08 00 1D 41 0A 00 CE 08 CF 09 +B0 13 D8 9E 3E 40 82 A8 3F 40 7B 38 B0 13 44 B7 +CE 0C CF 0D 0C 43 3D 40 80 3F B0 13 6A 95 C4 0C +C5 0D 1C 4A 5C F6 B0 13 72 E6 CE 06 CF 07 B0 13 +6A 95 C5 0C CA 0D CC 08 CD 09 B0 13 7C 95 CE 0C +CF 0D CC 05 CD 0A B0 13 D0 BE CE 06 CF 07 B0 13 +DE 9E 81 4C 04 00 81 4D 06 00 1C 41 18 00 1D 41 +1A 00 1E 41 04 00 1F 41 06 00 B0 13 D0 BE 81 4C +00 00 81 4D 02 00 38 40 11 00 3A 40 32 1D 39 40 +5C F6 3C 49 B0 13 72 E6 2E 41 1F 41 02 00 B0 13 +44 B7 2A 52 8A 4C FC FF 8A 4D FE FF 18 83 F1 23 +31 50 20 00 64 16 10 01 B0 13 4C DE C8 0C C9 0D +1C 41 0C 00 1D 41 0E 00 10 01 B0 13 D8 9E CE 0C +CF 0D CC 04 CD 05 B0 13 44 B7 10 01 1E 41 10 00 +1F 41 12 00 B0 13 D8 9E 10 01 3C 40 79 1D 0D 43 +3E 40 21 00 B0 13 5C ED 7C 40 30 00 B0 13 5A C6 +7C 40 30 00 B0 13 0A D7 4C 93 AF 20 7C 40 31 00 +B0 13 0A D7 7C 90 06 00 A5 20 7C 40 36 00 B0 13 +5A C6 B0 13 10 97 FD 23 B2 40 01 02 34 0F 0F 42 +32 C2 03 43 B2 B0 10 00 02 0F FC 27 B2 40 51 7E +10 0F B2 B0 10 00 02 0F FC 27 F2 40 3D 00 11 0F +B2 B0 10 00 02 0F FC 27 F2 40 FE 00 11 0F B2 B0 +20 00 02 0F FC 27 C2 43 10 0F B2 B0 80 00 02 0F +FC 27 F2 90 51 00 20 0F 72 20 B2 B0 10 00 02 0F +FC 27 F2 40 3D 00 11 0F 02 4F 3B 40 7C F5 4E 43 +6C 4B 4F 4E 5F 02 5D 4F 7D F5 B0 13 1E DF 2B 53 +5E 53 7E 90 20 00 F4 2B 3D 40 7C F5 4E 43 6C 4D +B0 13 0A D7 4F 4E 5F 02 CF 9C 7D F5 4D 20 2D 53 +5E 53 7E 90 20 00 F3 2B 7C 40 36 00 B0 13 5A C6 +B0 13 10 97 FD 23 7C 40 0C 00 5D 42 16 1E B0 13 +1E DF B0 13 80 E8 6C 43 B0 13 4A EA 7C 40 34 00 +B0 13 5A C6 A2 B3 30 0F FD 27 3E 40 10 00 7C 40 +34 00 B0 13 0A D7 5C F3 5F 42 9A 1D 4F 5F 4C DF +C2 4C 9A 1D 1E 83 F3 23 F2 D0 80 00 9A 1D B0 13 +CC E1 7C 40 32 00 B0 13 5A C6 D2 43 78 1D B2 40 +36 00 9E 1D B2 40 E2 04 A0 1D 3C 40 79 1D 0D 43 +3E 40 1F 00 B0 13 5C ED 3C 40 98 1D 0D 43 2E 43 +B0 13 5C ED 32 D2 10 01 32 C2 03 43 FF 3F 32 C2 +03 43 FF 3F 32 C2 03 43 FF 3F 32 C2 03 43 FF 3F +7C 40 3D 00 B0 13 5A C6 7C B0 F0 FF 10 01 1A 14 +CA 0C 6D 93 3C 24 5D 93 0E 24 6D 92 60 20 B0 13 +62 98 6D 42 B0 13 DA E8 C2 43 2F 1E 4C 43 4D 43 +B0 13 DA E8 54 3C C2 93 2F 1E 1A 20 B2 B0 40 00 +08 1E 09 20 B0 13 F2 97 5A 93 07 20 5C 42 30 1E +B0 13 A4 E9 02 3C B0 13 0A 98 B0 13 3C 98 C9 0C +5C 42 31 1E B0 13 18 98 B0 13 62 98 6D 43 E0 3F +B0 13 54 98 C9 0C 5C 42 32 1E B0 13 18 98 7D 40 +1F 00 7E 40 29 00 B0 13 60 EF 5D 43 D1 3F 5F 42 +2E 1E 4F 93 24 24 C2 93 2F 1E 1A 20 4F 4F 2F 83 +0F 24 1F 83 1C 20 B2 B0 40 00 08 1E 07 20 B0 13 +F2 97 5C 42 30 1E B0 13 A4 E9 02 3C B0 13 0A 98 +B0 13 3C 98 CA 0C 5C 42 31 1E B0 13 2E 98 07 3C +B0 13 54 98 CA 0C 5C 42 32 1E B0 13 2E 98 19 16 +10 01 5C 42 30 1E B0 13 FE EA CF 0C CC 0A B0 13 +44 98 4C 4F B0 13 20 98 10 01 B0 13 44 98 5C 42 +30 1E B0 13 20 98 10 01 B0 13 20 98 CC 0A 10 01 +B0 13 70 98 CC 09 5E 43 B0 13 7A AF 10 01 B0 13 +70 98 CC 0A 5E 43 B0 13 7A AF 10 01 CC 0A B0 13 +54 98 10 01 7D 40 4A 00 7E 40 60 00 B0 13 60 EF +C9 0C 10 01 7D 40 48 00 7E 40 5E 00 B0 13 60 EF +10 01 7D 40 1E 00 7E 40 28 00 B0 13 60 EF 10 01 +0D 43 6E 43 4F 43 B0 13 06 B5 CD 0C 10 01 1A 14 +31 80 16 00 B0 13 9A DB CA 0C 0A 93 03 20 3C 40 +03 00 97 3C 5C 43 CD 0A B0 13 4E B0 4C 93 04 20 +CC 0A B0 13 7C F0 F3 3F B0 13 82 F0 CD 0C C9 01 +39 52 CC 09 2E 42 B0 13 4A ED 81 49 00 00 CF 01 +3F 50 0C 00 81 4F 02 00 F1 40 09 00 04 00 E1 43 +05 00 CD 01 3D 50 0E 00 3C 40 6C 1E B0 13 F8 E9 +D1 4A 09 00 12 00 D1 42 75 1E 0D 00 B0 13 A8 F0 +C1 4C 13 00 D1 43 0C 00 B0 13 AC F0 C1 4C 14 00 +2C 43 3D 40 03 00 CE 01 B0 13 FA B7 0C 93 59 20 +B0 13 6A F0 C9 0C E1 43 05 00 CF 01 3F 50 0C 00 +81 4F 02 00 CF 0A 3F 50 03 00 81 4F 00 00 79 90 +03 00 06 24 59 93 02 20 B0 13 B8 E6 B0 13 E2 E7 +B0 13 B6 DE 79 90 03 00 07 24 59 93 03 24 B0 13 +C2 E7 02 3C B0 13 E2 E5 2C 43 2D 43 CE 01 B0 13 +FA B7 0C 93 05 24 CC 0A B0 13 7C F0 1C 43 29 3C +3F 40 7F 00 5F F1 0C 00 5F 93 09 24 7F 90 03 00 +06 24 CC 0A B0 13 7C F0 3C 40 05 00 1A 3C EA 43 +00 00 DA 41 0E 00 0A 00 D2 4A 0B 00 77 1D F1 90 +40 00 0F 00 02 20 5F 43 02 3C 7F 40 03 00 CA 4F +01 00 D2 53 75 1E C2 93 75 1E 02 20 D2 43 75 1E +0C 43 31 50 16 00 19 16 10 01 3A 14 31 82 C9 0C +F9 90 14 00 00 00 05 28 B0 13 AC F0 C9 9C 14 00 +74 20 3C 40 0E 00 0C 59 CD 01 B0 13 3C EF 91 92 +6E 1E 02 00 6A 20 91 92 6C 1E 00 00 66 20 58 49 +12 00 3A 40 05 00 0A 59 3C 40 05 00 0C 59 CD 08 +B0 13 50 DC 0C 93 48 20 C2 93 70 1E 56 24 B0 13 +9A DB C7 0C 07 93 51 24 3C 40 03 00 0C 57 CD 0A +2E 42 B0 13 4A ED 6C 43 CD 07 B0 13 4E B0 4C 93 +03 24 D2 93 74 1E 04 20 CC 07 B0 13 7C F0 3D 3C +5F 42 74 1E CE 0F 5E 53 C2 4E 74 1E 4F 4F DF 47 +0B 00 72 1E C7 48 0A 00 E7 43 00 00 F9 90 40 00 +13 00 02 20 5F 43 02 3C 7F 40 03 00 C7 4F 01 00 +D1 47 09 00 06 00 B0 13 A8 F0 C1 4C 07 00 B0 13 +FA 9A B0 13 E8 9A CD 01 B0 13 08 9B D5 27 B0 13 +D0 9A 0C 93 12 24 D0 3F B0 13 FA 9A D1 4C 09 00 +06 00 B0 13 A8 F0 C1 4C 07 00 B0 13 E8 9A CD 01 +B0 13 08 9B 02 24 B0 13 D0 9A 31 52 37 16 10 01 +3C 40 03 00 0C 59 CD 0A 2E 42 B0 13 4A ED CC 09 +4D 43 B0 13 40 E1 10 01 3E 40 07 00 5E F9 0A 00 +3F 40 03 00 4F 8E 6C 43 10 01 F1 40 81 00 08 00 +D1 49 0D 00 09 00 10 01 2D 52 6E 42 B0 13 76 C0 +C9 0C 09 93 10 01 C2 43 17 1D 5F 42 F2 1C 2F 83 +99 24 1F 83 3F 24 1F 83 23 24 1F 83 06 24 2F 83 +96 20 F2 D0 20 00 F0 1C 10 01 E2 43 F2 1C 3C 40 +1E 1D 4D 43 4E 4D 5E 02 5F 4E F3 1C 47 18 0F 5F +5E 4E F4 1C 0E 5F 2C 53 8C 4E FE FF 5D 53 7D 90 +09 00 F0 2B E2 43 18 1D F2 40 09 00 17 1D 10 01 +E2 43 F2 1C 5E 42 F3 1C 47 18 0E 5E 5F 42 F4 1C +0E 5F 82 4E 1A 1D 5F 42 F5 1C 47 18 0F 5F 5D 42 +F6 1C 0F 5D 82 4F 1C 1D D2 43 18 1D 4F 8E C2 4F +17 1D 10 01 3E 40 BF FF 1E F2 08 1E 5F 42 F3 1C +5F 03 3F F0 C0 FF 0E DF 82 4E 08 1E 3F 40 7F 00 +5F F2 F3 1C C2 4F 30 1E D2 42 F4 1C 31 1E D2 42 +F5 1C 32 1E 5F 42 F6 1C 47 18 0F 5F 5E 42 F7 1C +0E 5F 82 4E CE 1E D2 42 F8 1C CC 1E D2 42 F9 1C +CB 1E D2 42 FA 1C E2 1E D2 42 FB 1C E3 1E 5F 42 +FC 1C 47 18 0F 5F 5E 42 FD 1C 0E 5F CF 0E 1F 52 +D4 1E 1F 82 D2 1E 82 4F D4 1E 82 4E D2 1E 5F 42 +FE 1C 47 18 0F 5F 5C 42 FF 1C 0C 5F 82 4C 20 1E +1D 42 1A 1E 1E 42 1C 1E 1F 42 1E 1E B0 13 B2 93 +7C 40 5A 00 3D 40 F4 F4 5E 43 B0 13 7A AF D2 43 +EE 1C 10 01 F2 40 03 00 F2 1C D2 43 17 1D 10 01 +0A 14 31 82 92 B3 8C 1C 0F 20 A2 B2 8C 1C 0C 20 +3F 40 0C 00 1F 52 E6 1E 6F 13 4C 93 0C 24 5C 43 +6D 43 80 13 0E 1E 07 3C 5C 43 B0 13 BA CE 5C 43 +5D 43 80 13 0E 1E A2 B3 0C 1E 1B 20 92 B3 8C 1C +12 20 B2 B2 8C 1C 0F 20 3F 40 0C 00 1F 52 E4 1E +6F 13 4C 93 5B 24 82 93 0C 1E 58 20 6C 43 6D 43 +80 13 12 1E 53 3C 6C 43 B0 13 BA CE 6C 43 5D 43 +F7 3F 6A 43 B2 B2 0C 1E 28 20 B2 B0 10 00 0C 1E +20 20 B2 B0 20 00 0C 1E 14 20 B2 B0 40 00 0C 1E +0C 20 B2 B0 80 00 0C 1E 1F 24 CC 01 3D 40 52 F5 +2E 42 B0 13 4A ED 5A 43 17 3C CC 01 3D 40 58 F5 +F7 3F CC 01 3D 40 5E F5 3E 40 06 00 B0 13 4A ED +0B 3C CC 01 3D 40 66 F5 F7 3F CC 01 3D 40 6E F5 +3E 40 06 00 B0 13 4A ED CC 0A B0 13 BA CE CC 0A +6D 42 80 13 12 1E 6A 93 07 24 7C 40 46 00 CD 01 +5E 43 B0 13 7A AF 06 3C 7C 40 5A 00 CD 01 5E 43 +B0 13 7A AF 82 43 0C 1E A2 D2 0C 1E 92 B3 8C 1C +10 24 B0 13 0C EF 6C 93 0C 20 7C 40 17 00 B0 13 +9C 9D 7C 40 18 00 B0 13 9C 9D 7C 40 19 00 B0 13 +9C 9D 82 43 8C 1C 31 52 0A 16 10 01 7D 40 03 00 +B0 13 DA E8 10 01 2A 14 C2 93 93 1E 8C 24 5D 93 +78 24 6D 93 15 24 6D 92 8D 20 B0 13 B8 DF C2 43 +58 1E 7C 40 1F 00 4D 43 B0 13 DA E8 6C 43 4D 43 +B0 13 DA E8 7C 40 03 00 4D 43 B0 13 DA E8 7A 3C +5F 42 5E 1E 0F 93 13 24 1F 83 0A 24 5A 42 5B 1E +7C 40 1A 00 7D 40 5A 00 5E 43 B0 13 E8 C5 10 3C +5A 42 5A 1E 7C 40 1A 00 7D 40 59 00 F5 3F 5A 42 +59 1E 7C 40 1A 00 7D 40 58 00 5E 43 B0 13 E8 C5 +CC 0A B0 13 A0 D3 3D 40 0A 00 B0 13 FA EB B0 13 +72 E6 3E 40 CD CC 3F 40 4C 3E B0 13 44 B7 C8 0C +C9 0D 1C 42 5C 1E B0 13 72 E6 3E 40 CD CC 3F 40 +4C 3F B0 13 44 B7 CE 0C CF 0D CC 08 CD 09 B0 13 +DE 9E B0 13 50 D7 82 4C 5C 1E 0D 43 7E 40 03 00 +4F 43 B0 13 06 B5 CD 0C 7C 40 47 00 5E 43 B0 13 +7A AF CC 0A B0 13 58 EE 4C 93 08 20 6C 43 4D 43 +B0 13 DA E8 7C 40 03 00 5D 43 9F 3F 6C 43 5D 43 +97 3F B0 13 26 ED 4C 93 0B 20 82 43 5C 1E B0 13 +0E C3 B2 40 10 0E 60 1E D2 43 58 1E D2 43 5E 1E +7C 40 1F 00 E9 3F 7C 40 47 00 3D 40 F0 F4 5E 43 +B0 13 7A AF 28 16 10 01 3B 40 80 00 01 3C 0B 43 +0A 14 09 14 08 14 07 14 21 83 3F B0 80 7F 7B 24 +3D B0 80 7F 05 20 0C 4E 0D 4F 8B 10 0D EB 73 3C +5D 02 08 4D 4D 10 38 F0 00 FF 0D D8 5F 02 08 4F +4F 10 38 F0 00 FF 0F D8 09 4C 0A 4D 3D F0 80 00 +C1 4D 00 00 0B EA 0B EF 3B C0 7F FF 3A D0 80 00 +3F D0 80 00 0A 9F 02 20 09 9E 0A 24 0B 2C 0D 4F +0F 4A 0A 4D 0C 4E 0E 49 09 4C 81 EB 00 00 02 3C +0B 93 4F 20 0C 43 08 4A 88 10 47 48 8F 10 48 8F +8F 10 0E 24 38 90 19 00 34 2C 12 C3 4F 10 5E 00 +5C 00 3C B0 00 10 02 24 3C D0 00 20 18 83 F5 23 +0B 93 0C 24 08 8C 09 7E 4A 7F 0C 48 4A 93 12 30 +5C 02 09 69 4A 6A 17 83 2C 24 F8 3F 09 5E 4A 6F +09 28 4A 10 59 00 5C 00 3C B0 00 10 02 24 3C D0 +00 20 17 53 3C B0 00 80 07 24 09 63 4A 63 07 63 +3C B0 00 60 01 20 19 C3 17 93 13 38 37 90 FF 00 +13 34 7A C0 80 00 87 10 D1 51 00 00 00 00 57 00 +0A D7 0C 49 0D 4A 21 53 07 16 08 16 09 16 0A 16 +10 01 0D 43 0C 43 F7 3F 3D 40 FF FE D1 61 00 00 +00 00 5D 00 3C 43 EF 3F 6D 93 1E 24 5D 93 8A 20 +C2 93 40 1E 08 20 3D 40 3A 1E 7C 40 5A 00 5E 43 +B0 13 7A AF 07 3C 3D 40 38 1E 7C 40 5A 00 5E 43 +B0 13 7A AF 7C 40 27 00 5D 43 B0 13 DA E8 7C 40 +28 00 5D 43 80 00 DA E8 B2 B0 20 00 8C 1C 6A 24 +C2 93 40 1E 38 20 5F 42 35 1E 4F 93 63 24 4F 4F +1F 83 1E 24 1F 83 16 24 1F 83 0E 24 1F 83 06 24 +3F 80 03 00 1B 24 1F 83 1F 24 10 01 5D 42 3A 1E +7C 40 21 00 B0 13 26 A1 5D 42 3B 1E 7C 40 22 00 +B0 13 26 A1 5D 42 3C 1E 7C 40 23 00 B0 13 26 A1 +5D 42 3D 1E 7C 40 24 00 B0 13 26 A1 5D 42 3E 1E +7C 40 25 00 B0 13 26 A1 5D 42 3F 1E 7C 40 26 00 +5E 43 80 00 E8 C5 5F 42 35 1E 1F 83 28 24 1F 83 +20 24 1F 83 18 24 1F 83 10 24 1F 83 08 24 1F 83 +21 20 5D 42 38 1E 7C 40 21 00 B0 13 26 A1 5D 42 +39 1E 7C 40 22 00 B0 13 26 A1 5D 42 3A 1E 7C 40 +23 00 B0 13 26 A1 5D 42 3B 1E 7C 40 24 00 B0 13 +26 A1 5D 42 3C 1E 7C 40 25 00 B0 13 26 A1 5D 42 +3D 1E CC 3F 10 01 5E 43 B0 13 E8 C5 10 01 1A 14 +C9 0C 1A 42 44 1E 4D 4D 1D 5A 0C 00 0D 8E 3D 80 +13 00 0D 93 81 34 3E 40 1A 00 1E 52 44 1E 6F 4E +3F F0 03 00 1F 83 4E 24 1F 83 2C 20 CA 43 12 00 +2F 42 6F BE 1A 20 1C 42 44 1E D2 9C 11 00 48 1E +09 2C C2 93 4A 1E 03 20 B0 13 74 D1 09 3C 8C 43 +18 00 06 3C B0 13 60 CE 1F 42 44 1E DF 53 11 00 +CC 09 5D 43 B0 13 64 DA 57 3C EE C2 00 00 1F 42 +44 1E 8F 43 00 00 8F 43 02 00 1C 42 44 1E B0 13 +74 D1 4A 3C 3C 40 80 00 5C 8A 13 00 CF 0A 2D 4F +1E 4F 02 00 3F 40 00 02 B0 13 F2 D5 1C 5A 0C 00 +3C 50 00 02 8A 4C 0C 00 1F 42 44 1E FF 40 22 00 +0F 00 3E 40 1A 00 1E 52 44 1E 3F 40 FC 00 6F FE +5F D3 28 3C 3C 40 40 00 5C 8A 13 00 2D 4A 1E 4A +02 00 3F 40 80 1C B0 13 F2 D5 1F 42 44 1E 1C 5F +0A 00 3C 50 00 06 8F 4C 0C 00 1F 42 44 1E DF 43 +0F 00 1A 42 44 1E CF 0A 5C 4F 13 00 2D 4F B0 13 +F0 EC CA 5C 0F 00 3E 40 1A 00 1E 52 44 1E 6F 4E +5F C3 6F D3 CE 4F 00 00 19 16 10 01 A2 D3 08 1E +82 93 76 1E 03 24 A2 B2 08 1E 68 20 B2 B0 20 00 +76 1E 5B 20 B2 B0 40 00 76 1E 4B 20 82 93 76 1E +69 24 92 B3 76 1E 32 20 A2 B3 76 1E 1A 20 A2 B2 +76 1E 0D 20 B2 B2 76 1E 5D 24 1F 42 E4 1E 0F 0F +6C 43 4F 13 B2 D2 8C 1C B2 C2 76 1E 53 3C 1F 42 +E6 1E 0F 0F 5C 43 4F 13 A2 D2 8C 1C A2 C2 76 1E +49 3C C2 43 89 1E 6C 43 6D 42 80 13 12 1E 1F 42 +E4 1E 1F 4F 10 00 82 4F E4 1E 00 18 D2 4F 08 00 +12 1E B2 D2 8C 1C A2 C3 76 1E 34 3C 5C 43 6D 42 +80 13 0E 1E 1F 42 E6 1E 1F 4F 10 00 82 4F E6 1E +00 18 D2 4F 08 00 0E 1E A2 D2 8C 1C 92 C3 76 1E +21 3C B2 F0 BF FF 76 1E 1F 42 E4 1E 3F 0F 04 00 +6C 43 4F 13 92 D3 8C 1C 15 3C B2 F0 DF FF 76 1E +1F 42 E6 1E 3F 0F 04 00 5C 43 F3 3F E2 B3 01 02 +03 24 D2 B3 01 02 04 20 92 D3 0C 1E B2 D2 0C 1E +82 43 76 1E 82 93 08 1E 09 24 92 B3 08 1E 06 24 +92 C3 08 1E B0 13 DC EE 92 D3 8C 1C A2 C3 08 1E +10 01 31 80 16 00 B0 13 50 E9 5C 42 E2 1E 4F 4C +81 4F 0E 00 81 43 10 00 5F 42 E3 1E 81 4F 12 00 +81 43 14 00 4C 4C 0D 43 6E 43 4F 43 B0 13 06 B5 +CD 0C 7C 40 4A 00 5E 43 B0 13 7A AF 7C 40 1E 00 +5D 43 B0 13 DA E8 1C 41 12 00 1D 41 14 00 6E 43 +4F 43 B0 13 06 B5 CD 0C 7C 40 48 00 5E 43 B0 13 +7A AF 4E 43 3A 3C 4F 4E 0F 93 1D 24 1F 83 35 20 +0F 43 81 43 00 00 B1 40 3B 00 02 00 81 43 04 00 +B1 40 23 00 06 00 F1 40 48 00 08 00 00 18 F1 40 +DA E6 0A 00 CC 01 3C 50 12 00 6D 43 4E 43 B0 13 +AE 89 4E 43 1A 3C 0F 43 81 43 00 00 B1 40 17 00 +02 00 81 43 04 00 B1 40 23 00 06 00 F1 40 4A 00 +08 00 00 18 F1 40 C4 D6 0A 00 CC 01 3C 50 0E 00 +6D 43 4E 43 B0 13 AE 89 5E 43 92 B3 08 1E 0B 20 +92 B3 76 1E C0 27 D2 41 0E 00 E2 1E D2 41 12 00 +E3 1E A2 D2 8C 1C 82 43 76 1E B2 D0 00 02 8C 1C +31 50 16 00 10 01 0A 14 31 80 16 00 B0 13 50 E9 +B2 B0 40 00 08 1E 0D 20 B0 13 E6 EA 3C B0 00 80 +0F 7F 3F E3 81 4C 0E 00 81 4F 10 00 1A 42 D2 1E +44 3C 1F 42 D2 1E 3F B0 00 80 0E 7E 3E E3 81 4F +0E 00 81 4E 10 00 CA 0F 38 3C B2 B0 40 00 08 1E +08 20 7C 40 1D 00 7D 40 46 00 5E 43 B0 13 E8 C5 +07 3C 7C 40 1D 00 7D 40 43 00 5E 43 B0 13 E8 C5 +7C 40 1F 00 5D 43 B0 13 DA E8 7C 40 0F 00 5D 43 +B0 13 DA E8 3F 40 19 FC B1 43 00 00 B1 40 E7 03 +02 00 81 43 04 00 B1 40 06 00 06 00 F1 40 49 00 +08 00 00 18 F1 40 DA E6 0A 00 CC 01 3C 50 0E 00 +7D 40 03 00 5E 43 B0 13 AE 89 92 B3 08 1E 1E 20 +92 B3 76 1E C2 27 B2 B0 40 00 08 1E 07 20 1C 41 +0E 00 B0 13 14 ED 81 4C 12 00 03 3C 91 41 0E 00 +12 00 1F 41 12 00 0F 8A 81 4F 14 00 92 51 14 00 +D4 1E 92 41 12 00 D2 1E A2 D2 8C 1C 82 43 76 1E +31 50 16 00 0A 16 10 01 B2 B0 20 00 08 1E 77 20 +B0 13 24 EF 4C 93 73 20 A2 B2 76 1E 70 24 1F 42 +EE 1D 0F 93 68 20 B0 13 A4 ED B0 13 C8 DC 7C 40 +0A 00 B0 13 4C F0 7C 42 B0 13 52 F0 82 43 F2 1D +82 43 F4 1D 7C 40 05 00 B0 13 1E F0 7C 40 0C 00 +5D 42 16 1E B0 13 00 DD 92 43 EE 1D 7C 40 17 00 +6D 43 B0 13 DA E8 7C 40 18 00 6D 43 B0 13 DA E8 +7C 40 19 00 6D 43 B0 13 DA E8 4C 43 B0 13 9A E5 +0C 93 0F 20 4C 43 1D 42 F2 1D 1E 42 F4 1D B0 13 +E8 D9 4C 43 B0 13 6E CF 4C 43 B0 13 9A E5 2C 93 +25 24 4C 43 B0 13 9A E5 1C 93 27 20 A2 43 EE 1D +82 93 F4 1D 0A 20 82 93 F2 1D 07 20 4C 43 B0 13 +7C E2 82 4C F2 1D 82 4D F4 1D 7C 40 17 00 B0 13 +60 A6 7C 40 18 00 B0 13 60 A6 7C 40 19 00 B0 13 +60 A6 7C 40 13 00 6D 43 80 00 DA E8 3C 40 99 19 +B0 13 8A CC D1 3F 2F 93 02 20 80 00 CE D4 10 01 +7D 40 03 00 B0 13 DA E8 10 01 1A 14 31 80 18 00 +B0 13 6A F0 C9 0C B0 13 82 F0 81 4C 10 00 CF 01 +2F 52 81 4F 12 00 F1 42 14 00 7A 40 03 00 C1 4A +15 00 CD 01 3D 50 06 00 3C 40 8A 1E B0 13 F8 E9 +D1 43 04 00 D1 42 92 1E 05 00 D1 43 0A 00 B0 13 +AC F0 C1 4C 0B 00 2C 43 3D 40 03 00 CE 01 3E 50 +10 00 B0 13 FA B7 C1 4A 15 00 CF 01 2F 52 81 4F +12 00 CF 01 3F 50 0C 00 81 4F 10 00 79 90 03 00 +06 24 59 93 02 20 B0 13 B8 E6 B0 13 E2 E7 B0 13 +B6 DE 3A 40 06 00 79 90 03 00 07 24 59 93 03 24 +B0 13 C2 E7 02 3C B0 13 E2 E5 2C 43 2D 43 CE 01 +3E 50 10 00 B0 13 FA B7 0C 93 1D 20 3F 40 7F 00 +5F F1 04 00 5F 93 03 24 7F 90 06 00 14 20 CC 01 +CD 01 3D 50 06 00 2E 42 B0 13 4A ED 2C 41 1D 41 +02 00 B0 13 92 ED CC 01 3C 50 0C 00 B0 13 48 EF +D2 53 92 1E 0A 43 CC 0A 31 50 18 00 19 16 10 01 +0A 14 21 83 C1 43 00 00 F2 90 03 00 78 1D 6B 20 +7C 40 3B 00 B0 13 0A D7 CE 0C 7C 40 3B 00 B0 13 +0A D7 4E 9C F9 23 4E 93 61 24 CC 01 5D 43 B0 13 +80 E0 6F 41 3F 50 03 00 4E 4E 0E 9F 38 20 F1 90 +1F 00 00 00 34 2C F1 90 0B 00 00 00 30 28 3C 40 +79 1D 0D 43 3E 40 1F 00 B0 13 5C ED E2 41 79 1D +3C 40 7A 1D 6D 41 B0 13 80 E0 3C 40 98 1D 6D 43 +B0 13 80 E0 F2 B0 80 FF 99 1D 14 24 92 53 AC 1D +82 63 AE 1D B0 13 A2 DA 4C 93 30 20 5C 42 98 1D +B0 13 70 E1 C2 4C 98 1D F2 F0 7F 00 99 1D B0 13 +A2 E7 24 3C 92 53 A8 1D 82 63 AA 1D 1F 3C 92 53 +B0 1D 82 63 B2 1D 0A 42 32 C2 03 43 7C 40 36 00 +B0 13 5A C6 7C 40 3D 00 B0 13 5A C6 7C B0 F0 FF +F9 23 7C 40 3A 00 B0 13 5A C6 7C 40 34 00 B0 13 +5A C6 02 4A 03 3C 32 C2 03 43 FF 3F 21 53 0A 16 +10 01 C2 93 40 1E 20 20 D2 53 3F 1E D2 53 41 1E +5F 42 41 1E 5F 83 7F 90 12 00 04 28 F2 42 35 1E +C2 43 41 1E F2 90 3A 00 3F 1E 0A 20 F2 40 30 00 +3F 1E D2 53 3E 1E D2 43 37 1E F2 40 07 00 35 1E +F2 90 3A 00 3E 1E 51 20 D2 43 35 1E D2 43 36 1E +3F 40 30 00 C2 4F 3E 1E D2 53 3D 1E F2 90 3A 00 +3D 1E 43 20 D2 53 35 1E C2 4F 3D 1E D2 53 3C 1E +F2 90 36 00 3C 1E 39 20 D2 53 35 1E C2 4F 3C 1E +D2 53 3B 1E F2 90 3A 00 3B 1E 2F 20 D2 53 35 1E +C2 4F 3B 1E D2 53 3A 1E 5E 42 3A 1E 7E 90 32 00 +1F 24 7E 90 36 00 21 20 D2 53 35 1E C2 4F 3A 1E +D2 53 39 1E F2 90 3A 00 39 1E 17 20 D2 53 35 1E +C2 4F 39 1E D2 53 38 1E F2 90 32 00 38 1E 0D 20 +B0 13 22 E8 D2 43 34 1E 5D 43 B0 13 08 A0 05 3C +D2 43 40 1E 5D 43 B0 13 08 A0 B2 D0 20 00 8C 1C +10 01 4D 4D 1D 93 19 24 2D 93 2A 24 2D 92 54 20 +82 43 18 1E B0 13 14 EA 7C 40 0B 00 4D 43 B0 13 +DA E8 7C 40 09 00 4D 43 B0 13 DA E8 6C 43 4D 43 +B0 13 24 AA 4D 43 80 00 DA E8 92 43 18 1E B0 13 +A8 D9 B2 B0 40 00 08 1E 06 20 7C 40 09 00 5D 43 +B0 13 DA E8 05 3C 7C 40 0B 00 5D 43 B0 13 DA E8 +82 93 24 1E 29 24 B2 B0 40 00 08 1E 19 20 1C 42 +20 1E B0 13 88 E9 3C 90 10 27 0D 34 0C 93 0D 34 +3C E3 1C 53 B0 13 0C AA 4D 43 B0 13 24 AA 5D 43 +B0 13 DA E8 0B 3C 3C 40 0F 27 B0 13 FA A9 06 3C +1C 42 20 1E 0C 93 EC 3B B0 13 FA A9 7C 40 46 00 +CD 0B 5E 43 80 00 7A AF 10 01 B0 13 0C AA 5D 43 +B0 13 24 AA 4D 43 B0 13 DA E8 10 01 3C B0 00 80 +0D 7D 3D E3 6E 42 7F 40 03 00 B0 13 06 B5 CB 0C +6C 43 10 01 B0 13 DA E8 7C 40 03 00 10 01 3A 14 +31 80 12 00 B0 13 50 E9 B2 B0 40 00 08 1E 12 20 +7C 40 09 00 5D 43 B0 13 DA E8 1C 42 20 1E B0 13 +88 E9 B0 13 08 AB 37 40 0C FE 38 43 39 40 0F 27 +0A 43 30 3C 7C 40 0B 00 5D 43 B0 13 DA E8 1E 42 +20 1E 3E B0 00 80 0F 7F 3F E3 81 4E 0E 00 81 4F +10 00 37 40 9C FF 38 43 39 40 A0 0F 0A 43 1A 3C +CF 07 CE 08 81 4E 00 00 81 49 02 00 81 4A 04 00 +B1 40 16 00 06 00 F1 40 46 00 08 00 00 18 F1 40 +DA E6 0A 00 CC 01 3C 50 0E 00 6D 42 7E 40 03 00 +B0 13 AE 89 92 B3 08 1E 19 20 92 B3 76 1E E0 27 +B2 B0 40 00 08 1E 06 20 1C 41 0E 00 B0 13 6C E9 +B0 13 08 AB 1C 41 0E 00 1D 42 1A 1E 1E 42 1C 1E +1F 42 1E 1E B0 13 B2 93 A2 D2 8C 1C 82 43 76 1E +31 50 12 00 37 16 10 01 3C B0 00 80 0F 7F 3F E3 +81 4C 12 00 81 4F 14 00 10 01 4D 4D 1D 93 14 24 +2D 93 34 24 2D 92 63 20 82 43 D0 1E 6C 43 4D 43 +B0 13 F0 AB 7C 40 0F 00 4D 43 B0 13 DA E8 7C 40 +1F 00 4D 43 80 00 DA E8 92 43 D0 1E 7C 40 1F 00 +5D 43 B0 13 DA E8 7C 40 0F 00 5D 43 B0 13 DA E8 +B2 B0 40 00 08 1E 08 20 7C 40 1D 00 7D 40 46 00 +5E 43 B0 13 E8 C5 07 3C 7C 40 1D 00 7D 40 43 00 +5E 43 B0 13 E8 C5 4C 43 B0 13 A6 BD B2 B0 40 00 +08 1E 04 20 B0 13 E6 EA CB 0C 02 3C 1B 42 D2 1E +0B 93 05 38 6C 43 5D 43 B0 13 F0 AB 0B 3C 3B E3 +1B 53 6C 43 4D 43 B0 13 DA E8 7C 40 03 00 5D 43 +B0 13 DA E8 3B 90 E8 03 02 38 3B 40 E7 03 CC 0B +3C B0 00 80 0D 7D 3D E3 7E 40 03 00 5F 43 B0 13 +06 B5 CD 0C 7C 40 49 00 5E 43 80 00 7A AF 10 01 +B0 13 DA E8 7C 40 03 00 4D 43 B0 13 DA E8 10 01 +5F 42 F2 1C 2F 83 03 24 1F 83 2C 24 10 01 D2 93 +18 1D 16 24 E2 93 18 1D 5D 20 CF 0C 5F 02 1E 4F +1E 1D CF 0E 8F 10 C2 4F F3 1C C2 4E F4 1C 4C 4C +3E 40 F5 1C 7F 40 03 00 B0 13 D6 AC FD 2B 10 01 +1F 42 1A 1D 0F 5C CE 0F 8E 10 C2 4E F3 1C C2 4F +F4 1C 4C 4C 3E 40 F5 1C 7F 40 03 00 B0 13 D6 AC +FD 2B 10 01 1F 42 08 1E 7F F0 C0 00 4F 5F 3E 40 +7F 00 5E F2 30 1E 4E DF C2 4E F3 1C D2 42 31 1E +F4 1C D2 42 32 1E F5 1C 1E 42 CE 1E CF 0E 8F 10 +C2 4F F6 1C C2 4E F7 1C D2 42 CC 1E F8 1C D2 42 +CB 1E F9 1C D2 42 E2 1E FA 1C D2 42 E3 1E FB 1C +1E 42 D2 1E CF 0E 8F 10 8F 11 C2 4F FC 1C C2 4E +FD 1C 1E 42 20 1E CF 0E 8F 10 8F 11 C2 4F FE 1C +C2 4E FF 1C 10 01 1E 53 CE 4C FF FF 5F 53 7F 90 +13 00 10 01 0A 14 CA 0D 6A 92 1F 24 B2 B0 40 00 +08 1E 10 20 5C 42 00 1E B0 13 72 E6 3E 40 12 14 +3F 40 1F 3F B0 13 44 B7 B0 13 50 D7 4C 4C B0 13 +A0 AD 04 3C 5C 42 00 1E B0 13 A0 AD 7C 40 47 00 +5E 43 B0 13 7A AF 5A 93 1D 24 6A 92 37 20 7C 40 +20 00 4D 43 B0 13 DA E8 7C 40 0A 00 4D 43 B0 13 +B0 AD 4D 43 B0 13 B0 AD 4D 43 B0 13 DA E8 7C 40 +0C 00 4D 43 B0 13 DA E8 7C 40 0E 00 4D 43 B0 13 +DA E8 1C 3C 7C 40 20 00 B0 13 BA AD B2 B0 40 00 +08 1E 09 20 7C 40 0B 00 B0 13 BA AD 7C 40 0C 00 +B0 13 BA AD 07 3C 7C 40 0A 00 5D 43 B0 13 B0 AD +B0 13 BA AD 7C 40 0E 00 B0 13 BA AD 0A 16 10 01 +0D 43 7E 40 03 00 5F 43 B0 13 06 B5 CD 0C 10 01 +B0 13 DA E8 7C 40 0B 00 10 01 5D 43 B0 13 DA E8 +10 01 0A 14 CA 0D 6A 92 3A 24 B2 B0 40 00 08 1E +18 20 1C 42 02 1E 1D 42 04 1E B0 13 1C E0 3E 40 +83 86 3F 40 7E 3D B0 13 44 B7 B0 13 38 D4 3D 90 +1E 00 04 28 11 20 3C 90 80 84 0E 2C B0 13 8E AE +17 3C 1C 42 02 1E 1D 42 04 1E 3D 90 1E 00 09 28 +03 20 3C 90 80 84 05 28 3C 40 3F 0D 3D 40 03 00 +ED 3F 3E 40 0A 00 0F 43 B0 13 1E D0 B0 13 8E AE +7C 40 5A 00 5E 43 B0 13 7A AF 5A 93 12 24 6A 92 +24 20 7C 40 11 00 4D 43 B0 13 DA E8 7C 40 12 00 +4D 43 B0 13 DA E8 7C 40 29 00 4D 43 B0 13 DA E8 +14 3C B2 B0 40 00 08 1E 06 20 7C 40 12 00 5D 43 +B0 13 DA E8 05 3C 7C 40 11 00 5D 43 B0 13 DA E8 +7C 40 29 00 5D 43 B0 13 DA E8 0A 16 10 01 7E 40 +06 00 7F 40 03 00 B0 13 06 B5 CD 0C 10 01 6A 14 +31 80 06 00 C6 0C 09 43 3A 40 00 1C 7F 40 03 00 +81 4F 00 00 2F 46 1F 93 06 24 0F 93 0B 20 58 46 +02 00 C7 09 10 3C 5C 46 02 00 B0 13 CA E3 C7 0C +07 93 02 20 0C 43 4D 3C 58 47 09 00 3F 40 03 00 +0F 57 81 4F 02 00 24 43 0F 42 32 C2 03 43 1E 43 +6E 9A 39 20 EA 42 00 00 02 4F 3F 40 0B 00 0F 5A +6F 4F 3F F0 3F 00 4E 48 0F 9E 2A 20 25 46 15 93 +0E 20 78 90 3F 00 06 20 3F 40 03 00 0F 57 81 4F +04 00 05 3C 3F 40 07 00 0F 5A 81 4F 04 00 1C 41 +04 00 1D 41 02 00 2E 42 B0 13 06 E6 4C 4C 05 93 +02 24 0C 93 0D 20 5F 4A 01 00 2E 41 4F 9E 08 2C +09 93 02 24 D9 43 00 00 81 4F 00 00 C9 0A 04 3C +DA 43 00 00 01 3C 02 4F 3A 50 23 00 14 83 BC 23 +CC 09 31 50 06 00 64 16 10 01 4A 14 C9 0E 4C 4C +3C 80 46 00 53 24 1C 83 4C 24 1C 83 46 24 1C 83 +41 24 1C 83 3B 24 3C 80 10 00 3C 90 09 00 55 2C +5C 06 00 18 50 4C A8 AF 06 B0 00 00 00 B0 00 00 +FC AF 00 00 F2 AF 00 00 EA AF 00 00 E6 AF 00 00 +DE AF 00 00 D6 AF 00 00 CC AF 00 00 7A 40 03 00 +78 40 22 00 2E 3C 6A 43 78 40 21 00 2A 3C 6A 43 +78 40 23 00 26 3C 6A 42 F7 3F 6A 43 78 40 25 00 +20 3C 7A 40 03 00 78 40 24 00 1B 3C 6A 42 F0 3F +7A 40 05 00 E5 3F 7A 40 06 00 E6 3F 6A 43 78 40 +1A 00 0F 3C 7A 40 03 00 FA 3F 6A 43 78 40 1C 00 +08 3C 7A 40 03 00 78 40 1B 00 03 3C 6A 42 78 40 +1A 00 C7 0D 4A 4A 06 43 CC 08 4C 56 7D 47 CE 09 +B0 13 E8 C5 16 53 1A 83 F7 23 46 16 10 01 4A 14 +21 83 C8 0D C7 0C 39 40 B9 1D CC 01 0D 43 1E 43 +B0 13 5C ED 46 43 09 98 25 24 2F 43 6F 99 22 20 +5A 49 09 00 7A 90 3E 00 1D 2C 57 93 13 24 3C 40 +03 00 0C 59 3D 40 03 00 0D 58 2E 42 B0 13 06 E6 +0C 93 10 20 4F 4A CA 01 3A 50 E0 FF 0A 5F DA 43 +00 00 08 3C C2 9A B6 1D 05 2C 4A 4A CF 01 0F 8A +DF 43 3D 00 39 50 0C 00 56 53 D5 27 CE 01 0F 43 +4C 43 CE 93 00 00 04 24 1E 53 5C 53 FA 27 09 3C +67 93 04 20 7C 50 20 00 4F 4C 03 3C 3F 40 3D 00 +4F 8C 67 93 0B 24 5E 42 B7 1D 0F 9E 12 38 5E 42 +B6 1D 0F 9E 0F 20 D2 83 B6 1D 0C 3C 5E 42 B6 1D +0E 9F 07 38 5E 42 B7 1D 0E 9F 04 34 C2 4F B7 1D +01 3C 0F 43 C8 4F 09 00 CC 0F 21 53 46 16 10 01 +0A 14 CA 0C 5C 43 B0 13 BA CE 5C 43 6D 42 80 13 +0E 1E 5C 43 5D 43 B0 13 1E 97 1A 93 02 20 5F 43 +01 3C 6F 43 C2 4F F2 1C C2 43 F3 1C C2 43 F4 1C +C2 43 F5 1C 7C 40 17 00 6D 43 B0 13 DA E8 7C 40 +18 00 6D 43 B0 13 DA E8 7C 40 19 00 6D 43 B0 13 +DA E8 3C 40 00 20 B0 13 8A CC B0 13 A4 ED 82 4A +EA 1C B2 40 10 0E EC 1C B0 13 AC B8 4C 93 06 24 +1A 93 02 20 B0 13 0E C3 B0 13 68 D9 82 43 EA 1C +B0 13 B8 DF B0 13 F8 ED 3C 40 00 20 B0 13 8A CC +C2 43 1D 02 82 43 76 1E 7C 40 17 00 6D 42 B0 13 +DA E8 7C 40 18 00 6D 42 B0 13 DA E8 7C 40 19 00 +6D 42 B0 13 DA E8 5C 43 B0 13 BA CE 5C 43 6D 42 +B0 13 1E 97 92 D3 8C 1C 0A 16 10 01 0A 14 CA 0C +5D 93 05 24 6D 92 34 20 C2 43 CA 1E 31 3C C2 93 +CA 1E 1A 20 5C 42 CB 1E B0 13 84 B2 03 20 B0 13 +64 B2 02 3C B0 13 74 B2 5C 42 CC 1E B0 13 84 B2 +03 20 B0 13 74 B2 02 3C B0 13 64 B2 B0 13 98 B2 +5D 43 B0 13 DA E8 14 3C 1C 42 CE 1E 0D 43 6E 42 +4F 43 B0 13 06 B5 CF 0C CC 0A 7D 40 46 00 7E 40 +5C 00 B0 13 A8 B2 B0 13 98 B2 4D 43 B0 13 DA E8 +0A 16 10 01 CC 0A 7D 40 48 00 7E 40 5E 00 B0 13 +A8 B2 10 01 CC 0A 7D 40 4A 00 7E 40 60 00 B0 13 +A8 B2 10 01 0D 43 6E 43 4F 43 B0 13 06 B5 CF 0C +B2 B0 40 00 08 1E 10 01 CC 0A 7D 40 1F 00 7E 40 +29 00 B0 13 60 EF 10 01 B0 13 60 EF CD 0F 5E 43 +B0 13 7A AF 10 01 1A 14 CA 0D C9 0C D2 93 78 1D +58 24 B0 13 CC E1 1D 43 6D 59 CC 09 B0 13 52 DF +49 43 4A 93 37 24 5A 93 32 20 6A 42 16 3C 7C 40 +36 00 B0 13 5A C6 7C 40 3D 00 B0 13 5A C6 7C B0 +F0 FF F9 23 7C 40 3A 00 B0 13 5A C6 4A 93 02 20 +59 43 2B 3C B0 13 7E EA 5A 83 7C 40 34 00 B0 13 +5A C6 A2 B3 30 0F FD 27 92 C3 32 0F 7C 40 35 00 +B0 13 5A C6 3C 40 19 00 B0 13 64 EA 92 B3 32 0F +D6 27 92 C3 32 0F 92 B3 30 0F FD 27 0E 3C 32 C2 +03 43 FF 3F 7C 40 35 00 B0 13 5A C6 B2 B0 00 02 +32 0F FC 27 B2 F0 FF FD 32 0F 7C 40 3B 00 B0 13 +5A C6 F2 90 03 00 78 1D 02 20 B0 13 8C EB CC 09 +03 3C 32 C2 03 43 FF 3F 19 16 10 01 B2 40 23 5A +5C 01 B0 13 6A E4 F2 40 A5 00 21 01 F2 D0 80 00 +20 01 C2 43 21 01 F2 D0 03 00 4A 02 92 C3 6C 01 +B2 D0 0C 00 6C 01 82 43 66 01 B2 40 44 00 68 01 +32 D0 40 00 82 43 60 01 B2 40 50 00 62 01 B2 40 +6E 11 64 01 32 C0 40 00 1E 14 3D 40 41 D1 0E 43 +1D 83 0E 73 FD 23 0D 93 FB 23 1D 16 00 3C B2 F0 +F0 FF 6E 01 A2 C3 02 01 A2 B3 02 01 F8 23 32 C2 +03 43 B2 40 52 2D C0 01 A2 43 C2 01 F2 40 0E 00 +D7 01 F2 F0 7F 00 03 02 F2 D0 80 00 05 02 F2 40 +11 00 CD 01 F2 40 12 00 CE 01 F2 40 13 00 CF 01 +82 43 C0 01 32 D2 B0 13 EA DF B0 13 28 EE B0 13 +9E E1 B0 13 78 E3 B0 13 DC E4 B0 13 3C EC 80 00 +86 C4 1A 14 CA 0C 5D 93 14 24 6D 92 47 20 4C 43 +4D 43 B0 13 DA E8 C2 93 E0 1E 06 20 7C 40 16 00 +6D 42 B0 13 DA E8 3A 3C 7C 40 16 00 7D 40 03 00 +F8 3F B2 B0 40 00 08 1E 10 20 5C 42 E2 1E B0 13 +FE EA CF 0C CC 0A B0 13 F6 B4 4C 4F B0 13 E0 B4 +5C 42 E2 1E B0 13 A4 E9 06 3C B0 13 F6 B4 5C 42 +E2 1E B0 13 E0 B4 CC 0A 7D 40 48 00 7E 40 5E 00 +B0 13 60 EF C9 0C 5C 42 E3 1E B0 13 E0 B4 CC 0A +7D 40 1E 00 7E 40 28 00 B0 13 60 EF 5D 43 B0 13 +DA E8 7C 40 16 00 6D 43 B0 13 DA E8 19 16 10 01 +0D 43 6E 43 4F 43 B0 13 06 B5 CD 0C CC 09 5E 43 +B0 13 7A AF 10 01 7D 40 4A 00 7E 40 60 00 B0 13 +60 EF C9 0C 10 01 4A 14 C7 0F C6 0E C9 0C CA 0D +C8 06 3C 40 E2 1C 3D 40 FC F4 3E 40 07 00 B0 13 +4A ED 48 93 4E 24 78 92 4C 2C 0A 93 1E 20 39 90 +B5 00 1B 2C 78 90 03 00 0D 2C CD 09 59 02 0D 59 +4F 48 0D 8F 3D 50 C5 F0 4E 48 3C 40 E2 1C B0 13 +4A ED 22 3C 4C 46 3C 50 DF 1C CD 09 59 02 0D 59 +3D 50 C2 F0 3E 40 03 00 F2 3F CC 09 CD 0A 3E 40 +0A 00 0F 43 B0 13 1E D0 7E 50 30 00 4F 46 CF 4E +E1 1C CC 09 CD 0A 3E 40 0A 00 0F 43 B0 13 1E D0 +C9 0C CA 0D 56 83 E9 23 3F 40 E2 1C 4D 43 08 3C +47 93 04 24 FF 40 20 00 00 00 57 83 1F 53 5D 53 +3E 40 30 00 6E 9F 05 20 4E 48 1E 83 4C 4D 0C 9E +EF 3B 3C 40 E2 1C 46 16 10 01 31 80 0E 00 CE 01 +3D 40 00 18 4F 43 1E 53 FE 4D FF FF 5F 53 7F 90 +0D 00 F9 2B F1 93 00 00 39 24 5F 41 01 00 C2 4F +16 1E 3F 90 15 00 05 38 3F 90 EC 00 02 34 C2 43 +16 1E 5F 41 02 00 47 18 0F 5F 5E 41 03 00 0E 5F +82 4E D4 1E 5F 41 04 00 47 18 0F 5F 5E 41 05 00 +0E 5F 82 4E A2 1E D2 41 06 00 12 1D D2 41 07 00 +13 1D D2 41 08 00 14 1D D2 41 09 00 15 1D F1 93 +0C 00 08 24 5F 41 0A 00 47 18 0F 5F 5E 41 0B 00 +0E 5F 01 3C 0E 43 82 4E 22 1E 16 3C E2 42 16 1E +B2 40 06 FF D4 1E B2 40 F6 FF A2 1E F2 40 79 00 +12 1D F2 40 56 00 13 1D F2 40 34 00 14 1D F2 40 +12 00 15 1D 82 43 22 1E 31 50 0E 00 10 01 0A 14 +CA 0C 1F 42 44 1E 8F 93 02 00 10 20 8F 93 00 00 +0D 20 C2 93 49 1E 0A 24 5E 42 49 1E 3E 50 64 00 +5D 42 DA 1E 0D 9E 02 34 4C 43 42 3C BF 40 00 70 +08 00 5C 42 51 1E 1D 42 4E 1E 1E 42 50 1E 3D F3 +3E F0 FF 00 3F 40 00 08 B0 13 F2 D5 1C 52 D8 1E +1F 42 44 1E 8F 4C 0A 00 1F 42 44 1E 9F 42 D8 1E +0C 00 1F 42 44 1E CF 43 14 00 1F 42 44 1E CF 43 +15 00 1F 42 44 1E 8F 93 02 00 05 20 8F 93 00 00 +02 20 EF D2 1A 00 1D 42 44 1E 1E 42 4E 1E 1F 42 +50 1E 3E F3 3F F0 FF 00 8D 4E 00 00 8D 4F 02 00 +1F 42 44 1E 9F 43 18 00 CC 0A B0 13 00 C1 5C 43 +0A 16 10 01 3A 14 07 4F 07 ED 0A 4F 5A 02 8A 10 +4A 4A 0A 93 49 24 7F D0 80 00 0B 4D 5B 02 8B 10 +4B 4B 0B 93 3F 24 7D D0 80 00 0B 5A 3B 80 7F 00 +08 43 09 43 0E 93 09 24 1A 43 5E 00 02 28 08 5C +09 6D 59 00 58 00 5A 02 F8 2B 0E 43 1A 43 5F 00 +02 28 08 5C 09 6D 59 00 58 00 5E 00 3E B0 00 10 +02 24 3E D0 00 20 4A 5A F2 23 49 93 02 34 1B 53 +03 3C 0E 6E 08 68 49 69 3E B0 00 80 07 24 08 63 +49 63 0B 63 3E B0 00 60 01 20 18 C3 1B 93 0C 38 +3B 90 FF 00 0C 34 49 59 8B 10 09 DB 57 02 59 00 +0D 49 0C 48 37 16 10 01 0C 43 0D 43 FB 3F 3D 40 +FF FE 3C 43 57 02 5D 00 F5 3F CF 0D CD 0E CE 0C +C2 93 D1 1D 06 20 B0 13 B4 EC 4C 93 02 20 2C 43 +10 01 2E 83 2C 24 1E 83 43 24 2E 83 20 24 1E 83 +3B 24 3E 80 03 00 34 24 1E 83 30 20 0E 43 8D 93 +00 00 09 20 0F 93 2A 20 1C 4D 02 00 1D 4D 04 00 +B0 13 92 ED 31 3C 1C 43 2C 9D 20 20 0F 93 1E 20 +1C 4D 02 00 1D 4D 04 00 B0 13 80 ED 25 3C 3F B0 +FE FF 14 20 CC 0F B0 13 DC E9 CE 0C 1D 3C 3F 90 +03 00 07 24 2F 93 0A 20 CC 0D B0 13 10 E1 CE 0C +13 3C CC 0D B0 13 18 D2 CE 0C 0E 3C 2E 43 0C 3C +B0 13 A0 F0 CE 0C 08 3C B0 13 A4 F0 CE 0C 04 3C +CC 0F B0 13 14 CF CE 0C CC 0E 10 01 0A 14 31 80 +06 00 B0 13 D8 ED 2E 42 CF 01 1F 53 3D 40 12 1D +1F 53 FF 4D FF FF 1E 83 FB 23 3C 40 05 00 0D 43 +CE 01 1E 53 B0 13 FA B7 D2 43 F0 1C 4A 43 B0 13 +F8 E1 0C 93 08 24 B0 13 42 B9 1A 2C F2 B0 20 00 +F0 1C F5 27 1F 3C E1 43 00 00 3C 40 03 00 3D 40 +0A 00 CE 01 B0 13 FA B7 4A 43 B0 13 94 F0 0C 93 +04 20 E2 43 F0 1C 5C 43 10 3C B0 13 42 B9 06 28 +C2 43 D1 1D E2 42 F0 1C 4C 43 07 3C F2 B0 20 00 +F0 1C EB 27 C2 43 D1 1D 4C 43 31 50 06 00 0A 16 +10 01 3C 40 E8 03 B0 13 E8 ED B2 40 2B 5A 5C 01 +CF 0A 1A 43 4A 5F 7F 90 0B 00 10 01 92 93 EA 1C +1C 24 C2 93 31 1D 0B 20 F2 B0 F0 FF F2 1C 04 20 +32 D0 D8 00 03 43 34 3C F2 40 05 00 31 1D D2 83 +31 1D 04 20 F2 F0 0F 00 F2 1C 2A 3C 3C 40 D7 03 +B0 13 8A CC F2 D2 F0 1C 23 3C 3C 40 A3 00 B0 13 +8A CC B2 B2 0A 1E 1C 24 F2 B0 20 00 01 02 18 24 +B2 C2 0A 1E B0 13 24 E3 D2 53 31 1D 5F 42 31 1D +5F 83 6F 93 0D 28 C2 43 31 1D D2 42 59 1E F3 1C +D2 42 5A 1E F4 1C D2 42 5B 1E F5 1C F2 D2 F0 1C +B2 B0 10 00 8C 1C 0A 24 5C 43 6D 43 B0 13 1E 97 +B2 F0 EF FF 8C 1C B2 40 2B 5A 5C 01 10 01 1A 14 +21 82 39 40 CB 00 3C 40 00 40 B0 13 8A CC 3C 40 +03 00 3D 40 05 00 0E 43 B0 13 FA B7 D1 43 02 00 +C1 49 03 00 CC 01 2C 53 6D 43 B0 13 2A CA 3C 40 +03 00 3D 42 0E 43 B0 13 FA B7 3C 40 0A 00 B0 13 +E8 ED CC 01 B0 13 62 D5 0C 93 18 20 C1 93 00 00 +F8 27 B0 13 16 9B 4A 43 5A 92 17 1D F2 2F 3C 40 +0A 00 B0 13 E8 ED 4C 4A B0 13 00 AC 3C 40 F2 1C +7D 40 13 00 B0 13 2A CA 5A 53 EE 3F 3C 40 03 00 +2D 42 0E 43 B0 13 FA B7 B2 40 2B 5A 5C 01 F2 B0 +20 00 F0 1C B8 27 C2 43 D1 1D 21 52 19 16 10 01 +1A 14 21 82 CA 0C F2 B0 40 00 01 02 3C 24 B0 13 +EC D3 82 4C 1E 1E B0 13 C2 CB 81 4C 00 00 81 4D +02 00 4A 93 03 20 B0 13 2C BB 27 3C 2C 41 1D 41 +02 00 B0 13 1C E0 3E 40 CD CC 3F 40 4C 3E B0 13 +44 B7 C9 0C CA 0D 1C 42 1A 1E 1D 42 1C 1E B0 13 +1C E0 3E 40 CD CC 3F 40 4C 3F B0 13 44 B7 CE 0C +CF 0D CC 09 CD 0A B0 13 DE 9E B0 13 38 D4 81 4C +00 00 81 4D 02 00 B0 13 2C BB 1E 42 1E 1E B0 13 +00 80 82 4C 20 1E 21 52 19 16 10 01 1C 41 04 00 +1D 41 06 00 82 4C 1A 1E 82 4D 1C 1E 10 01 5C 43 +B0 13 BA CE 5C 43 6D 42 80 13 0E 1E B0 13 B8 DF +B0 13 A8 D9 B0 13 14 EA 4C 43 B0 13 A6 BD 7C 40 +17 00 6D 43 B0 13 DA E8 7C 40 18 00 6D 43 B0 13 +DA E8 7C 40 19 00 6D 43 B0 13 DA E8 3C 40 00 20 +B0 13 8A CC B0 13 A4 ED B2 40 03 00 EA 1C B2 40 +10 0E EC 1C B0 13 AC B8 4C 93 02 24 B0 13 FE B9 +82 43 EA 1C B0 13 F8 ED 3C 40 00 20 B0 13 8A CC +C2 43 1D 02 82 43 76 1E 7C 40 17 00 6D 42 B0 13 +DA E8 7C 40 18 00 6D 42 B0 13 DA E8 7C 40 19 00 +6D 42 B0 13 DA E8 92 D3 8C 1C 10 01 5A 14 C6 0F +C7 0E C5 0D C9 0C 18 41 1C 00 C7 43 00 00 B0 13 +9E AE CA 0C 0A 93 02 20 2C 42 3C 3C 1F 43 2F 99 +02 24 09 43 09 3C 5C 49 02 00 B0 13 CA E3 C9 0C +09 93 02 20 2C 43 2E 3C 5E 4A 02 00 7E 80 0B 00 +C7 4E 00 00 3D 40 0E 00 0D 5A 4E 4E CC 05 B0 13 +4A ED 09 93 06 24 D9 4A 21 00 07 00 D9 4A 22 00 +08 00 06 93 07 24 3D 40 07 00 0D 5A CC 06 2E 42 +B0 13 4A ED 08 93 06 24 3F 40 07 00 5F FA 0C 00 +C8 4F 00 00 5D 4A 01 00 5C 43 B0 13 24 E2 CA 43 +00 00 0C 43 55 16 10 01 4F 43 4C 93 2D 24 5C 93 +20 24 6C 93 13 24 7C 90 03 00 2A 20 A2 D2 22 03 +A2 C2 24 03 B2 C2 22 03 B0 13 B8 F0 B0 13 06 BD +1F 42 20 03 6F F2 B2 C2 22 03 1A 3C A2 D2 24 03 +B0 13 F4 BC B0 13 06 BD A2 D2 22 03 B0 13 B8 F0 +0F 3C A2 D2 24 03 B2 C2 22 03 A2 D2 22 03 B0 13 +B8 F0 B0 13 EA BC 04 3C A2 D2 24 03 B0 13 EA BC +4C 43 4F 93 01 20 5C 43 10 01 B0 13 06 BD B0 13 +F4 BC 10 01 A2 C2 22 03 B0 13 B8 F0 B2 C2 22 03 +B0 13 B8 F0 10 01 B2 D2 22 03 B0 13 B8 F0 10 01 +1A 14 CB 0C 7B 90 BD 00 07 24 4C 43 7B 90 31 00 +40 28 7B 90 3D 00 3D 2C 0A 42 32 C2 03 43 B2 F0 +BF FF 02 0F B2 B0 10 00 02 0F FC 27 7B 90 3D 00 +26 2C 4C 43 B0 13 A2 EB C9 0C 4C 43 7D 40 29 00 +B0 13 00 DD C2 4B 11 0F A2 B2 30 0F 13 24 7B 90 +32 00 10 24 7B 90 39 00 0D 24 7B 90 38 00 0A 24 +A2 B2 30 0F FD 23 0D 14 3D 40 BF 0C 1D 83 FE 23 +0D 16 03 43 4C 43 CD 09 B0 13 00 DD 03 3C F2 40 +BD 00 11 0F 5C 42 21 0F B2 B0 40 00 02 0F FC 27 +02 4A 19 16 10 01 0A 14 21 82 CA 0C 0C 43 3D 40 +00 08 3E 40 0A 00 B0 13 F2 C8 0D 43 3E 40 07 0D +0F 43 B0 13 1E E7 3C 80 B9 65 3D 70 5E 00 3E 40 +00 08 0F 43 B0 13 28 D9 81 4C 00 00 81 4D 02 00 +1E 42 D4 1E 3E B0 00 80 0F 7F 3F E3 81 5E 00 00 +81 6F 02 00 5A 93 1A 20 1E 42 D2 1E 3E B0 00 80 +0F 7F 3F E3 1F 91 02 00 0D 38 02 20 2E 91 0A 28 +81 9F 02 00 04 38 0C 20 81 9E 00 00 09 2C 92 83 +D2 1E 06 3C 1E 53 82 4E D2 1E 02 3C A2 41 D2 1E +B2 D0 40 00 8C 1C 21 52 0A 16 10 01 4C 43 B0 13 +9A E5 0C 93 42 24 1C 83 42 20 B0 13 46 F0 4C 4C +C2 4C FA 1D B0 13 82 E7 C2 4C 00 1E B0 13 62 E7 +0D 43 82 4C 02 1E 82 4D 04 1E 5C 42 FA 1D 7C 90 +41 00 28 28 1D 42 F8 1D 0D 93 24 24 4C 4C 3C 80 +3C 00 B0 13 10 EC CF 0C 44 19 0F 10 D2 93 F6 1D +03 20 46 19 0C 10 0F 8C CD 0F 0E 43 1D 52 FC 1D +1E 62 FE 1D 3E 90 EB 0B 04 28 08 20 3D 90 01 C2 +05 2C 82 5F FC 1D 82 63 FE 1D 04 3C 82 43 FC 1D +82 43 FE 1D 92 43 F0 1D 10 01 80 00 CE D4 10 01 +3A 14 07 4F 07 ED 0A 4F 5A 02 8A 10 4A 4A 0A 93 +38 24 7F D0 80 00 0B 4D 5B 02 8B 10 4B 4B 0B 93 +2B 24 7D D0 80 00 0B 8A 3B 50 7F 00 3A 40 18 00 +08 43 09 43 0C 8E 0D 7F 03 2C 0C 5E 0D 6F 12 C3 +08 68 09 69 5C 02 0D 6D 1A 83 F4 23 49 93 03 30 +1A 53 1B 83 EF 3F 0C 7E 0D 7F 08 63 49 63 0B 63 +1B 93 0C 38 3B 90 FF 00 0C 34 49 59 8B 10 09 DB +57 02 59 00 0D 49 0C 48 37 16 10 01 0C 43 0D 43 +FB 3F 3C 40 FF FE 3D 43 57 02 5D 00 F5 3F 2A 14 +21 83 C9 0C 3F 40 0B 00 0F 59 68 4F 3A 40 3F 00 +4A F8 3C 40 07 00 0C 59 1D 42 64 1E 2E 42 B0 13 +06 E6 0C 93 2D 24 78 B0 40 00 2A 20 4A 93 10 24 +7A 90 07 00 0D 2C 4A 4A 5A 06 00 18 5F 4A 7A F6 +2C 43 0C 59 4F 13 1C 93 1B 20 D9 43 00 00 1A 3C +7A 90 3F 00 03 24 7A 90 20 00 12 28 2C 43 0C 59 +CD 01 B0 13 EA BF 4C 93 0B 24 D9 43 00 00 00 18 +C2 93 68 1E 07 24 6C 41 80 13 68 1E 4C 93 02 24 +C9 43 00 00 21 53 28 16 10 01 4A 14 C7 0D C8 0C +39 40 B9 1D 3A 40 3F 00 5A F8 09 00 26 43 2F 43 +6F 99 32 20 5A 99 09 00 2F 20 7A 90 3F 00 0B 24 +3C 40 03 00 0C 59 3D 40 05 00 0D 58 2E 42 B0 13 +06 E6 0C 93 21 20 D7 49 0B 00 00 00 57 43 7A 90 +3F 00 16 24 3F 40 0A 00 0F 58 6F 4F 7F B0 80 FF +0A 20 7F B2 0D 24 D9 98 0B 00 02 00 02 20 C9 43 +02 00 47 43 05 3C 5D 49 0A 00 CC 08 B0 13 0A C4 +B0 13 B8 EE CC 07 05 3C 39 50 0C 00 16 83 C7 23 +4C 43 46 16 10 01 4A 14 C9 0F C7 0E C6 0D CA 0C +6C 43 B0 13 FE C4 C8 0C 08 93 02 20 0C 43 36 3C +CF 07 7F 50 0B 00 C8 4F 02 00 3E 40 0B 00 0E 58 +3F 40 80 00 6F FE 4F DA CE 4F 00 00 D8 42 62 1E +0D 00 D2 53 62 1E FD 27 F8 F0 BF 00 0C 00 5F 48 +0C 00 7F F0 F8 00 4F D9 C8 4F 0C 00 F8 F0 7F 00 +0C 00 F8 C2 0C 00 FE F0 7F 00 00 00 3C 40 0E 00 +0C 58 4E 47 CD 06 B0 13 4A ED 3C 40 07 00 0C 58 +1D 42 64 1E 2E 42 B0 13 4A ED CC 08 46 16 10 01 +1F 42 44 1E CF 43 11 00 1F 42 44 1E DF 42 51 1E +13 00 1F 42 44 1E 5E 42 D8 1E 5E 8F 0C 00 CF 4E +16 00 1F 42 44 1E 5E 4F 16 00 8E 11 8F 5E 0A 00 +1F 42 44 1E DF 5F 16 00 15 00 1F 42 44 1E DF 42 +DA 1E 12 00 1F 42 44 1E FF 92 12 00 02 2C FF 42 +12 00 1F 42 44 1E 9F 42 52 1E 04 00 9F 42 54 1E +06 00 1F 42 44 1E DF 42 56 1E 0E 00 1F 42 44 1E +EF B2 1A 00 03 20 4D 43 B0 13 64 DA B0 13 60 CE +D2 C3 D6 1E 10 01 4F 14 1F 42 6E 03 2F 83 36 24 +2F 83 27 24 2F 83 03 24 2F 83 1A 24 31 3C B2 F0 +EF FF 48 03 92 C3 48 03 82 93 50 03 02 20 0F 43 +05 3C 1F 42 50 03 1F 92 50 03 FB 23 1F 52 C0 1E +82 4F 58 03 B2 D0 10 00 48 03 80 13 BC 1E 18 3C +B2 F0 EF FF 4A 03 92 C3 4A 03 B2 D0 80 00 08 1E +0F 3C B2 F0 EF FF 46 03 92 C3 46 03 B0 13 8C DC +B2 D0 10 00 46 03 B0 13 52 A8 02 3C B0 13 D8 DB +B1 C0 D0 00 14 00 4B 16 00 13 0A 14 CA 0D 4C 4C +3C 90 07 00 0E 34 3C 90 06 00 2F 24 1C 83 30 24 +1C 83 14 24 1C 83 2C 24 1C 83 27 24 1C 83 28 24 +2A 3C 3C 80 07 00 2C 93 23 28 2C 83 1E 24 1C 83 +1F 24 1C 83 1A 24 1C 83 1B 24 1D 3C 3A B0 03 00 +0E 20 CC 0A 3D 40 64 00 B0 13 FA EB 0E 93 0A 20 +CC 0A 3D 40 90 01 B0 13 FA EB 0E 93 03 24 7C 40 +1C 00 0A 3C 7C 40 1D 00 07 3C 7C 40 1E 00 04 3C +7C 40 1F 00 01 3C 4C 43 0A 16 10 01 3C 40 B5 1D +0D 43 3E 40 1C 00 B0 13 5C ED E2 43 B5 1D F2 40 +3D 00 B6 1D F2 40 20 00 B7 1D D2 43 B8 1D B0 13 +4E E5 B0 13 02 E8 B0 13 C0 E9 B0 13 D0 EF B0 13 +F2 E3 B0 13 C6 EF B0 13 E0 E0 3F 40 B9 1D CF 43 +00 00 3F 50 0C 00 CF 43 00 00 C2 93 C5 1D 15 20 +E2 43 C5 1D F2 40 03 00 C6 1D 7F 40 3F 00 C2 4F +CE 1D C2 4F CF 1D F2 43 D0 1D B0 13 82 F0 CD 0C +3C 40 C8 1D 2E 42 B0 13 4A ED 0C 43 10 01 F2 D0 +A9 00 C1 05 F2 D0 80 00 C0 05 F2 40 1E 00 C6 05 +C2 43 C7 05 D2 C3 C0 05 F2 F0 DF 00 19 02 F2 F0 +DF 00 05 02 F2 F0 DF 00 04 02 F2 D0 20 00 06 02 +F2 D0 E0 00 0A 02 A2 D3 22 03 92 D3 22 03 3C 40 +47 01 B0 13 8A CC F2 F0 DF 00 1D 02 F2 D0 20 00 +1B 02 6C 42 6D 43 B0 13 F6 CA 6C 42 7D 40 0A 00 +B0 13 F6 CA 6C 42 6D 42 B0 13 F6 CA 3C 40 A3 00 +B0 13 8A CC 6C 43 7D 40 82 00 80 00 F6 CA 1E 42 +44 1E 5F 4E 15 00 8F 11 3F 90 40 00 0B 34 3F 90 +C1 FF 14 34 FE 50 40 00 15 00 1F 42 44 1E 9F 83 +08 00 07 3C FE 80 40 00 15 00 1F 42 44 1E 9F 53 +08 00 1F 42 44 1E 5F 4F 15 00 8F 11 1E 42 44 1E +CE 5F 14 00 1E 42 44 1E 5F 4E 14 00 8F 11 3F 90 +40 00 0B 34 3F 90 C1 FF 0F 34 FE 50 40 00 14 00 +1F 42 44 1E 9F 83 0A 00 10 01 FE 80 40 00 14 00 +1F 42 44 1E 9F 53 0A 00 10 01 1A 14 31 80 22 00 +C9 0D 5A 4C 0B 00 3F 40 CF 00 5F F1 0A 00 5F D2 +66 1E 7F F0 BF 00 C1 4F 0A 00 3D 40 05 00 0D 5C +CC 01 1C 53 2E 42 B0 13 4A ED CC 01 3C 50 05 00 +1D 42 64 1E 2E 42 B0 13 4A ED 3D 40 C0 00 5D F1 +09 00 4D D9 F1 40 0B 00 00 00 C1 4A 0B 00 3F 40 +70 00 5F F1 0A 00 7F D0 0B 00 C1 4F 0A 00 7D F0 +3F 00 C1 4D 09 00 CC 01 4D 43 B0 13 B6 B2 31 50 +22 00 19 16 10 01 21 82 F2 F0 BF 00 05 02 F2 F0 +BF 00 19 02 B2 D0 0C 00 22 03 B2 D0 0C 00 24 03 +C2 43 76 1D 3C 40 CC 0C B0 13 8A CC 7C 40 06 00 +5D 43 B0 13 C6 CF C1 4C 00 00 3C 40 CC 0C B0 13 +8A CC 7C 40 07 00 4D 43 B0 13 CC C6 C1 4C 01 00 +D1 B3 01 00 12 20 C1 93 01 00 0F 24 7C 40 7F 00 +4D 43 B0 13 CC C6 C1 4C 02 00 D1 93 02 00 03 24 +C2 43 76 1D 02 3C D2 43 76 1D 21 52 10 01 2A 14 +5C 93 03 20 3F 40 00 1C 02 3C 3F 40 46 1C 2D 43 +08 43 CB 08 4E 43 79 40 03 00 CF 93 00 00 06 20 +6C 93 02 20 CC 0F 24 3C CB 0F 0C 3C 5C 93 0A 20 +5E 53 2A 42 6A 9F 06 24 5A 4F 01 00 4A 99 02 2C +C8 0F C9 0A 3F 50 23 00 1D 83 E7 23 0B 93 0C 20 +08 93 02 20 0C 43 0C 3C CB 08 5D 4B 01 00 B0 13 +24 E2 EB 43 01 00 03 3C 5E 53 CB 4E 01 00 CC 0B +28 16 10 01 3C 40 10 00 3D 40 00 0A 3E 40 0B 00 +B0 13 F2 C8 5C 06 3D 40 29 00 B0 13 FA EB 1F 42 +A2 1E 0F 5C 3F 90 69 01 03 2C 1C 42 A0 1E 03 3C +1C 42 A0 1E CF 0C 5C 06 0C 5F 5C 02 3D 40 0A 00 +B0 13 FA EB 82 4C A0 1E 3C 90 F0 00 08 28 B2 F0 +DF FF 08 1E 7C 42 4D 43 B0 13 DA E8 07 3C B2 D0 +20 00 08 1E 7C 42 5D 43 B0 13 DA E8 B2 D2 8C 1C +B2 D0 80 00 8C 1C 10 01 1A 14 CF 0E CA 0C 7A 90 +1A 00 31 28 7A 90 2A 00 2E 2C 4E 4A 5E 02 1C 4E +8E 1C 4E 4A 5E 4E E8 F5 7D 90 30 00 05 2C 7D 90 +2D 00 05 20 6B 43 08 3C 7D 90 5B 00 02 28 4B 43 +03 3C 4B 4D 5B 4B 8C F5 7A 90 21 00 11 28 C9 0B +43 18 49 59 43 19 4B 10 4B D9 7A 90 21 00 08 20 +7D 90 31 00 03 24 7D 90 4C 00 02 20 7B 40 80 00 +CD 0B B0 13 A6 CD 19 16 10 01 0A 14 CE 0C 0B 42 +32 C2 03 43 B2 F0 BF FF 02 0F B2 B0 10 00 02 0F +FC 27 7E 90 31 00 23 28 7E 90 3D 00 20 2C 4C 43 +B0 13 0A D7 CA 0C 4C 43 7D 40 29 00 B0 13 1E DF +C2 4E 11 0F A2 B2 30 0F 0D 24 7E 90 32 00 0A 24 +7E 90 38 00 07 24 A2 B2 30 0F FD 23 3C 40 F8 02 +B0 13 64 EA 4C 43 CD 0A B0 13 1E DF 02 3C C2 4E +11 0F 5C 42 21 0F 02 4B 0A 16 10 01 0A 14 CB 0D +CA 0C 4C 43 B0 13 78 BC 7C 40 22 00 B0 13 2E C7 +0C 24 CC 0A B0 13 2E C7 08 24 5C 43 B0 13 78 BC +7C 40 23 00 B0 13 2E C7 02 20 0C 43 16 3C 5B 93 +05 24 4C 43 B0 13 6A D2 4D 4C 0B 3C 5C 43 B0 13 +6A D2 4C 4C 4D 4C 8D 10 4C 43 B0 13 6A D2 4C 4C +0D DC 6C 43 B0 13 78 BC CC 0D 0A 16 10 01 B0 13 +A6 D8 7C 40 03 00 B0 13 78 BC 4C 93 10 01 7C 40 +36 00 B0 13 10 BD 4C 43 3D 40 12 F6 7E 40 27 00 +B0 13 DA D7 7C 40 2C 00 7D 40 88 00 B0 13 00 DD +7C 40 2D 00 7D 40 31 00 B0 13 00 DD 7C 40 2E 00 +7D 40 09 00 B0 13 00 DD 7C 40 36 00 B0 13 10 BD +7C 40 33 00 B0 13 10 BD 7C 40 3D 00 B0 13 10 BD +7C B0 70 00 F9 23 7C 40 36 00 B0 13 10 BD 82 43 +C4 1E B2 D0 01 02 34 0F 82 43 32 0F 10 01 7C 40 +36 00 B0 13 10 BD F2 B0 10 00 D6 1E 1F 24 7C 40 +0A 00 5D 42 98 1E B0 13 00 DD F2 90 7F 00 99 1E +03 38 7D 40 0C 00 02 3C 5D 42 99 1E 7C 40 0C 00 +B0 13 00 DD F2 B2 D6 1E 03 20 7D 40 11 00 02 3C +7D 40 15 00 7C 40 12 00 B0 13 00 DD 7C 40 34 00 +B0 13 10 BD B2 F0 FE FD 32 0F B2 F0 FE FD 32 0F +B2 D0 01 02 36 0F A2 43 C4 1E 10 01 4C 4C C2 93 +93 1E 02 20 4C 43 10 01 41 18 4C 5C 4C 4C F2 F0 +DF 00 06 02 A2 C3 22 03 5F 42 CC 05 C2 4C CE 05 +3F 40 E8 03 D2 B3 DD 05 03 20 1F 83 FB 23 18 3C +0F 93 16 24 5F 42 CC 05 C2 43 CE 05 3F 40 E8 03 +D2 B3 DD 05 03 20 1F 83 FB 23 0A 3C 0F 93 08 24 +5C 42 CC 05 A2 D3 22 03 F2 D0 20 00 06 02 10 01 +C2 43 93 1E 4C 43 10 01 0A 14 CA 0D CB 0C 7B 93 +02 24 CF 0B 02 3C 4B 43 4F 43 4E 4B 4F 4F 0F 8E +1F 53 4C 4B 3D 40 1C 00 B0 13 10 EC 1C 52 BE F6 +4A 93 09 24 8C 43 00 00 8C 43 02 00 CC 43 1A 00 +FC 40 7F 00 10 00 8C 43 18 00 FC F0 FC 00 1A 00 +8C 43 04 00 8C 43 06 00 CC 43 0E 00 CC 43 12 00 +CC 43 0F 00 CC 43 11 00 5B 53 1F 83 DA 23 0A 16 +10 01 1A 14 C9 0D 3A 40 81 00 0A 5C 82 DA B0 01 +CF 09 3F 50 10 00 82 4F 00 07 B2 40 00 02 02 07 +7E 50 10 00 C2 4E 10 07 92 43 0C 07 2C 43 B0 13 +8A CC A2 D3 00 07 C2 43 EA 1E 92 D3 00 07 3C 40 +05 00 B0 13 8A CC C2 93 EA 1E FD 27 39 D0 03 00 +82 C9 00 07 B2 F0 EF FF 00 07 82 CA B0 01 82 43 +0C 07 1C 42 E8 1E 19 16 10 01 B2 40 F4 F2 E6 1E +B2 40 72 F3 E4 1E 00 18 D2 42 FC F2 0E 1E 00 18 +D2 42 7A F3 12 1E 82 43 76 1E 82 43 08 1E 82 43 +0A 1E 82 43 8C 1C 82 43 0C 1E 92 D3 8C 1C B0 13 +CA B5 B0 13 4E E6 B0 13 DC EC B0 13 46 EB B0 13 +E4 EF B0 13 22 E8 B0 13 E8 D8 B0 13 90 EE B0 13 +A8 DD B0 13 EE EF B0 13 F8 EF B0 13 B6 ED 80 00 +74 C5 1A 14 21 82 CA 0C 3C 40 05 00 0C 5A 5D 4A +0E 00 B0 13 14 DC 0C 93 02 20 3F 42 03 3C B0 13 +7C F0 0F 43 F1 40 82 00 00 00 D1 4A 0D 00 01 00 +C1 4F 02 00 6C 43 CD 01 7E 40 03 00 7F 40 03 00 +B0 13 76 C0 C9 0C 09 93 0D 24 3C 40 03 00 0C 59 +3D 40 05 00 0D 5A 2E 42 B0 13 4A ED CC 09 4D 43 +B0 13 40 E1 21 52 19 16 10 01 2A 14 C8 0D C9 0C +5C 42 77 1D B0 13 CA E3 CA 0C B0 13 6A F0 0A 93 +24 24 CC 0A 5D 43 B0 13 28 E5 0C 93 1F 20 09 93 +1D 24 5C 4A 0A 00 5F 4A 01 00 CD 09 CE 08 B0 13 +76 C0 C9 0C 09 93 0E 24 3C 40 03 00 0C 59 3D 40 +03 00 0D 5A 2E 42 B0 13 4A ED CC 09 5D 43 B0 13 +40 E1 04 3C 3C 40 03 00 01 3C 2C 43 28 16 10 01 +0E 42 32 C2 03 43 4C 93 2C 24 4F 4C 3F 50 00 7E +B2 B0 10 00 02 0F FC 27 82 4F 10 0F B2 B0 10 00 +02 0F FC 27 F2 40 3D 00 11 0F B2 B0 10 00 02 0F +FC 27 F2 40 FE 00 11 0F B2 B0 20 00 02 0F FC 27 +C2 43 10 0F B2 B0 80 00 02 0F FC 27 5D 42 20 0F +B2 B0 10 00 02 0F FC 27 F2 40 3D 00 11 0F 4D 9C +D7 23 02 4E 10 01 4C 4C C2 93 93 1E 2E 24 41 18 +4C 5C 6C D3 F2 F0 DF 00 06 02 A2 C3 22 03 5F 42 +CC 05 C2 4C CE 05 3F 40 E8 03 D2 B3 DD 05 03 20 +1F 83 FB 23 18 3C 0F 93 16 24 5F 42 CC 05 C2 4D +CE 05 3F 40 E8 03 D2 B3 DD 05 03 20 1F 83 FB 23 +0A 3C 0F 93 08 24 5F 42 CC 05 A2 D3 22 03 F2 D0 +20 00 06 02 10 01 C2 43 93 1E 10 01 0A 14 CA 0D +6A 92 1A 24 B0 13 0C EF 4C 93 08 20 7C 40 47 00 +3D 40 2A F5 5E 43 B0 13 7A AF 0E 3C 5C 42 FA 1D +0D 43 7E 40 03 00 6F 43 B0 13 06 B5 CD 0C 7C 40 +47 00 5E 43 B0 13 7A AF B0 13 0C EF 4C 93 0F 20 +5A 93 08 24 6A 92 0B 20 7C 40 13 00 4D 43 B0 13 +DA E8 05 3C 7C 40 13 00 5D 43 B0 13 DA E8 0A 16 +10 01 21 82 81 43 00 00 81 43 02 00 7C 40 7F 00 +4D 43 B0 13 CC C6 81 4C 00 00 81 43 02 00 2C 41 +1F 41 02 00 47 18 0C 5C 0D 43 3C F0 00 07 0D F3 +B0 13 3A DB 81 4C 00 00 81 4D 02 00 7C 40 80 00 +5D 43 B0 13 CC C6 81 DC 00 00 12 C3 11 10 02 00 +11 10 00 00 12 C3 11 10 02 00 11 10 00 00 2C 41 +1D 41 02 00 21 52 10 01 1F 42 38 0F 1E 42 0E 0F +0E 93 14 20 0F 93 28 24 3F 90 14 00 0C 20 B2 B0 +00 02 36 0F 03 20 32 C2 03 43 FF 3F B2 F0 FF FD +32 0F 80 00 60 A7 32 C2 03 43 FF 3F 2E 93 11 20 +1F 42 0C 0F 2F 93 0A 24 2F 92 08 24 3F 90 06 00 +05 24 3F 92 03 24 32 C2 03 43 FF 3F 32 C2 03 43 +FF 3F 32 C2 03 43 FF 3F 10 01 B2 B0 30 00 40 03 +2B 24 B2 F0 EF FF 4A 03 B2 F0 7F FF 08 1E 82 93 +50 03 02 20 0F 43 05 3C 1F 42 50 03 1F 92 50 03 +FB 23 0F 5C 82 4F 5A 03 92 C3 4A 03 B2 D0 10 00 +4A 03 B0 13 3E F0 B2 40 2B 5A 5C 01 B0 13 C8 EC +4C 93 03 24 6D 43 B0 13 08 A0 32 C2 03 43 B2 B0 +80 00 08 1E EE 27 32 D2 10 01 B2 F0 FE FD 36 0F +B2 F0 FE FD 32 0F B2 F0 FE FD 32 0F 92 43 C4 1E +7C 40 32 00 B0 13 A2 EB C2 4C C6 1E 7C 43 3D 40 +4E 1E 7E 40 0A 00 B0 13 96 D7 7C 43 B0 13 A2 EB +C2 4C DA 1E 7C B0 80 FF 04 20 F2 80 80 00 DA 1E +03 3C F2 F0 7F 00 DA 1E 1F 42 C8 1E 3F 80 10 00 +82 4F D8 1E 80 00 26 DA 5D 93 10 24 6D 93 08 24 +6D 92 19 20 82 43 9C 1E 7C 42 4D 43 80 00 DA E8 +B0 13 88 CD B2 F0 7F FF 8C 1C 10 01 7C 42 5D 43 +B0 13 DA E8 92 43 9C 1E B0 13 88 CD 7C 40 29 00 +5D 43 80 00 DA E8 10 01 1C 42 A0 1E 0D 43 7E 40 +03 00 4F 43 B0 13 06 B5 CD 0C 7C 40 5D 00 5E 43 +B0 13 7A AF 10 01 5F 93 20 24 4F 93 1B 24 6F 93 +12 24 7F 90 03 00 05 24 6F 92 1C 20 B0 13 F6 CD +10 01 4E 4E 3E E3 CF 0E 6F FC 4D DF CC 4D 00 00 +CC FE 20 00 10 01 B0 13 F6 CD CC DD 00 00 CC DD +20 00 10 01 CC CE 00 00 10 01 6F 4C 4F CE 4D DF +CC 4D 00 00 10 01 4E 4E 3E E3 CC FE 00 00 CC FE +20 00 10 01 92 53 26 1E 82 63 28 1E 1F 43 5F 52 +32 1E 3F 90 3C 00 1F 20 C2 43 32 1E 1F 43 5F 52 +31 1E 3F 90 3C 00 12 20 C2 43 31 1E 1F 43 5F 52 +30 1E F2 40 03 00 2E 1E 3F 90 18 00 03 24 C2 4F +30 1E 10 01 C2 43 30 1E 80 00 08 D3 C2 4F 31 1E +E2 43 2E 1E 10 01 C2 4F 32 1E D2 43 2E 1E 10 01 +0A 14 1F 42 44 1E DF 53 13 00 B0 13 8E C3 1F 42 +44 1E 1E 4F 08 00 1E 5F 0A 00 8F 4E 0C 00 1F 42 +44 1E 9F 4F 0C 00 0A 00 1A 42 44 1E CF 0A 5C 4F +13 00 2D 4F 1E 4F 02 00 3F 40 00 08 B0 13 F2 D5 +8A 8C 0C 00 1F 42 44 1E CF 43 0F 00 1F 42 44 1E +FF F0 FC 00 1A 00 0A 16 10 01 0A 14 CA 0C 7D 40 +46 00 7E 40 5A 00 B0 13 60 EF 0D 43 4E 43 B0 13 +7A AF 5A 93 0D 24 7C 40 29 00 B0 13 0C CF 7C 40 +27 00 B0 13 0C CF 7C 40 28 00 B0 13 0C CF 0C 3C +7C 40 1F 00 B0 13 0C CF 7C 40 20 00 B0 13 0C CF +7C 40 1E 00 B0 13 0C CF 0A 16 10 01 4D 43 B0 13 +DA E8 10 01 0A 14 0A 43 2C 92 22 24 3C 90 05 00 +1C 24 3C 92 17 24 3C 90 0A 00 12 20 2F 4D 0F 93 +0A 24 1F 83 06 24 1F 83 02 24 2C 43 16 3C 6C 43 +03 3C 5C 43 01 3C 4C 43 B0 13 4A EA 0C 43 0D 3C +2A 43 0A 3C B0 13 E2 E7 07 3C B0 13 B8 E6 04 3C +B0 13 C2 E7 B0 13 E2 E5 CC 0A 0A 16 10 01 1A 14 +C9 0C 79 93 02 24 CA 09 02 3C 49 43 4A 43 4F 49 +4A 4A 0A 8F 1A 53 CC 09 B0 13 9A E5 0C 93 09 20 +4C 49 3D 40 1C 00 B0 13 10 EC 1C 52 BE F6 B0 13 +74 D1 59 53 1A 83 EF 23 E2 B3 D6 1E 0A 24 B0 13 +A8 EF 4C 93 06 20 D2 C3 D6 1E B0 13 C8 ED B0 13 +5E F0 19 16 10 01 0A 14 21 83 CA 0D CB 0C 4C 43 +B0 13 78 BC 7C 40 22 00 B0 13 02 D0 0E 24 CC 0B +B0 13 02 D0 0A 24 CC 0A B0 13 10 D0 C1 4C 00 00 +6C 43 B0 13 78 BC 5C 43 01 3C 4C 43 21 53 0A 16 +10 01 B0 13 10 D0 C1 4C 04 00 C1 93 04 00 10 01 +B0 13 A6 D8 7C 40 03 00 B0 13 78 BC 10 01 0A 14 +09 14 09 43 0A 43 1B 43 0F 93 04 24 09 4D 0D 4C +0C 43 0D 3C 5C 02 0D 6D 09 69 09 8E 04 28 1C D3 +5B 02 F8 2B 03 3C 09 5E 5B 02 F4 2B 1B 43 5C 02 +0D 6D 09 69 0A 6A 09 8E 0A 7F 04 28 1C D3 5B 02 +F6 2B 04 3C 09 5E 0A 6F 5B 02 F1 2B 0E 49 0F 4A +09 16 0A 16 10 01 0A 14 7C 40 23 00 B0 13 A2 EB +CA 0C 7A D0 20 00 CD 0A 7C 40 23 00 B0 13 00 DD +7C 40 C4 00 B0 13 90 CA 7C 40 33 00 B0 13 10 BD +7C 40 3D 00 B0 13 10 BD 7C B0 70 00 F9 23 3D 40 +DF 00 4D FA 7C 40 23 00 B0 13 00 DD 7C 40 36 00 +B0 13 10 BD 82 43 C4 1E 0A 16 10 01 0A 14 CA 0D +6A 92 17 24 1C 42 FC 1D 1D 42 FE 1D 3E 40 E8 03 +0F 43 B0 13 1E D0 7E 40 06 00 7F 40 05 00 B0 13 +06 B5 CD 0C 7C 40 5A 00 5E 43 B0 13 7A AF 5A 93 +08 24 6A 92 0B 20 7C 40 10 00 4D 43 B0 13 DA E8 +05 3C 7C 40 10 00 5D 43 B0 13 DA E8 0A 16 10 01 +B2 B0 20 00 08 1E 25 20 B0 13 0C EF 4C 93 21 20 +B0 13 24 EF 4C 93 1D 20 D2 53 89 1E E2 93 89 1E +18 20 4C 43 4D 43 B0 13 DA E8 5C 43 B0 13 BA CE +7C 40 5A 00 3D 40 0A F5 5E 43 B0 13 7A AF 7C 40 +46 00 3D 40 40 F5 5E 43 B0 13 7A AF 3F 40 00 10 +C0 0F 10 01 AC 43 18 00 FC F0 FC 00 1A 00 CC 43 +12 00 5F 42 4A 1E C2 93 4B 1E 06 24 5E 42 4A 1E +12 C3 4E 10 4E 11 4F 8E CC 4F 13 00 E2 B3 D6 1E +11 20 F2 D0 06 00 D6 1E B0 13 AC EE 82 4C 42 1E +C2 93 4B 1E 04 20 B2 50 E0 7F 42 1E 10 01 B2 50 +C0 53 42 1E 10 01 2A 14 1A 41 10 00 49 4C 1B 42 +44 1E 1B 4B 0C 00 0B 89 3B 80 32 00 28 4D C9 0B +09 88 09 93 02 38 28 9E 15 20 8D 4B 00 00 1D 42 +44 1E 4C 4C 1C 5D 0C 00 3C 50 10 00 8E 4C 00 00 +1E 42 44 1E DF 4E 0F 00 00 00 1F 42 44 1E DA 4F +10 00 00 00 28 16 10 01 1A 14 CA 0C 5C 4A 05 00 +CF 0C 3F 80 03 00 06 24 2F 83 2F 93 03 28 7F 40 +03 00 01 3C 5F 43 4C 4C 1D 4A 02 00 5E 4A 04 00 +B0 13 76 C0 C9 0C 09 93 0C 24 3C 40 03 00 0C 59 +2D 4A 2E 42 B0 13 4A ED CC 09 5D 43 B0 13 40 E1 +02 3C 3C 40 03 00 19 16 10 01 A2 D2 22 03 A2 C2 +24 03 3E 42 4F 43 B2 C2 22 03 B0 13 AE D2 4F 5F +A2 B2 20 03 01 24 5F D3 1E 83 F5 23 A2 D2 24 03 +B2 C2 22 03 5C 93 03 24 A2 D2 22 03 02 3C A2 C2 +22 03 B0 13 AE D2 B2 C2 22 03 CC 0F 10 01 B0 13 +B8 F0 B2 D2 22 03 B0 13 B8 F0 10 01 D2 B3 D6 1E +1D 24 A2 93 46 1E 1A 24 1F 42 44 1E 2C 4F 1D 4F +02 00 0D 93 08 20 0C 93 06 20 82 93 46 1E 0E 20 +92 43 46 1E 0F 3C 1E 42 4E 1E 1F 42 50 1E 3E F3 +3F F0 FF 00 0F 9D 02 20 0E 9C 02 24 4C 43 10 01 +A2 43 46 1E 5C 43 10 01 2A 14 19 43 59 52 CB 1E +18 42 CE 1E 5A 42 CC 1E 4C 4A CD 08 B0 13 0A C2 +4C 4C 0C 99 11 34 5A 53 3A 90 0D 00 05 34 C2 4A +CC 1E D2 43 CB 1E 0A 3C D2 43 CB 1E D2 43 CC 1E +18 53 82 48 CE 1E 02 3C C2 49 CB 1E 92 D3 8C 1C +28 16 10 01 F2 B0 10 00 01 02 10 20 D2 B3 01 02 +06 24 C2 93 7F 1E 19 20 B2 D2 76 1E 0C 3C 82 43 +7C 1E F2 40 0A 00 7F 1E 80 00 88 F0 C2 93 7F 1E +0C 20 A2 D2 76 1E 92 53 7C 1E 92 42 26 1E 2A 1E +92 42 28 1E 2C 1E 80 00 8E F0 D2 83 7F 1E 10 01 +2A 14 4A 4C 4C 4A B0 13 58 EE 4C 93 02 20 7A E3 +5A 53 3A B0 00 80 0B 7B 3B E3 38 40 96 F6 09 43 +0F 43 1C 43 0D 43 CE 0F B0 13 08 EE 0C FA 0D FB +CE 0F B0 13 18 EE 3D 48 B0 13 10 EC 09 5C 1F 53 +3F 90 07 00 EE 3B CC 09 28 16 10 01 21 83 81 43 +00 00 7C 40 81 00 5D 43 B0 13 CC C6 81 4C 00 00 +B1 B0 00 20 00 00 02 20 4E 43 08 3C B1 D0 00 C0 +00 00 B1 E3 00 00 91 53 00 00 5E 43 2C 41 5C 03 +CF 0C 4E 93 04 24 3C 40 AC 0A 0C 8F 03 3C 3C 40 +AC 0A 0C 5F 21 53 10 01 0B 4D 0E 4B 0D 93 1F 30 +3B F0 80 7F 1C 24 5B 02 8B 10 7E D0 80 00 3B 80 +7F 00 15 30 3B 90 20 00 0F 34 3B 80 17 00 05 30 +1B 83 08 30 5C 02 0E 6E FB 3F 5E 01 5C 00 1B 53 +01 24 FB 3F 0D 4E 10 01 3C 43 3D 43 10 01 0C 43 +0D 43 10 01 0B 4D 0B EF 0A 30 0D 93 12 30 0D 9F +02 24 19 34 16 3C 0C 9E 18 24 13 28 14 3C 3D B0 +80 7F 04 20 3F B0 80 7F 01 20 0F 24 0D 9F 0B 34 +08 3C 0F 9D 02 24 07 34 04 3C 0E 9C EC 27 01 28 +02 3C 3C 43 10 01 1C 43 10 01 0C 43 10 01 82 43 +EE 1D 4C 43 B0 13 58 F0 B0 13 F8 ED C2 43 FA 1D +C2 43 00 1E 82 43 02 1E 82 43 04 1E 92 D3 8C 1C +7C 40 13 00 6D 42 B0 13 DA E8 7C 40 17 00 6D 42 +B0 13 DA E8 7C 40 18 00 6D 42 B0 13 DA E8 7C 40 +19 00 6D 42 80 00 DA E8 E2 93 AA 1E 13 24 B0 13 +50 EC C2 93 AA 1E 1C 24 82 43 90 03 B2 D0 10 00 +80 03 F2 D0 80 00 0B 02 E2 43 AA 1E 92 42 A8 1E +C0 1E 10 01 B2 F0 CF FF 80 03 F2 F0 7F 00 03 02 +F2 F0 7F 00 0B 02 D2 43 AA 1E 92 42 A6 1E C0 1E +10 01 1A 14 31 80 06 00 C9 0C 5A 42 77 1D CC 0A +B0 13 CA E3 0C 93 02 20 2C 43 13 3C 4D 43 B0 13 +28 E5 0C 93 0E 20 91 43 02 00 C1 4A 04 00 81 43 +00 00 CC 01 2C 53 3D 40 F2 1C CE 09 0F 43 B0 13 +DC BB 31 50 06 00 19 16 10 01 C2 93 A4 1E 20 20 +C2 4C A4 1E B2 40 8F 02 A6 1E 82 4D A8 1E B2 40 +14 01 80 03 B2 40 05 00 92 03 B2 40 80 00 82 03 +F2 D0 80 00 0B 02 00 18 F2 40 18 D5 BC 1E 3C 40 +8F 02 B0 13 D0 E2 92 42 A8 1E C0 1E E2 43 AA 1E +10 01 1A 14 CA 0D CB 0C CC 0A CD 0E B0 13 78 DB +4D 4C CC 0A 49 4B 5C E9 F0 F3 47 18 0C 5C 4B ED +5B 4B F0 F3 0B 5C 4A 4A 47 18 0A 5A CC 0E 4C DD +0C 5A 0C EB 0F 9C 06 2C 3E 40 FF 7F 0C FE 5E 03 +0F 9C FC 2B 19 16 10 01 F2 40 A5 00 21 01 4E 4C +4F 4E 8F 10 0E 5F 3E 50 00 44 82 4E 24 01 4F 4C +3F 50 00 44 82 4F 26 01 92 B3 2C 01 FD 27 C2 4C +20 01 B2 F0 F9 FF 2C 01 A2 B3 2C 01 03 24 A2 B2 +2C 01 FD 27 82 4E 26 01 C2 43 21 01 10 01 1A 14 +3F 40 D2 F6 9F 00 FF FF 12 24 3D 40 D2 F6 0C 3C +4F 13 2A 52 12 3C 3C 4D CA 0D CE 09 B0 13 4A ED +0A 59 CD 0A 1D 53 1D C3 39 4D 09 93 F4 23 3F 40 +FF FF 3F 93 05 24 3A 40 FF FF 0F 0A DF 03 E8 23 +19 16 10 01 1A 14 21 83 CB 0F CA 0D C9 0C 5E 41 +0E 00 B2 B0 40 00 08 1E 10 20 4C 4A B0 13 FE EA +C1 4E 00 00 4C 4C CD 0C 0E 43 CC 09 CF 0B B0 13 +DA E6 4C 4A B0 13 A4 E9 05 3C C1 4E 00 00 0E 43 +B0 13 DA E6 21 53 19 16 10 01 7C 90 3C 00 06 28 +7C 90 3E 00 03 24 32 C2 03 43 FF 3F 0F 42 32 C2 +03 43 B2 B0 10 00 02 0F FC 27 7C 90 2F 00 08 28 +7C 90 3E 00 05 24 7C D0 C0 00 C2 4C 13 0F 04 3C +7C D0 80 00 C2 4C 13 0F 5C 42 22 0F 02 4F 10 01 +0B 4D 0E 4B 3B F0 80 7F 1C 24 5B 02 8B 10 7E D0 +80 00 3B 80 7F 00 15 30 3B 90 10 00 10 34 5E 01 +5C 00 1E 93 01 24 FB 3F 1B 83 03 30 5C 02 0E 6E +FB 3F 0D 93 02 34 3E E3 1E 53 0C 4E 10 01 3C 43 +10 01 0C 43 10 01 0A 14 CB 0D 0A 42 32 C2 03 43 +B2 B0 10 00 02 0F FC 27 7C D0 C0 00 C2 4C 13 0F +4F 4E 1F 83 0A 24 B2 B0 80 00 02 0F FC 27 1D 53 +DD 42 22 0F FF FF 1F 83 F6 23 4D 4E 0D 5B DD 42 +20 0F FF FF 02 4A 0A 16 10 01 0B 42 32 C2 03 43 +B2 B0 10 00 02 0F FC 27 4C 4C 47 18 0C 5C 3C D0 +00 40 6F 4D 0F 5C 82 4F 10 0F 6E 93 0C 28 1D 53 +4E 4E 1E 83 E2 4D 10 0F B2 B0 20 00 02 0F FC 27 +1D 53 1E 83 F7 23 5F 42 20 0F 02 4B 10 01 92 B3 +0A 1E 03 24 5C 43 B0 13 A6 BD A2 B2 0A 1E 03 24 +5C 43 B0 13 A0 BA B2 B2 0A 1E 02 24 B0 13 E8 EE +A2 B3 0A 1E 02 24 B0 13 74 C5 B2 B0 10 00 0A 1E +05 24 6C 43 3D 40 99 19 B0 13 AA D5 82 43 0A 1E +10 01 1A 14 C9 0C 3D 40 0C 00 0D 59 6E 49 7E 80 +0B 00 5C 43 7F 40 03 00 B0 13 76 C0 CA 0C 0A 93 +10 24 3C 40 03 00 0C 5A 3D 40 05 00 0D 59 2E 42 +B0 13 4A ED FA D0 80 00 0E 00 CC 0A 4D 43 B0 13 +40 E1 19 16 10 01 A2 D2 24 03 7F 40 80 00 3E 42 +B2 C2 22 03 CD 0C 4D FF 4D 9F 03 24 A2 C2 22 03 +02 3C A2 D2 22 03 12 C3 4F 10 B0 13 B8 F0 B2 D2 +22 03 B0 13 B8 F0 1E 83 EB 23 B2 C2 22 03 A2 D2 +22 03 A2 C2 24 03 10 01 82 43 18 1E 82 43 24 1E +82 43 20 1E C2 93 76 1D 16 24 B0 13 02 E5 B0 13 +A8 D9 B0 13 14 EA 1C 42 22 1E 0C 93 0C 24 1C 52 +20 1E 82 4C 20 1E 1D 42 1A 1E 1E 42 1C 1E 1F 42 +1E 1E 80 00 B2 93 10 01 0A 14 0A 43 0F 93 05 34 +3E E3 3F E3 1E 53 0F 63 1A D3 0D 93 05 34 3C E3 +3D E3 1C 53 0D 63 3A E3 B0 13 1E D0 1A B3 04 24 +3C E3 3D E3 1C 53 0D 63 2A B3 04 24 3E E3 3F E3 +1E 53 0F 63 0A 16 10 01 B0 13 5C B9 F2 B2 F0 1C +14 24 3C 40 03 00 3D 40 05 00 0E 43 B0 13 FA B7 +3C 40 F2 1C 6D 42 B0 13 2A CA 3C 40 03 00 2D 42 +0E 43 B0 13 FA B7 F2 C2 F0 1C F2 B0 20 00 F0 1C +E3 27 C2 43 D1 1D 10 01 C2 93 76 1D 15 24 82 93 +24 1E 19 20 F2 F0 BF 00 1D 02 F2 D0 40 00 1B 02 +B0 13 54 EF B2 40 10 0E 24 1E F2 B0 40 00 01 02 +FC 27 4C 43 80 00 A0 BA 7C 40 47 00 3D 40 F0 F4 +5E 43 80 00 7A AF 10 01 0A 14 CA 0D CB 0E 4C 4C +3D 40 1C 00 B0 13 10 EC 1F 42 BE F6 0F 5C 8F 93 +18 00 0F 20 8F 4A 00 00 8F 4B 02 00 0B 93 06 20 +0A 93 04 20 1C 52 BE F6 EC C2 1A 00 FF 40 7F 00 +10 00 0A 16 10 01 0A 14 5A 42 57 1E 3C 40 4E 1E +B0 13 82 DE 4C 4C 0C EA 47 18 0C 5C 8C 10 4C 4C +CA 0C C2 4A 57 1E 3A 90 21 00 05 20 D2 D3 D6 1E +B0 13 5E F0 05 3C F2 F0 EF 00 D6 1E B0 13 AE C7 +0A 16 10 01 4C 93 1C 20 4C 43 B0 13 9A E5 0C 93 +04 24 1C 83 09 24 1C 83 13 20 C2 43 DC 1E C2 43 +DD 1E 82 43 DE 1E 10 01 1F 42 BE F6 D2 4F 0E 00 +DC 1E 1E 4F 06 00 92 4F 04 00 DE 1E C2 4E DD 1E +10 01 1A 14 C2 93 A2 1D 16 24 3C 40 7A 1D 29 42 +3A 40 C2 F6 3B 40 A4 1D 4E 43 4F 43 7D 4C 7D 9B +01 20 5E 53 7D 9A 01 20 5F 53 19 83 F7 23 6F 92 +02 24 6E 92 02 20 4C 43 01 3C 5C 43 19 16 10 01 +D2 B3 D6 1E 14 24 1D 42 4E 1E 1E 42 50 1E 3D F3 +3E F0 FF 00 1F 42 44 1E 1E 9F 02 00 08 20 2D 9F +06 20 DF 92 51 1E 13 00 04 24 D2 C3 D6 1E 4C 43 +10 01 EF C2 1A 00 B0 13 00 C1 5C 43 10 01 5C 02 +0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 +0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 +0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 +0D 6D 5C 02 0D 6D 5C 02 0D 6D 10 01 5D 03 5C 00 +5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 +5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 +5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 +5D 03 5C 00 5D 03 5C 00 10 01 0A 14 3F 40 B9 1D +2E 43 0C 43 2D 43 6D 9F 05 20 3F 50 0C 00 1C 53 +1E 83 F8 23 6C 93 02 20 0C 43 0C 3C 4C 4C 3D 40 +0C 00 B0 13 10 EC 3A 40 B9 1D 0A 5C CC 0A B0 13 +70 DD CC 0A 0A 16 10 01 92 C3 44 03 82 93 9A 1E +0E 24 B0 13 9A 82 92 93 9A 1E 03 24 B0 13 86 DF +02 3C B0 13 AE C7 1C 42 94 1E 80 00 BC E8 F2 C2 +D6 1E B0 13 AE C7 1C 42 96 1E B0 13 BC E8 92 43 +9A 1E 10 01 3A 14 C8 0D C7 0C 3A 40 B9 1D 29 43 +2F 43 6F 9A 0E 20 3D 40 03 00 0D 5A CC 07 2E 42 +B0 13 06 E6 0C 93 05 20 58 9A 0A 00 02 20 CC 0A +05 3C 3A 50 0C 00 19 83 EB 23 0C 43 37 16 10 01 +3A 14 C8 0D C7 0C 3A 40 B9 1D 49 43 2F 43 6F 9A +0E 20 3C 40 03 00 0C 5A CD 07 2E 42 B0 13 06 E6 +0C 93 05 20 CA 98 0A 00 02 20 CC 0A 05 3C 3A 50 +0C 00 59 53 EB 27 0C 43 37 16 10 01 C2 93 40 1E +14 20 3F 40 47 01 1F 52 56 03 C2 93 36 1E 08 20 +C2 93 37 1E 0E 24 3F 80 03 00 C2 43 37 1E 09 3C +3F 80 05 00 C2 43 36 1E F8 3F 3F 40 00 80 1F 52 +56 03 82 4F 56 03 10 01 82 43 4C 1E B0 13 64 F0 +F2 40 21 00 48 1E F2 40 06 00 4A 1E C2 43 49 1E +D2 43 4B 1E 7C 43 5D 43 B0 13 88 C8 B0 13 3E C7 +B0 13 76 D0 7C 40 0C 00 5D 42 16 1E 80 00 00 DD +21 83 0F 42 32 C2 03 43 B2 B0 10 00 02 0F FC 27 +4C 4C 47 18 0C 5C 3C D0 00 40 4D 4D 0C 5D 82 4C +10 0F B2 B0 20 00 02 0F FC 27 5E 42 20 0F 81 4E +00 00 02 4F 21 53 10 01 5F 14 1A 42 38 0F 4A 4A +B0 13 24 EF 4C 93 10 20 7A 90 14 00 04 24 4A 93 +0D 20 03 43 0B 3C 1F 42 EE 1D 1F 93 02 24 2F 93 +05 20 B0 13 02 ED 02 3C B0 13 28 CC 5A 16 00 13 +21 83 CC 43 0A 00 EC 43 00 00 DC 42 B8 1D 0B 00 +D2 53 B8 1D 02 3C D2 53 B8 1D C2 93 B8 1D FB 27 +F2 93 B8 1D F8 27 5C 42 B8 1D CD 01 B0 13 A2 E3 +4C 93 F1 23 21 53 10 01 82 43 EE 1D 82 43 F2 1D +82 43 F4 1D 82 43 F0 1D C2 43 FA 1D C2 43 00 1E +82 43 02 1E 82 43 04 1E 82 43 FC 1D 82 43 FE 1D +C2 43 F6 1D B2 40 4B 00 F8 1D C2 43 06 1E 10 01 +B0 13 7C B3 B0 13 5A C9 B0 13 7C 87 B0 13 00 EF +82 93 76 1E 03 20 82 93 08 1E 02 24 B0 13 4C A2 +82 93 0A 1E 02 24 B0 13 1E D8 82 93 8C 1C EE 27 +B0 13 60 9C EB 3F 0A 14 CA 0C 5D 42 EE 1E B0 13 +B0 E0 4C 93 0E 24 B0 13 6E ED CD 0C 1C 43 0C 5A +2E 42 B0 13 06 E6 0C 93 02 20 0C 43 05 3C 2C 43 +03 3C B0 13 B8 EE 1C 43 0A 16 10 01 0E 4C 0D 4C +0D 93 16 24 03 34 3D E3 1D 53 0F 30 3B 40 8F 00 +1B 83 5D 02 FD 2B 4C 4D 8C 10 8D 10 4D 4D 8B 10 +0D DB 5E 02 5D 00 5C 00 10 01 3D 40 00 C7 0C 43 +10 01 0A 14 3A 40 09 00 0F 43 6D 4C 3B 42 4E 4D +0E EF 3E 90 80 00 04 38 4F 5F 7F E0 97 00 01 3C +4F 5F 4F 4F 4D 5D 1B 83 F2 23 1C 53 1A 83 ED 23 +CC 0F 0A 16 10 01 1D 42 9E 1D 0F 42 32 C2 03 43 +D2 43 9C 1D 02 4F 0D 93 07 24 B0 13 9E E8 C2 93 +9B 1D 02 20 1D 83 F9 23 0F 42 32 C2 03 43 C2 43 +9B 1D C2 43 9C 1D 02 4F 10 01 B0 13 16 F0 1F 42 +44 1E FF 90 7F 00 10 00 0A 24 2C 93 05 34 3C 93 +0D 34 DF 83 10 00 10 01 DF 53 10 00 10 01 CF 4C +10 00 1F 42 44 1E FF 50 0C 00 10 00 10 01 7C 90 +2F 00 06 28 7C 90 3E 00 03 24 32 C2 03 43 FF 3F +0F 42 32 C2 03 43 B2 B0 10 00 02 0F FC 27 C2 4C +11 0F B2 B0 20 00 02 0F FC 27 C2 4D 10 0F 02 4F +10 01 4D 93 03 20 32 C2 03 43 FF 3F 0F 42 32 C2 +03 43 B2 B0 10 00 02 0F FC 27 F2 40 7F 00 11 0F +4D 4D B2 B0 20 00 02 0F FC 27 F2 4C 10 0F 1D 83 +F8 23 02 4F 10 01 B2 F0 FE FD 36 0F B2 F0 FE FD +32 0F 7C 40 36 00 B0 13 10 BD 7C 40 3A 00 B0 13 +10 BD 7C 40 36 00 B0 13 10 BD 7C 40 32 00 B0 13 +10 BD 82 43 C4 1E 10 01 F2 F0 DF 00 1B 02 92 C3 +22 03 F2 F0 DF 00 03 02 F2 F0 1F 00 02 02 F2 F0 +1F 00 0A 02 A2 C3 22 03 F2 D0 20 00 05 02 F2 D0 +E0 00 04 02 A2 D3 24 03 10 01 21 83 7C 40 30 00 +B0 13 10 BD 81 43 00 00 02 3C 91 53 00 00 B1 90 +64 00 00 00 FA 2B 7C 40 36 00 B0 13 10 BD 7C B0 +70 00 F9 23 82 43 06 0F 21 53 10 01 0C 93 02 20 +0D 93 14 24 3B 40 9F 00 1B 83 5C 02 0D 6D FC 2B +12 C3 5D 00 5C 00 3E 40 06 00 5D 01 5C 00 1E 83 +FC 37 8B 10 0D DB 12 C3 5D 00 5C 00 10 01 A2 B2 +76 1E 15 24 5F 42 E0 1E 4F 93 0A 24 5F 93 0F 20 +C2 43 E0 1E 92 D3 0C 1E B2 D0 80 00 0C 1E 10 01 +D2 43 E0 1E 92 D3 0C 1E B2 D0 40 00 0C 1E 10 01 +4D 93 03 20 32 C2 03 43 FF 3F 0F 42 32 C2 03 43 +4D 4D B2 B0 10 00 02 0F FC 27 F2 40 BF 00 13 0F +1C 53 DC 42 22 0F FF FF 1D 83 F3 23 02 4F 10 01 +CF 0C FF B0 80 FF 0C 00 02 20 6C 43 10 01 CF 9D +0D 00 0C 20 B0 13 6E ED CD 0C 1C 43 0C 5F 2E 42 +B0 13 06 E6 0C 93 02 20 4C 43 10 01 5C 43 10 01 +82 93 6E 1E 09 20 82 93 6C 1E 06 20 B2 40 04 03 +6C 1E B2 40 02 01 6E 1E B0 13 76 EB C2 4C 75 1E +4C 93 FA 27 3C 40 72 1E 0D 43 1E 43 80 00 5C ED +31 80 06 00 81 43 02 00 D1 4C 05 00 04 00 CF 0C +3F 50 06 00 81 4F 00 00 1D 4C 02 00 2E 42 0E 5C +2F 4C CC 01 2C 53 B0 13 DC BB 31 50 06 00 10 01 +0A 14 CA 0C 3F 40 CF 00 5F FA 0C 00 5F D2 66 1E +CA 4F 0C 00 2C 43 0C 5A B0 13 B6 B2 4C 93 02 20 +0C 43 02 3C 3C 40 09 00 CA 43 00 00 0A 16 10 01 +7C 90 80 00 09 28 4C 4C 3C 80 00 01 2D 43 B0 13 +50 E2 3C 80 4A 00 04 3C 4C 4C 5C 03 3C 80 4A 00 +3C 90 80 FF 02 34 3C 40 80 FF 8C 11 10 01 92 C3 +22 03 F2 F0 DF 00 03 02 F2 F0 1F 00 02 02 A2 C3 +22 03 F2 D0 20 00 05 02 F2 D0 E0 00 04 02 A2 D3 +24 03 92 D3 24 03 D2 43 93 1E 10 01 B2 F0 FF FD +36 0F 7C 40 36 00 B0 13 5A C6 7C 40 3D 00 B0 13 +5A C6 7C B0 F0 FF F9 23 7C 40 3A 00 B0 13 5A C6 +B2 F0 FF FD 32 0F 10 01 C2 93 D1 1D 0E 20 B0 13 +8A 95 B0 13 8C C2 0C 93 0C 20 B0 13 B8 E6 B0 13 +6E ED B0 13 BE E5 B0 13 62 E8 D2 43 D1 1D 80 00 +6A A6 10 01 5C 93 13 20 0C 42 32 C2 03 43 2E 43 +3F 40 00 1C CF 93 00 00 05 24 5D 9F 01 00 02 2C +DF 83 01 00 3F 50 23 00 1E 83 F4 23 02 4C 10 01 +0B 43 0D 93 03 34 3D E3 1D 53 1B D3 0C 93 03 34 +3C E3 1C 53 3B E3 B0 13 FA EB 1B B3 02 24 3C E3 +1C 53 2B B3 02 24 3E E3 1E 53 10 01 4C 4C 3D 40 +1C 00 B0 13 10 EC CF 0C 1F 52 BE F6 EF B2 1A 00 +03 24 0F 43 0D 43 05 3C 1C 52 BE F6 2F 4C 1D 4C +02 00 CC 0F 10 01 C2 93 4A 1E 09 24 1F 42 44 1E +DF 83 13 00 1F 42 44 1E CF 93 13 00 02 24 5C 43 +10 01 8F 43 18 00 5D 43 B0 13 64 DA 4C 43 10 01 +82 4C C0 1E 82 93 50 03 02 20 0F 43 05 3C 1F 42 +50 03 1F 92 50 03 FB 23 0F 5C 82 4F 58 03 92 C3 +48 03 B2 D0 10 00 48 03 10 01 31 40 FC 2B 00 18 +F2 40 BC F0 AC 1E 00 18 F2 40 BC F0 B0 1E B0 13 +98 F0 0C 93 02 24 B0 13 7E D6 0C 43 B0 13 E0 DD +B0 13 9C F0 92 B3 22 03 11 24 7C 40 06 00 B0 13 +1C C8 C2 4C 59 1E 7C 40 07 00 B0 13 1C C8 C2 4C +5A 1E 7C 42 B0 13 1C C8 C2 4C 5B 1E 10 01 5D 93 +12 20 C2 93 89 1E 0A 24 E2 93 89 1E 0C 2C 7C 40 +5A 00 3D 40 04 F5 5E 43 80 00 7A AF 7C 40 5A 00 +3D 40 0A F5 F8 3F 10 01 B2 D0 06 00 06 0A B2 40 +1D 7B 00 0A B2 40 ED 00 04 0A F2 D0 E0 00 4A 02 +F2 D0 E0 00 44 02 B2 43 0A 0A B2 40 FF 00 0C 0A +10 01 3F 40 B9 1D 0E 43 2B 43 6B 9F 07 20 CF 9C +0B 00 04 20 CD 4E 00 00 5C 43 10 01 3F 50 0C 00 +1E 53 2E 93 F1 3B 4C 43 10 01 21 83 CD 01 B0 13 +A2 E3 4C 93 0B 24 6C 41 3D 40 0C 00 B0 13 10 EC +EC 93 B9 1D 03 20 3C 50 B9 1D 01 3C 0C 43 21 53 +10 01 82 93 8C 1E 09 20 82 93 8A 1E 06 20 B2 40 +08 07 8A 1E B2 40 06 05 8C 1E 00 18 C2 43 8E 1E +B0 13 76 EB C2 4C 92 1E 10 01 B2 B0 20 00 08 1E +0F 20 B0 13 0C EF 4C 93 0B 20 F2 C2 03 02 F2 C2 +05 02 F2 C2 1B 02 2C 43 B0 13 20 B1 F2 D2 1B 02 +10 01 B2 B0 20 00 08 1E 0F 20 B0 13 0C EF 4C 93 +0B 20 F2 C2 03 02 F2 C2 05 02 F2 C2 1B 02 1C 43 +B0 13 20 B1 F2 D2 1B 02 10 01 3C 40 03 00 5C F2 +20 01 7C 90 03 00 03 2C 5C 53 B0 13 38 D6 6C 92 +03 28 5C 83 B0 13 90 E4 7C 90 03 00 EE 23 10 01 +F2 40 A5 00 21 01 4E 4C 4F 4E 8F 10 0E 5F 3E 50 +00 44 82 4E 26 01 92 B3 2C 01 FD 27 C2 4C 20 01 +C2 43 21 01 10 01 3F 40 13 00 6F 9C 09 24 5F 4C +0C 00 1F 83 07 24 1F 83 07 20 B0 13 C2 C9 04 3C +DC 43 0C 00 B0 13 CA 99 0C 43 10 01 F2 F0 E0 00 +05 02 F2 F0 E0 00 03 02 F2 D0 1F 00 07 02 F2 F0 +E0 00 19 02 F2 F0 E0 00 1D 02 F2 D0 1F 00 1B 02 +10 01 1A 14 39 40 11 00 3F 40 32 1D 3A 40 5C F6 +3C 4A B0 13 72 E6 2F 52 8F 4C FC FF 8F 4D FE FF +19 83 F6 23 19 16 10 01 4D 93 03 24 5F 4C 0A 00 +02 3C 5F 4C 09 00 4F 93 06 24 CC 93 00 00 03 24 +7F 90 20 00 02 2C 2C 43 10 01 0C 43 10 01 3C 40 +80 1E 0D 43 2E 42 B0 13 5C ED C2 93 88 1E 09 20 +3C 40 84 1E 3D 40 A4 F6 2E 42 B0 13 4A ED D2 43 +88 1E 10 01 B2 B0 20 00 08 1E 0E 20 B0 13 0C EF +4C 93 0A 20 F2 C2 03 02 F2 C2 05 02 F2 C2 1B 02 +B0 13 3E BB F2 D2 1B 02 10 01 4C 4C 3D 40 1C 00 +B0 13 10 EC CF 0C 1F 52 BE F6 EF B2 1A 00 02 24 +2C 43 10 01 1C 52 BE F6 1C 4C 18 00 10 01 CE 0C +6D 4E 5D 92 C2 F6 0C 24 7C 40 09 00 B0 13 1E DF +2D 42 3F 40 A4 1D 1F 53 FF 4E FF FF 1D 83 FB 23 +10 01 0A 14 0A 42 32 C2 03 43 D2 93 78 1D 08 24 +B0 13 C2 E7 7C 40 32 00 B0 13 5A C6 D2 43 78 1D +02 4A 0A 16 10 01 0E 93 02 20 0C 43 10 01 1D 83 +1C 83 1D 53 6B 4D 1C 53 6F 4C 4F 9B 02 20 1E 83 +F8 23 4B 4B 4C 4F 0C 8B 10 01 0A 14 CA 0C 5D 42 +17 1E B0 13 B0 E0 4C 93 04 20 B0 13 B8 EE 1C 43 +04 3C CC 0A B0 13 F4 EE 0C 43 0A 16 10 01 82 43 +26 1E 82 43 28 1E E2 42 30 1E F2 40 1E 00 31 1E +C2 43 32 1E C2 43 2F 1E 82 43 2A 1E 82 43 2C 1E +10 01 0D 4C 0D 93 0E 24 3B 40 8F 00 1B 83 5D 02 +FD 2B 4C 4D 8C 10 8D 10 4D 4D 8B 10 0D DB 12 C3 +5D 00 5C 00 10 01 82 43 90 03 B2 40 C0 00 92 03 +B2 D0 10 00 80 03 92 B3 82 03 FD 27 B2 F0 EF FF +80 03 92 C3 82 03 10 01 D2 93 78 1D 0D 20 7C 40 +36 00 B0 13 5A C6 7C 40 3D 00 B0 13 5A C6 7C B0 +F0 FF F9 23 E2 43 78 1D 10 01 0A 14 CB 0E CA 0C +CE 0F CC 0D CD 0B 5F 41 08 00 B0 13 06 B5 CD 0C +CC 0A 6E 43 B0 13 7A AF 0A 16 10 01 0A 14 CA 0C +5D 42 75 1E B0 13 B0 E0 4C 93 04 20 B0 13 B8 EE +1C 43 03 3C CC 0A B0 13 B6 E4 0A 16 10 01 02 12 +32 C2 03 43 82 4C D0 04 82 4D D2 04 82 4E E0 04 +82 4F E2 04 1C 42 E4 04 1D 42 E6 04 32 41 10 01 +D2 43 34 1E 92 42 50 03 56 03 B0 13 8C DC 92 C3 +46 03 B2 D0 10 00 46 03 7C 40 14 00 5D 43 80 00 +DA E8 1F 42 BE F6 BF 90 FF 00 02 00 05 28 06 20 +BF 90 00 FF 00 00 02 2C 0C 43 10 01 1C 42 DE 1E +10 01 1F 42 BE F6 BF 90 FF 00 02 00 05 28 06 20 +BF 90 00 FF 00 00 02 2C 4C 43 10 01 5C 42 DD 1E +10 01 0A 14 5C 43 B0 13 FE C4 CA 0C 0A 93 07 24 +2C 43 0C 5A B0 13 C4 EE CC 0A B0 13 5E BF 0A 16 +10 01 D2 93 78 1D 09 24 F2 90 03 00 78 1D 08 20 +B0 13 CC E1 E2 43 78 1D 10 01 32 C2 03 43 FF 3F +10 01 D2 93 78 1D 09 24 F2 90 03 00 78 1D 08 24 +F2 40 03 00 78 1D 80 00 8C EB 32 C2 03 43 FF 3F +10 01 C2 43 66 1E 00 18 C2 43 68 1E B0 13 6E ED +82 4C 64 1E B0 13 76 EB C2 4C 62 1E 4C 93 FA 27 +10 01 3C 40 38 1E 3D 40 2E F5 3E 42 B0 13 4A ED +C2 43 37 1E C2 43 36 1E C2 43 34 1E C2 43 40 1E +10 01 B2 F0 CF FF 80 03 F2 F0 7F 00 03 02 F2 F0 +7F 00 0B 02 B2 F0 EF FF 82 03 B0 13 26 F0 80 00 +E4 EF D2 92 C2 F6 A4 1D 08 24 D2 43 A2 1D 7C 40 +07 00 7D 40 07 00 80 00 1E DF 32 C2 03 43 FF 3F +B0 13 CC E1 7C 40 0A 00 5D 42 C6 F6 B0 13 1E DF +F2 90 03 00 78 1D 02 20 80 00 8C EB 10 01 3F 40 +3E 00 0E 42 32 C2 03 43 B0 13 96 E6 02 4E C2 93 +9B 1D 03 20 1F 83 3F 93 F4 23 10 01 CF 0C 82 4F +54 03 92 C3 44 03 B0 13 AC EE 2F 83 0F 8C 3F 90 +00 80 02 28 92 D3 44 03 10 01 CF 0D 7C 90 2A 00 +0A 2C 4E 4C 5D 4E E8 F5 4C 4C 5C 02 1C 4C 8E 1C +CE 0D 80 00 A6 CD 10 01 0C 9D 02 2C 80 00 4A ED +0C 5E 0D 5E 0E 93 06 24 1D 83 1C 83 EC 4D 00 00 +1E 83 FA 23 10 01 CD 0C C2 93 88 1E 02 24 4C 43 +10 01 3C 40 84 1E 2E 42 B0 13 4A ED D2 43 88 1E +5C 43 10 01 D2 93 E0 1E 0A 20 D2 92 E3 1E 31 1E +06 20 D2 92 E2 1E 30 1E 02 20 E2 43 E0 1E 10 01 +5C 43 B0 13 BA CE 6C 43 B0 13 BA CE 5C 43 6D 42 +80 13 0E 1E 6C 43 6D 42 20 00 12 1E 3C B0 00 80 +0D 7D 3D E3 3E 40 3D 00 0F 43 B0 13 1E E7 3E 40 +C8 00 0F 43 80 00 28 D9 3C B0 00 80 0D 7D 3D E3 +3E 40 52 00 0F 43 B0 13 1E E7 3E 40 19 00 0F 43 +80 00 28 D9 B0 13 74 EE 4C 93 08 20 4C 43 4D 43 +B0 13 DA E8 5C 43 5D 43 80 00 DA E8 4C 43 FB 3F +3C 40 00 1C 0D 43 3E 40 46 00 B0 13 5C ED 3C 40 +46 1C 0D 43 3E 40 46 00 80 00 5C ED 0A 14 CF 0C +CC 0D 2A 43 0F 93 05 20 B0 13 16 E9 4C 93 01 24 +0A 43 CC 0A 0A 16 10 01 21 82 CF 0C CC 0D A1 4F +00 00 91 4F 02 00 02 00 CD 01 2E 42 B0 13 F8 E8 +21 52 10 01 C2 93 76 1D 0A 24 B0 13 DA EF F2 F0 +BF 00 1B 02 F2 F0 BF 00 1D 02 82 43 24 1E 10 01 +1F 42 44 1E 5C 4F 11 00 6C 93 02 2C 3C 42 10 01 +5C 53 4C 5C 4C 5C 4C 4C 10 01 7C 90 03 00 07 2C +4C 4C 5D 4C CA F6 7C 40 3E 00 80 00 1E DF 32 C2 +03 43 FF 3F 0C 93 0A 24 5C 0F 1C 53 0F 42 32 C2 +03 43 B0 13 96 E6 02 4F 1C 83 F8 23 10 01 B0 13 +76 EB 7C F0 0F 00 5C 53 4E 4C 1C 42 A0 1D B0 13 +64 EA 1E 83 FA 23 10 01 B2 90 06 00 0E 07 08 20 +92 42 20 07 E8 1E D2 43 EA 1E B1 C0 D0 00 00 00 +00 13 B2 F0 EF FF 46 03 C2 43 34 1E 7C 40 14 00 +4D 43 B0 13 DA E8 5D 43 80 00 08 A0 6D 42 B0 13 +66 EE 4F 43 C2 93 06 1E 01 20 5F 43 C2 4F 06 1E +5D 43 80 00 66 EE 1C 42 D2 1E CF 0C 5F 0A 0C 5F +3D 40 05 00 B0 13 50 E2 3C 50 40 01 10 01 4C 93 +06 24 7C 90 0D 00 06 28 7C 80 0C 00 10 01 3F 40 +0C 00 4C 5F 10 01 3D 40 FF 00 3E 40 0C 00 3F 40 +20 0A 1F 53 CF 4D FF FF 1E 83 FB 23 10 01 5D 42 +92 1E B0 13 B0 E0 4C 93 02 24 0C 43 10 01 B0 13 +B8 EE 1C 43 10 01 F2 40 06 00 E2 1E F2 40 1E 00 +E3 1E F2 40 0A 00 E1 1E C2 43 E0 1E 10 01 D2 53 +5E 1E F2 90 03 00 5E 1E 02 28 C2 43 5E 1E 82 43 +5C 1E 80 00 24 E3 5C 42 9A 1D 3D 40 6D 00 B0 13 +10 EC 7C 50 43 00 C2 4C 9A 1D 10 01 B2 F0 FF FD +32 0F 7C 40 34 00 B0 13 5A C6 B2 D0 00 02 36 0F +10 01 0F 42 32 C2 03 43 7C D0 C0 00 C2 4C 13 0F +5C 42 22 0F 02 4F 10 01 B2 D0 10 00 08 1E 00 18 +F2 40 54 D3 BC 1E 3C 40 99 19 80 00 D0 E2 0E 93 +08 20 2D 93 06 2C 5D 06 3D 50 AE F6 6E 43 80 00 +7A AF 10 01 0E 93 08 20 2D 93 06 2C 5D 06 3D 50 +B6 F6 6E 43 80 00 7A AF 10 01 0E 43 0F 4C 1C 43 +5F 02 0E 6E 0E 9D 01 28 0E 8D 0C 6C F9 2B 10 01 +02 12 32 C2 03 43 82 4C C0 04 82 4D C8 04 1C 42 +CA 04 32 41 10 01 B2 B2 76 1E 07 24 C2 93 34 1E +02 20 80 00 40 E7 80 00 B2 EA 10 01 B2 40 FF 7F +52 03 B2 D0 10 00 42 03 B2 D0 24 01 40 03 10 01 +5F 42 A4 1E 5F 83 D2 83 A4 1E 0F 93 02 20 80 00 +42 E8 10 01 3E 40 0C 00 3F 40 20 0A 1F 53 CF 43 +FF FF 1E 83 FB 23 10 01 5D 93 07 20 7C 40 5A 00 +3D 40 1A F5 5E 43 80 00 7A AF 10 01 5D 93 07 20 +7C 40 5A 00 3D 40 22 F5 5E 43 80 00 7A AF 10 01 +5D 93 07 20 7C 40 5A 00 3D 40 12 F5 5E 43 80 00 +7A AF 10 01 3C 80 05 00 05 24 3C 80 05 00 02 24 +4C 43 10 01 5C 43 10 01 4C 43 D2 93 34 1E 05 20 +B2 90 E2 F2 E4 1E 01 20 5C 43 10 01 B2 40 D9 07 +CE 1E F2 42 CC 1E D2 43 CB 1E C2 43 CA 1E 10 01 +4C ED 4F 4C CC 0D 8C 10 5C EF F0 F3 7C F0 1F 00 +10 01 1F 42 50 03 82 4F C8 1E 1F 92 50 03 F9 23 +80 00 EA CC CF 0C 5F 06 0C 5F 3C 80 40 06 3D 40 +09 00 80 00 50 E2 4C 43 D2 93 58 1E 04 20 82 93 +60 1E 01 24 5C 43 10 01 4C 43 92 93 18 1E 04 20 +82 93 24 1E 01 24 5C 43 10 01 CF 0C 0E 93 05 24 +1F 53 FF 4D FF FF 1E 83 FB 23 10 01 0E 93 06 24 +4D 4D 1C 53 CC 4D FF FF 1E 83 FB 23 10 01 C2 93 +88 1E 03 24 3C 40 84 1E 10 01 3C 40 A4 F6 10 01 +0D 93 02 20 0C 93 04 24 82 4C 8A 1E 82 4D 8C 1E +10 01 0D 93 02 20 0C 93 04 24 82 4C 6C 1E 82 4D +6E 1E 10 01 B0 13 EA DF B2 F0 EF FF 32 0F B2 D0 +10 00 36 0F 10 01 82 43 9C 1E F2 40 0F 00 9E 1E +B2 40 2C 01 A0 1E 10 01 A2 43 9A 1E 92 C3 44 03 +B2 D0 10 00 44 03 10 01 A2 D2 80 03 82 43 80 03 +B2 D0 00 02 80 03 10 01 CE 0C 3C 40 E8 03 B0 13 +64 EA 1E 83 FA 23 10 01 82 43 32 0F 82 43 36 0F +B0 13 EA DF 80 00 28 EE 3E F0 1F 00 04 24 5C 02 +0D 6D 1E 83 FC 23 10 01 3E F0 1F 00 04 24 5D 03 +5C 00 1E 83 FC 23 10 01 7C 40 36 00 B0 13 10 BD +7C 40 39 00 80 00 10 BD 4F 43 C2 93 CA 1E 01 20 +5F 43 C2 4F CA 1E 10 01 4F 43 C2 93 2F 1E 01 20 +5F 43 C2 4F 2F 1E 10 01 4F 43 7C B0 80 FF 01 20 +5F 43 CC 0F 10 01 C2 93 06 1E 02 20 80 00 CC D0 +80 00 C2 AD 4F 43 7C 90 0C 00 01 2C 5F 43 CC 0F +10 01 B0 13 B2 EA B0 13 22 E8 5D 43 80 00 08 A0 +D2 43 5E 1E 82 43 60 1E C2 43 58 1E 10 01 B2 F0 +1F FF 04 0A 4C 4C 82 DC 04 0A 10 01 1C 42 50 03 +1C 92 50 03 FB 23 10 01 C2 93 9C 1D 02 24 D2 43 +9B 1D 10 01 3D 40 79 1D 3E 40 21 00 80 00 4A ED +B2 F0 DF FF 40 03 82 43 50 03 10 01 5C 43 B0 13 +BA CE 6C 43 80 00 BA CE B0 13 24 E3 B2 D0 00 04 +8C 1C 10 01 DC 93 0C 00 02 20 80 00 62 D8 10 01 +B0 13 3E F0 B2 40 2B 5A 5C 01 10 01 4C 43 A2 93 +EE 1D 01 20 5C 43 10 01 4C 43 92 93 EE 1D 01 20 +5C 43 10 01 4C 43 82 93 EA 1C 01 24 5C 43 10 01 +4C 43 92 93 D0 1E 01 20 5C 43 10 01 CF 0C CC 0D +CD 0F 2E 42 80 00 F8 E8 CD 0C 3C 40 80 1E 2E 42 +80 00 4A ED 7C 40 03 00 7D 40 0B 00 80 00 C6 CF +5C 93 02 20 CC 0D 10 01 CC 0E 10 01 1C 42 8C 1C +49 19 0C 10 5C F3 10 01 1C 42 8C 1C 48 19 0C 10 +5C F3 10 01 1C 42 8C 1C 46 19 0C 10 5C F3 10 01 +1C 42 8C 1C 44 19 0C 10 5C F3 10 01 1C 42 8C 1C +45 19 0C 10 5C F3 10 01 1C 42 44 03 7C F0 10 00 +10 01 B2 F0 EF FF 44 03 80 00 86 DF B2 F0 EF FF +08 1E 80 00 26 F0 B0 13 76 EB C2 4C EE 1E 10 01 +B0 13 76 EB C2 4C 17 1E 10 01 7C 40 03 00 4D 43 +80 00 C6 CF C2 43 A4 1E C2 43 AA 1E 10 01 82 43 +EA 1C E2 42 16 1D 10 01 82 43 D0 1E 4C 43 80 00 +A6 BD 1C 42 8C 1C 8C 10 5C F3 10 01 1C 42 8C 1C +5C 0F 5C F3 10 01 5C 42 C6 1E 8C 11 10 01 4C 5C +C2 4C 49 1E 10 01 B2 F0 EF FF 48 03 10 01 B2 D0 +20 00 40 03 10 01 D2 43 E0 1E 80 00 42 E8 32 D0 +D8 00 03 43 10 01 5C 42 DC 1E 10 01 C2 4C 48 1E +10 01 C2 4C 4A 1E 10 01 4D 43 80 00 88 C8 92 D3 +44 03 10 01 92 C3 44 03 10 01 5C 42 78 1D 10 01 +A2 D2 06 0A 10 01 82 43 76 1E 10 01 CC 43 00 00 +10 01 3C 40 C2 F6 10 01 92 D3 04 0A 10 01 92 C3 +04 0A 10 01 80 00 7E 98 1C 43 10 01 03 43 FF 3F +2C 43 10 01 2C 43 10 01 4C 43 10 01 6C 43 10 01 +0C 43 10 01 0C 43 10 01 03 43 10 01 10 01 10 01 +10 01 30 30 30 30 30 31 30 30 32 30 30 33 30 30 +34 30 30 35 30 30 36 30 30 37 30 30 38 30 30 39 +30 31 30 30 31 31 30 31 32 30 31 33 30 31 34 30 +31 35 30 31 36 30 31 37 30 31 38 30 31 39 30 32 +30 30 32 31 30 32 32 30 32 33 30 32 34 30 32 35 +30 32 36 30 32 37 30 32 38 30 32 39 30 33 30 30 +33 31 30 33 32 30 33 33 30 33 34 30 33 35 30 33 +36 30 33 37 30 33 38 30 33 39 30 34 30 30 34 31 +30 34 32 30 34 33 30 34 34 30 34 35 30 34 36 30 +34 37 30 34 38 30 34 39 30 35 30 30 35 31 30 35 +32 30 35 33 30 35 34 30 35 35 30 35 36 30 35 37 +30 35 38 30 35 39 30 36 30 30 36 31 30 36 32 30 +36 33 30 36 34 30 36 35 30 36 36 30 36 37 30 36 +38 30 36 39 30 37 30 30 37 31 30 37 32 30 37 33 +30 37 34 30 37 35 30 37 36 30 37 37 30 37 38 30 +37 39 30 38 30 30 38 31 30 38 32 30 38 33 30 38 +34 30 38 35 30 38 36 30 38 37 30 38 38 30 38 39 +30 39 30 30 39 31 30 39 32 30 39 33 30 39 34 30 +39 35 30 39 36 30 39 37 30 39 38 30 39 39 31 30 +30 31 30 31 31 30 32 31 30 33 31 30 34 31 30 35 +31 30 36 31 30 37 31 30 38 31 30 39 31 31 30 31 +31 31 31 31 32 31 31 33 31 31 34 31 31 35 31 31 +36 31 31 37 31 31 38 31 31 39 31 32 30 31 32 31 +31 32 32 31 32 33 31 32 34 31 32 35 31 32 36 31 +32 37 31 32 38 31 32 39 31 33 30 31 33 31 31 33 +32 31 33 33 31 33 34 31 33 35 31 33 36 31 33 37 +31 33 38 31 33 39 31 34 30 31 34 31 31 34 32 31 +34 33 31 34 34 31 34 35 31 34 36 31 34 37 31 34 +38 31 34 39 31 35 30 31 35 31 31 35 32 31 35 33 +31 35 34 31 35 35 31 35 36 31 35 37 31 35 38 31 +35 39 31 36 30 31 36 31 31 36 32 31 36 33 31 36 +34 31 36 35 31 36 36 31 36 37 31 36 38 31 36 39 +31 37 30 31 37 31 31 37 32 31 37 33 31 37 34 31 +37 35 31 37 36 31 37 37 31 37 38 31 37 39 31 38 +30 00 26 EC 00 00 82 EE 00 00 08 A0 00 00 90 EF +00 00 84 F3 48 EE 00 00 CC 8B 00 00 1E 97 00 00 +0C F0 00 00 06 F3 4E E0 00 00 62 A3 00 00 42 B4 +00 00 78 EF 00 00 18 F3 BE F0 00 00 66 A4 00 00 +1A AB 00 00 9C EF 00 00 2A F3 C0 F0 00 00 2E AA +00 00 42 A9 00 00 0C F0 00 00 3C F3 68 A5 00 00 +76 F0 00 00 5C CB 00 00 0C F0 00 00 4E F3 BE F0 +00 00 BE F0 00 00 E4 AC 00 00 0C F0 00 00 60 F3 +5E EB 00 00 BE F0 00 00 A6 9D 00 00 6C EF 00 00 +F4 F2 38 EE 00 00 D0 8F 00 00 EC B1 00 00 02 F0 +00 00 E2 F2 BE F0 00 00 BE F0 00 00 48 CD 00 00 +84 EF 00 00 96 F3 42 E4 00 00 BE F0 00 00 8C EC +00 00 0C F0 00 00 A8 F3 1A E4 00 00 BE F0 00 00 +78 EC 00 00 0C F0 00 00 BA F3 74 E5 00 00 BE F0 +00 00 A0 EC 00 00 0C F0 00 00 CC F3 CC EA 00 00 +C2 91 00 00 66 EE 00 00 0C F0 00 00 DE F3 20 D1 +00 00 BE F0 00 00 4E E3 00 00 0C F0 00 00 72 F3 +01 80 40 20 10 08 84 42 21 90 48 A4 52 29 14 0A +85 C2 61 B0 58 AC D6 6B 35 9A CD 66 33 99 4C A6 +53 A9 54 2A 95 CA E5 F2 79 3C 9E CF 67 B3 D9 6C +B6 5B 2D 16 0B 05 82 41 A0 50 28 94 4A A5 D2 69 +34 1A 8D 46 23 91 C8 E4 72 39 1C 8E C7 E3 F1 F8 +FC FE FF 7F 3F 1F 0F 07 83 C1 E0 70 38 9C CE E7 +F3 F9 7C BE DF 6F 37 9B 4D 26 13 89 44 22 11 88 +C4 62 31 98 CC E6 73 B9 5C AE D7 EB 75 BA DD 6E +B7 DB 6D 36 1B 0D 06 03 81 C0 60 30 18 8C C6 63 +B1 D8 EC F6 7B 3D 1E 8F 47 A3 D1 E8 F4 7A BD 5E +AF 57 AB 55 AA D5 EA F5 FA FD 7E BF 5F 2F 17 8B +45 A2 51 A8 D4 6A B5 DA ED 76 3B 1D 0E 87 C3 E1 +F0 78 BC DE EF 77 BB 5D 2E 97 CB 65 B2 59 2C 96 +4B 25 92 49 24 12 09 04 02 01 80 40 20 10 08 84 +42 21 90 48 A4 52 29 14 0A 85 C2 61 B0 58 AC D6 +6B 35 9A CD 66 33 99 4C A6 53 A9 54 2A 95 CA E5 +45 52 52 00 20 20 44 4F 4E 45 00 00 30 30 30 30 +30 30 30 00 20 43 4F 4E 46 00 20 52 46 42 53 4C +00 00 20 20 53 59 4E 43 00 00 20 20 20 50 50 54 +00 00 20 20 20 41 43 43 00 00 2D 2D 2D 00 30 30 +30 30 30 30 30 30 00 00 4C 42 00 00 4B 47 00 00 +20 52 41 4D 00 00 30 34 33 30 00 00 43 43 34 33 +30 00 20 4F 46 46 00 00 20 20 4F 4E 00 00 4C 4F +42 41 54 54 00 00 20 20 4F 50 45 4E 00 00 20 20 +4C 4F 3F 54 00 00 2D 2D 2D 2D 00 00 02 1B 01 1E +17 3C 18 10 06 1E 08 05 03 47 0B 08 0C 00 0D 22 +0E B1 0F 3B 10 7B 11 83 12 13 13 22 14 F8 15 42 +19 1D 1A 1C 1B C7 1C 00 1D B2 21 B6 22 10 23 EA +24 2A 25 00 26 1F 2C 81 2D 35 2E 09 F5 60 B6 F2 +63 D3 D7 70 F7 F3 00 00 00 00 00 86 00 77 C7 95 +E6 97 17 F3 67 05 F0 87 85 75 46 C6 37 F5 06 D3 +87 C4 C4 02 67 E3 B6 00 03 01 04 08 10 80 80 80 +80 20 40 02 01 80 04 02 10 20 40 08 08 80 08 08 +08 08 F7 F7 F7 F7 20 40 04 80 7F 7F 7F 7F 7F 10 +01 80 2F 1E 1B 07 37 B2 0A 04 00 00 00 0C 00 23 +2A D4 4D 3B 15 11 F8 57 07 0C 10 1D 1C C7 10 B0 +FF FF F9 B6 10 EA 2A 00 1F 00 67 FF 00 00 6F 00 +1C 02 DD 03 B1 05 9D 07 A2 09 C4 0B 07 0E 6E 10 +01 13 C6 15 C8 18 11 1C B5 1F CC 23 07 04 F5 03 +E8 03 B6 03 84 03 52 03 20 03 EE 02 BC 02 8A 02 +58 02 26 02 F4 01 C2 01 90 01 5E 01 2C 01 2A E6 +00 00 FC E6 00 00 2E EB 00 00 B4 F0 00 00 B0 F0 +00 00 16 DE 00 00 12 00 24 00 47 00 8F 00 1E 01 +3B 02 76 04 79 56 34 12 02 01 01 01 00 00 32 34 +48 00 31 32 48 00 4D 41 4C 45 46 45 4D 41 D2 1D +D2 1D FF FF FF FF 14 32 50 6E 0F 27 8B 00 02 00 +00 +@f6d2 +01 00 C2 1E 00 00 01 00 7E 1E 00 00 01 00 7F 1E +0A 00 54 00 8E 1C 20 0A 20 0A 20 0A 20 0A 24 0A +2A 0A 29 0A 27 0A 26 0A 24 0A 24 0A 26 0A 26 0A +24 0A 26 0A 24 0A 26 0A 26 0A 26 0A 21 0A 22 0A +20 0A 23 0A 24 0A 25 0A 26 0A 21 0A 22 0A 23 0A +25 0A 20 0A 20 0A 24 0A 2B 0A 2B 0A 2A 0A 29 0A +28 0A 27 0A 20 0A 24 0A 28 0A 02 00 E4 1E 00 00 +01 00 41 1E 00 00 01 00 31 1D 00 00 02 00 E6 1E +00 00 01 00 D1 1D 00 00 01 00 78 1D 00 00 01 00 +9A 1D 00 00 01 00 9B 1D 00 00 01 00 9C 1D 00 00 +02 00 9E 1D 00 00 02 00 A0 1D 00 00 01 00 A2 1D +00 00 01 00 A4 1D FF 00 04 00 A8 1D 00 00 00 00 +04 00 AC 1D 00 00 00 00 04 00 B0 1D 00 00 00 00 +01 00 88 1E 00 00 01 00 62 1E 00 00 02 00 64 1E +00 00 01 00 66 1E 00 00 04 00 68 1E 00 00 00 00 +01 00 B4 1D 01 00 01 00 17 1E 00 00 02 00 EC 1E +00 00 01 00 EE 1E 00 00 04 00 6C 1E 00 00 00 00 +01 00 70 1E 00 00 01 00 74 1E 00 00 01 00 75 1E +00 00 04 00 8A 1E 00 00 00 00 04 00 8E 1E 00 00 +00 00 01 00 92 1E 00 00 01 00 48 1E 00 00 01 00 +49 1E 00 00 01 00 4A 1E 00 00 01 00 4B 1E 00 00 +02 00 94 1E 00 00 02 00 96 1E 00 00 01 00 98 1E +00 00 01 00 99 1E 00 00 01 00 C6 1E 00 00 02 00 +C8 1E 00 00 02 00 D8 1E 00 00 01 00 DA 1E 00 00 +00 00 +@ffe0 +D6 8D +@ffea +38 DD 86 C1 16 85 98 EA +@fffe +FA E2 +q diff --git a/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_datalogger_433MHz.txt b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_datalogger_433MHz.txt new file mode 100755 index 0000000..1fba0cf --- /dev/null +++ b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_datalogger_433MHz.txt @@ -0,0 +1,1514 @@ +@9e00 +5A 14 31 80 1A 00 CA 0E B0 13 DA E6 0E 43 3F 40 +C8 42 B0 13 C4 C8 81 4C 12 00 81 4D 14 00 CC 0A +B0 13 E8 ED 0E 43 3F 40 20 41 B0 13 C4 C8 81 4C +16 00 81 4D 18 00 36 40 11 00 37 40 BA 1D 0A 43 +28 47 19 47 02 00 CC 08 CD 09 1E 41 12 00 1F 41 +14 00 B0 13 36 DC 0C 93 0A 38 81 48 08 00 81 49 +0A 00 27 52 1A 53 16 83 EB 23 4A 4A 03 3C 4A 4A +0A 93 7E 24 3A 90 0F 00 3D 38 3A 90 0F 00 23 24 +B0 13 86 A0 1E 42 FA 1D 1F 42 FC 1D B0 13 C4 B0 +C9 0C CA 0D 1C 42 FA 1D 1D 42 FC 1D 1E 42 F6 1D +1F 42 F8 1D B0 13 3A A0 1C 42 34 FA 1C 82 32 FA +B0 13 4C A0 1C 42 34 FA B0 13 60 A0 81 4C 00 00 +81 4D 02 00 73 3C B0 13 24 A0 C9 0C CA 0D 1C 42 +F6 1D 1D 42 F8 1D 1E 41 08 00 1F 41 0A 00 B0 13 +3A A0 1C 42 32 FA 1C 82 30 FA B0 13 4C A0 1C 42 +30 FA E2 3F C9 0A 59 02 16 49 12 FA 5A 06 17 4A +BA 1D 18 4A BC 1D B0 13 24 A0 C5 0C CA 0D B0 13 +86 A0 CE 07 CF 08 B0 13 C4 B0 3E 40 34 80 3F 40 +37 3A B0 13 10 A0 CC 05 CD 0A B0 13 40 C2 C5 0C +CA 0D CC 07 CD 08 1E 41 08 00 1F 41 0A 00 B0 13 +90 A0 CC 05 CD 0A B0 13 C4 C8 C8 0C CA 0D 1C 49 +14 FA 0C 86 B0 13 0A E5 CE 0C CF 0D CC 08 CD 0A +B0 13 40 C2 C9 0C CA 0D CC 06 B0 13 60 A0 A6 3F +B0 13 86 A0 1E 42 BA 1D 1F 42 BC 1D B0 13 C4 B0 +C9 0C CA 0D 1C 42 BE 1D 1D 42 C0 1D 1E 42 BA 1D +1F 42 BC 1D B0 13 3A A0 1C 42 16 FA 1C 82 14 FA +B0 13 56 A0 81 4C 00 00 81 4D 02 00 2C 41 1D 41 +02 00 B0 13 6A A0 3E 40 F4 FD 3F 40 D4 3B B0 13 +10 A0 1C 41 16 00 1D 41 18 00 B0 13 C4 C8 81 4C +04 00 81 4D 06 00 1C 41 04 00 1D 41 06 00 B0 13 +6A A0 2E 41 1F 41 02 00 B0 13 40 C2 81 4C 0C 00 +81 4D 0E 00 1C 41 0C 00 1D 41 0E 00 B0 13 76 DE +81 4C 10 00 1C 41 10 00 31 50 1A 00 55 16 10 01 +B0 13 40 C2 CE 0C CF 0D 0C 43 3D 40 80 3F B0 13 +90 A0 10 01 1C 41 16 00 1D 41 18 00 1E 41 0C 00 +1F 41 0E 00 B0 13 C4 B0 10 01 B0 13 90 A0 CC 09 +CD 0A B0 13 C4 C8 C9 0C CA 0D 10 01 B0 13 56 A0 +C9 0C CA 0D 10 01 B0 13 78 A0 B0 13 40 C2 10 01 +B0 13 78 A0 B0 13 CA B0 10 01 3E 40 E7 6F 3F 40 +63 3B B0 13 40 C2 10 01 B0 13 0A E5 CE 0C CF 0D +CC 09 CD 0A 10 01 1C 41 16 00 1D 41 18 00 10 01 +B0 13 C4 B0 CE 0C CF 0D 10 01 4A 14 31 82 B0 13 +B2 F3 C8 0C CF 08 3F 50 FF 7F 81 4F 06 00 91 41 +06 00 04 00 82 43 A8 1E 4A 43 49 43 4C 49 B0 13 +0C A3 1F 4C 18 00 1F 83 1D 24 1F 83 14 24 D2 B3 +36 1F 47 24 1E 42 B0 1E 1F 42 B2 1E 3E F3 3F F0 +FF 00 1F 9C 02 00 3D 20 2E 9C 3B 20 D2 C3 36 1F +82 43 A8 1E 36 3C 5A 53 B0 13 50 DB 4C 93 31 24 +C7 09 2F 3C B0 13 FA F0 C6 0C CC 09 B0 13 CC DF +4C 93 0C 20 CC 09 CD 06 CE 08 B0 13 58 B5 1F 42 +A6 1E AF 93 18 00 09 20 5A 53 07 3C 82 43 A8 1E +E2 B2 36 1F 02 20 B0 13 A8 E5 1F 42 A6 1E 9F 93 +18 00 0F 20 CF 01 3F 50 03 00 81 4F 00 00 CC 06 +CD 01 3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 +08 DA 59 53 AB 27 4A 93 50 24 92 93 A8 1E 18 38 +4C 47 B0 13 0C A3 CC 07 B0 13 8A C1 4C 93 10 24 +5A 83 CF 01 3F 50 03 00 81 4F 00 00 7C 42 CD 01 +3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 08 DA +4A 93 33 24 1F 42 A4 1E 0F 88 1F 93 2C 34 E2 B2 +36 1F 0D 20 E2 D2 36 1F C2 93 AD 1E 04 20 B2 50 +E0 7F A4 1E 20 3C B2 50 C0 53 A4 1E 1C 3C E2 C2 +36 1F C2 93 AD 1E 03 24 3F 40 40 6C 02 3C 3F 40 +20 00 82 5F A4 1E 49 43 4C 49 B0 13 0C A3 AC 93 +18 00 07 20 CC 09 B0 13 F2 E9 4C 93 02 20 5A 83 +04 24 59 53 F1 27 4A 93 0E 20 F2 F0 F9 00 36 1F +91 91 06 00 04 00 02 24 0E 43 08 3C B0 13 58 F4 +A2 43 FC 1E 70 3C E2 D3 36 1F 1E 43 1F 41 06 00 +0F 88 0F 93 54 38 0E 93 3C 24 E2 B2 36 1F 16 20 +1F 41 06 00 1F 82 A4 1E 3F 80 42 00 0F 93 31 38 +F2 40 07 00 FA 1E C2 43 FB 1E F2 D0 18 00 36 1F +92 42 A4 1E F6 1E A2 43 FC 1E 4B 3C 1F 41 06 00 +0F 88 3F 80 42 00 1F 93 1C 38 F2 40 07 00 FA 1E +C2 43 FB 1E F2 D0 18 00 36 1F 1F 41 06 00 1F 82 +A4 1E 3F 80 42 00 0F 93 05 34 1F 41 06 00 3F 80 +42 00 02 3C 1F 42 A4 1E 82 4F F6 1E 92 43 FC 1E +28 3C D2 41 02 00 FA 1E D2 41 03 00 FB 1E 5F 42 +36 1F 7F C2 7F D0 10 00 C2 4F 36 1F 92 41 06 00 +F6 1E 92 41 04 00 F8 1E 82 43 FC 1E 12 3C D2 91 +02 00 FA 1E 09 24 D2 41 02 00 FA 1E D2 41 03 00 +FB 1E F2 D0 10 00 36 1F 92 41 04 00 F6 1E 92 43 +FC 1E D2 C3 36 1F 31 52 46 16 10 01 3D 40 1C 00 +B0 13 1A F2 1C 52 7A FA 82 4C A6 1E 10 01 6A 14 +31 80 20 00 C8 0F C9 0D CA 0E 81 43 0C 00 81 43 +0E 00 B0 13 0A E5 81 4C 14 00 81 4D 16 00 CC 09 +CD 0A B0 13 DA E6 0E 43 3F 40 C8 42 B0 13 C4 C8 +81 4C 18 00 81 4D 1A 00 CC 08 B0 13 E8 ED 0E 43 +3F 40 20 41 B0 13 C4 C8 81 4C 1C 00 81 4D 1E 00 +1C 41 14 00 1D 41 16 00 3E 40 F4 FD 3F 40 D4 3B +B0 13 40 C2 1E 41 1C 00 1F 41 1E 00 B0 13 CA B0 +81 4C 10 00 81 4D 12 00 1C 41 10 00 1D 41 12 00 +3E 40 E7 6F 3F 40 63 3B B0 13 40 C2 CE 0C CF 0D +1C 41 14 00 1D 41 16 00 B0 13 C4 C8 81 4C 08 00 +81 4D 0A 00 36 40 10 00 37 40 14 FA 0A 43 2C 47 +B0 13 C4 A4 CE 08 CF 09 B0 13 36 DC 0C 93 08 38 +81 48 0C 00 81 49 0E 00 27 53 1A 53 16 83 EF 23 +4A 4A 5A 02 1C 4A 34 FA B0 13 E8 ED C6 0C C7 0D +1C 4A 14 FA B0 13 C4 A4 B0 13 E8 A4 C4 0C C5 0D +1C 41 08 00 1D 41 0A 00 CE 08 CF 09 B0 13 C4 B0 +3E 40 82 A8 3F 40 7B 38 B0 13 40 C2 CE 0C CF 0D +0C 43 3D 40 80 3F B0 13 D6 A4 C4 0C C5 0D 1C 4A +36 FA B0 13 E8 ED CE 06 CF 07 B0 13 D6 A4 C5 0C +CA 0D CC 08 CD 09 B0 13 E8 A4 CE 0C CF 0D CC 05 +CD 0A B0 13 C4 C8 CE 06 CF 07 B0 13 CA B0 81 4C +04 00 81 4D 06 00 1C 41 18 00 1D 41 1A 00 1E 41 +04 00 1F 41 06 00 B0 13 C4 C8 81 4C 00 00 81 4D +02 00 38 40 11 00 3A 40 BA 1D 39 40 36 FA 3C 49 +B0 13 E8 ED 2E 41 1F 41 02 00 B0 13 40 C2 2A 52 +8A 4C FC FF 8A 4D FE FF 18 83 F1 23 31 50 20 00 +64 16 10 01 B0 13 0A E5 C8 0C C9 0D 1C 41 0C 00 +1D 41 0E 00 10 01 B0 13 C4 B0 CE 0C CF 0D CC 04 +CD 05 B0 13 40 C2 10 01 1E 41 10 00 1F 41 12 00 +B0 13 C4 B0 10 01 4F 14 5D 42 1B 02 B2 B0 20 00 +D8 1E D4 20 B2 B0 40 00 D8 1E D0 20 82 43 D8 1E +5E 42 1D 02 4E FD 4B 43 B0 13 12 F4 4C 93 62 20 +7E B0 1F 00 0F 24 32 C2 03 43 C2 43 1B 02 32 D2 +3C 40 A3 00 B0 13 5A DA 92 42 96 1E 9A 1E 92 42 +98 1E 9C 1E 6E B2 39 20 6E B3 22 20 7E B0 10 00 +17 20 5E B3 0E 20 7E B2 6C 24 F2 B2 01 02 69 24 +D2 43 DD 1E C2 43 DC 1E F2 D2 03 02 F2 D2 05 02 +60 3C D2 B3 01 02 5D 24 B2 D2 D8 1E 5B 43 59 3C +F2 B0 10 00 01 02 55 24 A2 D2 D8 1E 5B 43 51 3C +E2 B3 01 02 0B 20 E2 B3 19 02 4B 24 A2 D3 D8 1E +B2 F0 FF FE D8 1E E2 C3 19 02 43 3C A2 D3 D8 1E +B2 F0 FF FE D8 1E 5B 43 3C 3C E2 B2 01 02 0B 20 +E2 B2 19 02 36 24 92 D3 D8 1E B2 F0 7F FF D8 1E +E2 C2 19 02 2E 3C 92 D3 D8 1E B2 F0 7F FF D8 1E +5B 43 27 3C D2 53 E0 1E 5F 42 E0 1E 5F 83 7F 90 +07 00 05 28 F2 F0 0F 00 7A 1D C2 43 E0 1E 6E B2 +13 20 6E B3 0D 20 7E B0 10 00 06 20 5E B3 11 24 +F2 D0 20 00 78 1D 0D 3C F2 D0 30 00 7A 1D 07 3C +F2 D0 20 00 7A 1D 03 3C F2 D0 10 00 7A 1D F2 D2 +78 1D A2 B3 D8 1E 03 24 B2 B2 D8 1E 0D 20 4B 93 +0D 24 B2 B0 10 00 86 1E 02 20 B0 13 80 DC 3C 40 +00 20 B0 13 5A DA 02 3C 82 43 D8 1E 7E B0 20 00 +02 24 A2 D2 88 1E 7E B0 40 00 02 24 A2 D3 88 1E +92 B3 D8 1E 03 20 A2 B3 D8 1E 18 24 3C 40 66 06 +B0 13 5A DA E2 B2 01 02 07 24 E2 D2 19 02 92 C3 +D8 1E B2 D0 80 00 D8 1E E2 B3 01 02 07 24 E2 D3 +19 02 A2 C3 D8 1E B2 D0 00 01 D8 1E 32 C2 03 43 +C2 43 1D 02 C2 4D 1B 02 32 D2 B1 C0 F0 00 14 00 +4B 16 00 13 4F 14 B2 F0 EF FF 42 03 92 C3 42 03 +B2 80 00 80 52 03 B2 D0 10 00 42 03 B0 13 E8 D5 +B2 D0 10 00 14 1D B0 13 06 F4 4C 93 C7 20 B0 13 +12 F4 4C 93 11 24 B2 90 03 00 72 1D 0D 20 C2 93 +76 1D 08 20 7C 40 5A 00 3D 40 00 F9 5E 43 B0 13 +D6 BC 02 3C D2 83 76 1D E2 93 9E 1E 02 28 92 D3 +88 1E B0 13 B6 F4 4C 93 02 24 B2 D2 88 1E B0 13 +F0 F4 4C 93 02 24 A2 D3 88 1E B0 13 FA F3 4C 93 +02 24 B0 13 72 EE B2 B0 20 00 86 1E 10 24 5E 42 +2A 1F CF 0E 5F 83 C2 4F 2A 1F 4E 93 08 20 92 D3 +8A 1E B2 D0 20 00 8A 1E F2 40 0F 00 2A 1F 82 93 +8A 1E 0F 24 92 B3 8A 1E 08 20 A2 B2 8A 1E 09 24 +A2 C2 8A 1E 92 D3 14 1D 04 3C 92 C3 8A 1E A2 D3 +8A 1E A2 B3 86 1E 0E 24 1F 42 96 1E 1E 42 98 1E +1F 82 9A 1E 1E 72 9C 1E 03 20 3F 90 1F 00 02 28 +92 D3 86 1E D2 93 DD 1E 0E 20 E2 92 DC 1E 03 2C +D2 53 DC 1E 08 3C F2 C2 03 02 F2 C2 05 02 C2 43 +DC 1E C2 43 DD 1E E2 B3 01 02 03 24 D2 B3 01 02 +2F 20 C2 43 1C 1F E2 B2 01 02 11 24 D2 53 DA 1E +F2 90 03 00 DA 1E 0D 28 B2 D0 20 00 D8 1E B2 F0 +7F FF D8 1E C2 43 DA 1E E2 C2 19 02 02 3C C2 43 +DA 1E E2 B3 01 02 11 24 D2 53 DB 1E F2 90 03 00 +DB 1E 2C 28 B2 D0 40 00 D8 1E B2 F0 FF FE D8 1E +C2 43 DB 1E E2 C3 19 02 21 3C C2 43 DB 1E 1E 3C +D2 53 1C 1F 5F 42 1C 1F 5F 83 7F 90 03 00 16 28 +1F 42 86 1E 2F C2 2E 42 1E C2 86 1E 0E DF 82 4E +86 1E 92 D3 8A 1E A2 B2 86 1E 04 20 B2 D0 10 00 +8A 1E 02 3C B2 D2 8A 1E C2 43 1C 1F B1 C0 D0 00 +14 00 4B 16 00 13 3C 40 01 1E 0D 43 3E 40 21 00 +B0 13 CC F2 7C 40 30 00 B0 13 EA CF 7C 40 30 00 +B0 13 30 DE 4C 93 AF 20 7C 40 31 00 B0 13 30 DE +7C 90 06 00 A5 20 7C 40 36 00 B0 13 EA CF B0 13 +0C AA FD 23 B2 40 01 02 34 0F 0F 42 32 C2 03 43 +B2 B0 10 00 02 0F FC 27 B2 40 51 7E 10 0F B2 B0 +10 00 02 0F FC 27 F2 40 3D 00 11 0F B2 B0 10 00 +02 0F FC 27 F2 40 FE 00 11 0F B2 B0 20 00 02 0F +FC 27 C2 43 10 0F B2 B0 80 00 02 0F FC 27 F2 90 +51 00 20 0F 72 20 B2 B0 10 00 02 0F FC 27 F2 40 +3D 00 11 0F 02 4F 3B 40 56 F9 4E 43 6C 4B 4F 4E +5F 02 5D 4F 57 F9 B0 13 DC E5 2B 53 5E 53 7E 90 +20 00 F4 2B 3D 40 56 F9 4E 43 6C 4D B0 13 30 DE +4F 4E 5F 02 CF 9C 57 F9 4D 20 2D 53 5E 53 7E 90 +20 00 F3 2B 7C 40 36 00 B0 13 EA CF B0 13 0C AA +FD 23 7C 40 0C 00 5D 42 94 1E B0 13 DC E5 B0 13 +D6 EF 6C 43 B0 13 14 F1 7C 40 34 00 B0 13 EA CF +A2 B3 30 0F FD 27 3E 40 10 00 7C 40 34 00 B0 13 +30 DE 5C F3 5F 42 22 1E 4F 5F 4C DF C2 4C 22 1E +1E 83 F3 23 F2 D0 80 00 22 1E B0 13 EC E8 7C 40 +32 00 B0 13 EA CF D2 43 00 1E B2 40 36 00 26 1E +B2 40 E2 04 28 1E 3C 40 01 1E 0D 43 3E 40 1F 00 +B0 13 CC F2 3C 40 20 1E 0D 43 2E 43 B0 13 CC F2 +32 D2 10 01 32 C2 03 43 FF 3F 32 C2 03 43 FF 3F +32 C2 03 43 FF 3F 32 C2 03 43 FF 3F 7C 40 3D 00 +B0 13 EA CF 7C B0 F0 FF 10 01 C2 43 9E 1D 5F 42 +7A 1D 2F 83 AA 24 1F 83 50 24 1F 83 33 24 1F 83 +16 24 1F 83 06 24 1F 83 A5 20 F2 D0 20 00 78 1D +10 01 7C 40 40 00 B0 13 0E E0 5C 53 7C 90 4F 00 +FA 2B B2 40 00 80 90 1C E2 C3 8C 1C 10 01 E2 43 +7A 1D 3C 40 A4 1D 4D 43 4E 4D 5E 02 5F 4E 7B 1D +47 18 0F 5F 5E 4E 7C 1D 0E 5F 2C 53 8C 4E FE FF +5D 53 7D 90 09 00 F0 2B E2 43 9F 1D F2 40 09 00 +9E 1D 10 01 E2 43 7A 1D 5E 42 7B 1D 47 18 0E 5E +5F 42 7C 1D 0E 5F 82 4E A0 1D 5F 42 7D 1D 47 18 +0F 5F 5D 42 7E 1D 0F 5D 82 4F A2 1D D2 43 9F 1D +4F 8E 5F 53 C2 4F 9E 1D 10 01 3E 40 BF FF 1E F2 +86 1E 5F 42 7B 1D 5F 03 3F F0 C0 FF 0E DF 82 4E +86 1E 3F 40 7F 00 5F F2 7B 1D C2 4F A0 1E D2 42 +7C 1D A1 1E D2 42 7D 1D A2 1E 5F 42 7E 1D 47 18 +0F 5F 5E 42 7F 1D 0E 5F 82 4E 34 1F D2 42 80 1D +32 1F D2 42 81 1D 31 1F 5F 42 84 1D 47 18 0F 5F +5E 42 85 1D 0E 5F CF 0E 1F 52 80 1E 1F 82 7E 1E +82 4F 80 1E 82 4E 7E 1E 5F 42 86 1D 47 18 0F 5F +5C 42 87 1D 0C 5F 82 4C 82 1E 1D 42 78 1E 1E 42 +7A 1E 1F 42 7C 1E B0 13 1E A3 D2 42 88 1D 8D 1C +D2 42 89 1D 8E 1C 7C 40 5A 00 3D 40 EA F8 5E 43 +B0 13 D6 BC D2 43 76 1D 10 01 F2 40 03 00 7A 1D +D2 43 9E 1D 10 01 1A 14 CA 0C 6D 93 3A 24 5D 93 +0E 24 6D 92 5C 20 B0 13 BE AC 6D 42 B0 13 30 F0 +C2 43 9F 1E 4C 43 4D 43 B0 13 30 F0 50 3C C2 93 +9F 1E 18 20 B2 B0 40 00 86 1E 07 20 B0 13 52 AC +5A 93 05 20 B0 13 8A F0 02 3C B0 13 66 AC B0 13 +98 AC C9 0C 5C 42 A1 1E B0 13 74 AC B0 13 BE AC +6D 43 E2 3F B0 13 B0 AC C9 0C 5C 42 A2 1E B0 13 +74 AC 7D 40 1F 00 7E 40 29 00 B0 13 42 F4 5D 43 +D3 3F 5F 42 9E 1E 4F 93 22 24 C2 93 9F 1E 18 20 +4F 4F 2F 83 0D 24 1F 83 1A 20 B2 B0 40 00 86 1E +05 20 B0 13 52 AC B0 13 8A F0 02 3C B0 13 66 AC +B0 13 98 AC CA 0C 5C 42 A1 1E B0 13 8A AC 07 3C +B0 13 B0 AC CA 0C 5C 42 A2 1E B0 13 8A AC 19 16 +10 01 B0 13 50 EE CF 0C CC 0A B0 13 A0 AC 4C 4F +B0 13 7C AC 10 01 B0 13 A0 AC 5C 42 A0 1E B0 13 +7C AC 10 01 B0 13 7C AC CC 0A 10 01 B0 13 CC AC +CC 09 5E 43 B0 13 D6 BC 10 01 B0 13 CC AC CC 0A +5E 43 B0 13 D6 BC 10 01 CC 0A B0 13 B0 AC 10 01 +7D 40 4A 00 7E 40 60 00 B0 13 42 F4 C9 0C 10 01 +7D 40 48 00 7E 40 5E 00 B0 13 42 F4 10 01 7D 40 +1E 00 7E 40 28 00 B0 13 42 F4 10 01 0D 43 6E 43 +4F 43 B0 13 D2 C0 CD 0C 10 01 0A 14 31 82 92 B3 +14 1D 0F 20 A2 B2 14 1D 0C 20 3F 40 0C 00 1F 52 +40 1F 6F 13 4C 93 0C 24 5C 43 6D 43 80 13 8C 1E +07 3C 5C 43 B0 13 44 D6 5C 43 5D 43 80 13 8C 1E +A2 B3 8A 1E 1B 20 92 B3 14 1D 12 20 B2 B2 14 1D +0F 20 3F 40 0C 00 1F 52 42 1F 6F 13 4C 93 61 24 +82 93 8A 1E 5E 20 6C 43 6D 43 80 13 90 1E 59 3C +6C 43 B0 13 44 D6 6C 43 5D 43 F7 3F 6A 43 B2 B2 +8A 1E 2E 20 B2 B0 10 00 8A 1E 26 20 B2 B0 20 00 +8A 1E 1E 20 B2 B0 00 01 8A 1E 14 20 5A 43 B2 B0 +40 00 8A 1E 0B 20 B2 B0 80 00 8A 1E 20 24 CC 01 +3D 40 2A F9 2E 42 B0 13 BA F2 19 3C CC 01 3D 40 +30 F9 F8 3F CC 01 3D 40 36 F9 3E 40 06 00 F3 3F +CC 01 3D 40 3E F9 F9 3F CC 01 3D 40 46 F9 F5 3F +CC 01 3D 40 4E F9 3E 40 06 00 B0 13 BA F2 CC 0A +B0 13 44 D6 CC 0A 6D 42 80 13 90 1E 6A 93 07 24 +7C 40 46 00 CD 01 5E 43 B0 13 D6 BC 06 3C 7C 40 +5A 00 CD 01 5E 43 B0 13 D6 BC 82 43 8A 1E A2 D2 +8A 1E 92 B3 14 1D 10 24 B0 13 FA F3 6C 93 0C 20 +7C 40 17 00 B0 13 22 AE 7C 40 18 00 B0 13 22 AE +7C 40 19 00 B0 13 22 AE 82 43 14 1D 31 52 0A 16 +10 01 7D 40 03 00 B0 13 30 F0 10 01 1A 14 31 80 +16 00 B0 13 88 E2 CA 0C 0A 93 03 20 3C 40 03 00 +97 3C 5C 43 CD 0A B0 13 AA BD 4C 93 04 20 CC 0A +B0 13 FC F4 F3 3F B0 13 02 F5 CD 0C C9 01 39 52 +CC 09 2E 42 B0 13 BA F2 81 49 00 00 CF 01 3F 50 +0C 00 81 4F 02 00 F1 40 09 00 04 00 E1 43 05 00 +CD 01 3D 50 0E 00 3C 40 CE 1E B0 13 DE F0 D1 4A +09 00 12 00 D1 42 D7 1E 0D 00 B0 13 22 F5 C1 4C +13 00 D1 43 0C 00 B0 13 26 F5 C1 4C 14 00 2C 43 +3D 40 03 00 CE 01 B0 13 F6 C2 0C 93 59 20 B0 13 +EA F4 C9 0C E1 43 05 00 CF 01 3F 50 0C 00 81 4F +02 00 CF 0A 3F 50 03 00 81 4F 00 00 79 90 03 00 +06 24 59 93 02 20 B0 13 2E EE B0 13 18 EF B0 13 +74 E5 79 90 03 00 07 24 59 93 03 24 B0 13 F8 EE +02 3C B0 13 58 ED 2C 43 2D 43 CE 01 B0 13 F6 C2 +0C 93 05 24 CC 0A B0 13 FC F4 1C 43 29 3C 3F 40 +7F 00 5F F1 0C 00 5F 93 09 24 7F 90 03 00 06 24 +CC 0A B0 13 FC F4 3C 40 05 00 1A 3C EA 43 00 00 +DA 41 0E 00 0A 00 D2 4A 0B 00 FF 1D F1 90 40 00 +0F 00 02 20 5F 43 02 3C 7F 40 03 00 CA 4F 01 00 +D2 53 D7 1E C2 93 D7 1E 02 20 D2 43 D7 1E 0C 43 +31 50 16 00 19 16 10 01 3A 14 31 82 C9 0C F9 90 +14 00 00 00 05 28 B0 13 26 F5 C9 9C 14 00 74 20 +3C 40 0E 00 0C 59 CD 01 B0 13 1E F4 91 92 D0 1E +02 00 6A 20 91 92 CE 1E 00 00 66 20 58 49 12 00 +3A 40 05 00 0A 59 3C 40 05 00 0C 59 CD 08 B0 13 +7C E3 0C 93 48 20 C2 93 D2 1E 56 24 B0 13 88 E2 +C7 0C 07 93 51 24 3C 40 03 00 0C 57 CD 0A 2E 42 +B0 13 BA F2 6C 43 CD 07 B0 13 AA BD 4C 93 03 24 +D2 93 D6 1E 04 20 CC 07 B0 13 FC F4 3D 3C 5F 42 +D6 1E CE 0F 5E 53 C2 4E D6 1E 4F 4F DF 47 0B 00 +D4 1E C7 48 0A 00 E7 43 00 00 F9 90 40 00 13 00 +02 20 5F 43 02 3C 7F 40 03 00 C7 4F 01 00 D1 47 +09 00 06 00 B0 13 22 F5 C1 4C 07 00 B0 13 A8 B0 +B0 13 96 B0 CD 01 B0 13 B6 B0 D5 27 B0 13 7E B0 +0C 93 12 24 D0 3F B0 13 A8 B0 D1 4C 09 00 06 00 +B0 13 22 F5 C1 4C 07 00 B0 13 96 B0 CD 01 B0 13 +B6 B0 02 24 B0 13 7E B0 31 52 37 16 10 01 3C 40 +03 00 0C 59 CD 0A 2E 42 B0 13 BA F2 CC 09 4D 43 +B0 13 30 E8 10 01 3E 40 07 00 5E F9 0A 00 3F 40 +03 00 4F 8E 6C 43 10 01 F1 40 81 00 08 00 D1 49 +0D 00 09 00 10 01 2D 52 6E 42 B0 13 6A CA C9 0C +09 93 10 01 3B 40 80 00 01 3C 0B 43 0A 14 09 14 +08 14 07 14 21 83 3F B0 80 7F 7B 24 3D B0 80 7F +05 20 0C 4E 0D 4F 8B 10 0D EB 73 3C 5D 02 08 4D +4D 10 38 F0 00 FF 0D D8 5F 02 08 4F 4F 10 38 F0 +00 FF 0F D8 09 4C 0A 4D 3D F0 80 00 C1 4D 00 00 +0B EA 0B EF 3B C0 7F FF 3A D0 80 00 3F D0 80 00 +0A 9F 02 20 09 9E 0A 24 0B 2C 0D 4F 0F 4A 0A 4D +0C 4E 0E 49 09 4C 81 EB 00 00 02 3C 0B 93 4F 20 +0C 43 08 4A 88 10 47 48 8F 10 48 8F 8F 10 0E 24 +38 90 19 00 34 2C 12 C3 4F 10 5E 00 5C 00 3C B0 +00 10 02 24 3C D0 00 20 18 83 F5 23 0B 93 0C 24 +08 8C 09 7E 4A 7F 0C 48 4A 93 12 30 5C 02 09 69 +4A 6A 17 83 2C 24 F8 3F 09 5E 4A 6F 09 28 4A 10 +59 00 5C 00 3C B0 00 10 02 24 3C D0 00 20 17 53 +3C B0 00 80 07 24 09 63 4A 63 07 63 3C B0 00 60 +01 20 19 C3 17 93 13 38 37 90 FF 00 13 34 7A C0 +80 00 87 10 D1 51 00 00 00 00 57 00 0A D7 0C 49 +0D 4A 21 53 07 16 08 16 09 16 0A 16 10 01 0D 43 +0C 43 F7 3F 3D 40 FF FE D1 61 00 00 00 00 5D 00 +3C 43 EF 3F 0A 14 B0 13 14 F3 B0 13 F4 E3 7C 40 +0A 00 B0 13 CC F4 7C 40 06 00 B0 13 D2 F4 82 43 +BE 1E 82 43 C0 1E 7C 40 05 00 B0 13 A6 F4 7C 40 +0C 00 5D 42 94 1E B0 13 2C E4 92 43 BA 1E 7C 40 +17 00 6D 43 B0 13 10 B3 6D 43 B0 13 1A B3 6D 43 +B0 13 30 F0 4C 43 B0 13 10 ED 0C 93 2A 20 4C 43 +1D 42 BE 1E 1E 42 C0 1E B0 13 52 E1 4C 43 B0 13 +52 D7 7A 40 28 00 04 3C 3C 40 99 19 B0 13 5A DA +4C 43 B0 13 10 ED 2C 93 04 20 CF 0A 5A 83 4F 93 +F3 23 4A 93 0E 20 7C 40 46 00 3D 40 0E F9 5E 43 +B0 13 D6 BC 2E 42 3C 40 00 40 B0 13 5A DA 1E 83 +FA 23 4C 43 B0 13 10 ED 1C 93 0D 24 7C 40 17 00 +6D 42 B0 13 10 B3 6D 42 B0 13 1A B3 6D 42 B0 13 +30 F0 4C 43 23 3C A2 43 BA 1E 82 93 C0 1E 0A 20 +82 93 BE 1E 07 20 4C 43 B0 13 C8 E9 82 4C BE 1E +82 4D C0 1E 7C 40 17 00 7D 40 03 00 B0 13 10 B3 +7D 40 03 00 B0 13 1A B3 7D 40 03 00 B0 13 30 F0 +7C 40 13 00 6D 43 B0 13 30 F0 5C 43 0A 16 10 01 +B0 13 30 F0 7C 40 18 00 10 01 B0 13 30 F0 7C 40 +19 00 10 01 1D 42 90 1C 3D 80 00 80 1D C3 5F 42 +7A 1D 2F 83 03 24 1F 83 2D 24 10 01 D2 93 9F 1D +15 24 E2 93 9F 1D 6A 20 5C 02 1F 4C A4 1D B0 13 +34 B4 5F 0E 3F 80 00 80 82 4F B8 1D 3E 40 7D 1D +7F 40 03 00 B0 13 1E B4 FD 2B 10 01 1F 42 A0 1D +0F 5C B0 13 34 B4 1C 52 A0 1D 5C 0E 3C 80 00 80 +82 4C B8 1D 3E 40 7D 1D 7F 40 03 00 B0 13 1E B4 +FD 2B 10 01 1F 42 86 1E 7F F0 C0 00 4F 5F 3E 40 +7F 00 5E F2 A0 1E 4E DF C2 4E 7B 1D D2 42 A1 1E +7C 1D D2 42 A2 1E 7D 1D 1E 42 34 1F CF 0E 8F 10 +C2 4F 7E 1D C2 4E 7F 1D D2 42 32 1F 80 1D D2 42 +31 1F 81 1D C2 43 82 1D C2 43 83 1D 1E 42 7E 1E +CF 0E 8F 10 8F 11 C2 4F 84 1D C2 4E 85 1D 1E 42 +82 1E CF 0E 8F 10 8F 11 C2 4F 86 1D C2 4E 87 1D +D2 42 8D 1C 88 1D D2 42 8E 1C 89 1D CF 0D 8F 10 +C2 4F 8A 1D C2 4D 8B 1D C2 43 8C 1D 10 01 1E 53 +1D 42 B8 1D EE 4D FF FF 92 53 B8 1D 5F 53 7F 90 +13 00 10 01 CE 0F 8E 10 C2 4E 7B 1D C2 4F 7C 1D +10 01 A2 D3 86 1E 82 93 D8 1E 03 24 A2 B2 86 1E +68 20 B2 B0 20 00 D8 1E 5B 20 B2 B0 40 00 D8 1E +4B 20 82 93 D8 1E 69 24 92 B3 D8 1E 32 20 A2 B3 +D8 1E 1A 20 A2 B2 D8 1E 0D 20 B2 B2 D8 1E 5D 24 +1F 42 42 1F 0F 0F 6C 43 4F 13 B2 D2 14 1D B2 C2 +D8 1E 53 3C 1F 42 40 1F 0F 0F 5C 43 4F 13 A2 D2 +14 1D A2 C2 D8 1E 49 3C C2 43 EB 1E 6C 43 6D 42 +80 13 90 1E 1F 42 42 1F 1F 4F 10 00 82 4F 42 1F +00 18 D2 4F 08 00 90 1E B2 D2 14 1D A2 C3 D8 1E +34 3C 5C 43 6D 42 80 13 8C 1E 1F 42 40 1F 1F 4F +10 00 82 4F 40 1F 00 18 D2 4F 08 00 8C 1E A2 D2 +14 1D 92 C3 D8 1E 21 3C B2 F0 BF FF D8 1E 1F 42 +42 1F 3F 0F 04 00 6C 43 4F 13 92 D3 14 1D 15 3C +B2 F0 DF FF D8 1E 1F 42 40 1F 3F 0F 04 00 5C 43 +F3 3F E2 B3 01 02 03 24 D2 B3 01 02 04 20 92 D3 +8A 1E B2 D2 8A 1E 82 43 D8 1E 82 93 86 1E 09 24 +92 B3 86 1E 06 24 92 C3 86 1E B0 13 D6 F3 92 D3 +14 1D A2 C3 86 1E 10 01 1A 14 C9 0C 1A 42 A6 1E +4D 4D 1D 5A 0C 00 0D 8E 3D 80 13 00 0D 93 78 34 +3E 40 1A 00 1E 52 A6 1E 6F 4E 3F F0 03 00 1F 83 +4F 24 1F 83 2C 20 CA 43 12 00 2F 42 6F BE 1A 20 +1C 42 A6 1E D2 9C 11 00 AA 1E 09 2C C2 93 AC 1E +03 20 B0 13 AA D7 09 3C 8C 43 18 00 06 3C B0 13 +8C D5 1F 42 A6 1E DF 53 11 00 CC 09 5D 43 B0 13 +92 E0 4E 3C EE C2 00 00 1F 42 A6 1E 8F 43 00 00 +8F 43 02 00 1C 42 A6 1E B0 13 AA D7 41 3C 3C 40 +80 00 5C 8A 13 00 CF 0A 2D 4F 1E 4F 02 00 3F 40 +00 02 B0 13 14 DD 1C 5A 0C 00 3C 50 00 02 8A 4C +0C 00 1F 42 A6 1E CF 43 0F 00 3F 40 1A 00 1F 52 +A6 1E 3E 40 FC 00 6E FF 5E D3 CF 4E 00 00 20 3C +3C 40 40 00 5C 8A 13 00 2D 4A 1E 4A 02 00 3F 40 +80 1C B0 13 14 DD 1F 42 A6 1E 1C 5F 0A 00 3C 50 +00 06 8F 4C 0C 00 1F 42 A6 1E DF 43 0F 00 3F 40 +1A 00 1F 52 A6 1E 6E 4F 5E C3 6E D3 CF 4E 00 00 +19 16 10 01 21 83 4E 4E 1E 83 48 24 1E 83 2C 24 +2E 83 1E 24 2E 82 13 24 3E 82 72 20 D2 B3 8C 1C +6F 24 E2 B3 8C 1C 6C 20 F2 90 65 00 92 1C 68 28 +B0 13 58 EF 4C 93 64 24 B0 13 04 C5 61 3C D2 B3 +8C 1C 5E 24 E2 B3 8C 1C 5B 20 B0 13 44 E9 58 3C +D2 B3 8C 1C 55 20 7C 40 40 00 B0 13 0E E0 5C 53 +7C 90 4F 00 FA 2B 4C 3C D2 B3 8C 1C 14 24 E2 B3 +8C 1C 11 20 D2 B3 92 1C 05 24 81 43 00 00 CC 01 +B0 13 64 B7 B1 40 FE FF 00 00 CC 01 6D 43 B0 13 +44 E9 B0 13 04 C5 D2 C3 8C 1C 32 3C 5F 42 8C 1C +1F F3 5E 42 8C 1C 2E F3 0E DF 0E 93 29 20 C2 43 +92 1C D2 42 8E 1C 8F 1C B1 40 FB FF 00 00 CC 01 +6D 43 B0 13 44 E9 3C 40 8D 1C B0 13 64 B7 3C 40 +8E 1C B0 13 64 B7 3C 40 31 1F B0 13 64 B7 3C 40 +32 1F B0 13 64 B7 3C 40 34 1F 6D 43 B0 13 44 E9 +3C 40 A0 1E 7D 40 03 00 B0 13 44 E9 D2 D3 8C 1C +21 53 10 01 5D 43 B0 13 44 E9 10 01 1A 14 31 80 +18 00 B0 13 EA F4 C9 0C B0 13 02 F5 81 4C 10 00 +CF 01 2F 52 81 4F 12 00 F1 42 14 00 7A 40 03 00 +C1 4A 15 00 CD 01 3D 50 06 00 3C 40 EC 1E B0 13 +DE F0 D1 43 04 00 D1 42 F4 1E 05 00 D1 43 0A 00 +B0 13 26 F5 C1 4C 0B 00 2C 43 3D 40 03 00 CE 01 +3E 50 10 00 B0 13 F6 C2 C1 4A 15 00 CF 01 2F 52 +81 4F 12 00 CF 01 3F 50 0C 00 81 4F 10 00 79 90 +03 00 06 24 59 93 02 20 B0 13 2E EE B0 13 18 EF +B0 13 74 E5 3A 40 06 00 79 90 03 00 07 24 59 93 +03 24 B0 13 F8 EE 02 3C B0 13 58 ED 2C 43 2D 43 +CE 01 3E 50 10 00 B0 13 F6 C2 0C 93 1D 20 3F 40 +7F 00 5F F1 04 00 5F 93 03 24 7F 90 06 00 14 20 +CC 01 CD 01 3D 50 06 00 2E 42 B0 13 BA F2 2C 41 +1D 41 02 00 B0 13 02 F3 CC 01 3C 50 0C 00 B0 13 +2A F4 D2 53 F4 1E 0A 43 CC 0A 31 50 18 00 19 16 +10 01 0A 14 21 83 C1 43 00 00 F2 90 03 00 00 1E +6B 20 7C 40 3B 00 B0 13 30 DE CE 0C 7C 40 3B 00 +B0 13 30 DE 4E 9C F9 23 4E 93 61 24 CC 01 5D 43 +B0 13 70 E7 6F 41 3F 50 03 00 4E 4E 0E 9F 38 20 +F1 90 1F 00 00 00 34 2C F1 90 0B 00 00 00 30 28 +3C 40 01 1E 0D 43 3E 40 1F 00 B0 13 CC F2 E2 41 +01 1E 3C 40 02 1E 6D 41 B0 13 70 E7 3C 40 20 1E +6D 43 B0 13 70 E7 F2 B0 80 FF 21 1E 14 24 92 53 +34 1E 82 63 36 1E B0 13 CE E1 4C 93 30 20 5C 42 +20 1E B0 13 90 E8 C2 4C 20 1E F2 F0 7F 00 21 1E +B0 13 D8 EE 24 3C 92 53 30 1E 82 63 32 1E 1F 3C +92 53 38 1E 82 63 3A 1E 0A 42 32 C2 03 43 7C 40 +36 00 B0 13 EA CF 7C 40 3D 00 B0 13 EA CF 7C B0 +F0 FF F9 23 7C 40 3A 00 B0 13 EA CF 7C 40 34 00 +B0 13 EA CF 02 4A 03 3C 32 C2 03 43 FF 3F 21 53 +0A 16 10 01 21 82 D2 83 8F 1C 66 20 5F 42 8D 1C +5F 93 51 24 6F 93 4C 24 6F 92 3F 24 7F 90 07 00 +2B 24 7F 90 03 00 22 24 7F 90 05 00 12 24 7F 90 +06 00 45 20 1E 42 7E 1E CF 0E 5F 0D C1 4F 00 00 +B0 13 2C BA C1 4E 01 00 C1 4D 02 00 7D 40 03 00 +36 3C D1 42 C2 1E 00 00 1E 42 82 1E CF 0E 8F 10 +8F 11 C1 4F 01 00 C1 4E 02 00 F0 3F D1 42 C2 1E +00 00 1E 42 7E 1E F2 3F D1 42 C2 1E 00 00 1E 42 +7E 1E CF 0E 5F 0D C1 4F 01 00 B0 13 2C BA C1 4E +02 00 C1 4D 03 00 6D 42 12 3C 1E 42 82 1E CF 0E +8F 10 8F 11 C1 4F 00 00 C1 4E 01 00 6D 43 07 3C +1E 42 7E 1E F4 3F D1 42 C2 1E 00 00 5D 43 CC 01 +7E 42 B0 13 64 B6 D2 42 8E 1C 8F 1C 0C 43 4D 43 +7E 40 10 00 B0 13 64 B6 21 52 10 01 1D 42 82 1E +43 18 4E 5E CF 0D 8F 10 8F 11 7F F0 0F 00 4E DF +10 01 0A 14 4A 4D 10 3C B2 B0 40 00 86 1E 06 20 +7C 40 09 00 5D 43 B0 13 30 F0 05 3C 7C 40 0B 00 +5D 43 B0 13 30 F0 2A 43 B0 13 F8 D6 1A 93 EC 27 +2A 93 13 24 2A 92 3A 20 B0 13 EE EA 7C 40 0B 00 +4D 43 B0 13 30 F0 7C 40 09 00 4D 43 B0 13 30 F0 +6C 43 4D 43 B0 13 14 BB 29 3C B2 B0 40 00 86 1E +19 20 B0 13 38 EF 3C 90 10 27 0F 34 0C 93 0F 34 +3C E3 1C 53 B0 13 FC BA 4D 43 B0 13 30 F0 7C 40 +03 00 5D 43 B0 13 30 F0 0B 3C 3C 40 0F 27 B0 13 +F0 BA 06 3C 1C 42 82 1E 0C 93 EA 3B B0 13 F0 BA +7C 40 46 00 CD 0B 5E 43 B0 13 D6 BC 0A 16 10 01 +B0 13 FC BA 5D 43 B0 13 14 BB 10 01 3C B0 00 80 +0D 7D 3D E3 6E 42 7F 40 03 00 B0 13 D2 C0 CB 0C +6C 43 10 01 B0 13 30 F0 7C 40 03 00 4D 43 B0 13 +30 F0 10 01 6A 14 31 80 06 00 C6 0C 09 43 3A 40 +00 1C 7F 40 03 00 81 4F 00 00 2F 46 1F 93 06 24 +0F 93 0B 20 58 46 02 00 C7 09 10 3C 5C 46 02 00 +B0 13 6A EB C7 0C 07 93 02 20 0C 43 4D 3C 58 47 +09 00 3F 40 03 00 0F 57 81 4F 02 00 24 43 0F 42 +32 C2 03 43 1E 43 6E 9A 39 20 EA 42 00 00 02 4F +3F 40 0B 00 0F 5A 6F 4F 3F F0 3F 00 4E 48 0F 9E +2A 20 25 46 15 93 0E 20 78 90 3F 00 06 20 3F 40 +03 00 0F 57 81 4F 04 00 05 3C 3F 40 07 00 0F 5A +81 4F 04 00 1C 41 04 00 1D 41 02 00 2E 42 B0 13 +7C ED 4C 4C 05 93 02 24 0C 93 0D 20 5F 4A 01 00 +2E 41 4F 9E 08 2C 09 93 02 24 D9 43 00 00 81 4F +00 00 C9 0A 04 3C DA 43 00 00 01 3C 02 4F 3A 50 +23 00 14 83 BC 23 CC 09 31 50 06 00 64 16 10 01 +4D 4D 1D 93 14 24 2D 93 31 24 2D 92 5B 20 B0 13 +EE EA 6C 43 4D 43 B0 13 C6 BC 7C 40 0F 00 4D 43 +B0 13 30 F0 7C 40 1F 00 4D 43 80 00 30 F0 B0 13 +F8 D6 7C 40 1F 00 5D 43 B0 13 30 F0 7C 40 0F 00 +5D 43 B0 13 30 F0 B2 B0 40 00 86 1E 08 20 7C 40 +1D 00 7D 40 46 00 5E 43 B0 13 78 CF 07 3C 7C 40 +1D 00 7D 40 43 00 5E 43 B0 13 78 CF B2 B0 40 00 +86 1E 04 20 B0 13 7C F1 CB 0C 02 3C 1B 42 7E 1E +0B 93 05 38 6C 43 5D 43 B0 13 C6 BC 0B 3C 3B E3 +1B 53 6C 43 4D 43 B0 13 30 F0 7C 40 03 00 5D 43 +B0 13 30 F0 CC 0B 3C B0 00 80 0D 7D 3D E3 7E 40 +03 00 5F 43 B0 13 D2 C0 CD 0C 7C 40 49 00 5E 43 +80 00 D6 BC 10 01 B0 13 30 F0 7C 40 03 00 4D 43 +B0 13 30 F0 10 01 4A 14 C9 0E 4C 4C 3C 80 46 00 +53 24 1C 83 4C 24 1C 83 46 24 1C 83 41 24 1C 83 +3B 24 3C 80 10 00 3C 90 09 00 55 2C 5C 06 00 18 +50 4C 04 BD 62 BD 00 00 5C BD 00 00 58 BD 00 00 +4E BD 00 00 46 BD 00 00 42 BD 00 00 3A BD 00 00 +32 BD 00 00 28 BD 00 00 7A 40 03 00 78 40 22 00 +2E 3C 6A 43 78 40 21 00 2A 3C 6A 43 78 40 23 00 +26 3C 6A 42 F7 3F 6A 43 78 40 25 00 20 3C 7A 40 +03 00 78 40 24 00 1B 3C 6A 42 F0 3F 7A 40 05 00 +E5 3F 7A 40 06 00 E6 3F 6A 43 78 40 1A 00 0F 3C +7A 40 03 00 FA 3F 6A 43 78 40 1C 00 08 3C 7A 40 +03 00 78 40 1B 00 03 3C 6A 42 78 40 1A 00 C7 0D +4A 4A 06 43 CC 08 4C 56 7D 47 CE 09 B0 13 78 CF +16 53 1A 83 F7 23 46 16 10 01 4A 14 21 83 C8 0D +C7 0C 39 40 41 1E CC 01 0D 43 1E 43 B0 13 CC F2 +46 43 09 98 25 24 2F 43 6F 99 22 20 5A 49 09 00 +7A 90 3E 00 1D 2C 57 93 13 24 3C 40 03 00 0C 59 +3D 40 03 00 0D 58 2E 42 B0 13 7C ED 0C 93 10 20 +4F 4A CA 01 3A 50 E0 FF 0A 5F DA 43 00 00 08 3C +C2 9A 3E 1E 05 2C 4A 4A CF 01 0F 8A DF 43 3D 00 +39 50 0C 00 56 53 D5 27 CE 01 0F 43 4C 43 CE 93 +00 00 04 24 1E 53 5C 53 FA 27 09 3C 67 93 04 20 +7C 50 20 00 4F 4C 03 3C 3F 40 3D 00 4F 8C 67 93 +0B 24 5E 42 3F 1E 0F 9E 12 38 5E 42 3E 1E 0F 9E +0F 20 D2 83 3E 1E 0C 3C 5E 42 3E 1E 0E 9F 07 38 +5E 42 3F 1E 0E 9F 04 34 C2 4F 3F 1E 01 3C 0F 43 +C8 4F 09 00 CC 0F 21 53 46 16 10 01 0A 14 CA 0C +5D 93 05 24 6D 92 34 20 C2 43 30 1F 31 3C C2 93 +30 1F 1A 20 5C 42 31 1F B0 13 14 BF 03 20 B0 13 +F4 BE 02 3C B0 13 04 BF 5C 42 32 1F B0 13 14 BF +03 20 B0 13 04 BF 02 3C B0 13 F4 BE B0 13 28 BF +5D 43 B0 13 30 F0 14 3C 1C 42 34 1F 0D 43 6E 42 +4F 43 B0 13 D2 C0 CF 0C CC 0A 7D 40 46 00 7E 40 +5C 00 B0 13 38 BF B0 13 28 BF 4D 43 B0 13 30 F0 +0A 16 10 01 CC 0A 7D 40 48 00 7E 40 5E 00 B0 13 +38 BF 10 01 CC 0A 7D 40 4A 00 7E 40 60 00 B0 13 +38 BF 10 01 0D 43 6E 43 4F 43 B0 13 D2 C0 CF 0C +B2 B0 40 00 86 1E 10 01 CC 0A 7D 40 1F 00 7E 40 +29 00 B0 13 42 F4 10 01 B0 13 42 F4 CD 0F 5E 43 +B0 13 D6 BC 10 01 1A 14 CA 0D C9 0C D2 93 00 1E +58 24 B0 13 EC E8 1D 43 6D 59 CC 09 B0 13 10 E6 +49 43 4A 93 37 24 5A 93 32 20 6A 42 16 3C 7C 40 +36 00 B0 13 EA CF 7C 40 3D 00 B0 13 EA CF 7C B0 +F0 FF F9 23 7C 40 3A 00 B0 13 EA CF 4A 93 02 20 +59 43 2B 3C B0 13 48 F1 5A 83 7C 40 34 00 B0 13 +EA CF A2 B3 30 0F FD 27 92 C3 32 0F 7C 40 35 00 +B0 13 EA CF 3C 40 19 00 B0 13 2E F1 92 B3 32 0F +D6 27 92 C3 32 0F 92 B3 30 0F FD 27 0E 3C 32 C2 +03 43 FF 3F 7C 40 35 00 B0 13 EA CF B2 B0 00 02 +32 0F FC 27 B2 F0 FF FD 32 0F 7C 40 3B 00 B0 13 +EA CF F2 90 03 00 00 1E 02 20 B0 13 C2 F1 CC 09 +03 3C 32 C2 03 43 FF 3F 19 16 10 01 B2 40 23 5A +5C 01 B0 13 BA EB F2 40 A5 00 21 01 F2 D0 80 00 +20 01 C2 43 21 01 F2 D0 03 00 4A 02 92 C3 6C 01 +B2 D0 0C 00 6C 01 82 43 66 01 B2 40 44 00 68 01 +32 D0 40 00 82 43 60 01 B2 40 50 00 62 01 B2 40 +6E 11 64 01 32 C0 40 00 1E 14 3D 40 41 D1 0E 43 +1D 83 0E 73 FD 23 0D 93 FB 23 1D 16 00 3C B2 F0 +F0 FF 6E 01 A2 C3 02 01 A2 B3 02 01 F8 23 32 C2 +03 43 B2 40 52 2D C0 01 A2 43 C2 01 F2 40 0E 00 +D7 01 F2 F0 7F 00 03 02 F2 D0 80 00 05 02 F2 40 +11 00 CD 01 F2 40 12 00 CE 01 F2 40 13 00 CF 01 +82 43 C0 01 32 D2 B0 13 A8 E6 B0 13 66 F3 B0 13 +BE E8 B0 13 C4 EA B0 13 2C EC B0 13 30 F2 80 00 +8A CE 4A 14 C8 0F C6 0E C9 0C CA 0D C7 06 3C 40 +6A 1D 3D 40 18 F9 3E 40 07 00 B0 13 BA F2 0A 93 +1C 20 39 90 B5 00 19 2C 77 90 03 00 0B 2C CD 09 +59 02 0D 59 3D 50 3B F5 3C 40 6A 1D 2E 43 B0 13 +BA F2 22 3C 4C 46 3C 50 67 1D CD 09 59 02 0D 59 +3D 50 3A F5 3E 40 03 00 F2 3F CC 09 CD 0A 3E 40 +0A 00 0F 43 B0 13 B2 D8 7E 50 30 00 4F 46 CF 4E +69 1D CC 09 CD 0A 3E 40 0A 00 0F 43 B0 13 B2 D8 +C9 0C CA 0D 56 83 E9 23 3F 40 6A 1D 4D 43 08 3C +48 93 04 24 FF 40 20 00 00 00 58 83 1F 53 5D 53 +3E 40 30 00 6E 9F 05 20 4E 47 1E 83 4C 4D 0C 9E +EF 3B 3C 40 6A 1D 46 16 10 01 0A 14 CA 0C 1F 42 +A6 1E 8F 93 02 00 10 20 8F 93 00 00 0D 20 C2 93 +AB 1E 0A 24 5E 42 AB 1E 3E 50 64 00 5D 42 3A 1F +0D 9E 02 34 4C 43 42 3C BF 40 00 70 08 00 5C 42 +B3 1E 1D 42 B0 1E 1E 42 B2 1E 3D F3 3E F0 FF 00 +3F 40 00 08 B0 13 14 DD 1C 52 38 1F 1F 42 A6 1E +8F 4C 0A 00 1F 42 A6 1E 9F 42 38 1F 0C 00 1F 42 +A6 1E CF 43 14 00 1F 42 A6 1E CF 43 15 00 1F 42 +A6 1E 8F 93 02 00 05 20 8F 93 00 00 02 20 EF D2 +1A 00 1D 42 A6 1E 1E 42 B0 1E 1F 42 B2 1E 3E F3 +3F F0 FF 00 8D 4E 00 00 8D 4F 02 00 1F 42 A6 1E +9F 43 18 00 CC 0A B0 13 7C CB 5C 43 0A 16 10 01 +3A 14 07 4F 07 ED 0A 4F 5A 02 8A 10 4A 4A 0A 93 +49 24 7F D0 80 00 0B 4D 5B 02 8B 10 4B 4B 0B 93 +3F 24 7D D0 80 00 0B 5A 3B 80 7F 00 08 43 09 43 +0E 93 09 24 1A 43 5E 00 02 28 08 5C 09 6D 59 00 +58 00 5A 02 F8 2B 0E 43 1A 43 5F 00 02 28 08 5C +09 6D 59 00 58 00 5E 00 3E B0 00 10 02 24 3E D0 +00 20 4A 5A F2 23 49 93 02 34 1B 53 03 3C 0E 6E +08 68 49 69 3E B0 00 80 07 24 08 63 49 63 0B 63 +3E B0 00 60 01 20 18 C3 1B 93 0C 38 3B 90 FF 00 +0C 34 49 59 8B 10 09 DB 57 02 59 00 0D 49 0C 48 +37 16 10 01 0C 43 0D 43 FB 3F 3D 40 FF FE 3C 43 +57 02 5D 00 F5 3F CF 0D CD 0E CE 0C C2 93 59 1E +06 20 B0 13 80 F2 4C 93 02 20 2C 43 10 01 2E 83 +2C 24 1E 83 43 24 2E 83 20 24 1E 83 3B 24 3E 80 +03 00 34 24 1E 83 30 20 0E 43 8D 93 00 00 09 20 +0F 93 2A 20 1C 4D 02 00 1D 4D 04 00 B0 13 02 F3 +31 3C 1C 43 2C 9D 20 20 0F 93 1E 20 1C 4D 02 00 +1D 4D 04 00 B0 13 F0 F2 25 3C 3F B0 FE FF 14 20 +CC 0F B0 13 C2 F0 CE 0C 1D 3C 3F 90 03 00 07 24 +2F 93 0A 20 CC 0D B0 13 00 E8 CE 0C 13 3C CC 0D +B0 13 AC DA CE 0C 0E 3C 2E 43 0C 3C B0 13 1A F5 +CE 0C 08 3C B0 13 1E F5 CE 0C 04 3C CC 0F B0 13 +9E D6 CE 0C CC 0E 10 01 0A 14 31 80 06 00 B0 13 +36 F3 2E 42 CF 01 1F 53 3D 40 9A 1D 1F 53 FF 4D +FF FF 1E 83 FB 23 3C 40 05 00 0D 43 CE 01 1E 53 +B0 13 F6 C2 D2 43 78 1D 4A 43 B0 13 18 E9 0C 93 +08 24 B0 13 3E C4 1A 2C F2 B0 20 00 78 1D F5 27 +1F 3C E1 43 00 00 3C 40 03 00 3D 40 0A 00 CE 01 +B0 13 F6 C2 4A 43 B0 13 0E F5 0C 93 04 20 E2 43 +78 1D 5C 43 10 3C B0 13 3E C4 06 28 C2 43 59 1E +E2 42 78 1D 4C 43 07 3C F2 B0 20 00 78 1D EB 27 +C2 43 59 1E 4C 43 31 50 06 00 0A 16 10 01 3C 40 +E8 03 B0 13 46 F3 B2 40 2B 5A 5C 01 CF 0A 1A 43 +4A 5F 7F 90 0B 00 10 01 31 80 0E 00 CE 01 3D 40 +00 18 4F 43 1E 53 FE 4D FF FF 5F 53 7F 90 0D 00 +F9 2B F1 93 00 00 30 24 5F 41 01 00 C2 4F 94 1E +3F 90 15 00 05 38 3F 90 EC 00 02 34 C2 43 94 1E +5F 41 04 00 47 18 0F 5F 5E 41 05 00 0E 5F 82 4E +2E 1F D2 41 06 00 9A 1D D2 41 07 00 9B 1D D2 41 +08 00 9C 1D D2 41 09 00 9D 1D F1 93 0C 00 08 24 +5F 41 0A 00 47 18 0F 5F 5E 41 0B 00 0E 5F 01 3C +0E 43 82 4E 84 1E 13 3C E2 42 94 1E B2 40 F6 FF +2E 1F F2 40 79 00 9A 1D F2 40 56 00 9B 1D F2 40 +34 00 9C 1D F2 40 12 00 9D 1D 82 43 84 1E 31 50 +0E 00 10 01 21 83 5F 42 92 1C 1D 42 90 1C 4C 4F +3E 40 FE 9D 0E 8C 0D 9E 02 2C 4B 43 09 3C 81 4D +00 00 2E 41 3F 40 FE 00 4F 8E C2 4F 92 1C 5B 43 +4E 43 15 3C 4F 4E 5D 4F 93 1C 5E 53 4F 4E 5F 4F +93 1C 47 18 0F 5F 0D 5F 5E 53 1C 42 90 1C CF 0C +2F 53 82 4F 90 1C B0 13 9A EA 5F 42 92 1C 4D 4F +1D 83 4C 4E 0C 9D E6 3B 4B 93 0C 20 5F B3 03 20 +C2 43 92 1C 1A 3C 4F 4F D2 4F 92 1C 93 1C D2 43 +92 1C 13 3C 3C 40 FE 9D 3D 40 FE FF B0 13 9A EA +C2 43 92 1C 5F 42 8C 1C 5F C3 6F D3 C2 4F 8C 1C +7C 40 15 00 6D 42 B0 13 30 F0 21 53 10 01 1A 14 +21 82 CA 0C F2 B0 40 00 01 02 42 24 B0 13 9E DB +82 4C 7C 1E 1C 52 80 1E 3C 80 A1 0A 82 4C 7E 1E +B0 13 AA D3 81 4C 00 00 81 4D 02 00 4A 93 03 20 +B0 13 46 C6 27 3C 2C 41 1D 41 02 00 B0 13 DA E6 +3E 40 CD CC 3F 40 4C 3E B0 13 40 C2 C9 0C CA 0D +1C 42 78 1E 1D 42 7A 1E B0 13 DA E6 3E 40 CD CC +3F 40 4C 3F B0 13 40 C2 CE 0C CF 0D CC 09 CD 0A +B0 13 CA B0 B0 13 EA DB 81 4C 00 00 81 4D 02 00 +B0 13 46 C6 1E 42 7C 1E B0 13 00 9E 82 4C 82 1E +21 52 19 16 10 01 1C 41 04 00 1D 41 06 00 82 4C +78 1E 82 4D 7A 1E 10 01 1A 14 21 82 39 40 CB 00 +3C 40 00 40 B0 13 5A DA 3C 40 03 00 3D 40 05 00 +0E 43 B0 13 F6 C2 D1 43 02 00 C1 49 03 00 CC 01 +2C 53 6D 43 B0 13 78 D2 3C 40 03 00 3D 42 0E 43 +B0 13 F6 C2 3C 40 0A 00 B0 13 46 F3 CC 01 B0 13 +5C DD 0C 93 18 20 C1 93 00 00 F8 27 B0 13 1A AA +4A 43 5A 92 9E 1D F2 2F 3C 40 0A 00 B0 13 46 F3 +4C 4A B0 13 24 B3 3C 40 7A 1D 7D 40 13 00 B0 13 +78 D2 5A 53 EE 3F 3C 40 03 00 2D 42 0E 43 B0 13 +F6 C2 B2 40 2B 5A 5C 01 F2 B0 20 00 78 1D B8 27 +C2 43 59 1E 21 52 19 16 10 01 5A 14 C6 0F C7 0E +C5 0D C9 0C 18 41 1C 00 C7 43 00 00 B0 13 24 BB +CA 0C 0A 93 02 20 2C 42 3C 3C 1F 43 2F 99 02 24 +09 43 09 3C 5C 49 02 00 B0 13 6A EB C9 0C 09 93 +02 20 2C 43 2E 3C 5E 4A 02 00 7E 80 0B 00 C7 4E +00 00 3D 40 0E 00 0D 5A 4E 4E CC 05 B0 13 BA F2 +09 93 06 24 D9 4A 21 00 07 00 D9 4A 22 00 08 00 +06 93 07 24 3D 40 07 00 0D 5A CC 06 2E 42 B0 13 +BA F2 08 93 06 24 3F 40 07 00 5F FA 0C 00 C8 4F +00 00 5D 4A 01 00 5C 43 B0 13 70 E9 CA 43 00 00 +0C 43 55 16 10 01 4F 43 4C 93 2D 24 5C 93 20 24 +6C 93 13 24 7C 90 03 00 2A 20 A2 D2 22 03 A2 C2 +24 03 B2 C2 22 03 B0 13 32 F5 B0 13 24 C8 1F 42 +20 03 6F F2 B2 C2 22 03 1A 3C A2 D2 24 03 B0 13 +12 C8 B0 13 24 C8 A2 D2 22 03 B0 13 32 F5 0F 3C +A2 D2 24 03 B2 C2 22 03 A2 D2 22 03 B0 13 32 F5 +B0 13 08 C8 04 3C A2 D2 24 03 B0 13 08 C8 4C 43 +4F 93 01 20 5C 43 10 01 B0 13 24 C8 B0 13 12 C8 +10 01 A2 C2 22 03 B0 13 32 F5 B2 C2 22 03 B0 13 +32 F5 10 01 B2 D2 22 03 B0 13 32 F5 10 01 1A 14 +CB 0C 7B 90 BD 00 07 24 4C 43 7B 90 31 00 40 28 +7B 90 3D 00 3D 2C 0A 42 32 C2 03 43 B2 F0 BF FF +02 0F B2 B0 10 00 02 0F FC 27 7B 90 3D 00 26 2C +4C 43 B0 13 D8 F1 C9 0C 4C 43 7D 40 29 00 B0 13 +2C E4 C2 4B 11 0F A2 B2 30 0F 13 24 7B 90 32 00 +10 24 7B 90 39 00 0D 24 7B 90 38 00 0A 24 A2 B2 +30 0F FD 23 0D 14 3D 40 BF 0C 1D 83 FE 23 0D 16 +03 43 4C 43 CD 09 B0 13 2C E4 03 3C F2 40 BD 00 +11 0F 5C 42 21 0F B2 B0 40 00 02 0F FC 27 02 4A +19 16 10 01 3A 14 07 4F 07 ED 0A 4F 5A 02 8A 10 +4A 4A 0A 93 38 24 7F D0 80 00 0B 4D 5B 02 8B 10 +4B 4B 0B 93 2B 24 7D D0 80 00 0B 8A 3B 50 7F 00 +3A 40 18 00 08 43 09 43 0C 8E 0D 7F 03 2C 0C 5E +0D 6F 12 C3 08 68 09 69 5C 02 0D 6D 1A 83 F4 23 +49 93 03 30 1A 53 1B 83 EF 3F 0C 7E 0D 7F 08 63 +49 63 0B 63 1B 93 0C 38 3B 90 FF 00 0C 34 49 59 +8B 10 09 DB 57 02 59 00 0D 49 0C 48 37 16 10 01 +0C 43 0D 43 FB 3F 3C 40 FF FE 3D 43 57 02 5D 00 +F5 3F 2A 14 21 83 C9 0C 3F 40 0B 00 0F 59 68 4F +3A 40 3F 00 4A F8 3C 40 07 00 0C 59 1D 42 C6 1E +2E 42 B0 13 7C ED 0C 93 2D 24 78 B0 40 00 2A 20 +4A 93 10 24 7A 90 07 00 0D 2C 4A 4A 5A 06 00 18 +5F 4A 54 FA 2C 43 0C 59 4F 13 1C 93 1B 20 D9 43 +00 00 1A 3C 7A 90 3F 00 03 24 7A 90 20 00 12 28 +2C 43 0C 59 CD 01 B0 13 DE C9 4C 93 0B 24 D9 43 +00 00 00 18 C2 93 CA 1E 07 24 6C 41 80 13 CA 1E +4C 93 02 24 C9 43 00 00 21 53 28 16 10 01 4A 14 +C7 0D C8 0C 39 40 41 1E 3A 40 3F 00 5A F8 09 00 +26 43 2F 43 6F 99 32 20 5A 99 09 00 2F 20 7A 90 +3F 00 0B 24 3C 40 03 00 0C 59 3D 40 05 00 0D 58 +2E 42 B0 13 7C ED 0C 93 21 20 D7 49 0B 00 00 00 +57 43 7A 90 3F 00 16 24 3F 40 0A 00 0F 58 6F 4F +7F B0 80 FF 0A 20 7F B2 0D 24 D9 98 0B 00 02 00 +02 20 C9 43 02 00 47 43 05 3C 5D 49 0A 00 CC 08 +B0 13 0E CE B0 13 BE F3 CC 07 05 3C 39 50 0C 00 +16 83 C7 23 4C 43 46 16 10 01 4A 14 C9 0F C7 0E +C6 0D CA 0C 6C 43 B0 13 02 CF C8 0C 08 93 02 20 +0C 43 36 3C CF 07 7F 50 0B 00 C8 4F 02 00 3E 40 +0B 00 0E 58 3F 40 80 00 6F FE 4F DA CE 4F 00 00 +D8 42 C4 1E 0D 00 D2 53 C4 1E FD 27 F8 F0 BF 00 +0C 00 5F 48 0C 00 7F F0 F8 00 4F D9 C8 4F 0C 00 +F8 F0 7F 00 0C 00 F8 C2 0C 00 FE F0 7F 00 00 00 +3C 40 0E 00 0C 58 4E 47 CD 06 B0 13 BA F2 3C 40 +07 00 0C 58 1D 42 C6 1E 2E 42 B0 13 BA F2 CC 08 +46 16 10 01 5C 43 B0 13 44 D6 5C 43 6D 42 80 13 +8C 1E B0 13 0C E7 7C 40 17 00 6D 43 B0 13 30 F0 +7C 40 18 00 6D 43 B0 13 30 F0 7C 40 19 00 6D 43 +B0 13 30 F0 B0 13 14 F3 B2 40 03 00 72 1D B2 40 +10 0E 74 1D B0 13 A8 C3 4C 93 02 24 B0 13 58 C6 +82 43 72 1D B0 13 56 F3 3C 40 00 20 B0 13 5A DA +C2 43 1D 02 82 43 D8 1E 7C 40 17 00 6D 42 B0 13 +30 F0 7C 40 18 00 6D 42 B0 13 30 F0 7C 40 19 00 +6D 42 B0 13 30 F0 92 D3 14 1D 10 01 1F 42 A6 1E +CF 43 11 00 1F 42 A6 1E DF 42 B3 1E 13 00 1F 42 +A6 1E 5E 42 38 1F 5E 8F 0C 00 CF 4E 16 00 1F 42 +A6 1E 5E 4F 16 00 8E 11 8F 5E 0A 00 1F 42 A6 1E +DF 5F 16 00 15 00 1F 42 A6 1E DF 42 3A 1F 12 00 +1F 42 A6 1E FF 92 12 00 02 2C FF 42 12 00 1F 42 +A6 1E 9F 42 B4 1E 04 00 9F 42 B6 1E 06 00 1F 42 +A6 1E DF 42 B8 1E 0E 00 1F 42 A6 1E EF B2 1A 00 +03 20 4D 43 B0 13 92 E0 B0 13 8C D5 D2 C3 36 1F +10 01 1E 42 A6 1E 5F 4E 15 00 8F 11 3F 90 40 00 +10 34 3F 90 C1 FF 19 34 FE 50 40 00 15 00 1F 42 +A6 1E 9F 83 08 00 1F 42 A6 1E 5F 4F 15 00 8F 11 +0C 3C FE 80 40 00 15 00 1F 42 A6 1E 9F 53 08 00 +1F 42 A6 1E 5F 4F 15 00 8F 11 1E 42 A6 1E CE 5F +14 00 1E 42 A6 1E 5F 4E 14 00 8F 11 3F 90 40 00 +0B 34 3F 90 C1 FF 0F 34 FE 50 40 00 14 00 1F 42 +A6 1E 9F 83 0A 00 10 01 FE 80 40 00 14 00 1F 42 +A6 1E 9F 53 0A 00 10 01 0A 14 5F 42 32 1F 3F 90 +07 00 0E 34 3F 90 06 00 31 24 1F 83 32 24 1F 83 +14 24 1F 83 2E 24 1F 83 29 24 1F 83 2A 24 2C 3C +3F 80 07 00 2F 93 25 28 2F 83 20 24 1F 83 21 24 +1F 83 1C 24 1F 83 1D 24 1F 3C 1A 42 34 1F 3A B0 +03 00 0E 20 CC 0A 3D 40 64 00 B0 13 04 F2 0E 93 +0A 20 CC 0A 3D 40 90 01 B0 13 04 F2 0E 93 03 24 +7C 40 1C 00 0A 3C 7C 40 1D 00 07 3C 7C 40 1E 00 +04 3C 7C 40 1F 00 01 3C 4C 43 0A 16 10 01 3C 40 +3D 1E 0D 43 3E 40 1C 00 B0 13 CC F2 E2 43 3D 1E +F2 40 3D 00 3E 1E F2 40 20 00 3F 1E D2 43 40 1E +B0 13 9E EC B0 13 78 EF B0 13 A6 F0 B0 13 6C F4 +B0 13 92 EB B0 13 62 F4 B0 13 D0 E7 3F 40 41 1E +CF 43 00 00 3F 50 0C 00 CF 43 00 00 C2 93 4D 1E +15 20 E2 43 4D 1E F2 40 03 00 4E 1E 7F 40 3F 00 +C2 4F 56 1E C2 4F 57 1E F2 43 58 1E B0 13 02 F5 +CD 0C 3C 40 50 1E 2E 42 B0 13 BA F2 0C 43 10 01 +7C 40 36 00 B0 13 2E C8 F2 B0 10 00 36 1F 27 24 +7C 40 0A 00 5D 42 FA 1E B0 13 2C E4 F2 90 7F 00 +FB 1E 07 38 7C 40 0C 00 7D 40 0C 00 B0 13 2C E4 +06 3C 7C 40 0C 00 5D 42 FB 1E B0 13 2C E4 F2 B2 +36 1F 07 20 7C 40 12 00 7D 40 11 00 B0 13 2C E4 +06 3C 7C 40 12 00 7D 40 15 00 B0 13 2C E4 7C 40 +34 00 B0 13 2E C8 B2 F0 FE FD 32 0F B2 F0 FE FD +32 0F B2 D0 01 02 36 0F A2 43 1E 1F 10 01 1A 14 +31 80 22 00 C9 0D 5A 4C 0B 00 3F 40 CF 00 5F F1 +0A 00 5F D2 C8 1E 7F F0 BF 00 C1 4F 0A 00 3D 40 +05 00 0D 5C CC 01 1C 53 2E 42 B0 13 BA F2 CC 01 +3C 50 05 00 1D 42 C6 1E 2E 42 B0 13 BA F2 3D 40 +C0 00 5D F1 09 00 4D D9 F1 40 0B 00 00 00 C1 4A +0B 00 3F 40 70 00 5F F1 0A 00 7F D0 0B 00 C1 4F +0A 00 7D F0 3F 00 C1 4D 09 00 CC 01 4D 43 B0 13 +46 BF 31 50 22 00 19 16 10 01 21 82 F2 F0 BF 00 +05 02 F2 F0 BF 00 19 02 B2 D0 0C 00 22 03 B2 D0 +0C 00 24 03 C2 43 FE 1D 3C 40 CC 0C B0 13 5A DA +7C 40 06 00 5D 43 B0 13 5A D8 C1 4C 00 00 3C 40 +CC 0C B0 13 5A DA 7C 40 07 00 4D 43 B0 13 5C D0 +C1 4C 01 00 D1 B3 01 00 12 20 C1 93 01 00 0F 24 +7C 40 7F 00 4D 43 B0 13 5C D0 C1 4C 02 00 D1 93 +02 00 03 24 C2 43 FE 1D 02 3C D2 43 FE 1D 21 52 +10 01 2A 14 5C 93 03 20 3F 40 00 1C 02 3C 3F 40 +46 1C 2D 43 08 43 CB 08 4E 43 79 40 03 00 CF 93 +00 00 06 20 6C 93 02 20 CC 0F 24 3C CB 0F 0C 3C +5C 93 0A 20 5E 53 2A 42 6A 9F 06 24 5A 4F 01 00 +4A 99 02 2C C8 0F C9 0A 3F 50 23 00 1D 83 E7 23 +0B 93 0C 20 08 93 02 20 0C 43 0C 3C CB 08 5D 4B +01 00 B0 13 70 E9 EB 43 01 00 03 3C 5E 53 CB 4E +01 00 CC 0B 28 16 10 01 1A 14 CF 0E CA 0C 7A 90 +1A 00 31 28 7A 90 2A 00 2E 2C 4E 4A 5E 02 1C 4E +16 1D 4E 4A 5E 4E C2 F9 7D 90 30 00 05 2C 7D 90 +2D 00 05 20 6B 43 08 3C 7D 90 5B 00 02 28 4B 43 +03 3C 4B 4D 5B 4B 66 F9 7A 90 21 00 11 28 C9 0B +43 18 49 59 43 19 4B 10 4B D9 7A 90 21 00 08 20 +7D 90 31 00 03 24 7D 90 4C 00 02 20 7B 40 80 00 +CD 0B B0 13 2E D5 19 16 10 01 0A 14 CE 0C 0B 42 +32 C2 03 43 B2 F0 BF FF 02 0F B2 B0 10 00 02 0F +FC 27 7E 90 31 00 23 28 7E 90 3D 00 20 2C 4C 43 +B0 13 30 DE CA 0C 4C 43 7D 40 29 00 B0 13 DC E5 +C2 4E 11 0F A2 B2 30 0F 0D 24 7E 90 32 00 0A 24 +7E 90 38 00 07 24 A2 B2 30 0F FD 23 3C 40 F8 02 +B0 13 2E F1 4C 43 CD 0A B0 13 DC E5 02 3C C2 4E +11 0F 5C 42 21 0F 02 4B 0A 16 10 01 0A 14 CB 0D +CA 0C 4C 43 B0 13 96 C7 7C 40 22 00 B0 13 BE D0 +0C 24 CC 0A B0 13 BE D0 08 24 5C 43 B0 13 96 C7 +7C 40 23 00 B0 13 BE D0 02 20 0C 43 16 3C 5B 93 +05 24 4C 43 B0 13 FE DA 4D 4C 0B 3C 5C 43 B0 13 +FE DA 4C 4C 4D 4C 8D 10 4C 43 B0 13 FE DA 4C 4C +0D DC 6C 43 B0 13 96 C7 CC 0D 0A 16 10 01 B0 13 +50 E0 7C 40 03 00 B0 13 96 C7 4C 93 10 01 7C 40 +36 00 B0 13 2E C8 4C 43 3D 40 EC F9 7E 40 27 00 +B0 13 00 DF 7C 40 2C 00 7D 40 88 00 B0 13 2C E4 +7C 40 2D 00 7D 40 31 00 B0 13 2C E4 7C 40 2E 00 +7D 40 09 00 B0 13 2C E4 7C 40 36 00 B0 13 2E C8 +7C 40 33 00 B0 13 2E C8 7C 40 3D 00 B0 13 2E C8 +7C B0 70 00 F9 23 7C 40 36 00 B0 13 2E C8 82 43 +1E 1F B2 D0 01 02 34 0F 82 43 32 0F 10 01 0A 14 +CA 0D CB 0C 7B 93 02 24 CF 0B 02 3C 4B 43 4F 43 +4E 4B 4F 4F 0F 8E 1F 53 4C 4B 3D 40 1C 00 B0 13 +1A F2 1C 52 7A FA 4A 93 09 24 8C 43 00 00 8C 43 +02 00 CC 43 1A 00 FC 40 7F 00 10 00 8C 43 18 00 +FC F0 FC 00 1A 00 8C 43 04 00 8C 43 06 00 CC 43 +0E 00 CC 43 12 00 CC 43 0F 00 CC 43 11 00 5B 53 +1F 83 DA 23 0A 16 10 01 B0 13 02 D8 5C 06 3D 40 +29 00 B0 13 04 F2 1F 42 2E 1F 0F 5C 3F 90 69 01 +03 2C 1C 42 2C 1F 03 3C 1C 42 2C 1F CF 0C 5C 06 +0C 5F 5C 02 3D 40 0A 00 B0 13 04 F2 82 4C 2C 1F +3C 90 F0 00 08 28 B2 F0 DF FF 86 1E 7C 42 4D 43 +B0 13 30 F0 07 3C B2 D0 20 00 86 1E 7C 42 5D 43 +B0 13 30 F0 B2 D2 14 1D B2 D0 80 00 14 1D 10 01 +1A 14 21 82 CA 0C 3C 40 05 00 0C 5A 5D 4A 0E 00 +B0 13 40 E3 0C 93 02 20 3F 42 03 3C B0 13 FC F4 +0F 43 F1 40 82 00 00 00 D1 4A 0D 00 01 00 C1 4F +02 00 6C 43 CD 01 7E 40 03 00 7F 40 03 00 B0 13 +6A CA C9 0C 09 93 0D 24 3C 40 03 00 0C 59 3D 40 +05 00 0D 5A 2E 42 B0 13 BA F2 CC 09 4D 43 B0 13 +30 E8 21 52 19 16 10 01 2A 14 C8 0D C9 0C 5C 42 +FF 1D B0 13 6A EB CA 0C B0 13 EA F4 0A 93 24 24 +CC 0A 5D 43 B0 13 78 EC 0C 93 1F 20 09 93 1D 24 +5C 4A 0A 00 5F 4A 01 00 CD 09 CE 08 B0 13 6A CA +C9 0C 09 93 0E 24 3C 40 03 00 0C 59 3D 40 03 00 +0D 5A 2E 42 B0 13 BA F2 CC 09 5D 43 B0 13 30 E8 +04 3C 3C 40 03 00 01 3C 2C 43 28 16 10 01 0E 42 +32 C2 03 43 4C 93 2C 24 4F 4C 3F 50 00 7E B2 B0 +10 00 02 0F FC 27 82 4F 10 0F B2 B0 10 00 02 0F +FC 27 F2 40 3D 00 11 0F B2 B0 10 00 02 0F FC 27 +F2 40 FE 00 11 0F B2 B0 20 00 02 0F FC 27 C2 43 +10 0F B2 B0 80 00 02 0F FC 27 5D 42 20 0F B2 B0 +10 00 02 0F FC 27 F2 40 3D 00 11 0F 4D 9C D7 23 +02 4E 10 01 0A 14 CA 0D 6A 92 1A 24 B0 13 FA F3 +4C 93 08 20 7C 40 47 00 3D 40 20 F9 5E 43 B0 13 +D6 BC 0E 3C 5C 42 C2 1E 0D 43 7E 40 03 00 6F 43 +B0 13 D2 C0 CD 0C 7C 40 47 00 5E 43 B0 13 D6 BC +B0 13 FA F3 4C 93 0F 20 5A 93 08 24 6A 92 0B 20 +7C 40 13 00 4D 43 B0 13 30 F0 05 3C 7C 40 13 00 +5D 43 B0 13 30 F0 0A 16 10 01 21 82 81 43 00 00 +81 43 02 00 7C 40 7F 00 4D 43 B0 13 5C D0 81 4C +00 00 81 43 02 00 2C 41 1F 41 02 00 47 18 0C 5C +0D 43 3C F0 00 07 0D F3 B0 13 28 E2 81 4C 00 00 +81 4D 02 00 7C 40 80 00 5D 43 B0 13 5C D0 81 DC +00 00 12 C3 11 10 02 00 11 10 00 00 12 C3 11 10 +02 00 11 10 00 00 2C 41 1D 41 02 00 21 52 10 01 +1F 42 38 0F 1E 42 0E 0F 0E 93 14 20 0F 93 28 24 +3F 90 14 00 0C 20 B2 B0 00 02 36 0F 03 20 32 C2 +03 43 FF 3F B2 F0 FF FD 32 0F 80 00 62 B8 32 C2 +03 43 FF 3F 2E 93 11 20 1F 42 0C 0F 2F 93 0A 24 +2F 92 08 24 3F 90 06 00 05 24 3F 92 03 24 32 C2 +03 43 FF 3F 32 C2 03 43 FF 3F 32 C2 03 43 FF 3F +10 01 B2 F0 FE FD 36 0F B2 F0 FE FD 32 0F B2 F0 +FE FD 32 0F 92 43 1E 1F 7C 40 32 00 B0 13 D8 F1 +C2 4C 20 1F 7C 43 3D 40 B0 1E 7E 40 0A 00 B0 13 +BC DE 7C 43 B0 13 D8 F1 C2 4C 3A 1F 7C B0 80 FF +04 20 F2 80 80 00 3A 1F 03 3C F2 F0 7F 00 3A 1F +1F 42 22 1F 3F 80 10 00 82 4F 38 1F 80 00 90 E1 +B2 40 5A F8 40 1F B2 40 B4 F8 42 1F 00 18 D2 42 +62 F8 8C 1E 00 18 D2 42 BC F8 90 1E 82 43 D8 1E +82 43 86 1E 82 43 88 1E 82 43 14 1D 82 43 8A 1E +92 D3 14 1D B2 D0 40 00 86 1E B0 13 58 C4 B0 13 +C4 ED B0 13 94 F2 B0 13 80 F4 B0 13 44 DF B0 13 +EE F1 B0 13 08 F5 B0 13 A4 F3 80 00 60 E8 5F 93 +20 24 4F 93 1B 24 6F 93 12 24 7F 90 03 00 05 24 +6F 92 1C 20 B0 13 7E D5 10 01 4E 4E 3E E3 CF 0E +6F FC 4D DF CC 4D 00 00 CC FE 20 00 10 01 B0 13 +7E D5 CC DD 00 00 CC DD 20 00 10 01 CC CE 00 00 +10 01 6F 4C 4F CE 4D DF CC 4D 00 00 10 01 4E 4E +3E E3 CC FE 00 00 CC FE 20 00 10 01 0A 14 1F 42 +A6 1E DF 53 13 00 B0 13 02 CC 1F 42 A6 1E 1E 4F +08 00 1E 5F 0A 00 8F 4E 0C 00 1F 42 A6 1E 9F 4F +0C 00 0A 00 1A 42 A6 1E CF 0A 5C 4F 13 00 2D 4F +1E 4F 02 00 3F 40 00 08 B0 13 14 DD 8A 8C 0C 00 +1F 42 A6 1E FF 40 07 00 0F 00 1F 42 A6 1E FF F0 +FC 00 1A 00 0A 16 10 01 92 53 96 1E 82 63 98 1E +1F 43 5F 52 A2 1E 3F 90 3C 00 1F 20 C2 43 A2 1E +1F 43 5F 52 A1 1E 3F 90 3C 00 12 20 C2 43 A1 1E +1F 43 5F 52 A0 1E F2 40 03 00 9E 1E 3F 90 18 00 +03 24 C2 4F A0 1E 10 01 C2 43 A0 1E 80 00 D2 E0 +C2 4F A1 1E E2 43 9E 1E 10 01 C2 4F A2 1E D2 43 +9E 1E 10 01 0A 14 CA 0C 7D 40 46 00 7E 40 5A 00 +B0 13 42 F4 0D 43 4E 43 B0 13 D6 BC 5A 93 0D 24 +7C 40 29 00 B0 13 96 D6 7C 40 27 00 B0 13 96 D6 +7C 40 28 00 B0 13 96 D6 0C 3C 7C 40 1F 00 B0 13 +96 D6 7C 40 20 00 B0 13 96 D6 7C 40 1E 00 B0 13 +96 D6 0A 16 10 01 4D 43 B0 13 30 F0 10 01 0A 14 +0A 43 2C 92 22 24 3C 90 05 00 1C 24 3C 92 17 24 +3C 90 0A 00 12 20 2F 4D 0F 93 0A 24 1F 83 06 24 +1F 83 02 24 2C 43 16 3C 6C 43 03 3C 5C 43 01 3C +4C 43 B0 13 14 F1 0C 43 0D 3C 2A 43 0A 3C B0 13 +18 EF 07 3C B0 13 2E EE 04 3C B0 13 F8 EE B0 13 +58 ED CC 0A 0A 16 10 01 C2 93 76 1E 29 20 C2 93 +FE 1D 07 20 7C 40 47 00 3D 40 14 F9 5E 43 80 00 +D6 BC F2 F0 BF 00 1D 02 F2 D0 40 00 1B 02 B0 13 +36 F4 D2 43 76 1E 7E 40 0F 00 07 3C 4E 93 0B 24 +3C 40 CC 0C B0 13 5A DA 5E 83 F2 B0 40 00 01 02 +F5 27 4E 93 02 20 C2 43 76 1E 4C 43 80 00 AE C5 +10 01 1A 14 C9 0C 79 93 02 24 CA 09 02 3C 49 43 +4A 43 4F 49 4A 4A 0A 8F 1A 53 CC 09 B0 13 10 ED +0C 93 09 20 4C 49 3D 40 1C 00 B0 13 1A F2 1C 52 +7A FA B0 13 AA D7 59 53 1A 83 EF 23 E2 B3 36 1F +0A 24 B0 13 4E F4 4C 93 06 20 D2 C3 36 1F B0 13 +26 F3 B0 13 DE F4 19 16 10 01 AC 43 18 00 FC F0 +FC 00 1A 00 CC 43 12 00 5F 42 AC 1E C2 93 AD 1E +03 20 CC 4F 13 00 08 3C 5E 42 AC 1E 12 C3 4E 10 +4E 11 4F 8E CC 4F 13 00 E2 B3 36 1F 11 20 F2 D0 +06 00 36 1F B0 13 B2 F3 82 4C A4 1E C2 93 AD 1E +04 20 B2 50 E0 7F A4 1E 10 01 B2 50 C0 53 A4 1E +10 01 B2 D0 91 00 B0 01 B2 40 10 0A 00 07 B2 40 +00 02 02 07 F2 40 1B 00 10 07 92 43 0C 07 2C 43 +B0 13 5A DA A2 D3 00 07 C2 43 46 1F 92 D3 00 07 +3C 40 05 00 B0 13 5A DA C2 93 46 1F FD 27 B2 F0 +FC F5 00 07 B2 F0 EF FF 00 07 B2 F0 6E FF B0 01 +82 43 0C 07 1C 42 44 1F 10 01 0A 14 21 83 CA 0D +CB 0C 4C 43 B0 13 96 C7 7C 40 22 00 B0 13 96 D8 +0E 24 CC 0B B0 13 96 D8 0A 24 CC 0A B0 13 A4 D8 +C1 4C 00 00 6C 43 B0 13 96 C7 5C 43 01 3C 4C 43 +21 53 0A 16 10 01 B0 13 A4 D8 C1 4C 04 00 C1 93 +04 00 10 01 B0 13 50 E0 7C 40 03 00 B0 13 96 C7 +10 01 0A 14 09 14 09 43 0A 43 1B 43 0F 93 04 24 +09 4D 0D 4C 0C 43 0D 3C 5C 02 0D 6D 09 69 09 8E +04 28 1C D3 5B 02 F8 2B 03 3C 09 5E 5B 02 F4 2B +1B 43 5C 02 0D 6D 09 69 0A 6A 09 8E 0A 7F 04 28 +1C D3 5B 02 F6 2B 04 3C 09 5E 0A 6F 5B 02 F1 2B +0E 49 0F 4A 09 16 0A 16 10 01 0A 14 7C 40 23 00 +B0 13 D8 F1 CA 0C 7A D0 20 00 CD 0A 7C 40 23 00 +B0 13 2C E4 7C 40 C6 00 B0 13 DE D2 7C 40 33 00 +B0 13 2E C8 7C 40 3D 00 B0 13 2E C8 7C B0 70 00 +F9 23 3D 40 DF 00 4D FA 7C 40 23 00 B0 13 2C E4 +7C 40 36 00 B0 13 2E C8 82 43 1E 1F 0A 16 10 01 +4F 14 1F 42 6E 03 2F 83 1E 24 2F 82 0B 24 2F 83 +1C 20 B2 F0 EF FF 4A 03 92 C3 4A 03 B2 D0 80 00 +86 1E 13 3C B2 F0 EF FF 48 03 92 C3 48 03 1F 42 +50 03 1F 52 1A 1F 82 4F 58 03 B2 D0 10 00 48 03 +80 13 16 1F 02 3C B0 13 04 E3 B1 C0 D0 00 14 00 +4B 16 00 13 B2 B0 20 00 86 1E 25 20 B0 13 FA F3 +4C 93 21 20 B0 13 12 F4 4C 93 1D 20 D2 53 EB 1E +E2 93 EB 1E 18 20 4C 43 4D 43 B0 13 30 F0 5C 43 +B0 13 44 D6 7C 40 5A 00 3D 40 F8 F8 5E 43 B0 13 +D6 BC 7C 40 46 00 3D 40 24 F9 5E 43 B0 13 D6 BC +3F 40 00 10 C0 0F 10 01 2A 14 1A 41 10 00 49 4C +1B 42 A6 1E 1B 4B 0C 00 0B 89 3B 80 32 00 28 4D +C9 0B 09 88 09 93 02 38 28 9E 15 20 8D 4B 00 00 +1D 42 A6 1E 4C 4C 1C 5D 0C 00 3C 50 10 00 8E 4C +00 00 1E 42 A6 1E DF 4E 0F 00 00 00 1F 42 A6 1E +DA 4F 10 00 00 00 28 16 10 01 B2 B0 30 00 40 03 +24 24 B2 F0 EF FF 4A 03 B2 F0 7F FF 86 1E 82 93 +50 03 02 20 0F 43 05 3C 1F 42 50 03 1F 92 50 03 +FB 23 0F 5C 82 4F 5A 03 92 C3 4A 03 B2 D0 10 00 +4A 03 B0 13 BE F4 B2 40 2B 5A 5C 01 32 C2 03 43 +B2 B0 80 00 86 1E F5 27 32 D2 10 01 1A 14 CA 0C +5C 4A 05 00 CF 0C 3F 80 03 00 06 24 2F 83 2F 93 +03 28 7F 40 03 00 01 3C 5F 43 4C 4C 1D 4A 02 00 +5E 4A 04 00 B0 13 6A CA C9 0C 09 93 0C 24 3C 40 +03 00 0C 59 2D 4A 2E 42 B0 13 BA F2 CC 09 5D 43 +B0 13 30 E8 02 3C 3C 40 03 00 19 16 10 01 A2 D2 +22 03 A2 C2 24 03 3E 42 4F 43 B2 C2 22 03 B0 13 +42 DB 4F 5F A2 B2 20 03 01 24 5F D3 1E 83 F5 23 +A2 D2 24 03 B2 C2 22 03 5C 93 03 24 A2 D2 22 03 +02 3C A2 C2 22 03 B0 13 42 DB B2 C2 22 03 CC 0F +10 01 B0 13 32 F5 B2 D2 22 03 B0 13 32 F5 10 01 +D2 B3 36 1F 1E 24 A2 93 A8 1E 1B 24 1F 42 A6 1E +2E 4F 1F 4F 02 00 0F 93 09 20 0E 93 07 20 82 93 +A8 1E 0F 20 92 43 A8 1E 5C 43 10 01 1C 42 B0 1E +1D 42 B2 1E 3C F3 3D F0 FF 00 0D 9F 02 20 0C 9E +02 24 4C 43 10 01 A2 43 A8 1E 5C 43 10 01 21 83 +81 43 00 00 7C 40 81 00 5D 43 B0 13 5C D0 81 4C +00 00 B1 B0 00 20 00 00 02 20 4E 43 08 3C B1 D0 +00 C0 00 00 B1 E3 00 00 91 53 00 00 5E 43 2C 41 +5C 03 CF 0C 4E 93 04 24 3C 40 AC 0A 0C 8F 03 3C +3C 40 AC 0A 0C 5F 21 53 10 01 0B 4D 0E 4B 0D 93 +1F 30 3B F0 80 7F 1C 24 5B 02 8B 10 7E D0 80 00 +3B 80 7F 00 15 30 3B 90 20 00 0F 34 3B 80 17 00 +05 30 1B 83 08 30 5C 02 0E 6E FB 3F 5E 01 5C 00 +1B 53 01 24 FB 3F 0D 4E 10 01 3C 43 3D 43 10 01 +0C 43 0D 43 10 01 0B 4D 0B EF 0A 30 0D 93 12 30 +0D 9F 02 24 19 34 16 3C 0C 9E 18 24 13 28 14 3C +3D B0 80 7F 04 20 3F B0 80 7F 01 20 0F 24 0D 9F +0B 34 08 3C 0F 9D 02 24 07 34 04 3C 0E 9C EC 27 +01 28 02 3C 3C 43 10 01 1C 43 10 01 0C 43 10 01 +C2 93 FE 1E 21 20 D2 43 FE 1E B2 40 8F 02 00 1F +B2 40 33 13 02 1F B2 40 14 01 80 03 B2 40 05 00 +92 03 B2 40 80 00 82 03 F2 D0 80 00 0B 02 00 18 +F2 40 CA DC 16 1F 3C 40 8F 02 B0 13 1C EA 92 42 +02 1F 1A 1F E2 43 04 1F 10 01 E2 93 04 1F 13 24 +B0 13 44 F2 C2 93 04 1F 1C 24 82 43 90 03 B2 D0 +10 00 80 03 F2 D0 80 00 0B 02 E2 43 04 1F 92 42 +02 1F 1A 1F 10 01 B2 F0 CF FF 80 03 F2 F0 7F 00 +03 02 F2 F0 7F 00 0B 02 D2 43 04 1F 92 42 00 1F +1A 1F 10 01 1A 14 CB 0E CA 0D CE 0C CC 0A CD 0B +B0 13 66 E2 4D 4C CC 0A 49 4E 5C E9 5A F7 47 18 +0C 5C 4E ED 5E 4E 5A F7 0E 5C 4A 4A 47 18 0A 5A +CC 0B 4C DD 0C 5A 0C EE 0F 9C 06 2C 3E 40 FF 7F +0C FE 5E 03 0F 9C FC 2B 19 16 10 01 1A 14 31 80 +06 00 C9 0C 5A 42 FF 1D CC 0A B0 13 6A EB 0C 93 +02 20 2C 43 13 3C 4D 43 B0 13 78 EC 0C 93 0E 20 +91 43 02 00 C1 4A 04 00 81 43 00 00 CC 01 2C 53 +3D 40 7A 1D CE 09 0F 43 B0 13 FA C6 31 50 06 00 +19 16 10 01 F2 40 A5 00 21 01 4E 4C 4F 4E 8F 10 +0E 5F 3E 50 00 44 82 4E 24 01 4F 4C 3F 50 00 44 +82 4F 26 01 92 B3 2C 01 FD 27 C2 4C 20 01 B2 F0 +F9 FF 2C 01 A2 B3 2C 01 03 24 A2 B2 2C 01 FD 27 +82 4E 26 01 C2 43 21 01 10 01 1A 14 3F 40 8E FA +9F 00 FF FF 12 24 3D 40 8E FA 0C 3C 4F 13 2A 52 +12 3C 3C 4D CA 0D CE 09 B0 13 BA F2 0A 59 CD 0A +1D 53 1D C3 39 4D 09 93 F4 23 3F 40 FF FF 3F 93 +05 24 3A 40 FF FF 0F 0A DF 03 E8 23 19 16 10 01 +7C 90 3C 00 06 28 7C 90 3E 00 03 24 32 C2 03 43 +FF 3F 0F 42 32 C2 03 43 B2 B0 10 00 02 0F FC 27 +7C 90 2F 00 08 28 7C 90 3E 00 05 24 7C D0 C0 00 +C2 4C 13 0F 04 3C 7C D0 80 00 C2 4C 13 0F 5C 42 +22 0F 02 4F 10 01 0B 4D 0E 4B 3B F0 80 7F 1C 24 +5B 02 8B 10 7E D0 80 00 3B 80 7F 00 15 30 3B 90 +10 00 10 34 5E 01 5C 00 1E 93 01 24 FB 3F 1B 83 +03 30 5C 02 0E 6E FB 3F 0D 93 02 34 3E E3 1E 53 +0C 4E 10 01 3C 43 10 01 0C 43 10 01 0A 14 CB 0D +0A 42 32 C2 03 43 B2 B0 10 00 02 0F FC 27 7C D0 +C0 00 C2 4C 13 0F 4F 4E 1F 83 0A 24 B2 B0 80 00 +02 0F FC 27 1D 53 DD 42 22 0F FF FF 1F 83 F6 23 +4D 4E 0D 5B DD 42 20 0F FF FF 02 4A 0A 16 10 01 +0B 42 32 C2 03 43 B2 B0 10 00 02 0F FC 27 4C 4C +47 18 0C 5C 3C D0 00 40 6F 4D 0F 5C 82 4F 10 0F +6E 93 0C 28 1D 53 4E 4E 1E 83 E2 4D 10 0F B2 B0 +20 00 02 0F FC 27 1D 53 1E 83 F7 23 5F 42 20 0F +02 4B 10 01 C2 43 76 1E 82 43 82 1E 82 43 7E 1E +82 43 80 1E C2 93 FE 1D 16 24 B0 13 52 EC B0 13 +F8 D6 B0 13 EE EA 1C 42 84 1E 0C 93 0C 24 1C 52 +82 1E 82 4C 82 1E 1D 42 78 1E 1E 42 7A 1E 1F 42 +7C 1E 80 00 1E A3 10 01 1A 14 C9 0C 3D 40 0C 00 +0D 59 6E 49 7E 80 0B 00 5C 43 7F 40 03 00 B0 13 +6A CA CA 0C 0A 93 10 24 3C 40 03 00 0C 5A 3D 40 +05 00 0D 59 2E 42 B0 13 BA F2 FA D0 80 00 0E 00 +CC 0A 4D 43 B0 13 30 E8 19 16 10 01 D2 B3 36 1F +0E 24 1D 42 B0 1E 1E 42 B2 1E 3D F3 3E F0 FF 00 +1F 42 A6 1E 1E 9F 02 00 02 20 2D 9F 02 24 4C 43 +10 01 DF 92 B3 1E 13 00 04 24 D2 C3 36 1F 4C 43 +10 01 EF C2 1A 00 B0 13 7C CB 5C 43 10 01 4F 4C +48 18 0F 5F 7C 90 40 00 1A 28 7C 90 4F 00 17 2C +92 B3 44 01 FD 23 32 C2 03 43 B2 40 00 A5 44 01 +B2 40 02 A5 40 01 8F 43 00 00 B2 40 40 A5 40 01 +B2 40 00 A5 40 01 B2 40 10 A5 44 01 32 D2 10 01 +A2 D2 24 03 7F 40 80 00 3E 42 B2 C2 22 03 CD 0C +4D FF 4D 9F 03 24 A2 C2 22 03 02 3C A2 D2 22 03 +12 C3 4F 10 B0 13 32 F5 B2 D2 22 03 B0 13 32 F5 +1E 83 EB 23 B2 C2 22 03 A2 D2 22 03 A2 C2 24 03 +10 01 4C 93 1D 20 4C 43 B0 13 10 ED 0C 93 04 24 +1C 83 09 24 1C 83 14 20 C2 43 3C 1F C2 43 3D 1F +82 43 3E 1F 10 01 1F 42 7A FA D2 4F 0E 00 3C 1F +1E 4F 04 00 1F 4F 06 00 C2 4F 3D 1F 82 4E 3E 1F +10 01 0A 14 1A 43 5A 52 31 1F D2 53 31 1F B0 13 +88 CC 4C 4C 0C 9A 11 34 1F 43 5F 52 32 1F 7F 90 +0D 00 05 2C D2 53 32 1F D2 43 31 1F 06 3C D2 43 +31 1F D2 43 32 1F 92 53 34 1F 92 D3 14 1D 0A 16 +10 01 0A 14 0A 43 0F 93 05 34 3E E3 3F E3 1E 53 +0F 63 1A D3 0D 93 05 34 3C E3 3D E3 1C 53 0D 63 +3A E3 B0 13 B2 D8 1A B3 04 24 3C E3 3D E3 1C 53 +0D 63 2A B3 04 24 3E E3 3F E3 1E 53 0F 63 0A 16 +10 01 0A 14 CA 0D CB 0E 4C 4C 3D 40 1C 00 B0 13 +1A F2 1F 42 7A FA 0F 5C 8F 93 18 00 0F 20 8F 4A +00 00 8F 4B 02 00 0B 93 06 20 0A 93 04 20 1C 52 +7A FA EC C2 1A 00 FF 40 7F 00 10 00 0A 16 10 01 +0A 14 5A 42 B9 1E 3C 40 B0 1E B0 13 40 E5 4C 4C +0C EA 47 18 0C 5C 8C 10 4C 4C CA 0C C2 4A B9 1E +3A 90 21 00 05 20 D2 D3 36 1F B0 13 DE F4 05 3C +F2 F0 EF 00 36 1F B0 13 90 CD 0A 16 10 01 1A 14 +C2 93 2A 1E 16 24 3C 40 02 1E 29 42 3A 40 7E FA +3B 40 2C 1E 4E 43 4F 43 7D 4C 7D 9B 01 20 5E 53 +7D 9A 01 20 5F 53 19 83 F7 23 6F 92 02 24 6E 92 +02 20 4C 43 01 3C 5C 43 19 16 10 01 5C 02 0D 6D +5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D +5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D +5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D +5C 02 0D 6D 5C 02 0D 6D 10 01 5D 03 5C 00 5D 03 +5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 +5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 +5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 +5C 00 5D 03 5C 00 10 01 0A 14 3F 40 41 1E 2E 43 +0C 43 2D 43 6D 9F 05 20 3F 50 0C 00 1C 53 1E 83 +F8 23 6C 93 02 20 0C 43 0C 3C 4C 4C 3D 40 0C 00 +B0 13 1A F2 3A 40 41 1E 0A 5C CC 0A B0 13 9C E4 +CC 0A 0A 16 10 01 82 43 BA 1E 4C 43 B0 13 D8 F4 +B0 13 56 F3 C2 43 C2 1E 92 D3 14 1D 7C 40 13 00 +6D 42 B0 13 30 F0 7C 40 17 00 6D 42 B0 13 30 F0 +7C 40 18 00 6D 42 B0 13 30 F0 7C 40 19 00 6D 42 +80 00 30 F0 92 C3 44 03 82 93 FC 1E 0E 24 B0 13 +9A A0 92 93 FC 1E 03 24 B0 13 44 E6 02 3C B0 13 +90 CD 1C 42 F6 1E 80 00 12 F0 F2 C2 36 1F B0 13 +90 CD 1C 42 F8 1E B0 13 12 F0 92 43 FC 1E 10 01 +3A 14 C8 0D C7 0C 3A 40 41 1E 29 43 2F 43 6F 9A +0E 20 3D 40 03 00 0D 5A CC 07 2E 42 B0 13 7C ED +0C 93 05 20 58 9A 0A 00 02 20 CC 0A 05 3C 3A 50 +0C 00 19 83 EB 23 0C 43 37 16 10 01 3A 14 C8 0D +C7 0C 3A 40 41 1E 49 43 2F 43 6F 9A 0E 20 3C 40 +03 00 0C 5A CD 07 2E 42 B0 13 7C ED 0C 93 05 20 +CA 98 0A 00 02 20 CC 0A 05 3C 3A 50 0C 00 59 53 +EB 27 0C 43 37 16 10 01 D2 B3 8D 1C 0A 24 B0 13 +FA F3 4C 93 06 20 B0 13 F4 B1 4C 93 02 20 B0 13 +C6 E2 F2 B0 06 00 8D 1C 02 24 B0 13 F8 D6 7C 40 +15 00 7D 40 03 00 B0 13 30 F0 0C 43 4D 43 5E 43 +80 00 64 B6 82 43 AE 1E B0 13 E4 F4 F2 40 21 00 +AA 1E F2 40 06 00 AC 1E C2 43 AB 1E D2 43 AD 1E +7C 43 5D 43 B0 13 3E D1 B0 13 CE D0 B0 13 0A D9 +7C 40 0C 00 5D 42 94 1E 80 00 2C E4 21 83 0F 42 +32 C2 03 43 B2 B0 10 00 02 0F FC 27 4C 4C 47 18 +0C 5C 3C D0 00 40 4D 4D 0C 5D 82 4C 10 0F B2 B0 +20 00 02 0F FC 27 5E 42 20 0F 81 4E 00 00 02 4F +21 53 10 01 5F 14 1A 42 38 0F 4A 4A B0 13 12 F4 +4C 93 10 20 7A 90 14 00 04 24 4A 93 0D 20 03 43 +0B 3C 1F 42 BA 1E 1F 93 02 24 2F 93 05 20 B0 13 +A8 F2 02 3C B0 13 10 D4 5A 16 00 13 21 83 CC 43 +0A 00 EC 43 00 00 DC 42 40 1E 0B 00 D2 53 40 1E +02 3C D2 53 40 1E C2 93 40 1E FB 27 F2 93 40 1E +F8 27 5C 42 40 1E CD 01 B0 13 42 EB 4C 93 F1 23 +21 53 10 01 0A 14 CA 0C 5D 42 4A 1F B0 13 A0 E7 +4C 93 0E 24 B0 13 DE F2 CD 0C 1C 43 0C 5A 2E 42 +B0 13 7C ED 0C 93 02 20 0C 43 05 3C 2C 43 03 3C +B0 13 BE F3 1C 43 0A 16 10 01 0E 4C 0D 4C 0D 93 +16 24 03 34 3D E3 1D 53 0F 30 3B 40 8F 00 1B 83 +5D 02 FD 2B 4C 4D 8C 10 8D 10 4D 4D 8B 10 0D DB +5E 02 5D 00 5C 00 10 01 3D 40 00 C7 0C 43 10 01 +0A 14 3A 40 09 00 0F 43 6D 4C 3B 42 4E 4D 0E EF +3E 90 80 00 04 38 4F 5F 7F E0 97 00 02 3C 4F 5F +4F 4F 4D 5D 1B 83 F2 23 1C 53 1A 83 ED 23 CC 0F +0A 16 10 01 1D 42 26 1E 0F 42 32 C2 03 43 D2 43 +24 1E 02 4F 0D 93 07 24 B0 13 F4 EF C2 93 23 1E +02 20 1D 83 F9 23 0F 42 32 C2 03 43 C2 43 23 1E +C2 43 24 1E 02 4F 10 01 B0 13 9E F4 1F 42 A6 1E +FF 90 7F 00 10 00 0A 24 2C 93 05 34 3C 93 0D 34 +DF 83 10 00 10 01 DF 53 10 00 10 01 CF 4C 10 00 +1F 42 A6 1E FF 50 0C 00 10 00 10 01 7C 90 2F 00 +06 28 7C 90 3E 00 03 24 32 C2 03 43 FF 3F 0F 42 +32 C2 03 43 B2 B0 10 00 02 0F FC 27 C2 4C 11 0F +B2 B0 20 00 02 0F FC 27 C2 4D 10 0F 02 4F 10 01 +4D 93 03 20 32 C2 03 43 FF 3F 0F 42 32 C2 03 43 +B2 B0 10 00 02 0F FC 27 F2 40 7F 00 11 0F 4D 4D +B2 B0 20 00 02 0F FC 27 F2 4C 10 0F 1D 83 F8 23 +02 4F 10 01 B2 F0 FE FD 36 0F B2 F0 FE FD 32 0F +7C 40 36 00 B0 13 2E C8 7C 40 3A 00 B0 13 2E C8 +7C 40 36 00 B0 13 2E C8 7C 40 32 00 B0 13 2E C8 +82 43 1E 1F 10 01 B0 13 0C C0 B0 13 D0 D4 B0 13 +EE F3 82 93 D8 1E 03 20 82 93 86 1E 02 24 B0 13 +42 B4 82 93 88 1E 02 24 B0 13 C4 EC 82 93 14 1D +EE 27 B0 13 DA AC EB 3F 21 83 7C 40 30 00 B0 13 +2E C8 81 43 00 00 02 3C 91 53 00 00 B1 90 64 00 +00 00 FA 2B 7C 40 36 00 B0 13 2E C8 7C B0 70 00 +F9 23 82 43 06 0F 21 53 10 01 0C 93 02 20 0D 93 +14 24 3B 40 9F 00 1B 83 5C 02 0D 6D FC 2B 12 C3 +5D 00 5C 00 3E 40 06 00 5D 01 5C 00 1E 83 FC 37 +8B 10 0D DB 12 C3 5D 00 5C 00 10 01 D2 B3 8D 1C +06 24 B0 13 FA F3 4C 93 02 24 B0 13 C6 E2 0C 43 +4D 43 6E 43 B0 13 64 B6 F2 B0 06 00 8D 1C 02 24 +B0 13 EE EA 7C 40 15 00 6D 42 80 00 30 F0 B2 B0 +20 00 86 1E 14 20 B0 13 12 F4 4C 93 10 20 A2 B2 +D8 1E 0D 24 1F 42 BA 1E 0F 93 05 20 B0 13 F4 B1 +4C 93 03 24 10 01 2F 93 02 20 80 00 C6 E2 10 01 +4D 93 03 20 32 C2 03 43 FF 3F 0F 42 32 C2 03 43 +4D 4D B2 B0 10 00 02 0F FC 27 F2 40 BF 00 13 0F +1C 53 DC 42 22 0F FF FF 1D 83 F3 23 02 4F 10 01 +CF 0C FF B0 80 FF 0C 00 02 20 6C 43 10 01 CF 9D +0D 00 0C 20 B0 13 DE F2 CD 0C 1C 43 0C 5F 2E 42 +B0 13 7C ED 0C 93 02 20 4C 43 10 01 5C 43 10 01 +82 93 D0 1E 09 20 82 93 CE 1E 06 20 B2 40 04 03 +CE 1E B2 40 02 01 D0 1E B0 13 AC F1 C2 4C D7 1E +4C 93 FA 27 3C 40 D4 1E 0D 43 1E 43 80 00 CC F2 +31 80 06 00 81 43 02 00 D1 4C 05 00 04 00 CF 0C +3F 50 06 00 81 4F 00 00 1D 4C 02 00 2E 42 0E 5C +2F 4C CC 01 2C 53 B0 13 FA C6 31 50 06 00 10 01 +0A 14 CA 0C 3F 40 CF 00 5F FA 0C 00 5F D2 C8 1E +CA 4F 0C 00 2C 43 0C 5A B0 13 46 BF 4C 93 02 20 +0C 43 02 3C 3C 40 09 00 CA 43 00 00 0A 16 10 01 +7C 40 40 00 B0 13 0E E0 5C 53 7C 90 4F 00 FA 2B +C2 43 8C 1C F2 40 06 00 8D 1C F2 40 05 00 8E 1C +C2 43 8F 1C B2 40 00 80 90 1C C2 43 92 1C 10 01 +7C 90 80 00 09 28 4C 4C 3C 80 00 01 2D 43 B0 13 +9C E9 3C 80 4A 00 04 3C 4C 4C 5C 03 3C 80 4A 00 +3C 90 80 FF 02 34 3C 40 80 FF 8C 11 10 01 92 C3 +22 03 F2 F0 DF 00 03 02 F2 F0 1F 00 02 02 A2 C3 +22 03 F2 D0 20 00 05 02 F2 D0 E0 00 04 02 A2 D3 +24 03 92 D3 24 03 D2 43 F5 1E 10 01 B2 F0 FF FD +36 0F 7C 40 36 00 B0 13 EA CF 7C 40 3D 00 B0 13 +EA CF 7C B0 F0 FF F9 23 7C 40 3A 00 B0 13 EA CF +B2 F0 FF FD 32 0F 10 01 C2 93 59 1E 0E 20 B0 13 +86 A8 B0 13 0E CD 0C 93 0C 20 B0 13 2E EE B0 13 +DE F2 B0 13 34 ED B0 13 B8 EF D2 43 59 1E 80 00 +6C B7 10 01 4D 93 13 24 4D 4D 0E 43 5F 42 92 1C +7F 90 80 00 09 2C CB 0F 5B 53 C2 4B 92 1C CB 0E +0B 5C 4F 4F EF 4B 93 1C 1E 53 1D 83 EF 23 10 01 +5C 93 13 20 0C 42 32 C2 03 43 2E 43 3F 40 00 1C +CF 93 00 00 05 24 5D 9F 01 00 02 2C DF 83 01 00 +3F 50 23 00 1E 83 F4 23 02 4C 10 01 0B 43 0D 93 +03 34 3D E3 1D 53 1B D3 0C 93 03 34 3C E3 1C 53 +3B E3 B0 13 04 F2 1B B3 02 24 3C E3 1C 53 2B B3 +02 24 3E E3 1E 53 10 01 4C 4C 3D 40 1C 00 B0 13 +1A F2 CF 0C 1F 52 7A FA EF B2 1A 00 03 24 0F 43 +0D 43 05 3C 1C 52 7A FA 2F 4C 1D 4C 02 00 CC 0F +10 01 C2 93 AC 1E 09 24 1F 42 A6 1E DF 83 13 00 +1F 42 A6 1E CF 93 13 00 02 24 5C 43 10 01 8F 43 +18 00 5D 43 B0 13 92 E0 4C 43 10 01 82 4C 1A 1F +82 93 50 03 02 20 0F 43 05 3C 1F 42 50 03 1F 92 +50 03 FB 23 0F 5C 82 4F 58 03 92 C3 48 03 B2 D0 +10 00 48 03 10 01 31 40 FC 2B 00 18 F2 40 36 F5 +06 1F 00 18 F2 40 36 F5 0A 1F B0 13 12 F5 0C 93 +02 24 B0 13 EA DD 0C 43 B0 13 76 E6 B0 13 16 F5 +5D 93 12 20 C2 93 EB 1E 0A 24 E2 93 EB 1E 0C 2C +7C 40 5A 00 3D 40 F2 F8 5E 43 80 00 D6 BC 7C 40 +5A 00 3D 40 F8 F8 F8 3F 10 01 92 B3 44 01 FD 23 +32 C2 03 43 B2 40 00 A5 44 01 B2 40 40 A5 40 01 +8C 4D 00 00 B2 40 00 A5 40 01 B2 40 10 A5 44 01 +32 D2 10 01 B2 D0 06 00 06 0A B2 40 1D 7B 00 0A +B2 40 ED 00 04 0A F2 D0 E0 00 4A 02 F2 D0 E0 00 +44 02 B2 43 0A 0A B2 40 FF 00 0C 0A 10 01 C2 93 +FE 1D 11 24 C2 93 76 1E 0E 24 B0 13 B6 F4 4C 93 +0A 20 B0 13 76 F4 C2 43 76 1E F2 F0 BF 00 1B 02 +F2 F0 BF 00 1D 02 10 01 F2 C2 03 02 F2 C2 05 02 +D2 B3 8C 1C 0B 20 E2 B3 8C 1C 02 20 80 00 B8 E3 +92 D3 8A 1E B2 D0 00 01 8A 1E 10 01 80 00 0C E7 +10 01 3F 40 41 1E 0E 43 2B 43 6B 9F 07 20 CF 9C +0B 00 04 20 CD 4E 00 00 5C 43 10 01 3F 50 0C 00 +1E 53 2E 93 F1 3B 4C 43 10 01 21 83 CD 01 B0 13 +42 EB 4C 93 0B 24 6C 41 3D 40 0C 00 B0 13 1A F2 +EC 93 41 1E 03 20 3C 50 41 1E 01 3C 0C 43 21 53 +10 01 82 93 EE 1E 09 20 82 93 EC 1E 06 20 B2 40 +08 07 EC 1E B2 40 06 05 EE 1E 00 18 C2 43 F0 1E +B0 13 AC F1 C2 4C F4 1E 10 01 3C 40 03 00 5C F2 +20 01 7C 90 03 00 03 2C 5C 53 B0 13 A4 DD 6C 92 +03 28 5C 83 B0 13 E0 EB 7C 90 03 00 EE 23 10 01 +F2 40 A5 00 21 01 4E 4C 4F 4E 8F 10 0E 5F 3E 50 +00 44 82 4E 26 01 92 B3 2C 01 FD 27 C2 4C 20 01 +C2 43 21 01 10 01 3F 40 13 00 6F 9C 09 24 5F 4C +0C 00 1F 83 07 24 1F 83 07 20 B0 13 10 D2 04 3C +DC 43 0C 00 B0 13 78 AF 0C 43 10 01 F2 F0 E0 00 +05 02 F2 F0 E0 00 03 02 F2 D0 1F 00 07 02 F2 F0 +E0 00 19 02 F2 F0 E0 00 1D 02 F2 D0 1F 00 1B 02 +10 01 1A 14 39 40 11 00 3F 40 BA 1D 3A 40 36 FA +3C 4A B0 13 E8 ED 2F 52 8F 4C FC FF 8F 4D FE FF +19 83 F6 23 19 16 10 01 4D 93 03 24 5F 4C 0A 00 +02 3C 5F 4C 09 00 4F 93 06 24 CC 93 00 00 03 24 +7F 90 20 00 02 2C 2C 43 10 01 0C 43 10 01 3C 40 +E2 1E 0D 43 2E 42 B0 13 CC F2 C2 93 EA 1E 09 20 +3C 40 E6 1E 3D 40 70 FA 2E 42 B0 13 BA F2 D2 43 +EA 1E 10 01 A2 B3 88 1E 03 24 5C 43 B0 13 AE C5 +B2 B2 88 1E 02 24 B0 13 54 B9 92 B3 88 1E 02 24 +B0 13 A8 D1 82 43 88 1E 10 01 B2 B0 20 00 86 1E +0E 20 B0 13 FA F3 4C 93 0A 20 F2 C2 03 02 F2 C2 +05 02 F2 C2 1B 02 B0 13 F4 CA F2 D2 1B 02 10 01 +4C 4C 3D 40 1C 00 B0 13 1A F2 CF 0C 1F 52 7A FA +EF B2 1A 00 02 24 2C 43 10 01 1C 52 7A FA 1C 4C +18 00 10 01 CE 0C 6D 4E 5D 92 7E FA 0C 24 7C 40 +09 00 B0 13 DC E5 2D 42 3F 40 2C 1E 1F 53 FF 4E +FF FF 1D 83 FB 23 10 01 0A 14 0A 42 32 C2 03 43 +D2 93 00 1E 08 24 B0 13 F8 EE 7C 40 32 00 B0 13 +EA CF D2 43 00 1E 02 4A 0A 16 10 01 0E 93 02 20 +0C 43 10 01 1D 83 1C 83 1D 53 6B 4D 1C 53 6F 4C +4F 9B 02 20 1E 83 F8 23 4B 4B 4C 4F 0C 8B 10 01 +0A 14 CA 0C 5D 42 95 1E B0 13 A0 E7 4C 93 04 20 +B0 13 BE F3 1C 43 04 3C CC 0A B0 13 E2 F3 0C 43 +0A 16 10 01 82 43 96 1E 82 43 98 1E E2 42 A0 1E +F2 40 1E 00 A1 1E C2 43 A2 1E C2 43 9F 1E 82 43 +9A 1E 82 43 9C 1E 10 01 0D 4C 0D 93 0E 24 3B 40 +8F 00 1B 83 5D 02 FD 2B 4C 4D 8C 10 8D 10 4D 4D +8B 10 0D DB 12 C3 5D 00 5C 00 10 01 82 43 90 03 +B2 40 C0 00 92 03 B2 D0 10 00 80 03 92 B3 82 03 +FD 27 B2 F0 EF FF 80 03 92 C3 82 03 10 01 D2 93 +00 1E 0D 20 7C 40 36 00 B0 13 EA CF 7C 40 3D 00 +B0 13 EA CF 7C B0 F0 FF F9 23 E2 43 00 1E 10 01 +5F 42 A0 1E 4F 93 09 24 7F 90 0D 00 02 2C CC 0F +10 01 CC 0F 7C 80 0C 00 10 01 3C 40 0C 00 4C 5F +10 01 4C 43 B0 13 10 ED 0C 93 09 24 1C 83 09 20 +B0 13 C6 F4 C2 4C C2 1E 92 43 BC 1E 10 01 80 00 +C6 E2 10 01 0A 14 CA 0C 5D 42 D7 1E B0 13 A0 E7 +4C 93 04 20 B0 13 BE F3 1C 43 03 3C CC 0A B0 13 +06 EC 0A 16 10 01 02 12 32 C2 03 43 82 4C D0 04 +82 4D D2 04 82 4E E0 04 82 4F E2 04 1C 42 E4 04 +1D 42 E6 04 32 41 10 01 0A 14 5C 43 B0 13 02 CF +CA 0C 0A 93 07 24 2C 43 0C 5A B0 13 CA F3 CC 0A +B0 13 52 C9 0A 16 10 01 D2 93 00 1E 09 24 F2 90 +03 00 00 1E 08 20 B0 13 EC E8 E2 43 00 1E 10 01 +32 C2 03 43 FF 3F 10 01 D2 93 00 1E 09 24 F2 90 +03 00 00 1E 08 24 F2 40 03 00 00 1E 80 00 C2 F1 +32 C2 03 43 FF 3F 10 01 1C 42 82 1E 3C B0 00 80 +0D 7D 3D E3 3E 40 52 00 0F 43 B0 13 B6 EE 3E 40 +19 00 0F 43 80 00 12 E1 B0 13 FA F3 4C 93 0A 24 +4C 43 1F 42 54 03 1F 82 50 03 3F 90 F5 01 03 28 +5C 43 10 01 5C 43 10 01 C2 43 C8 1E 00 18 C2 43 +CA 1E B0 13 DE F2 82 4C C6 1E B0 13 AC F1 C2 4C +C4 1E 4C 93 FA 27 10 01 B2 F0 CF FF 80 03 F2 F0 +7F 00 03 02 F2 F0 7F 00 0B 02 B2 F0 EF FF 82 03 +B0 13 AE F4 80 00 80 F4 D2 92 7E FA 2C 1E 08 24 +D2 43 2A 1E 7C 40 07 00 7D 40 07 00 80 00 DC E5 +32 C2 03 43 FF 3F B0 13 EC E8 7C 40 0A 00 5D 42 +82 FA B0 13 DC E5 F2 90 03 00 00 1E 02 20 80 00 +C2 F1 10 01 3F 40 3E 00 0E 42 32 C2 03 43 B0 13 +0C EE 02 4E C2 93 23 1E 03 20 1F 83 3F 93 F4 23 +10 01 CF 0C 82 4F 54 03 92 C3 44 03 B0 13 B2 F3 +2F 83 0F 8C 3F 90 00 80 02 28 92 D3 44 03 10 01 +CF 0D 7C 90 2A 00 0A 2C 4E 4C 5D 4E C2 F9 4C 4C +5C 02 1C 4C 16 1D CE 0D 80 00 2E D5 10 01 0C 9D +02 2C 80 00 BA F2 0C 5E 0D 5E 0E 93 06 24 1D 83 +1C 83 EC 4D 00 00 1E 83 FA 23 10 01 CD 0C C2 93 +EA 1E 02 24 4C 43 10 01 3C 40 E6 1E 2E 42 B0 13 +BA F2 D2 43 EA 1E 5C 43 10 01 B0 13 96 F3 4C 93 +08 20 4C 43 4D 43 B0 13 30 F0 5C 43 5D 43 80 00 +30 F0 4C 43 FB 3F 3C 40 00 1C 0D 43 3E 40 46 00 +B0 13 CC F2 3C 40 46 1C 0D 43 3E 40 46 00 80 00 +CC F2 0A 14 CF 0C CC 0D 2A 43 0F 93 05 20 B0 13 +6C F0 4C 93 01 24 0A 43 CC 0A 0A 16 10 01 21 82 +CF 0C CC 0D A1 4F 00 00 91 4F 02 00 02 00 CD 01 +2E 42 B0 13 4E F0 21 52 10 01 1F 42 A6 1E 5C 4F +11 00 6C 93 02 2C 3C 42 10 01 5C 53 4C 5C 4C 5C +4C 4C 10 01 7C 90 03 00 07 2C 4C 4C 5D 4C 86 FA +7C 40 3E 00 80 00 DC E5 32 C2 03 43 FF 3F 0C 93 +0A 24 5C 0F 1C 53 0F 42 32 C2 03 43 B0 13 0C EE +02 4F 1C 83 F8 23 10 01 B0 13 AC F1 7C F0 0F 00 +5C 53 4E 4C 1C 42 28 1E B0 13 2E F1 1E 83 FA 23 +10 01 B2 90 06 00 0E 07 08 20 92 42 20 07 44 1F +D2 43 46 1F B1 C0 D0 00 00 00 00 13 1C 42 7E 1E +CF 0C 5F 0A 0C 5F 3D 40 05 00 B0 13 9C E9 3C 50 +40 01 10 01 5D 42 F4 1E B0 13 A0 E7 4C 93 02 24 +0C 43 10 01 B0 13 BE F3 1C 43 10 01 5C 42 22 1E +3D 40 6D 00 B0 13 1A F2 7C 50 43 00 C2 4C 22 1E +10 01 B2 F0 FF FD 32 0F 7C 40 34 00 B0 13 EA CF +B2 D0 00 02 36 0F 10 01 0F 42 32 C2 03 43 7C D0 +C0 00 C2 4C 13 0F 5C 42 22 0F 02 4F 10 01 82 43 +BA 1E 82 43 BE 1E 82 43 C0 1E 82 43 BC 1E C2 43 +C2 1E 10 01 0E 43 0F 4C 1C 43 5F 02 0E 6E 0E 9D +01 28 0E 8D 0C 6C F9 2B 10 01 02 12 32 C2 03 43 +82 4C C0 04 82 4D C8 04 1C 42 CA 04 32 41 10 01 +B2 40 FF 7F 52 03 B2 D0 10 00 42 03 B2 D0 24 01 +40 03 10 01 5F 42 FE 1E 5F 83 D2 83 FE 1E 0F 93 +02 20 80 00 98 EF 10 01 5D 93 07 20 7C 40 5B 00 +3D 40 08 F9 5E 43 80 00 D6 BC 10 01 5D 93 07 20 +7C 40 5A 00 3D 40 00 F9 5E 43 80 00 D6 BC 10 01 +3C 80 05 00 05 24 3C 80 05 00 02 24 4C 43 10 01 +5C 43 10 01 B2 40 D9 07 34 1F F2 42 32 1F D2 43 +31 1F C2 43 30 1F 10 01 1F 42 50 03 82 4F 22 1F +1F 92 50 03 F9 23 80 00 72 D4 CF 0C 0E 93 05 24 +1F 53 FF 4D FF FF 1E 83 FB 23 10 01 0E 93 06 24 +4D 4D 1C 53 CC 4D FF FF 1E 83 FB 23 10 01 C2 93 +EA 1E 03 24 3C 40 E6 1E 10 01 3C 40 70 FA 10 01 +0D 93 02 20 0C 93 04 24 82 4C EC 1E 82 4D EE 1E +10 01 0D 93 02 20 0C 93 04 24 82 4C CE 1E 82 4D +D0 1E 10 01 B0 13 A8 E6 B2 F0 EF FF 32 0F B2 D0 +10 00 36 0F 10 01 A2 43 FC 1E 92 C3 44 03 B2 D0 +10 00 44 03 10 01 A2 D2 80 03 82 43 80 03 B2 D0 +00 02 80 03 10 01 CE 0C 3C 40 E8 03 B0 13 2E F1 +1E 83 FA 23 10 01 82 43 32 0F 82 43 36 0F B0 13 +A8 E6 80 00 66 F3 7C 40 36 00 B0 13 2E C8 7C 40 +39 00 80 00 2E C8 4F 43 C2 93 30 1F 01 20 5F 43 +C2 4F 30 1F 10 01 4F 43 C2 93 9F 1E 01 20 5F 43 +C2 4F 9F 1E 10 01 4C 43 F2 90 0C 00 A0 1E 01 2C +5C 43 10 01 F2 40 0F 00 2A 1F B2 40 2C 01 2C 1F +10 01 1C 42 50 03 1C 92 50 03 FB 23 10 01 C2 93 +24 1E 02 24 D2 43 23 1E 10 01 3D 40 01 1E 3E 40 +21 00 80 00 BA F2 5C 43 B0 13 44 D6 6C 43 80 00 +44 D6 DC 93 0C 00 02 20 80 00 88 DF 10 01 B0 13 +BE F4 B2 40 2B 5A 5C 01 10 01 4C 43 A2 93 BA 1E +01 20 5C 43 10 01 4C 43 92 93 BA 1E 01 20 5C 43 +10 01 4C 43 82 93 72 1D 01 24 5C 43 10 01 CF 0C +CC 0D CD 0F 2E 42 80 00 4E F0 CD 0C 3C 40 E2 1E +2E 42 80 00 BA F2 7C 40 03 00 7D 40 0B 00 80 00 +5A D8 5C 93 02 20 CC 0D 10 01 CC 0E 10 01 1C 42 +44 03 7C F0 10 00 10 01 B2 F0 EF FF 44 03 80 00 +44 E6 B0 13 AC F1 C2 4C 4A 1F 10 01 B0 13 AC F1 +C2 4C 95 1E 10 01 7C 40 03 00 4D 43 80 00 5A D8 +C2 43 FE 1E C2 43 04 1F 10 01 1C 42 14 1D 8C 10 +5C F3 10 01 1C 42 14 1D 5C 0F 5C F3 10 01 5C 42 +20 1F 8C 11 10 01 4C 5C C2 4C AB 1E 10 01 B2 F0 +EF FF 48 03 10 01 1C 43 5C F2 8C 1C 10 01 32 D0 +D8 00 03 43 10 01 5C 42 3C 1F 10 01 C2 4C AA 1E +10 01 C2 4C AC 1E 10 01 4D 43 80 00 3E D1 92 D3 +44 03 10 01 92 C3 44 03 10 01 5C 42 00 1E 10 01 +5C 42 76 1E 10 01 82 43 D8 1E 10 01 CC 43 00 00 +10 01 3C 40 7E FA 10 01 82 43 72 1D 10 01 80 00 +2C AE 1C 43 10 01 03 43 FF 3F 2C 43 10 01 2C 43 +10 01 4C 43 10 01 6C 43 10 01 0C 43 10 01 0C 43 +10 01 03 43 10 01 10 01 10 01 30 30 30 30 30 31 +30 30 32 30 30 33 30 30 34 30 30 35 30 30 36 30 +30 37 30 30 38 30 30 39 30 31 30 30 31 31 30 31 +32 30 31 33 30 31 34 30 31 35 30 31 36 30 31 37 +30 31 38 30 31 39 30 32 30 30 32 31 30 32 32 30 +32 33 30 32 34 30 32 35 30 32 36 30 32 37 30 32 +38 30 32 39 30 33 30 30 33 31 30 33 32 30 33 33 +30 33 34 30 33 35 30 33 36 30 33 37 30 33 38 30 +33 39 30 34 30 30 34 31 30 34 32 30 34 33 30 34 +34 30 34 35 30 34 36 30 34 37 30 34 38 30 34 39 +30 35 30 30 35 31 30 35 32 30 35 33 30 35 34 30 +35 35 30 35 36 30 35 37 30 35 38 30 35 39 30 36 +30 30 36 31 30 36 32 30 36 33 30 36 34 30 36 35 +30 36 36 30 36 37 30 36 38 30 36 39 30 37 30 30 +37 31 30 37 32 30 37 33 30 37 34 30 37 35 30 37 +36 30 37 37 30 37 38 30 37 39 30 38 30 30 38 31 +30 38 32 30 38 33 30 38 34 30 38 35 30 38 36 30 +38 37 30 38 38 30 38 39 30 39 30 30 39 31 30 39 +32 30 39 33 30 39 34 30 39 35 30 39 36 30 39 37 +30 39 38 30 39 39 31 30 30 31 30 31 31 30 32 31 +30 33 31 30 34 31 30 35 31 30 36 31 30 37 31 30 +38 31 30 39 31 31 30 31 31 31 31 31 32 31 31 33 +31 31 34 31 31 35 31 31 36 31 31 37 31 31 38 31 +31 39 31 32 30 31 32 31 31 32 32 31 32 33 31 32 +34 31 32 35 31 32 36 31 32 37 31 32 38 31 32 39 +31 33 30 31 33 31 31 33 32 31 33 33 31 33 34 31 +33 35 31 33 36 31 33 37 31 33 38 31 33 39 31 34 +30 31 34 31 31 34 32 31 34 33 31 34 34 31 34 35 +31 34 36 31 34 37 31 34 38 31 34 39 31 35 30 31 +35 31 31 35 32 31 35 33 31 35 34 31 35 35 31 35 +36 31 35 37 31 35 38 31 35 39 31 36 30 31 36 31 +31 36 32 31 36 33 31 36 34 31 36 35 31 36 36 31 +36 37 31 36 38 31 36 39 31 37 30 31 37 31 31 37 +32 31 37 33 31 37 34 31 37 35 31 37 36 31 37 37 +31 37 38 31 37 39 31 38 30 00 01 80 40 20 10 08 +84 42 21 90 48 A4 52 29 14 0A 85 C2 61 B0 58 AC +D6 6B 35 9A CD 66 33 99 4C A6 53 A9 54 2A 95 CA +E5 F2 79 3C 9E CF 67 B3 D9 6C B6 5B 2D 16 0B 05 +82 41 A0 50 28 94 4A A5 D2 69 34 1A 8D 46 23 91 +C8 E4 72 39 1C 8E C7 E3 F1 F8 FC FE FF 7F 3F 1F +0F 07 83 C1 E0 70 38 9C CE E7 F3 F9 7C BE DF 6F +37 9B 4D 26 13 89 44 22 11 88 C4 62 31 98 CC E6 +73 B9 5C AE D7 EB 75 BA DD 6E B7 DB 6D 36 1B 0D +06 03 81 C0 60 30 18 8C C6 63 B1 D8 EC F6 7B 3D +1E 8F 47 A3 D1 E8 F4 7A BD 5E AF 57 AB 55 AA D5 +EA F5 FA FD 7E BF 5F 2F 17 8B 45 A2 51 A8 D4 6A +B5 DA ED 76 3B 1D 0E 87 C3 E1 F0 78 BC DE EF 77 +BB 5D 2E 97 CB 65 B2 59 2C 96 4B 25 92 49 24 12 +09 04 02 01 80 40 20 10 08 84 42 21 90 48 A4 52 +29 14 0A 85 C2 61 B0 58 AC D6 6B 35 9A CD 66 33 +99 4C A6 53 A9 54 2A 95 CA E5 86 F3 00 00 38 F5 +00 00 86 AB 00 00 94 F4 00 00 6C F8 38 F5 00 00 +38 F5 00 00 00 BC 00 00 94 F4 00 00 7E F8 38 F5 +00 00 38 F5 00 00 42 BA 00 00 94 F4 00 00 90 F8 +3E E7 00 00 F6 F4 00 00 44 D3 00 00 94 F4 00 00 +5A F8 76 F3 00 00 38 F5 00 00 7C BE 00 00 8A F4 +00 00 B4 F8 18 EB 00 00 38 F5 00 00 58 F2 00 00 +94 F4 00 00 C6 F8 EA EC 00 00 38 F5 00 00 6C F2 +00 00 94 F4 00 00 D8 F8 B4 D9 00 00 38 F5 00 00 +70 EA 00 00 94 F4 00 00 A2 F8 20 20 44 4F 4E 45 +00 00 20 43 4F 4E 46 00 20 52 46 42 53 4C 00 00 +20 20 53 59 4E 43 00 00 20 44 4C 4F 47 00 46 41 +49 4C 00 00 45 52 52 00 30 30 30 30 30 30 30 00 +2D 2D 2D 00 20 52 41 4D 00 00 20 4F 46 46 00 00 +20 20 4F 4E 00 00 20 4E 4F 4D 45 4D 00 00 4C 4F +42 41 54 54 00 00 20 20 4F 50 45 4E 00 00 20 20 +4C 4F 3F 54 00 00 02 1B 01 1E 17 3C 18 10 06 1E +08 05 03 47 0B 08 0C 00 0D 10 0E B0 0F 71 10 7B +11 83 12 13 13 22 14 F8 15 42 19 1D 1A 1C 1B C7 +1C 00 1D B2 21 B6 22 10 23 EA 24 2A 25 00 26 1F +2C 81 2D 35 2E 09 F5 60 B6 F2 63 D3 D7 70 F7 F3 +00 00 00 00 00 86 00 77 C7 95 E6 97 17 F3 67 05 +F0 87 85 75 46 C6 37 F5 06 D3 87 C4 C4 02 67 E3 +B6 00 03 01 04 08 10 80 80 80 80 20 40 02 01 80 +04 02 10 20 40 08 08 80 08 08 08 08 F7 F7 F7 F7 +20 40 04 80 7F 7F 7F 7F 7F 10 01 80 2F 1E 1B 07 +37 B2 0A 04 00 00 00 0C 00 10 AA 56 4D 3B 15 11 +F8 57 07 0C 10 1D 1C C7 10 B0 FF FF F9 B6 10 EA +2A 00 1F 00 67 FF 00 00 6F 00 1C 02 DD 03 B1 05 +9D 07 A2 09 C4 0B 07 0E 6E 10 01 13 C6 15 C8 18 +11 1C B5 1F CC 23 07 04 F5 03 E8 03 B6 03 84 03 +52 03 20 03 EE 02 BC 02 8A 02 58 02 26 02 F4 01 +C2 01 90 01 5E 01 2C 01 A0 ED 00 00 94 EE 00 00 +94 F1 00 00 2E F5 00 00 2A F5 00 00 D4 E4 00 00 +79 56 34 12 02 01 01 01 00 00 5A 1E 5A 1E FF FF +FF FF 00 32 50 6E 0F 27 8D 00 02 00 00 +@fa8e +01 00 1C 1F 00 00 01 00 E0 1E 00 00 01 00 E1 1E +0A 00 54 00 16 1D 20 0A 20 0A 20 0A 20 0A 24 0A +2A 0A 29 0A 27 0A 26 0A 24 0A 24 0A 26 0A 26 0A +24 0A 26 0A 24 0A 26 0A 26 0A 26 0A 21 0A 22 0A +20 0A 23 0A 24 0A 25 0A 26 0A 21 0A 22 0A 23 0A +25 0A 20 0A 20 0A 24 0A 2B 0A 2B 0A 2A 0A 29 0A +28 0A 27 0A 20 0A 24 0A 28 0A 02 00 40 1F 00 00 +02 00 42 1F 00 00 01 00 59 1E 00 00 01 00 00 1E +00 00 01 00 22 1E 00 00 01 00 23 1E 00 00 01 00 +24 1E 00 00 02 00 26 1E 00 00 02 00 28 1E 00 00 +01 00 2A 1E 00 00 01 00 2C 1E FF 00 04 00 30 1E +00 00 00 00 04 00 34 1E 00 00 00 00 04 00 38 1E +00 00 00 00 01 00 EA 1E 00 00 01 00 C4 1E 00 00 +02 00 C6 1E 00 00 01 00 C8 1E 00 00 04 00 CA 1E +00 00 00 00 01 00 3C 1E 01 00 01 00 95 1E 00 00 +02 00 48 1F 00 00 01 00 4A 1F 00 00 04 00 CE 1E +00 00 00 00 01 00 D2 1E 00 00 01 00 D6 1E 00 00 +01 00 D7 1E 00 00 04 00 EC 1E 00 00 00 00 04 00 +F0 1E 00 00 00 00 01 00 F4 1E 00 00 01 00 AA 1E +00 00 01 00 AB 1E 00 00 01 00 AC 1E 00 00 01 00 +AD 1E 00 00 02 00 F6 1E 00 00 02 00 F8 1E 00 00 +01 00 FA 1E 00 00 01 00 FB 1E 00 00 01 00 20 1F +00 00 02 00 22 1F 00 00 02 00 38 1F 00 00 01 00 +3A 1F 00 00 00 00 +@ffe0 +F6 A4 +@ffea +64 E4 60 D9 C4 A6 62 F1 +@fffe +46 EA +q diff --git a/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_datalogger_868MHz.txt b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_datalogger_868MHz.txt new file mode 100755 index 0000000..fc17c09 --- /dev/null +++ b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_datalogger_868MHz.txt @@ -0,0 +1,1514 @@ +@9e00 +5A 14 31 80 1A 00 CA 0E B0 13 DA E6 0E 43 3F 40 +C8 42 B0 13 C4 C8 81 4C 12 00 81 4D 14 00 CC 0A +B0 13 E8 ED 0E 43 3F 40 20 41 B0 13 C4 C8 81 4C +16 00 81 4D 18 00 36 40 11 00 37 40 BA 1D 0A 43 +28 47 19 47 02 00 CC 08 CD 09 1E 41 12 00 1F 41 +14 00 B0 13 36 DC 0C 93 0A 38 81 48 08 00 81 49 +0A 00 27 52 1A 53 16 83 EB 23 4A 4A 03 3C 4A 4A +0A 93 7E 24 3A 90 0F 00 3D 38 3A 90 0F 00 23 24 +B0 13 86 A0 1E 42 FA 1D 1F 42 FC 1D B0 13 C4 B0 +C9 0C CA 0D 1C 42 FA 1D 1D 42 FC 1D 1E 42 F6 1D +1F 42 F8 1D B0 13 3A A0 1C 42 34 FA 1C 82 32 FA +B0 13 4C A0 1C 42 34 FA B0 13 60 A0 81 4C 00 00 +81 4D 02 00 73 3C B0 13 24 A0 C9 0C CA 0D 1C 42 +F6 1D 1D 42 F8 1D 1E 41 08 00 1F 41 0A 00 B0 13 +3A A0 1C 42 32 FA 1C 82 30 FA B0 13 4C A0 1C 42 +30 FA E2 3F C9 0A 59 02 16 49 12 FA 5A 06 17 4A +BA 1D 18 4A BC 1D B0 13 24 A0 C5 0C CA 0D B0 13 +86 A0 CE 07 CF 08 B0 13 C4 B0 3E 40 34 80 3F 40 +37 3A B0 13 10 A0 CC 05 CD 0A B0 13 40 C2 C5 0C +CA 0D CC 07 CD 08 1E 41 08 00 1F 41 0A 00 B0 13 +90 A0 CC 05 CD 0A B0 13 C4 C8 C8 0C CA 0D 1C 49 +14 FA 0C 86 B0 13 0A E5 CE 0C CF 0D CC 08 CD 0A +B0 13 40 C2 C9 0C CA 0D CC 06 B0 13 60 A0 A6 3F +B0 13 86 A0 1E 42 BA 1D 1F 42 BC 1D B0 13 C4 B0 +C9 0C CA 0D 1C 42 BE 1D 1D 42 C0 1D 1E 42 BA 1D +1F 42 BC 1D B0 13 3A A0 1C 42 16 FA 1C 82 14 FA +B0 13 56 A0 81 4C 00 00 81 4D 02 00 2C 41 1D 41 +02 00 B0 13 6A A0 3E 40 F4 FD 3F 40 D4 3B B0 13 +10 A0 1C 41 16 00 1D 41 18 00 B0 13 C4 C8 81 4C +04 00 81 4D 06 00 1C 41 04 00 1D 41 06 00 B0 13 +6A A0 2E 41 1F 41 02 00 B0 13 40 C2 81 4C 0C 00 +81 4D 0E 00 1C 41 0C 00 1D 41 0E 00 B0 13 76 DE +81 4C 10 00 1C 41 10 00 31 50 1A 00 55 16 10 01 +B0 13 40 C2 CE 0C CF 0D 0C 43 3D 40 80 3F B0 13 +90 A0 10 01 1C 41 16 00 1D 41 18 00 1E 41 0C 00 +1F 41 0E 00 B0 13 C4 B0 10 01 B0 13 90 A0 CC 09 +CD 0A B0 13 C4 C8 C9 0C CA 0D 10 01 B0 13 56 A0 +C9 0C CA 0D 10 01 B0 13 78 A0 B0 13 40 C2 10 01 +B0 13 78 A0 B0 13 CA B0 10 01 3E 40 E7 6F 3F 40 +63 3B B0 13 40 C2 10 01 B0 13 0A E5 CE 0C CF 0D +CC 09 CD 0A 10 01 1C 41 16 00 1D 41 18 00 10 01 +B0 13 C4 B0 CE 0C CF 0D 10 01 4A 14 31 82 B0 13 +B2 F3 C8 0C CF 08 3F 50 FF 7F 81 4F 06 00 91 41 +06 00 04 00 82 43 A8 1E 4A 43 49 43 4C 49 B0 13 +0C A3 1F 4C 18 00 1F 83 1D 24 1F 83 14 24 D2 B3 +36 1F 47 24 1E 42 B0 1E 1F 42 B2 1E 3E F3 3F F0 +FF 00 1F 9C 02 00 3D 20 2E 9C 3B 20 D2 C3 36 1F +82 43 A8 1E 36 3C 5A 53 B0 13 50 DB 4C 93 31 24 +C7 09 2F 3C B0 13 FA F0 C6 0C CC 09 B0 13 CC DF +4C 93 0C 20 CC 09 CD 06 CE 08 B0 13 58 B5 1F 42 +A6 1E AF 93 18 00 09 20 5A 53 07 3C 82 43 A8 1E +E2 B2 36 1F 02 20 B0 13 A8 E5 1F 42 A6 1E 9F 93 +18 00 0F 20 CF 01 3F 50 03 00 81 4F 00 00 CC 06 +CD 01 3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 +08 DA 59 53 AB 27 4A 93 50 24 92 93 A8 1E 18 38 +4C 47 B0 13 0C A3 CC 07 B0 13 8A C1 4C 93 10 24 +5A 83 CF 01 3F 50 03 00 81 4F 00 00 7C 42 CD 01 +3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 08 DA +4A 93 33 24 1F 42 A4 1E 0F 88 1F 93 2C 34 E2 B2 +36 1F 0D 20 E2 D2 36 1F C2 93 AD 1E 04 20 B2 50 +E0 7F A4 1E 20 3C B2 50 C0 53 A4 1E 1C 3C E2 C2 +36 1F C2 93 AD 1E 03 24 3F 40 40 6C 02 3C 3F 40 +20 00 82 5F A4 1E 49 43 4C 49 B0 13 0C A3 AC 93 +18 00 07 20 CC 09 B0 13 F2 E9 4C 93 02 20 5A 83 +04 24 59 53 F1 27 4A 93 0E 20 F2 F0 F9 00 36 1F +91 91 06 00 04 00 02 24 0E 43 08 3C B0 13 58 F4 +A2 43 FC 1E 70 3C E2 D3 36 1F 1E 43 1F 41 06 00 +0F 88 0F 93 54 38 0E 93 3C 24 E2 B2 36 1F 16 20 +1F 41 06 00 1F 82 A4 1E 3F 80 42 00 0F 93 31 38 +F2 40 07 00 FA 1E C2 43 FB 1E F2 D0 18 00 36 1F +92 42 A4 1E F6 1E A2 43 FC 1E 4B 3C 1F 41 06 00 +0F 88 3F 80 42 00 1F 93 1C 38 F2 40 07 00 FA 1E +C2 43 FB 1E F2 D0 18 00 36 1F 1F 41 06 00 1F 82 +A4 1E 3F 80 42 00 0F 93 05 34 1F 41 06 00 3F 80 +42 00 02 3C 1F 42 A4 1E 82 4F F6 1E 92 43 FC 1E +28 3C D2 41 02 00 FA 1E D2 41 03 00 FB 1E 5F 42 +36 1F 7F C2 7F D0 10 00 C2 4F 36 1F 92 41 06 00 +F6 1E 92 41 04 00 F8 1E 82 43 FC 1E 12 3C D2 91 +02 00 FA 1E 09 24 D2 41 02 00 FA 1E D2 41 03 00 +FB 1E F2 D0 10 00 36 1F 92 41 04 00 F6 1E 92 43 +FC 1E D2 C3 36 1F 31 52 46 16 10 01 3D 40 1C 00 +B0 13 1A F2 1C 52 7A FA 82 4C A6 1E 10 01 6A 14 +31 80 20 00 C8 0F C9 0D CA 0E 81 43 0C 00 81 43 +0E 00 B0 13 0A E5 81 4C 14 00 81 4D 16 00 CC 09 +CD 0A B0 13 DA E6 0E 43 3F 40 C8 42 B0 13 C4 C8 +81 4C 18 00 81 4D 1A 00 CC 08 B0 13 E8 ED 0E 43 +3F 40 20 41 B0 13 C4 C8 81 4C 1C 00 81 4D 1E 00 +1C 41 14 00 1D 41 16 00 3E 40 F4 FD 3F 40 D4 3B +B0 13 40 C2 1E 41 1C 00 1F 41 1E 00 B0 13 CA B0 +81 4C 10 00 81 4D 12 00 1C 41 10 00 1D 41 12 00 +3E 40 E7 6F 3F 40 63 3B B0 13 40 C2 CE 0C CF 0D +1C 41 14 00 1D 41 16 00 B0 13 C4 C8 81 4C 08 00 +81 4D 0A 00 36 40 10 00 37 40 14 FA 0A 43 2C 47 +B0 13 C4 A4 CE 08 CF 09 B0 13 36 DC 0C 93 08 38 +81 48 0C 00 81 49 0E 00 27 53 1A 53 16 83 EF 23 +4A 4A 5A 02 1C 4A 34 FA B0 13 E8 ED C6 0C C7 0D +1C 4A 14 FA B0 13 C4 A4 B0 13 E8 A4 C4 0C C5 0D +1C 41 08 00 1D 41 0A 00 CE 08 CF 09 B0 13 C4 B0 +3E 40 82 A8 3F 40 7B 38 B0 13 40 C2 CE 0C CF 0D +0C 43 3D 40 80 3F B0 13 D6 A4 C4 0C C5 0D 1C 4A +36 FA B0 13 E8 ED CE 06 CF 07 B0 13 D6 A4 C5 0C +CA 0D CC 08 CD 09 B0 13 E8 A4 CE 0C CF 0D CC 05 +CD 0A B0 13 C4 C8 CE 06 CF 07 B0 13 CA B0 81 4C +04 00 81 4D 06 00 1C 41 18 00 1D 41 1A 00 1E 41 +04 00 1F 41 06 00 B0 13 C4 C8 81 4C 00 00 81 4D +02 00 38 40 11 00 3A 40 BA 1D 39 40 36 FA 3C 49 +B0 13 E8 ED 2E 41 1F 41 02 00 B0 13 40 C2 2A 52 +8A 4C FC FF 8A 4D FE FF 18 83 F1 23 31 50 20 00 +64 16 10 01 B0 13 0A E5 C8 0C C9 0D 1C 41 0C 00 +1D 41 0E 00 10 01 B0 13 C4 B0 CE 0C CF 0D CC 04 +CD 05 B0 13 40 C2 10 01 1E 41 10 00 1F 41 12 00 +B0 13 C4 B0 10 01 4F 14 5D 42 1B 02 B2 B0 20 00 +D8 1E D4 20 B2 B0 40 00 D8 1E D0 20 82 43 D8 1E +5E 42 1D 02 4E FD 4B 43 B0 13 12 F4 4C 93 62 20 +7E B0 1F 00 0F 24 32 C2 03 43 C2 43 1B 02 32 D2 +3C 40 A3 00 B0 13 5A DA 92 42 96 1E 9A 1E 92 42 +98 1E 9C 1E 6E B2 39 20 6E B3 22 20 7E B0 10 00 +17 20 5E B3 0E 20 7E B2 6C 24 F2 B2 01 02 69 24 +D2 43 DD 1E C2 43 DC 1E F2 D2 03 02 F2 D2 05 02 +60 3C D2 B3 01 02 5D 24 B2 D2 D8 1E 5B 43 59 3C +F2 B0 10 00 01 02 55 24 A2 D2 D8 1E 5B 43 51 3C +E2 B3 01 02 0B 20 E2 B3 19 02 4B 24 A2 D3 D8 1E +B2 F0 FF FE D8 1E E2 C3 19 02 43 3C A2 D3 D8 1E +B2 F0 FF FE D8 1E 5B 43 3C 3C E2 B2 01 02 0B 20 +E2 B2 19 02 36 24 92 D3 D8 1E B2 F0 7F FF D8 1E +E2 C2 19 02 2E 3C 92 D3 D8 1E B2 F0 7F FF D8 1E +5B 43 27 3C D2 53 E0 1E 5F 42 E0 1E 5F 83 7F 90 +07 00 05 28 F2 F0 0F 00 7A 1D C2 43 E0 1E 6E B2 +13 20 6E B3 0D 20 7E B0 10 00 06 20 5E B3 11 24 +F2 D0 20 00 78 1D 0D 3C F2 D0 30 00 7A 1D 07 3C +F2 D0 20 00 7A 1D 03 3C F2 D0 10 00 7A 1D F2 D2 +78 1D A2 B3 D8 1E 03 24 B2 B2 D8 1E 0D 20 4B 93 +0D 24 B2 B0 10 00 86 1E 02 20 B0 13 80 DC 3C 40 +00 20 B0 13 5A DA 02 3C 82 43 D8 1E 7E B0 20 00 +02 24 A2 D2 88 1E 7E B0 40 00 02 24 A2 D3 88 1E +92 B3 D8 1E 03 20 A2 B3 D8 1E 18 24 3C 40 66 06 +B0 13 5A DA E2 B2 01 02 07 24 E2 D2 19 02 92 C3 +D8 1E B2 D0 80 00 D8 1E E2 B3 01 02 07 24 E2 D3 +19 02 A2 C3 D8 1E B2 D0 00 01 D8 1E 32 C2 03 43 +C2 43 1D 02 C2 4D 1B 02 32 D2 B1 C0 F0 00 14 00 +4B 16 00 13 4F 14 B2 F0 EF FF 42 03 92 C3 42 03 +B2 80 00 80 52 03 B2 D0 10 00 42 03 B0 13 E8 D5 +B2 D0 10 00 14 1D B0 13 06 F4 4C 93 C7 20 B0 13 +12 F4 4C 93 11 24 B2 90 03 00 72 1D 0D 20 C2 93 +76 1D 08 20 7C 40 5A 00 3D 40 00 F9 5E 43 B0 13 +D6 BC 02 3C D2 83 76 1D E2 93 9E 1E 02 28 92 D3 +88 1E B0 13 B6 F4 4C 93 02 24 B2 D2 88 1E B0 13 +F0 F4 4C 93 02 24 A2 D3 88 1E B0 13 FA F3 4C 93 +02 24 B0 13 72 EE B2 B0 20 00 86 1E 10 24 5E 42 +2A 1F CF 0E 5F 83 C2 4F 2A 1F 4E 93 08 20 92 D3 +8A 1E B2 D0 20 00 8A 1E F2 40 0F 00 2A 1F 82 93 +8A 1E 0F 24 92 B3 8A 1E 08 20 A2 B2 8A 1E 09 24 +A2 C2 8A 1E 92 D3 14 1D 04 3C 92 C3 8A 1E A2 D3 +8A 1E A2 B3 86 1E 0E 24 1F 42 96 1E 1E 42 98 1E +1F 82 9A 1E 1E 72 9C 1E 03 20 3F 90 1F 00 02 28 +92 D3 86 1E D2 93 DD 1E 0E 20 E2 92 DC 1E 03 2C +D2 53 DC 1E 08 3C F2 C2 03 02 F2 C2 05 02 C2 43 +DC 1E C2 43 DD 1E E2 B3 01 02 03 24 D2 B3 01 02 +2F 20 C2 43 1C 1F E2 B2 01 02 11 24 D2 53 DA 1E +F2 90 03 00 DA 1E 0D 28 B2 D0 20 00 D8 1E B2 F0 +7F FF D8 1E C2 43 DA 1E E2 C2 19 02 02 3C C2 43 +DA 1E E2 B3 01 02 11 24 D2 53 DB 1E F2 90 03 00 +DB 1E 2C 28 B2 D0 40 00 D8 1E B2 F0 FF FE D8 1E +C2 43 DB 1E E2 C3 19 02 21 3C C2 43 DB 1E 1E 3C +D2 53 1C 1F 5F 42 1C 1F 5F 83 7F 90 03 00 16 28 +1F 42 86 1E 2F C2 2E 42 1E C2 86 1E 0E DF 82 4E +86 1E 92 D3 8A 1E A2 B2 86 1E 04 20 B2 D0 10 00 +8A 1E 02 3C B2 D2 8A 1E C2 43 1C 1F B1 C0 D0 00 +14 00 4B 16 00 13 3C 40 01 1E 0D 43 3E 40 21 00 +B0 13 CC F2 7C 40 30 00 B0 13 EA CF 7C 40 30 00 +B0 13 30 DE 4C 93 AF 20 7C 40 31 00 B0 13 30 DE +7C 90 06 00 A5 20 7C 40 36 00 B0 13 EA CF B0 13 +0C AA FD 23 B2 40 01 02 34 0F 0F 42 32 C2 03 43 +B2 B0 10 00 02 0F FC 27 B2 40 51 7E 10 0F B2 B0 +10 00 02 0F FC 27 F2 40 3D 00 11 0F B2 B0 10 00 +02 0F FC 27 F2 40 FE 00 11 0F B2 B0 20 00 02 0F +FC 27 C2 43 10 0F B2 B0 80 00 02 0F FC 27 F2 90 +51 00 20 0F 72 20 B2 B0 10 00 02 0F FC 27 F2 40 +3D 00 11 0F 02 4F 3B 40 56 F9 4E 43 6C 4B 4F 4E +5F 02 5D 4F 57 F9 B0 13 DC E5 2B 53 5E 53 7E 90 +20 00 F4 2B 3D 40 56 F9 4E 43 6C 4D B0 13 30 DE +4F 4E 5F 02 CF 9C 57 F9 4D 20 2D 53 5E 53 7E 90 +20 00 F3 2B 7C 40 36 00 B0 13 EA CF B0 13 0C AA +FD 23 7C 40 0C 00 5D 42 94 1E B0 13 DC E5 B0 13 +D6 EF 6C 43 B0 13 14 F1 7C 40 34 00 B0 13 EA CF +A2 B3 30 0F FD 27 3E 40 10 00 7C 40 34 00 B0 13 +30 DE 5C F3 5F 42 22 1E 4F 5F 4C DF C2 4C 22 1E +1E 83 F3 23 F2 D0 80 00 22 1E B0 13 EC E8 7C 40 +32 00 B0 13 EA CF D2 43 00 1E B2 40 36 00 26 1E +B2 40 E2 04 28 1E 3C 40 01 1E 0D 43 3E 40 1F 00 +B0 13 CC F2 3C 40 20 1E 0D 43 2E 43 B0 13 CC F2 +32 D2 10 01 32 C2 03 43 FF 3F 32 C2 03 43 FF 3F +32 C2 03 43 FF 3F 32 C2 03 43 FF 3F 7C 40 3D 00 +B0 13 EA CF 7C B0 F0 FF 10 01 C2 43 9E 1D 5F 42 +7A 1D 2F 83 AA 24 1F 83 50 24 1F 83 33 24 1F 83 +16 24 1F 83 06 24 1F 83 A5 20 F2 D0 20 00 78 1D +10 01 7C 40 40 00 B0 13 0E E0 5C 53 7C 90 4F 00 +FA 2B B2 40 00 80 90 1C E2 C3 8C 1C 10 01 E2 43 +7A 1D 3C 40 A4 1D 4D 43 4E 4D 5E 02 5F 4E 7B 1D +47 18 0F 5F 5E 4E 7C 1D 0E 5F 2C 53 8C 4E FE FF +5D 53 7D 90 09 00 F0 2B E2 43 9F 1D F2 40 09 00 +9E 1D 10 01 E2 43 7A 1D 5E 42 7B 1D 47 18 0E 5E +5F 42 7C 1D 0E 5F 82 4E A0 1D 5F 42 7D 1D 47 18 +0F 5F 5D 42 7E 1D 0F 5D 82 4F A2 1D D2 43 9F 1D +4F 8E 5F 53 C2 4F 9E 1D 10 01 3E 40 BF FF 1E F2 +86 1E 5F 42 7B 1D 5F 03 3F F0 C0 FF 0E DF 82 4E +86 1E 3F 40 7F 00 5F F2 7B 1D C2 4F A0 1E D2 42 +7C 1D A1 1E D2 42 7D 1D A2 1E 5F 42 7E 1D 47 18 +0F 5F 5E 42 7F 1D 0E 5F 82 4E 34 1F D2 42 80 1D +32 1F D2 42 81 1D 31 1F 5F 42 84 1D 47 18 0F 5F +5E 42 85 1D 0E 5F CF 0E 1F 52 80 1E 1F 82 7E 1E +82 4F 80 1E 82 4E 7E 1E 5F 42 86 1D 47 18 0F 5F +5C 42 87 1D 0C 5F 82 4C 82 1E 1D 42 78 1E 1E 42 +7A 1E 1F 42 7C 1E B0 13 1E A3 D2 42 88 1D 8D 1C +D2 42 89 1D 8E 1C 7C 40 5A 00 3D 40 EA F8 5E 43 +B0 13 D6 BC D2 43 76 1D 10 01 F2 40 03 00 7A 1D +D2 43 9E 1D 10 01 1A 14 CA 0C 6D 93 3A 24 5D 93 +0E 24 6D 92 5C 20 B0 13 BE AC 6D 42 B0 13 30 F0 +C2 43 9F 1E 4C 43 4D 43 B0 13 30 F0 50 3C C2 93 +9F 1E 18 20 B2 B0 40 00 86 1E 07 20 B0 13 52 AC +5A 93 05 20 B0 13 8A F0 02 3C B0 13 66 AC B0 13 +98 AC C9 0C 5C 42 A1 1E B0 13 74 AC B0 13 BE AC +6D 43 E2 3F B0 13 B0 AC C9 0C 5C 42 A2 1E B0 13 +74 AC 7D 40 1F 00 7E 40 29 00 B0 13 42 F4 5D 43 +D3 3F 5F 42 9E 1E 4F 93 22 24 C2 93 9F 1E 18 20 +4F 4F 2F 83 0D 24 1F 83 1A 20 B2 B0 40 00 86 1E +05 20 B0 13 52 AC B0 13 8A F0 02 3C B0 13 66 AC +B0 13 98 AC CA 0C 5C 42 A1 1E B0 13 8A AC 07 3C +B0 13 B0 AC CA 0C 5C 42 A2 1E B0 13 8A AC 19 16 +10 01 B0 13 50 EE CF 0C CC 0A B0 13 A0 AC 4C 4F +B0 13 7C AC 10 01 B0 13 A0 AC 5C 42 A0 1E B0 13 +7C AC 10 01 B0 13 7C AC CC 0A 10 01 B0 13 CC AC +CC 09 5E 43 B0 13 D6 BC 10 01 B0 13 CC AC CC 0A +5E 43 B0 13 D6 BC 10 01 CC 0A B0 13 B0 AC 10 01 +7D 40 4A 00 7E 40 60 00 B0 13 42 F4 C9 0C 10 01 +7D 40 48 00 7E 40 5E 00 B0 13 42 F4 10 01 7D 40 +1E 00 7E 40 28 00 B0 13 42 F4 10 01 0D 43 6E 43 +4F 43 B0 13 D2 C0 CD 0C 10 01 0A 14 31 82 92 B3 +14 1D 0F 20 A2 B2 14 1D 0C 20 3F 40 0C 00 1F 52 +40 1F 6F 13 4C 93 0C 24 5C 43 6D 43 80 13 8C 1E +07 3C 5C 43 B0 13 44 D6 5C 43 5D 43 80 13 8C 1E +A2 B3 8A 1E 1B 20 92 B3 14 1D 12 20 B2 B2 14 1D +0F 20 3F 40 0C 00 1F 52 42 1F 6F 13 4C 93 61 24 +82 93 8A 1E 5E 20 6C 43 6D 43 80 13 90 1E 59 3C +6C 43 B0 13 44 D6 6C 43 5D 43 F7 3F 6A 43 B2 B2 +8A 1E 2E 20 B2 B0 10 00 8A 1E 26 20 B2 B0 20 00 +8A 1E 1E 20 B2 B0 00 01 8A 1E 14 20 5A 43 B2 B0 +40 00 8A 1E 0B 20 B2 B0 80 00 8A 1E 20 24 CC 01 +3D 40 2A F9 2E 42 B0 13 BA F2 19 3C CC 01 3D 40 +30 F9 F8 3F CC 01 3D 40 36 F9 3E 40 06 00 F3 3F +CC 01 3D 40 3E F9 F9 3F CC 01 3D 40 46 F9 F5 3F +CC 01 3D 40 4E F9 3E 40 06 00 B0 13 BA F2 CC 0A +B0 13 44 D6 CC 0A 6D 42 80 13 90 1E 6A 93 07 24 +7C 40 46 00 CD 01 5E 43 B0 13 D6 BC 06 3C 7C 40 +5A 00 CD 01 5E 43 B0 13 D6 BC 82 43 8A 1E A2 D2 +8A 1E 92 B3 14 1D 10 24 B0 13 FA F3 6C 93 0C 20 +7C 40 17 00 B0 13 22 AE 7C 40 18 00 B0 13 22 AE +7C 40 19 00 B0 13 22 AE 82 43 14 1D 31 52 0A 16 +10 01 7D 40 03 00 B0 13 30 F0 10 01 1A 14 31 80 +16 00 B0 13 88 E2 CA 0C 0A 93 03 20 3C 40 03 00 +97 3C 5C 43 CD 0A B0 13 AA BD 4C 93 04 20 CC 0A +B0 13 FC F4 F3 3F B0 13 02 F5 CD 0C C9 01 39 52 +CC 09 2E 42 B0 13 BA F2 81 49 00 00 CF 01 3F 50 +0C 00 81 4F 02 00 F1 40 09 00 04 00 E1 43 05 00 +CD 01 3D 50 0E 00 3C 40 CE 1E B0 13 DE F0 D1 4A +09 00 12 00 D1 42 D7 1E 0D 00 B0 13 22 F5 C1 4C +13 00 D1 43 0C 00 B0 13 26 F5 C1 4C 14 00 2C 43 +3D 40 03 00 CE 01 B0 13 F6 C2 0C 93 59 20 B0 13 +EA F4 C9 0C E1 43 05 00 CF 01 3F 50 0C 00 81 4F +02 00 CF 0A 3F 50 03 00 81 4F 00 00 79 90 03 00 +06 24 59 93 02 20 B0 13 2E EE B0 13 18 EF B0 13 +74 E5 79 90 03 00 07 24 59 93 03 24 B0 13 F8 EE +02 3C B0 13 58 ED 2C 43 2D 43 CE 01 B0 13 F6 C2 +0C 93 05 24 CC 0A B0 13 FC F4 1C 43 29 3C 3F 40 +7F 00 5F F1 0C 00 5F 93 09 24 7F 90 03 00 06 24 +CC 0A B0 13 FC F4 3C 40 05 00 1A 3C EA 43 00 00 +DA 41 0E 00 0A 00 D2 4A 0B 00 FF 1D F1 90 40 00 +0F 00 02 20 5F 43 02 3C 7F 40 03 00 CA 4F 01 00 +D2 53 D7 1E C2 93 D7 1E 02 20 D2 43 D7 1E 0C 43 +31 50 16 00 19 16 10 01 3A 14 31 82 C9 0C F9 90 +14 00 00 00 05 28 B0 13 26 F5 C9 9C 14 00 74 20 +3C 40 0E 00 0C 59 CD 01 B0 13 1E F4 91 92 D0 1E +02 00 6A 20 91 92 CE 1E 00 00 66 20 58 49 12 00 +3A 40 05 00 0A 59 3C 40 05 00 0C 59 CD 08 B0 13 +7C E3 0C 93 48 20 C2 93 D2 1E 56 24 B0 13 88 E2 +C7 0C 07 93 51 24 3C 40 03 00 0C 57 CD 0A 2E 42 +B0 13 BA F2 6C 43 CD 07 B0 13 AA BD 4C 93 03 24 +D2 93 D6 1E 04 20 CC 07 B0 13 FC F4 3D 3C 5F 42 +D6 1E CE 0F 5E 53 C2 4E D6 1E 4F 4F DF 47 0B 00 +D4 1E C7 48 0A 00 E7 43 00 00 F9 90 40 00 13 00 +02 20 5F 43 02 3C 7F 40 03 00 C7 4F 01 00 D1 47 +09 00 06 00 B0 13 22 F5 C1 4C 07 00 B0 13 A8 B0 +B0 13 96 B0 CD 01 B0 13 B6 B0 D5 27 B0 13 7E B0 +0C 93 12 24 D0 3F B0 13 A8 B0 D1 4C 09 00 06 00 +B0 13 22 F5 C1 4C 07 00 B0 13 96 B0 CD 01 B0 13 +B6 B0 02 24 B0 13 7E B0 31 52 37 16 10 01 3C 40 +03 00 0C 59 CD 0A 2E 42 B0 13 BA F2 CC 09 4D 43 +B0 13 30 E8 10 01 3E 40 07 00 5E F9 0A 00 3F 40 +03 00 4F 8E 6C 43 10 01 F1 40 81 00 08 00 D1 49 +0D 00 09 00 10 01 2D 52 6E 42 B0 13 6A CA C9 0C +09 93 10 01 3B 40 80 00 01 3C 0B 43 0A 14 09 14 +08 14 07 14 21 83 3F B0 80 7F 7B 24 3D B0 80 7F +05 20 0C 4E 0D 4F 8B 10 0D EB 73 3C 5D 02 08 4D +4D 10 38 F0 00 FF 0D D8 5F 02 08 4F 4F 10 38 F0 +00 FF 0F D8 09 4C 0A 4D 3D F0 80 00 C1 4D 00 00 +0B EA 0B EF 3B C0 7F FF 3A D0 80 00 3F D0 80 00 +0A 9F 02 20 09 9E 0A 24 0B 2C 0D 4F 0F 4A 0A 4D +0C 4E 0E 49 09 4C 81 EB 00 00 02 3C 0B 93 4F 20 +0C 43 08 4A 88 10 47 48 8F 10 48 8F 8F 10 0E 24 +38 90 19 00 34 2C 12 C3 4F 10 5E 00 5C 00 3C B0 +00 10 02 24 3C D0 00 20 18 83 F5 23 0B 93 0C 24 +08 8C 09 7E 4A 7F 0C 48 4A 93 12 30 5C 02 09 69 +4A 6A 17 83 2C 24 F8 3F 09 5E 4A 6F 09 28 4A 10 +59 00 5C 00 3C B0 00 10 02 24 3C D0 00 20 17 53 +3C B0 00 80 07 24 09 63 4A 63 07 63 3C B0 00 60 +01 20 19 C3 17 93 13 38 37 90 FF 00 13 34 7A C0 +80 00 87 10 D1 51 00 00 00 00 57 00 0A D7 0C 49 +0D 4A 21 53 07 16 08 16 09 16 0A 16 10 01 0D 43 +0C 43 F7 3F 3D 40 FF FE D1 61 00 00 00 00 5D 00 +3C 43 EF 3F 0A 14 B0 13 14 F3 B0 13 F4 E3 7C 40 +0A 00 B0 13 CC F4 7C 40 06 00 B0 13 D2 F4 82 43 +BE 1E 82 43 C0 1E 7C 40 05 00 B0 13 A6 F4 7C 40 +0C 00 5D 42 94 1E B0 13 2C E4 92 43 BA 1E 7C 40 +17 00 6D 43 B0 13 10 B3 6D 43 B0 13 1A B3 6D 43 +B0 13 30 F0 4C 43 B0 13 10 ED 0C 93 2A 20 4C 43 +1D 42 BE 1E 1E 42 C0 1E B0 13 52 E1 4C 43 B0 13 +52 D7 7A 40 28 00 04 3C 3C 40 99 19 B0 13 5A DA +4C 43 B0 13 10 ED 2C 93 04 20 CF 0A 5A 83 4F 93 +F3 23 4A 93 0E 20 7C 40 46 00 3D 40 0E F9 5E 43 +B0 13 D6 BC 2E 42 3C 40 00 40 B0 13 5A DA 1E 83 +FA 23 4C 43 B0 13 10 ED 1C 93 0D 24 7C 40 17 00 +6D 42 B0 13 10 B3 6D 42 B0 13 1A B3 6D 42 B0 13 +30 F0 4C 43 23 3C A2 43 BA 1E 82 93 C0 1E 0A 20 +82 93 BE 1E 07 20 4C 43 B0 13 C8 E9 82 4C BE 1E +82 4D C0 1E 7C 40 17 00 7D 40 03 00 B0 13 10 B3 +7D 40 03 00 B0 13 1A B3 7D 40 03 00 B0 13 30 F0 +7C 40 13 00 6D 43 B0 13 30 F0 5C 43 0A 16 10 01 +B0 13 30 F0 7C 40 18 00 10 01 B0 13 30 F0 7C 40 +19 00 10 01 1D 42 90 1C 3D 80 00 80 1D C3 5F 42 +7A 1D 2F 83 03 24 1F 83 2D 24 10 01 D2 93 9F 1D +15 24 E2 93 9F 1D 6A 20 5C 02 1F 4C A4 1D B0 13 +34 B4 5F 0E 3F 80 00 80 82 4F B8 1D 3E 40 7D 1D +7F 40 03 00 B0 13 1E B4 FD 2B 10 01 1F 42 A0 1D +0F 5C B0 13 34 B4 1C 52 A0 1D 5C 0E 3C 80 00 80 +82 4C B8 1D 3E 40 7D 1D 7F 40 03 00 B0 13 1E B4 +FD 2B 10 01 1F 42 86 1E 7F F0 C0 00 4F 5F 3E 40 +7F 00 5E F2 A0 1E 4E DF C2 4E 7B 1D D2 42 A1 1E +7C 1D D2 42 A2 1E 7D 1D 1E 42 34 1F CF 0E 8F 10 +C2 4F 7E 1D C2 4E 7F 1D D2 42 32 1F 80 1D D2 42 +31 1F 81 1D C2 43 82 1D C2 43 83 1D 1E 42 7E 1E +CF 0E 8F 10 8F 11 C2 4F 84 1D C2 4E 85 1D 1E 42 +82 1E CF 0E 8F 10 8F 11 C2 4F 86 1D C2 4E 87 1D +D2 42 8D 1C 88 1D D2 42 8E 1C 89 1D CF 0D 8F 10 +C2 4F 8A 1D C2 4D 8B 1D C2 43 8C 1D 10 01 1E 53 +1D 42 B8 1D EE 4D FF FF 92 53 B8 1D 5F 53 7F 90 +13 00 10 01 CE 0F 8E 10 C2 4E 7B 1D C2 4F 7C 1D +10 01 A2 D3 86 1E 82 93 D8 1E 03 24 A2 B2 86 1E +68 20 B2 B0 20 00 D8 1E 5B 20 B2 B0 40 00 D8 1E +4B 20 82 93 D8 1E 69 24 92 B3 D8 1E 32 20 A2 B3 +D8 1E 1A 20 A2 B2 D8 1E 0D 20 B2 B2 D8 1E 5D 24 +1F 42 42 1F 0F 0F 6C 43 4F 13 B2 D2 14 1D B2 C2 +D8 1E 53 3C 1F 42 40 1F 0F 0F 5C 43 4F 13 A2 D2 +14 1D A2 C2 D8 1E 49 3C C2 43 EB 1E 6C 43 6D 42 +80 13 90 1E 1F 42 42 1F 1F 4F 10 00 82 4F 42 1F +00 18 D2 4F 08 00 90 1E B2 D2 14 1D A2 C3 D8 1E +34 3C 5C 43 6D 42 80 13 8C 1E 1F 42 40 1F 1F 4F +10 00 82 4F 40 1F 00 18 D2 4F 08 00 8C 1E A2 D2 +14 1D 92 C3 D8 1E 21 3C B2 F0 BF FF D8 1E 1F 42 +42 1F 3F 0F 04 00 6C 43 4F 13 92 D3 14 1D 15 3C +B2 F0 DF FF D8 1E 1F 42 40 1F 3F 0F 04 00 5C 43 +F3 3F E2 B3 01 02 03 24 D2 B3 01 02 04 20 92 D3 +8A 1E B2 D2 8A 1E 82 43 D8 1E 82 93 86 1E 09 24 +92 B3 86 1E 06 24 92 C3 86 1E B0 13 D6 F3 92 D3 +14 1D A2 C3 86 1E 10 01 1A 14 C9 0C 1A 42 A6 1E +4D 4D 1D 5A 0C 00 0D 8E 3D 80 13 00 0D 93 78 34 +3E 40 1A 00 1E 52 A6 1E 6F 4E 3F F0 03 00 1F 83 +4F 24 1F 83 2C 20 CA 43 12 00 2F 42 6F BE 1A 20 +1C 42 A6 1E D2 9C 11 00 AA 1E 09 2C C2 93 AC 1E +03 20 B0 13 AA D7 09 3C 8C 43 18 00 06 3C B0 13 +8C D5 1F 42 A6 1E DF 53 11 00 CC 09 5D 43 B0 13 +92 E0 4E 3C EE C2 00 00 1F 42 A6 1E 8F 43 00 00 +8F 43 02 00 1C 42 A6 1E B0 13 AA D7 41 3C 3C 40 +80 00 5C 8A 13 00 CF 0A 2D 4F 1E 4F 02 00 3F 40 +00 02 B0 13 14 DD 1C 5A 0C 00 3C 50 00 02 8A 4C +0C 00 1F 42 A6 1E CF 43 0F 00 3F 40 1A 00 1F 52 +A6 1E 3E 40 FC 00 6E FF 5E D3 CF 4E 00 00 20 3C +3C 40 40 00 5C 8A 13 00 2D 4A 1E 4A 02 00 3F 40 +80 1C B0 13 14 DD 1F 42 A6 1E 1C 5F 0A 00 3C 50 +00 06 8F 4C 0C 00 1F 42 A6 1E DF 43 0F 00 3F 40 +1A 00 1F 52 A6 1E 6E 4F 5E C3 6E D3 CF 4E 00 00 +19 16 10 01 21 83 4E 4E 1E 83 48 24 1E 83 2C 24 +2E 83 1E 24 2E 82 13 24 3E 82 72 20 D2 B3 8C 1C +6F 24 E2 B3 8C 1C 6C 20 F2 90 65 00 92 1C 68 28 +B0 13 58 EF 4C 93 64 24 B0 13 04 C5 61 3C D2 B3 +8C 1C 5E 24 E2 B3 8C 1C 5B 20 B0 13 44 E9 58 3C +D2 B3 8C 1C 55 20 7C 40 40 00 B0 13 0E E0 5C 53 +7C 90 4F 00 FA 2B 4C 3C D2 B3 8C 1C 14 24 E2 B3 +8C 1C 11 20 D2 B3 92 1C 05 24 81 43 00 00 CC 01 +B0 13 64 B7 B1 40 FE FF 00 00 CC 01 6D 43 B0 13 +44 E9 B0 13 04 C5 D2 C3 8C 1C 32 3C 5F 42 8C 1C +1F F3 5E 42 8C 1C 2E F3 0E DF 0E 93 29 20 C2 43 +92 1C D2 42 8E 1C 8F 1C B1 40 FB FF 00 00 CC 01 +6D 43 B0 13 44 E9 3C 40 8D 1C B0 13 64 B7 3C 40 +8E 1C B0 13 64 B7 3C 40 31 1F B0 13 64 B7 3C 40 +32 1F B0 13 64 B7 3C 40 34 1F 6D 43 B0 13 44 E9 +3C 40 A0 1E 7D 40 03 00 B0 13 44 E9 D2 D3 8C 1C +21 53 10 01 5D 43 B0 13 44 E9 10 01 1A 14 31 80 +18 00 B0 13 EA F4 C9 0C B0 13 02 F5 81 4C 10 00 +CF 01 2F 52 81 4F 12 00 F1 42 14 00 7A 40 03 00 +C1 4A 15 00 CD 01 3D 50 06 00 3C 40 EC 1E B0 13 +DE F0 D1 43 04 00 D1 42 F4 1E 05 00 D1 43 0A 00 +B0 13 26 F5 C1 4C 0B 00 2C 43 3D 40 03 00 CE 01 +3E 50 10 00 B0 13 F6 C2 C1 4A 15 00 CF 01 2F 52 +81 4F 12 00 CF 01 3F 50 0C 00 81 4F 10 00 79 90 +03 00 06 24 59 93 02 20 B0 13 2E EE B0 13 18 EF +B0 13 74 E5 3A 40 06 00 79 90 03 00 07 24 59 93 +03 24 B0 13 F8 EE 02 3C B0 13 58 ED 2C 43 2D 43 +CE 01 3E 50 10 00 B0 13 F6 C2 0C 93 1D 20 3F 40 +7F 00 5F F1 04 00 5F 93 03 24 7F 90 06 00 14 20 +CC 01 CD 01 3D 50 06 00 2E 42 B0 13 BA F2 2C 41 +1D 41 02 00 B0 13 02 F3 CC 01 3C 50 0C 00 B0 13 +2A F4 D2 53 F4 1E 0A 43 CC 0A 31 50 18 00 19 16 +10 01 0A 14 21 83 C1 43 00 00 F2 90 03 00 00 1E +6B 20 7C 40 3B 00 B0 13 30 DE CE 0C 7C 40 3B 00 +B0 13 30 DE 4E 9C F9 23 4E 93 61 24 CC 01 5D 43 +B0 13 70 E7 6F 41 3F 50 03 00 4E 4E 0E 9F 38 20 +F1 90 1F 00 00 00 34 2C F1 90 0B 00 00 00 30 28 +3C 40 01 1E 0D 43 3E 40 1F 00 B0 13 CC F2 E2 41 +01 1E 3C 40 02 1E 6D 41 B0 13 70 E7 3C 40 20 1E +6D 43 B0 13 70 E7 F2 B0 80 FF 21 1E 14 24 92 53 +34 1E 82 63 36 1E B0 13 CE E1 4C 93 30 20 5C 42 +20 1E B0 13 90 E8 C2 4C 20 1E F2 F0 7F 00 21 1E +B0 13 D8 EE 24 3C 92 53 30 1E 82 63 32 1E 1F 3C +92 53 38 1E 82 63 3A 1E 0A 42 32 C2 03 43 7C 40 +36 00 B0 13 EA CF 7C 40 3D 00 B0 13 EA CF 7C B0 +F0 FF F9 23 7C 40 3A 00 B0 13 EA CF 7C 40 34 00 +B0 13 EA CF 02 4A 03 3C 32 C2 03 43 FF 3F 21 53 +0A 16 10 01 21 82 D2 83 8F 1C 66 20 5F 42 8D 1C +5F 93 51 24 6F 93 4C 24 6F 92 3F 24 7F 90 07 00 +2B 24 7F 90 03 00 22 24 7F 90 05 00 12 24 7F 90 +06 00 45 20 1E 42 7E 1E CF 0E 5F 0D C1 4F 00 00 +B0 13 2C BA C1 4E 01 00 C1 4D 02 00 7D 40 03 00 +36 3C D1 42 C2 1E 00 00 1E 42 82 1E CF 0E 8F 10 +8F 11 C1 4F 01 00 C1 4E 02 00 F0 3F D1 42 C2 1E +00 00 1E 42 7E 1E F2 3F D1 42 C2 1E 00 00 1E 42 +7E 1E CF 0E 5F 0D C1 4F 01 00 B0 13 2C BA C1 4E +02 00 C1 4D 03 00 6D 42 12 3C 1E 42 82 1E CF 0E +8F 10 8F 11 C1 4F 00 00 C1 4E 01 00 6D 43 07 3C +1E 42 7E 1E F4 3F D1 42 C2 1E 00 00 5D 43 CC 01 +7E 42 B0 13 64 B6 D2 42 8E 1C 8F 1C 0C 43 4D 43 +7E 40 10 00 B0 13 64 B6 21 52 10 01 1D 42 82 1E +43 18 4E 5E CF 0D 8F 10 8F 11 7F F0 0F 00 4E DF +10 01 0A 14 4A 4D 10 3C B2 B0 40 00 86 1E 06 20 +7C 40 09 00 5D 43 B0 13 30 F0 05 3C 7C 40 0B 00 +5D 43 B0 13 30 F0 2A 43 B0 13 F8 D6 1A 93 EC 27 +2A 93 13 24 2A 92 3A 20 B0 13 EE EA 7C 40 0B 00 +4D 43 B0 13 30 F0 7C 40 09 00 4D 43 B0 13 30 F0 +6C 43 4D 43 B0 13 14 BB 29 3C B2 B0 40 00 86 1E +19 20 B0 13 38 EF 3C 90 10 27 0F 34 0C 93 0F 34 +3C E3 1C 53 B0 13 FC BA 4D 43 B0 13 30 F0 7C 40 +03 00 5D 43 B0 13 30 F0 0B 3C 3C 40 0F 27 B0 13 +F0 BA 06 3C 1C 42 82 1E 0C 93 EA 3B B0 13 F0 BA +7C 40 46 00 CD 0B 5E 43 B0 13 D6 BC 0A 16 10 01 +B0 13 FC BA 5D 43 B0 13 14 BB 10 01 3C B0 00 80 +0D 7D 3D E3 6E 42 7F 40 03 00 B0 13 D2 C0 CB 0C +6C 43 10 01 B0 13 30 F0 7C 40 03 00 4D 43 B0 13 +30 F0 10 01 6A 14 31 80 06 00 C6 0C 09 43 3A 40 +00 1C 7F 40 03 00 81 4F 00 00 2F 46 1F 93 06 24 +0F 93 0B 20 58 46 02 00 C7 09 10 3C 5C 46 02 00 +B0 13 6A EB C7 0C 07 93 02 20 0C 43 4D 3C 58 47 +09 00 3F 40 03 00 0F 57 81 4F 02 00 24 43 0F 42 +32 C2 03 43 1E 43 6E 9A 39 20 EA 42 00 00 02 4F +3F 40 0B 00 0F 5A 6F 4F 3F F0 3F 00 4E 48 0F 9E +2A 20 25 46 15 93 0E 20 78 90 3F 00 06 20 3F 40 +03 00 0F 57 81 4F 04 00 05 3C 3F 40 07 00 0F 5A +81 4F 04 00 1C 41 04 00 1D 41 02 00 2E 42 B0 13 +7C ED 4C 4C 05 93 02 24 0C 93 0D 20 5F 4A 01 00 +2E 41 4F 9E 08 2C 09 93 02 24 D9 43 00 00 81 4F +00 00 C9 0A 04 3C DA 43 00 00 01 3C 02 4F 3A 50 +23 00 14 83 BC 23 CC 09 31 50 06 00 64 16 10 01 +4D 4D 1D 93 14 24 2D 93 31 24 2D 92 5B 20 B0 13 +EE EA 6C 43 4D 43 B0 13 C6 BC 7C 40 0F 00 4D 43 +B0 13 30 F0 7C 40 1F 00 4D 43 80 00 30 F0 B0 13 +F8 D6 7C 40 1F 00 5D 43 B0 13 30 F0 7C 40 0F 00 +5D 43 B0 13 30 F0 B2 B0 40 00 86 1E 08 20 7C 40 +1D 00 7D 40 46 00 5E 43 B0 13 78 CF 07 3C 7C 40 +1D 00 7D 40 43 00 5E 43 B0 13 78 CF B2 B0 40 00 +86 1E 04 20 B0 13 7C F1 CB 0C 02 3C 1B 42 7E 1E +0B 93 05 38 6C 43 5D 43 B0 13 C6 BC 0B 3C 3B E3 +1B 53 6C 43 4D 43 B0 13 30 F0 7C 40 03 00 5D 43 +B0 13 30 F0 CC 0B 3C B0 00 80 0D 7D 3D E3 7E 40 +03 00 5F 43 B0 13 D2 C0 CD 0C 7C 40 49 00 5E 43 +80 00 D6 BC 10 01 B0 13 30 F0 7C 40 03 00 4D 43 +B0 13 30 F0 10 01 4A 14 C9 0E 4C 4C 3C 80 46 00 +53 24 1C 83 4C 24 1C 83 46 24 1C 83 41 24 1C 83 +3B 24 3C 80 10 00 3C 90 09 00 55 2C 5C 06 00 18 +50 4C 04 BD 62 BD 00 00 5C BD 00 00 58 BD 00 00 +4E BD 00 00 46 BD 00 00 42 BD 00 00 3A BD 00 00 +32 BD 00 00 28 BD 00 00 7A 40 03 00 78 40 22 00 +2E 3C 6A 43 78 40 21 00 2A 3C 6A 43 78 40 23 00 +26 3C 6A 42 F7 3F 6A 43 78 40 25 00 20 3C 7A 40 +03 00 78 40 24 00 1B 3C 6A 42 F0 3F 7A 40 05 00 +E5 3F 7A 40 06 00 E6 3F 6A 43 78 40 1A 00 0F 3C +7A 40 03 00 FA 3F 6A 43 78 40 1C 00 08 3C 7A 40 +03 00 78 40 1B 00 03 3C 6A 42 78 40 1A 00 C7 0D +4A 4A 06 43 CC 08 4C 56 7D 47 CE 09 B0 13 78 CF +16 53 1A 83 F7 23 46 16 10 01 4A 14 21 83 C8 0D +C7 0C 39 40 41 1E CC 01 0D 43 1E 43 B0 13 CC F2 +46 43 09 98 25 24 2F 43 6F 99 22 20 5A 49 09 00 +7A 90 3E 00 1D 2C 57 93 13 24 3C 40 03 00 0C 59 +3D 40 03 00 0D 58 2E 42 B0 13 7C ED 0C 93 10 20 +4F 4A CA 01 3A 50 E0 FF 0A 5F DA 43 00 00 08 3C +C2 9A 3E 1E 05 2C 4A 4A CF 01 0F 8A DF 43 3D 00 +39 50 0C 00 56 53 D5 27 CE 01 0F 43 4C 43 CE 93 +00 00 04 24 1E 53 5C 53 FA 27 09 3C 67 93 04 20 +7C 50 20 00 4F 4C 03 3C 3F 40 3D 00 4F 8C 67 93 +0B 24 5E 42 3F 1E 0F 9E 12 38 5E 42 3E 1E 0F 9E +0F 20 D2 83 3E 1E 0C 3C 5E 42 3E 1E 0E 9F 07 38 +5E 42 3F 1E 0E 9F 04 34 C2 4F 3F 1E 01 3C 0F 43 +C8 4F 09 00 CC 0F 21 53 46 16 10 01 0A 14 CA 0C +5D 93 05 24 6D 92 34 20 C2 43 30 1F 31 3C C2 93 +30 1F 1A 20 5C 42 31 1F B0 13 14 BF 03 20 B0 13 +F4 BE 02 3C B0 13 04 BF 5C 42 32 1F B0 13 14 BF +03 20 B0 13 04 BF 02 3C B0 13 F4 BE B0 13 28 BF +5D 43 B0 13 30 F0 14 3C 1C 42 34 1F 0D 43 6E 42 +4F 43 B0 13 D2 C0 CF 0C CC 0A 7D 40 46 00 7E 40 +5C 00 B0 13 38 BF B0 13 28 BF 4D 43 B0 13 30 F0 +0A 16 10 01 CC 0A 7D 40 48 00 7E 40 5E 00 B0 13 +38 BF 10 01 CC 0A 7D 40 4A 00 7E 40 60 00 B0 13 +38 BF 10 01 0D 43 6E 43 4F 43 B0 13 D2 C0 CF 0C +B2 B0 40 00 86 1E 10 01 CC 0A 7D 40 1F 00 7E 40 +29 00 B0 13 42 F4 10 01 B0 13 42 F4 CD 0F 5E 43 +B0 13 D6 BC 10 01 1A 14 CA 0D C9 0C D2 93 00 1E +58 24 B0 13 EC E8 1D 43 6D 59 CC 09 B0 13 10 E6 +49 43 4A 93 37 24 5A 93 32 20 6A 42 16 3C 7C 40 +36 00 B0 13 EA CF 7C 40 3D 00 B0 13 EA CF 7C B0 +F0 FF F9 23 7C 40 3A 00 B0 13 EA CF 4A 93 02 20 +59 43 2B 3C B0 13 48 F1 5A 83 7C 40 34 00 B0 13 +EA CF A2 B3 30 0F FD 27 92 C3 32 0F 7C 40 35 00 +B0 13 EA CF 3C 40 19 00 B0 13 2E F1 92 B3 32 0F +D6 27 92 C3 32 0F 92 B3 30 0F FD 27 0E 3C 32 C2 +03 43 FF 3F 7C 40 35 00 B0 13 EA CF B2 B0 00 02 +32 0F FC 27 B2 F0 FF FD 32 0F 7C 40 3B 00 B0 13 +EA CF F2 90 03 00 00 1E 02 20 B0 13 C2 F1 CC 09 +03 3C 32 C2 03 43 FF 3F 19 16 10 01 B2 40 23 5A +5C 01 B0 13 BA EB F2 40 A5 00 21 01 F2 D0 80 00 +20 01 C2 43 21 01 F2 D0 03 00 4A 02 92 C3 6C 01 +B2 D0 0C 00 6C 01 82 43 66 01 B2 40 44 00 68 01 +32 D0 40 00 82 43 60 01 B2 40 50 00 62 01 B2 40 +6E 11 64 01 32 C0 40 00 1E 14 3D 40 41 D1 0E 43 +1D 83 0E 73 FD 23 0D 93 FB 23 1D 16 00 3C B2 F0 +F0 FF 6E 01 A2 C3 02 01 A2 B3 02 01 F8 23 32 C2 +03 43 B2 40 52 2D C0 01 A2 43 C2 01 F2 40 0E 00 +D7 01 F2 F0 7F 00 03 02 F2 D0 80 00 05 02 F2 40 +11 00 CD 01 F2 40 12 00 CE 01 F2 40 13 00 CF 01 +82 43 C0 01 32 D2 B0 13 A8 E6 B0 13 66 F3 B0 13 +BE E8 B0 13 C4 EA B0 13 2C EC B0 13 30 F2 80 00 +8A CE 4A 14 C8 0F C6 0E C9 0C CA 0D C7 06 3C 40 +6A 1D 3D 40 18 F9 3E 40 07 00 B0 13 BA F2 0A 93 +1C 20 39 90 B5 00 19 2C 77 90 03 00 0B 2C CD 09 +59 02 0D 59 3D 50 3B F5 3C 40 6A 1D 2E 43 B0 13 +BA F2 22 3C 4C 46 3C 50 67 1D CD 09 59 02 0D 59 +3D 50 3A F5 3E 40 03 00 F2 3F CC 09 CD 0A 3E 40 +0A 00 0F 43 B0 13 B2 D8 7E 50 30 00 4F 46 CF 4E +69 1D CC 09 CD 0A 3E 40 0A 00 0F 43 B0 13 B2 D8 +C9 0C CA 0D 56 83 E9 23 3F 40 6A 1D 4D 43 08 3C +48 93 04 24 FF 40 20 00 00 00 58 83 1F 53 5D 53 +3E 40 30 00 6E 9F 05 20 4E 47 1E 83 4C 4D 0C 9E +EF 3B 3C 40 6A 1D 46 16 10 01 0A 14 CA 0C 1F 42 +A6 1E 8F 93 02 00 10 20 8F 93 00 00 0D 20 C2 93 +AB 1E 0A 24 5E 42 AB 1E 3E 50 64 00 5D 42 3A 1F +0D 9E 02 34 4C 43 42 3C BF 40 00 70 08 00 5C 42 +B3 1E 1D 42 B0 1E 1E 42 B2 1E 3D F3 3E F0 FF 00 +3F 40 00 08 B0 13 14 DD 1C 52 38 1F 1F 42 A6 1E +8F 4C 0A 00 1F 42 A6 1E 9F 42 38 1F 0C 00 1F 42 +A6 1E CF 43 14 00 1F 42 A6 1E CF 43 15 00 1F 42 +A6 1E 8F 93 02 00 05 20 8F 93 00 00 02 20 EF D2 +1A 00 1D 42 A6 1E 1E 42 B0 1E 1F 42 B2 1E 3E F3 +3F F0 FF 00 8D 4E 00 00 8D 4F 02 00 1F 42 A6 1E +9F 43 18 00 CC 0A B0 13 7C CB 5C 43 0A 16 10 01 +3A 14 07 4F 07 ED 0A 4F 5A 02 8A 10 4A 4A 0A 93 +49 24 7F D0 80 00 0B 4D 5B 02 8B 10 4B 4B 0B 93 +3F 24 7D D0 80 00 0B 5A 3B 80 7F 00 08 43 09 43 +0E 93 09 24 1A 43 5E 00 02 28 08 5C 09 6D 59 00 +58 00 5A 02 F8 2B 0E 43 1A 43 5F 00 02 28 08 5C +09 6D 59 00 58 00 5E 00 3E B0 00 10 02 24 3E D0 +00 20 4A 5A F2 23 49 93 02 34 1B 53 03 3C 0E 6E +08 68 49 69 3E B0 00 80 07 24 08 63 49 63 0B 63 +3E B0 00 60 01 20 18 C3 1B 93 0C 38 3B 90 FF 00 +0C 34 49 59 8B 10 09 DB 57 02 59 00 0D 49 0C 48 +37 16 10 01 0C 43 0D 43 FB 3F 3D 40 FF FE 3C 43 +57 02 5D 00 F5 3F CF 0D CD 0E CE 0C C2 93 59 1E +06 20 B0 13 80 F2 4C 93 02 20 2C 43 10 01 2E 83 +2C 24 1E 83 43 24 2E 83 20 24 1E 83 3B 24 3E 80 +03 00 34 24 1E 83 30 20 0E 43 8D 93 00 00 09 20 +0F 93 2A 20 1C 4D 02 00 1D 4D 04 00 B0 13 02 F3 +31 3C 1C 43 2C 9D 20 20 0F 93 1E 20 1C 4D 02 00 +1D 4D 04 00 B0 13 F0 F2 25 3C 3F B0 FE FF 14 20 +CC 0F B0 13 C2 F0 CE 0C 1D 3C 3F 90 03 00 07 24 +2F 93 0A 20 CC 0D B0 13 00 E8 CE 0C 13 3C CC 0D +B0 13 AC DA CE 0C 0E 3C 2E 43 0C 3C B0 13 1A F5 +CE 0C 08 3C B0 13 1E F5 CE 0C 04 3C CC 0F B0 13 +9E D6 CE 0C CC 0E 10 01 0A 14 31 80 06 00 B0 13 +36 F3 2E 42 CF 01 1F 53 3D 40 9A 1D 1F 53 FF 4D +FF FF 1E 83 FB 23 3C 40 05 00 0D 43 CE 01 1E 53 +B0 13 F6 C2 D2 43 78 1D 4A 43 B0 13 18 E9 0C 93 +08 24 B0 13 3E C4 1A 2C F2 B0 20 00 78 1D F5 27 +1F 3C E1 43 00 00 3C 40 03 00 3D 40 0A 00 CE 01 +B0 13 F6 C2 4A 43 B0 13 0E F5 0C 93 04 20 E2 43 +78 1D 5C 43 10 3C B0 13 3E C4 06 28 C2 43 59 1E +E2 42 78 1D 4C 43 07 3C F2 B0 20 00 78 1D EB 27 +C2 43 59 1E 4C 43 31 50 06 00 0A 16 10 01 3C 40 +E8 03 B0 13 46 F3 B2 40 2B 5A 5C 01 CF 0A 1A 43 +4A 5F 7F 90 0B 00 10 01 31 80 0E 00 CE 01 3D 40 +00 18 4F 43 1E 53 FE 4D FF FF 5F 53 7F 90 0D 00 +F9 2B F1 93 00 00 30 24 5F 41 01 00 C2 4F 94 1E +3F 90 15 00 05 38 3F 90 EC 00 02 34 C2 43 94 1E +5F 41 04 00 47 18 0F 5F 5E 41 05 00 0E 5F 82 4E +2E 1F D2 41 06 00 9A 1D D2 41 07 00 9B 1D D2 41 +08 00 9C 1D D2 41 09 00 9D 1D F1 93 0C 00 08 24 +5F 41 0A 00 47 18 0F 5F 5E 41 0B 00 0E 5F 01 3C +0E 43 82 4E 84 1E 13 3C E2 42 94 1E B2 40 F6 FF +2E 1F F2 40 79 00 9A 1D F2 40 56 00 9B 1D F2 40 +34 00 9C 1D F2 40 12 00 9D 1D 82 43 84 1E 31 50 +0E 00 10 01 21 83 5F 42 92 1C 1D 42 90 1C 4C 4F +3E 40 FE 9D 0E 8C 0D 9E 02 2C 4B 43 09 3C 81 4D +00 00 2E 41 3F 40 FE 00 4F 8E C2 4F 92 1C 5B 43 +4E 43 15 3C 4F 4E 5D 4F 93 1C 5E 53 4F 4E 5F 4F +93 1C 47 18 0F 5F 0D 5F 5E 53 1C 42 90 1C CF 0C +2F 53 82 4F 90 1C B0 13 9A EA 5F 42 92 1C 4D 4F +1D 83 4C 4E 0C 9D E6 3B 4B 93 0C 20 5F B3 03 20 +C2 43 92 1C 1A 3C 4F 4F D2 4F 92 1C 93 1C D2 43 +92 1C 13 3C 3C 40 FE 9D 3D 40 FE FF B0 13 9A EA +C2 43 92 1C 5F 42 8C 1C 5F C3 6F D3 C2 4F 8C 1C +7C 40 15 00 6D 42 B0 13 30 F0 21 53 10 01 1A 14 +21 82 CA 0C F2 B0 40 00 01 02 42 24 B0 13 9E DB +82 4C 7C 1E 1C 52 80 1E 3C 80 A1 0A 82 4C 7E 1E +B0 13 AA D3 81 4C 00 00 81 4D 02 00 4A 93 03 20 +B0 13 46 C6 27 3C 2C 41 1D 41 02 00 B0 13 DA E6 +3E 40 CD CC 3F 40 4C 3E B0 13 40 C2 C9 0C CA 0D +1C 42 78 1E 1D 42 7A 1E B0 13 DA E6 3E 40 CD CC +3F 40 4C 3F B0 13 40 C2 CE 0C CF 0D CC 09 CD 0A +B0 13 CA B0 B0 13 EA DB 81 4C 00 00 81 4D 02 00 +B0 13 46 C6 1E 42 7C 1E B0 13 00 9E 82 4C 82 1E +21 52 19 16 10 01 1C 41 04 00 1D 41 06 00 82 4C +78 1E 82 4D 7A 1E 10 01 1A 14 21 82 39 40 CB 00 +3C 40 00 40 B0 13 5A DA 3C 40 03 00 3D 40 05 00 +0E 43 B0 13 F6 C2 D1 43 02 00 C1 49 03 00 CC 01 +2C 53 6D 43 B0 13 78 D2 3C 40 03 00 3D 42 0E 43 +B0 13 F6 C2 3C 40 0A 00 B0 13 46 F3 CC 01 B0 13 +5C DD 0C 93 18 20 C1 93 00 00 F8 27 B0 13 1A AA +4A 43 5A 92 9E 1D F2 2F 3C 40 0A 00 B0 13 46 F3 +4C 4A B0 13 24 B3 3C 40 7A 1D 7D 40 13 00 B0 13 +78 D2 5A 53 EE 3F 3C 40 03 00 2D 42 0E 43 B0 13 +F6 C2 B2 40 2B 5A 5C 01 F2 B0 20 00 78 1D B8 27 +C2 43 59 1E 21 52 19 16 10 01 5A 14 C6 0F C7 0E +C5 0D C9 0C 18 41 1C 00 C7 43 00 00 B0 13 24 BB +CA 0C 0A 93 02 20 2C 42 3C 3C 1F 43 2F 99 02 24 +09 43 09 3C 5C 49 02 00 B0 13 6A EB C9 0C 09 93 +02 20 2C 43 2E 3C 5E 4A 02 00 7E 80 0B 00 C7 4E +00 00 3D 40 0E 00 0D 5A 4E 4E CC 05 B0 13 BA F2 +09 93 06 24 D9 4A 21 00 07 00 D9 4A 22 00 08 00 +06 93 07 24 3D 40 07 00 0D 5A CC 06 2E 42 B0 13 +BA F2 08 93 06 24 3F 40 07 00 5F FA 0C 00 C8 4F +00 00 5D 4A 01 00 5C 43 B0 13 70 E9 CA 43 00 00 +0C 43 55 16 10 01 4F 43 4C 93 2D 24 5C 93 20 24 +6C 93 13 24 7C 90 03 00 2A 20 A2 D2 22 03 A2 C2 +24 03 B2 C2 22 03 B0 13 32 F5 B0 13 24 C8 1F 42 +20 03 6F F2 B2 C2 22 03 1A 3C A2 D2 24 03 B0 13 +12 C8 B0 13 24 C8 A2 D2 22 03 B0 13 32 F5 0F 3C +A2 D2 24 03 B2 C2 22 03 A2 D2 22 03 B0 13 32 F5 +B0 13 08 C8 04 3C A2 D2 24 03 B0 13 08 C8 4C 43 +4F 93 01 20 5C 43 10 01 B0 13 24 C8 B0 13 12 C8 +10 01 A2 C2 22 03 B0 13 32 F5 B2 C2 22 03 B0 13 +32 F5 10 01 B2 D2 22 03 B0 13 32 F5 10 01 1A 14 +CB 0C 7B 90 BD 00 07 24 4C 43 7B 90 31 00 40 28 +7B 90 3D 00 3D 2C 0A 42 32 C2 03 43 B2 F0 BF FF +02 0F B2 B0 10 00 02 0F FC 27 7B 90 3D 00 26 2C +4C 43 B0 13 D8 F1 C9 0C 4C 43 7D 40 29 00 B0 13 +2C E4 C2 4B 11 0F A2 B2 30 0F 13 24 7B 90 32 00 +10 24 7B 90 39 00 0D 24 7B 90 38 00 0A 24 A2 B2 +30 0F FD 23 0D 14 3D 40 BF 0C 1D 83 FE 23 0D 16 +03 43 4C 43 CD 09 B0 13 2C E4 03 3C F2 40 BD 00 +11 0F 5C 42 21 0F B2 B0 40 00 02 0F FC 27 02 4A +19 16 10 01 3A 14 07 4F 07 ED 0A 4F 5A 02 8A 10 +4A 4A 0A 93 38 24 7F D0 80 00 0B 4D 5B 02 8B 10 +4B 4B 0B 93 2B 24 7D D0 80 00 0B 8A 3B 50 7F 00 +3A 40 18 00 08 43 09 43 0C 8E 0D 7F 03 2C 0C 5E +0D 6F 12 C3 08 68 09 69 5C 02 0D 6D 1A 83 F4 23 +49 93 03 30 1A 53 1B 83 EF 3F 0C 7E 0D 7F 08 63 +49 63 0B 63 1B 93 0C 38 3B 90 FF 00 0C 34 49 59 +8B 10 09 DB 57 02 59 00 0D 49 0C 48 37 16 10 01 +0C 43 0D 43 FB 3F 3C 40 FF FE 3D 43 57 02 5D 00 +F5 3F 2A 14 21 83 C9 0C 3F 40 0B 00 0F 59 68 4F +3A 40 3F 00 4A F8 3C 40 07 00 0C 59 1D 42 C6 1E +2E 42 B0 13 7C ED 0C 93 2D 24 78 B0 40 00 2A 20 +4A 93 10 24 7A 90 07 00 0D 2C 4A 4A 5A 06 00 18 +5F 4A 54 FA 2C 43 0C 59 4F 13 1C 93 1B 20 D9 43 +00 00 1A 3C 7A 90 3F 00 03 24 7A 90 20 00 12 28 +2C 43 0C 59 CD 01 B0 13 DE C9 4C 93 0B 24 D9 43 +00 00 00 18 C2 93 CA 1E 07 24 6C 41 80 13 CA 1E +4C 93 02 24 C9 43 00 00 21 53 28 16 10 01 4A 14 +C7 0D C8 0C 39 40 41 1E 3A 40 3F 00 5A F8 09 00 +26 43 2F 43 6F 99 32 20 5A 99 09 00 2F 20 7A 90 +3F 00 0B 24 3C 40 03 00 0C 59 3D 40 05 00 0D 58 +2E 42 B0 13 7C ED 0C 93 21 20 D7 49 0B 00 00 00 +57 43 7A 90 3F 00 16 24 3F 40 0A 00 0F 58 6F 4F +7F B0 80 FF 0A 20 7F B2 0D 24 D9 98 0B 00 02 00 +02 20 C9 43 02 00 47 43 05 3C 5D 49 0A 00 CC 08 +B0 13 0E CE B0 13 BE F3 CC 07 05 3C 39 50 0C 00 +16 83 C7 23 4C 43 46 16 10 01 4A 14 C9 0F C7 0E +C6 0D CA 0C 6C 43 B0 13 02 CF C8 0C 08 93 02 20 +0C 43 36 3C CF 07 7F 50 0B 00 C8 4F 02 00 3E 40 +0B 00 0E 58 3F 40 80 00 6F FE 4F DA CE 4F 00 00 +D8 42 C4 1E 0D 00 D2 53 C4 1E FD 27 F8 F0 BF 00 +0C 00 5F 48 0C 00 7F F0 F8 00 4F D9 C8 4F 0C 00 +F8 F0 7F 00 0C 00 F8 C2 0C 00 FE F0 7F 00 00 00 +3C 40 0E 00 0C 58 4E 47 CD 06 B0 13 BA F2 3C 40 +07 00 0C 58 1D 42 C6 1E 2E 42 B0 13 BA F2 CC 08 +46 16 10 01 5C 43 B0 13 44 D6 5C 43 6D 42 80 13 +8C 1E B0 13 0C E7 7C 40 17 00 6D 43 B0 13 30 F0 +7C 40 18 00 6D 43 B0 13 30 F0 7C 40 19 00 6D 43 +B0 13 30 F0 B0 13 14 F3 B2 40 03 00 72 1D B2 40 +10 0E 74 1D B0 13 A8 C3 4C 93 02 24 B0 13 58 C6 +82 43 72 1D B0 13 56 F3 3C 40 00 20 B0 13 5A DA +C2 43 1D 02 82 43 D8 1E 7C 40 17 00 6D 42 B0 13 +30 F0 7C 40 18 00 6D 42 B0 13 30 F0 7C 40 19 00 +6D 42 B0 13 30 F0 92 D3 14 1D 10 01 1F 42 A6 1E +CF 43 11 00 1F 42 A6 1E DF 42 B3 1E 13 00 1F 42 +A6 1E 5E 42 38 1F 5E 8F 0C 00 CF 4E 16 00 1F 42 +A6 1E 5E 4F 16 00 8E 11 8F 5E 0A 00 1F 42 A6 1E +DF 5F 16 00 15 00 1F 42 A6 1E DF 42 3A 1F 12 00 +1F 42 A6 1E FF 92 12 00 02 2C FF 42 12 00 1F 42 +A6 1E 9F 42 B4 1E 04 00 9F 42 B6 1E 06 00 1F 42 +A6 1E DF 42 B8 1E 0E 00 1F 42 A6 1E EF B2 1A 00 +03 20 4D 43 B0 13 92 E0 B0 13 8C D5 D2 C3 36 1F +10 01 1E 42 A6 1E 5F 4E 15 00 8F 11 3F 90 40 00 +10 34 3F 90 C1 FF 19 34 FE 50 40 00 15 00 1F 42 +A6 1E 9F 83 08 00 1F 42 A6 1E 5F 4F 15 00 8F 11 +0C 3C FE 80 40 00 15 00 1F 42 A6 1E 9F 53 08 00 +1F 42 A6 1E 5F 4F 15 00 8F 11 1E 42 A6 1E CE 5F +14 00 1E 42 A6 1E 5F 4E 14 00 8F 11 3F 90 40 00 +0B 34 3F 90 C1 FF 0F 34 FE 50 40 00 14 00 1F 42 +A6 1E 9F 83 0A 00 10 01 FE 80 40 00 14 00 1F 42 +A6 1E 9F 53 0A 00 10 01 0A 14 5F 42 32 1F 3F 90 +07 00 0E 34 3F 90 06 00 31 24 1F 83 32 24 1F 83 +14 24 1F 83 2E 24 1F 83 29 24 1F 83 2A 24 2C 3C +3F 80 07 00 2F 93 25 28 2F 83 20 24 1F 83 21 24 +1F 83 1C 24 1F 83 1D 24 1F 3C 1A 42 34 1F 3A B0 +03 00 0E 20 CC 0A 3D 40 64 00 B0 13 04 F2 0E 93 +0A 20 CC 0A 3D 40 90 01 B0 13 04 F2 0E 93 03 24 +7C 40 1C 00 0A 3C 7C 40 1D 00 07 3C 7C 40 1E 00 +04 3C 7C 40 1F 00 01 3C 4C 43 0A 16 10 01 3C 40 +3D 1E 0D 43 3E 40 1C 00 B0 13 CC F2 E2 43 3D 1E +F2 40 3D 00 3E 1E F2 40 20 00 3F 1E D2 43 40 1E +B0 13 9E EC B0 13 78 EF B0 13 A6 F0 B0 13 6C F4 +B0 13 92 EB B0 13 62 F4 B0 13 D0 E7 3F 40 41 1E +CF 43 00 00 3F 50 0C 00 CF 43 00 00 C2 93 4D 1E +15 20 E2 43 4D 1E F2 40 03 00 4E 1E 7F 40 3F 00 +C2 4F 56 1E C2 4F 57 1E F2 43 58 1E B0 13 02 F5 +CD 0C 3C 40 50 1E 2E 42 B0 13 BA F2 0C 43 10 01 +7C 40 36 00 B0 13 2E C8 F2 B0 10 00 36 1F 27 24 +7C 40 0A 00 5D 42 FA 1E B0 13 2C E4 F2 90 7F 00 +FB 1E 07 38 7C 40 0C 00 7D 40 0C 00 B0 13 2C E4 +06 3C 7C 40 0C 00 5D 42 FB 1E B0 13 2C E4 F2 B2 +36 1F 07 20 7C 40 12 00 7D 40 11 00 B0 13 2C E4 +06 3C 7C 40 12 00 7D 40 15 00 B0 13 2C E4 7C 40 +34 00 B0 13 2E C8 B2 F0 FE FD 32 0F B2 F0 FE FD +32 0F B2 D0 01 02 36 0F A2 43 1E 1F 10 01 1A 14 +31 80 22 00 C9 0D 5A 4C 0B 00 3F 40 CF 00 5F F1 +0A 00 5F D2 C8 1E 7F F0 BF 00 C1 4F 0A 00 3D 40 +05 00 0D 5C CC 01 1C 53 2E 42 B0 13 BA F2 CC 01 +3C 50 05 00 1D 42 C6 1E 2E 42 B0 13 BA F2 3D 40 +C0 00 5D F1 09 00 4D D9 F1 40 0B 00 00 00 C1 4A +0B 00 3F 40 70 00 5F F1 0A 00 7F D0 0B 00 C1 4F +0A 00 7D F0 3F 00 C1 4D 09 00 CC 01 4D 43 B0 13 +46 BF 31 50 22 00 19 16 10 01 21 82 F2 F0 BF 00 +05 02 F2 F0 BF 00 19 02 B2 D0 0C 00 22 03 B2 D0 +0C 00 24 03 C2 43 FE 1D 3C 40 CC 0C B0 13 5A DA +7C 40 06 00 5D 43 B0 13 5A D8 C1 4C 00 00 3C 40 +CC 0C B0 13 5A DA 7C 40 07 00 4D 43 B0 13 5C D0 +C1 4C 01 00 D1 B3 01 00 12 20 C1 93 01 00 0F 24 +7C 40 7F 00 4D 43 B0 13 5C D0 C1 4C 02 00 D1 93 +02 00 03 24 C2 43 FE 1D 02 3C D2 43 FE 1D 21 52 +10 01 2A 14 5C 93 03 20 3F 40 00 1C 02 3C 3F 40 +46 1C 2D 43 08 43 CB 08 4E 43 79 40 03 00 CF 93 +00 00 06 20 6C 93 02 20 CC 0F 24 3C CB 0F 0C 3C +5C 93 0A 20 5E 53 2A 42 6A 9F 06 24 5A 4F 01 00 +4A 99 02 2C C8 0F C9 0A 3F 50 23 00 1D 83 E7 23 +0B 93 0C 20 08 93 02 20 0C 43 0C 3C CB 08 5D 4B +01 00 B0 13 70 E9 EB 43 01 00 03 3C 5E 53 CB 4E +01 00 CC 0B 28 16 10 01 1A 14 CF 0E CA 0C 7A 90 +1A 00 31 28 7A 90 2A 00 2E 2C 4E 4A 5E 02 1C 4E +16 1D 4E 4A 5E 4E C2 F9 7D 90 30 00 05 2C 7D 90 +2D 00 05 20 6B 43 08 3C 7D 90 5B 00 02 28 4B 43 +03 3C 4B 4D 5B 4B 66 F9 7A 90 21 00 11 28 C9 0B +43 18 49 59 43 19 4B 10 4B D9 7A 90 21 00 08 20 +7D 90 31 00 03 24 7D 90 4C 00 02 20 7B 40 80 00 +CD 0B B0 13 2E D5 19 16 10 01 0A 14 CE 0C 0B 42 +32 C2 03 43 B2 F0 BF FF 02 0F B2 B0 10 00 02 0F +FC 27 7E 90 31 00 23 28 7E 90 3D 00 20 2C 4C 43 +B0 13 30 DE CA 0C 4C 43 7D 40 29 00 B0 13 DC E5 +C2 4E 11 0F A2 B2 30 0F 0D 24 7E 90 32 00 0A 24 +7E 90 38 00 07 24 A2 B2 30 0F FD 23 3C 40 F8 02 +B0 13 2E F1 4C 43 CD 0A B0 13 DC E5 02 3C C2 4E +11 0F 5C 42 21 0F 02 4B 0A 16 10 01 0A 14 CB 0D +CA 0C 4C 43 B0 13 96 C7 7C 40 22 00 B0 13 BE D0 +0C 24 CC 0A B0 13 BE D0 08 24 5C 43 B0 13 96 C7 +7C 40 23 00 B0 13 BE D0 02 20 0C 43 16 3C 5B 93 +05 24 4C 43 B0 13 FE DA 4D 4C 0B 3C 5C 43 B0 13 +FE DA 4C 4C 4D 4C 8D 10 4C 43 B0 13 FE DA 4C 4C +0D DC 6C 43 B0 13 96 C7 CC 0D 0A 16 10 01 B0 13 +50 E0 7C 40 03 00 B0 13 96 C7 4C 93 10 01 7C 40 +36 00 B0 13 2E C8 4C 43 3D 40 EC F9 7E 40 27 00 +B0 13 00 DF 7C 40 2C 00 7D 40 88 00 B0 13 2C E4 +7C 40 2D 00 7D 40 31 00 B0 13 2C E4 7C 40 2E 00 +7D 40 09 00 B0 13 2C E4 7C 40 36 00 B0 13 2E C8 +7C 40 33 00 B0 13 2E C8 7C 40 3D 00 B0 13 2E C8 +7C B0 70 00 F9 23 7C 40 36 00 B0 13 2E C8 82 43 +1E 1F B2 D0 01 02 34 0F 82 43 32 0F 10 01 0A 14 +CA 0D CB 0C 7B 93 02 24 CF 0B 02 3C 4B 43 4F 43 +4E 4B 4F 4F 0F 8E 1F 53 4C 4B 3D 40 1C 00 B0 13 +1A F2 1C 52 7A FA 4A 93 09 24 8C 43 00 00 8C 43 +02 00 CC 43 1A 00 FC 40 7F 00 10 00 8C 43 18 00 +FC F0 FC 00 1A 00 8C 43 04 00 8C 43 06 00 CC 43 +0E 00 CC 43 12 00 CC 43 0F 00 CC 43 11 00 5B 53 +1F 83 DA 23 0A 16 10 01 B0 13 02 D8 5C 06 3D 40 +29 00 B0 13 04 F2 1F 42 2E 1F 0F 5C 3F 90 69 01 +03 2C 1C 42 2C 1F 03 3C 1C 42 2C 1F CF 0C 5C 06 +0C 5F 5C 02 3D 40 0A 00 B0 13 04 F2 82 4C 2C 1F +3C 90 F0 00 08 28 B2 F0 DF FF 86 1E 7C 42 4D 43 +B0 13 30 F0 07 3C B2 D0 20 00 86 1E 7C 42 5D 43 +B0 13 30 F0 B2 D2 14 1D B2 D0 80 00 14 1D 10 01 +1A 14 21 82 CA 0C 3C 40 05 00 0C 5A 5D 4A 0E 00 +B0 13 40 E3 0C 93 02 20 3F 42 03 3C B0 13 FC F4 +0F 43 F1 40 82 00 00 00 D1 4A 0D 00 01 00 C1 4F +02 00 6C 43 CD 01 7E 40 03 00 7F 40 03 00 B0 13 +6A CA C9 0C 09 93 0D 24 3C 40 03 00 0C 59 3D 40 +05 00 0D 5A 2E 42 B0 13 BA F2 CC 09 4D 43 B0 13 +30 E8 21 52 19 16 10 01 2A 14 C8 0D C9 0C 5C 42 +FF 1D B0 13 6A EB CA 0C B0 13 EA F4 0A 93 24 24 +CC 0A 5D 43 B0 13 78 EC 0C 93 1F 20 09 93 1D 24 +5C 4A 0A 00 5F 4A 01 00 CD 09 CE 08 B0 13 6A CA +C9 0C 09 93 0E 24 3C 40 03 00 0C 59 3D 40 03 00 +0D 5A 2E 42 B0 13 BA F2 CC 09 5D 43 B0 13 30 E8 +04 3C 3C 40 03 00 01 3C 2C 43 28 16 10 01 0E 42 +32 C2 03 43 4C 93 2C 24 4F 4C 3F 50 00 7E B2 B0 +10 00 02 0F FC 27 82 4F 10 0F B2 B0 10 00 02 0F +FC 27 F2 40 3D 00 11 0F B2 B0 10 00 02 0F FC 27 +F2 40 FE 00 11 0F B2 B0 20 00 02 0F FC 27 C2 43 +10 0F B2 B0 80 00 02 0F FC 27 5D 42 20 0F B2 B0 +10 00 02 0F FC 27 F2 40 3D 00 11 0F 4D 9C D7 23 +02 4E 10 01 0A 14 CA 0D 6A 92 1A 24 B0 13 FA F3 +4C 93 08 20 7C 40 47 00 3D 40 20 F9 5E 43 B0 13 +D6 BC 0E 3C 5C 42 C2 1E 0D 43 7E 40 03 00 6F 43 +B0 13 D2 C0 CD 0C 7C 40 47 00 5E 43 B0 13 D6 BC +B0 13 FA F3 4C 93 0F 20 5A 93 08 24 6A 92 0B 20 +7C 40 13 00 4D 43 B0 13 30 F0 05 3C 7C 40 13 00 +5D 43 B0 13 30 F0 0A 16 10 01 21 82 81 43 00 00 +81 43 02 00 7C 40 7F 00 4D 43 B0 13 5C D0 81 4C +00 00 81 43 02 00 2C 41 1F 41 02 00 47 18 0C 5C +0D 43 3C F0 00 07 0D F3 B0 13 28 E2 81 4C 00 00 +81 4D 02 00 7C 40 80 00 5D 43 B0 13 5C D0 81 DC +00 00 12 C3 11 10 02 00 11 10 00 00 12 C3 11 10 +02 00 11 10 00 00 2C 41 1D 41 02 00 21 52 10 01 +1F 42 38 0F 1E 42 0E 0F 0E 93 14 20 0F 93 28 24 +3F 90 14 00 0C 20 B2 B0 00 02 36 0F 03 20 32 C2 +03 43 FF 3F B2 F0 FF FD 32 0F 80 00 62 B8 32 C2 +03 43 FF 3F 2E 93 11 20 1F 42 0C 0F 2F 93 0A 24 +2F 92 08 24 3F 90 06 00 05 24 3F 92 03 24 32 C2 +03 43 FF 3F 32 C2 03 43 FF 3F 32 C2 03 43 FF 3F +10 01 B2 F0 FE FD 36 0F B2 F0 FE FD 32 0F B2 F0 +FE FD 32 0F 92 43 1E 1F 7C 40 32 00 B0 13 D8 F1 +C2 4C 20 1F 7C 43 3D 40 B0 1E 7E 40 0A 00 B0 13 +BC DE 7C 43 B0 13 D8 F1 C2 4C 3A 1F 7C B0 80 FF +04 20 F2 80 80 00 3A 1F 03 3C F2 F0 7F 00 3A 1F +1F 42 22 1F 3F 80 10 00 82 4F 38 1F 80 00 90 E1 +B2 40 5A F8 40 1F B2 40 B4 F8 42 1F 00 18 D2 42 +62 F8 8C 1E 00 18 D2 42 BC F8 90 1E 82 43 D8 1E +82 43 86 1E 82 43 88 1E 82 43 14 1D 82 43 8A 1E +92 D3 14 1D B2 D0 40 00 86 1E B0 13 58 C4 B0 13 +C4 ED B0 13 94 F2 B0 13 80 F4 B0 13 44 DF B0 13 +EE F1 B0 13 08 F5 B0 13 A4 F3 80 00 60 E8 5F 93 +20 24 4F 93 1B 24 6F 93 12 24 7F 90 03 00 05 24 +6F 92 1C 20 B0 13 7E D5 10 01 4E 4E 3E E3 CF 0E +6F FC 4D DF CC 4D 00 00 CC FE 20 00 10 01 B0 13 +7E D5 CC DD 00 00 CC DD 20 00 10 01 CC CE 00 00 +10 01 6F 4C 4F CE 4D DF CC 4D 00 00 10 01 4E 4E +3E E3 CC FE 00 00 CC FE 20 00 10 01 0A 14 1F 42 +A6 1E DF 53 13 00 B0 13 02 CC 1F 42 A6 1E 1E 4F +08 00 1E 5F 0A 00 8F 4E 0C 00 1F 42 A6 1E 9F 4F +0C 00 0A 00 1A 42 A6 1E CF 0A 5C 4F 13 00 2D 4F +1E 4F 02 00 3F 40 00 08 B0 13 14 DD 8A 8C 0C 00 +1F 42 A6 1E FF 40 07 00 0F 00 1F 42 A6 1E FF F0 +FC 00 1A 00 0A 16 10 01 92 53 96 1E 82 63 98 1E +1F 43 5F 52 A2 1E 3F 90 3C 00 1F 20 C2 43 A2 1E +1F 43 5F 52 A1 1E 3F 90 3C 00 12 20 C2 43 A1 1E +1F 43 5F 52 A0 1E F2 40 03 00 9E 1E 3F 90 18 00 +03 24 C2 4F A0 1E 10 01 C2 43 A0 1E 80 00 D2 E0 +C2 4F A1 1E E2 43 9E 1E 10 01 C2 4F A2 1E D2 43 +9E 1E 10 01 0A 14 CA 0C 7D 40 46 00 7E 40 5A 00 +B0 13 42 F4 0D 43 4E 43 B0 13 D6 BC 5A 93 0D 24 +7C 40 29 00 B0 13 96 D6 7C 40 27 00 B0 13 96 D6 +7C 40 28 00 B0 13 96 D6 0C 3C 7C 40 1F 00 B0 13 +96 D6 7C 40 20 00 B0 13 96 D6 7C 40 1E 00 B0 13 +96 D6 0A 16 10 01 4D 43 B0 13 30 F0 10 01 0A 14 +0A 43 2C 92 22 24 3C 90 05 00 1C 24 3C 92 17 24 +3C 90 0A 00 12 20 2F 4D 0F 93 0A 24 1F 83 06 24 +1F 83 02 24 2C 43 16 3C 6C 43 03 3C 5C 43 01 3C +4C 43 B0 13 14 F1 0C 43 0D 3C 2A 43 0A 3C B0 13 +18 EF 07 3C B0 13 2E EE 04 3C B0 13 F8 EE B0 13 +58 ED CC 0A 0A 16 10 01 C2 93 76 1E 29 20 C2 93 +FE 1D 07 20 7C 40 47 00 3D 40 14 F9 5E 43 80 00 +D6 BC F2 F0 BF 00 1D 02 F2 D0 40 00 1B 02 B0 13 +36 F4 D2 43 76 1E 7E 40 0F 00 07 3C 4E 93 0B 24 +3C 40 CC 0C B0 13 5A DA 5E 83 F2 B0 40 00 01 02 +F5 27 4E 93 02 20 C2 43 76 1E 4C 43 80 00 AE C5 +10 01 1A 14 C9 0C 79 93 02 24 CA 09 02 3C 49 43 +4A 43 4F 49 4A 4A 0A 8F 1A 53 CC 09 B0 13 10 ED +0C 93 09 20 4C 49 3D 40 1C 00 B0 13 1A F2 1C 52 +7A FA B0 13 AA D7 59 53 1A 83 EF 23 E2 B3 36 1F +0A 24 B0 13 4E F4 4C 93 06 20 D2 C3 36 1F B0 13 +26 F3 B0 13 DE F4 19 16 10 01 AC 43 18 00 FC F0 +FC 00 1A 00 CC 43 12 00 5F 42 AC 1E C2 93 AD 1E +03 20 CC 4F 13 00 08 3C 5E 42 AC 1E 12 C3 4E 10 +4E 11 4F 8E CC 4F 13 00 E2 B3 36 1F 11 20 F2 D0 +06 00 36 1F B0 13 B2 F3 82 4C A4 1E C2 93 AD 1E +04 20 B2 50 E0 7F A4 1E 10 01 B2 50 C0 53 A4 1E +10 01 B2 D0 91 00 B0 01 B2 40 10 0A 00 07 B2 40 +00 02 02 07 F2 40 1B 00 10 07 92 43 0C 07 2C 43 +B0 13 5A DA A2 D3 00 07 C2 43 46 1F 92 D3 00 07 +3C 40 05 00 B0 13 5A DA C2 93 46 1F FD 27 B2 F0 +FC F5 00 07 B2 F0 EF FF 00 07 B2 F0 6E FF B0 01 +82 43 0C 07 1C 42 44 1F 10 01 0A 14 21 83 CA 0D +CB 0C 4C 43 B0 13 96 C7 7C 40 22 00 B0 13 96 D8 +0E 24 CC 0B B0 13 96 D8 0A 24 CC 0A B0 13 A4 D8 +C1 4C 00 00 6C 43 B0 13 96 C7 5C 43 01 3C 4C 43 +21 53 0A 16 10 01 B0 13 A4 D8 C1 4C 04 00 C1 93 +04 00 10 01 B0 13 50 E0 7C 40 03 00 B0 13 96 C7 +10 01 0A 14 09 14 09 43 0A 43 1B 43 0F 93 04 24 +09 4D 0D 4C 0C 43 0D 3C 5C 02 0D 6D 09 69 09 8E +04 28 1C D3 5B 02 F8 2B 03 3C 09 5E 5B 02 F4 2B +1B 43 5C 02 0D 6D 09 69 0A 6A 09 8E 0A 7F 04 28 +1C D3 5B 02 F6 2B 04 3C 09 5E 0A 6F 5B 02 F1 2B +0E 49 0F 4A 09 16 0A 16 10 01 0A 14 7C 40 23 00 +B0 13 D8 F1 CA 0C 7A D0 20 00 CD 0A 7C 40 23 00 +B0 13 2C E4 7C 40 C6 00 B0 13 DE D2 7C 40 33 00 +B0 13 2E C8 7C 40 3D 00 B0 13 2E C8 7C B0 70 00 +F9 23 3D 40 DF 00 4D FA 7C 40 23 00 B0 13 2C E4 +7C 40 36 00 B0 13 2E C8 82 43 1E 1F 0A 16 10 01 +4F 14 1F 42 6E 03 2F 83 1E 24 2F 82 0B 24 2F 83 +1C 20 B2 F0 EF FF 4A 03 92 C3 4A 03 B2 D0 80 00 +86 1E 13 3C B2 F0 EF FF 48 03 92 C3 48 03 1F 42 +50 03 1F 52 1A 1F 82 4F 58 03 B2 D0 10 00 48 03 +80 13 16 1F 02 3C B0 13 04 E3 B1 C0 D0 00 14 00 +4B 16 00 13 B2 B0 20 00 86 1E 25 20 B0 13 FA F3 +4C 93 21 20 B0 13 12 F4 4C 93 1D 20 D2 53 EB 1E +E2 93 EB 1E 18 20 4C 43 4D 43 B0 13 30 F0 5C 43 +B0 13 44 D6 7C 40 5A 00 3D 40 F8 F8 5E 43 B0 13 +D6 BC 7C 40 46 00 3D 40 24 F9 5E 43 B0 13 D6 BC +3F 40 00 10 C0 0F 10 01 2A 14 1A 41 10 00 49 4C +1B 42 A6 1E 1B 4B 0C 00 0B 89 3B 80 32 00 28 4D +C9 0B 09 88 09 93 02 38 28 9E 15 20 8D 4B 00 00 +1D 42 A6 1E 4C 4C 1C 5D 0C 00 3C 50 10 00 8E 4C +00 00 1E 42 A6 1E DF 4E 0F 00 00 00 1F 42 A6 1E +DA 4F 10 00 00 00 28 16 10 01 B2 B0 30 00 40 03 +24 24 B2 F0 EF FF 4A 03 B2 F0 7F FF 86 1E 82 93 +50 03 02 20 0F 43 05 3C 1F 42 50 03 1F 92 50 03 +FB 23 0F 5C 82 4F 5A 03 92 C3 4A 03 B2 D0 10 00 +4A 03 B0 13 BE F4 B2 40 2B 5A 5C 01 32 C2 03 43 +B2 B0 80 00 86 1E F5 27 32 D2 10 01 1A 14 CA 0C +5C 4A 05 00 CF 0C 3F 80 03 00 06 24 2F 83 2F 93 +03 28 7F 40 03 00 01 3C 5F 43 4C 4C 1D 4A 02 00 +5E 4A 04 00 B0 13 6A CA C9 0C 09 93 0C 24 3C 40 +03 00 0C 59 2D 4A 2E 42 B0 13 BA F2 CC 09 5D 43 +B0 13 30 E8 02 3C 3C 40 03 00 19 16 10 01 A2 D2 +22 03 A2 C2 24 03 3E 42 4F 43 B2 C2 22 03 B0 13 +42 DB 4F 5F A2 B2 20 03 01 24 5F D3 1E 83 F5 23 +A2 D2 24 03 B2 C2 22 03 5C 93 03 24 A2 D2 22 03 +02 3C A2 C2 22 03 B0 13 42 DB B2 C2 22 03 CC 0F +10 01 B0 13 32 F5 B2 D2 22 03 B0 13 32 F5 10 01 +D2 B3 36 1F 1E 24 A2 93 A8 1E 1B 24 1F 42 A6 1E +2E 4F 1F 4F 02 00 0F 93 09 20 0E 93 07 20 82 93 +A8 1E 0F 20 92 43 A8 1E 5C 43 10 01 1C 42 B0 1E +1D 42 B2 1E 3C F3 3D F0 FF 00 0D 9F 02 20 0C 9E +02 24 4C 43 10 01 A2 43 A8 1E 5C 43 10 01 21 83 +81 43 00 00 7C 40 81 00 5D 43 B0 13 5C D0 81 4C +00 00 B1 B0 00 20 00 00 02 20 4E 43 08 3C B1 D0 +00 C0 00 00 B1 E3 00 00 91 53 00 00 5E 43 2C 41 +5C 03 CF 0C 4E 93 04 24 3C 40 AC 0A 0C 8F 03 3C +3C 40 AC 0A 0C 5F 21 53 10 01 0B 4D 0E 4B 0D 93 +1F 30 3B F0 80 7F 1C 24 5B 02 8B 10 7E D0 80 00 +3B 80 7F 00 15 30 3B 90 20 00 0F 34 3B 80 17 00 +05 30 1B 83 08 30 5C 02 0E 6E FB 3F 5E 01 5C 00 +1B 53 01 24 FB 3F 0D 4E 10 01 3C 43 3D 43 10 01 +0C 43 0D 43 10 01 0B 4D 0B EF 0A 30 0D 93 12 30 +0D 9F 02 24 19 34 16 3C 0C 9E 18 24 13 28 14 3C +3D B0 80 7F 04 20 3F B0 80 7F 01 20 0F 24 0D 9F +0B 34 08 3C 0F 9D 02 24 07 34 04 3C 0E 9C EC 27 +01 28 02 3C 3C 43 10 01 1C 43 10 01 0C 43 10 01 +C2 93 FE 1E 21 20 D2 43 FE 1E B2 40 8F 02 00 1F +B2 40 33 13 02 1F B2 40 14 01 80 03 B2 40 05 00 +92 03 B2 40 80 00 82 03 F2 D0 80 00 0B 02 00 18 +F2 40 CA DC 16 1F 3C 40 8F 02 B0 13 1C EA 92 42 +02 1F 1A 1F E2 43 04 1F 10 01 E2 93 04 1F 13 24 +B0 13 44 F2 C2 93 04 1F 1C 24 82 43 90 03 B2 D0 +10 00 80 03 F2 D0 80 00 0B 02 E2 43 04 1F 92 42 +02 1F 1A 1F 10 01 B2 F0 CF FF 80 03 F2 F0 7F 00 +03 02 F2 F0 7F 00 0B 02 D2 43 04 1F 92 42 00 1F +1A 1F 10 01 1A 14 CB 0E CA 0D CE 0C CC 0A CD 0B +B0 13 66 E2 4D 4C CC 0A 49 4E 5C E9 5A F7 47 18 +0C 5C 4E ED 5E 4E 5A F7 0E 5C 4A 4A 47 18 0A 5A +CC 0B 4C DD 0C 5A 0C EE 0F 9C 06 2C 3E 40 FF 7F +0C FE 5E 03 0F 9C FC 2B 19 16 10 01 1A 14 31 80 +06 00 C9 0C 5A 42 FF 1D CC 0A B0 13 6A EB 0C 93 +02 20 2C 43 13 3C 4D 43 B0 13 78 EC 0C 93 0E 20 +91 43 02 00 C1 4A 04 00 81 43 00 00 CC 01 2C 53 +3D 40 7A 1D CE 09 0F 43 B0 13 FA C6 31 50 06 00 +19 16 10 01 F2 40 A5 00 21 01 4E 4C 4F 4E 8F 10 +0E 5F 3E 50 00 44 82 4E 24 01 4F 4C 3F 50 00 44 +82 4F 26 01 92 B3 2C 01 FD 27 C2 4C 20 01 B2 F0 +F9 FF 2C 01 A2 B3 2C 01 03 24 A2 B2 2C 01 FD 27 +82 4E 26 01 C2 43 21 01 10 01 1A 14 3F 40 8E FA +9F 00 FF FF 12 24 3D 40 8E FA 0C 3C 4F 13 2A 52 +12 3C 3C 4D CA 0D CE 09 B0 13 BA F2 0A 59 CD 0A +1D 53 1D C3 39 4D 09 93 F4 23 3F 40 FF FF 3F 93 +05 24 3A 40 FF FF 0F 0A DF 03 E8 23 19 16 10 01 +7C 90 3C 00 06 28 7C 90 3E 00 03 24 32 C2 03 43 +FF 3F 0F 42 32 C2 03 43 B2 B0 10 00 02 0F FC 27 +7C 90 2F 00 08 28 7C 90 3E 00 05 24 7C D0 C0 00 +C2 4C 13 0F 04 3C 7C D0 80 00 C2 4C 13 0F 5C 42 +22 0F 02 4F 10 01 0B 4D 0E 4B 3B F0 80 7F 1C 24 +5B 02 8B 10 7E D0 80 00 3B 80 7F 00 15 30 3B 90 +10 00 10 34 5E 01 5C 00 1E 93 01 24 FB 3F 1B 83 +03 30 5C 02 0E 6E FB 3F 0D 93 02 34 3E E3 1E 53 +0C 4E 10 01 3C 43 10 01 0C 43 10 01 0A 14 CB 0D +0A 42 32 C2 03 43 B2 B0 10 00 02 0F FC 27 7C D0 +C0 00 C2 4C 13 0F 4F 4E 1F 83 0A 24 B2 B0 80 00 +02 0F FC 27 1D 53 DD 42 22 0F FF FF 1F 83 F6 23 +4D 4E 0D 5B DD 42 20 0F FF FF 02 4A 0A 16 10 01 +0B 42 32 C2 03 43 B2 B0 10 00 02 0F FC 27 4C 4C +47 18 0C 5C 3C D0 00 40 6F 4D 0F 5C 82 4F 10 0F +6E 93 0C 28 1D 53 4E 4E 1E 83 E2 4D 10 0F B2 B0 +20 00 02 0F FC 27 1D 53 1E 83 F7 23 5F 42 20 0F +02 4B 10 01 C2 43 76 1E 82 43 82 1E 82 43 7E 1E +82 43 80 1E C2 93 FE 1D 16 24 B0 13 52 EC B0 13 +F8 D6 B0 13 EE EA 1C 42 84 1E 0C 93 0C 24 1C 52 +82 1E 82 4C 82 1E 1D 42 78 1E 1E 42 7A 1E 1F 42 +7C 1E 80 00 1E A3 10 01 1A 14 C9 0C 3D 40 0C 00 +0D 59 6E 49 7E 80 0B 00 5C 43 7F 40 03 00 B0 13 +6A CA CA 0C 0A 93 10 24 3C 40 03 00 0C 5A 3D 40 +05 00 0D 59 2E 42 B0 13 BA F2 FA D0 80 00 0E 00 +CC 0A 4D 43 B0 13 30 E8 19 16 10 01 D2 B3 36 1F +0E 24 1D 42 B0 1E 1E 42 B2 1E 3D F3 3E F0 FF 00 +1F 42 A6 1E 1E 9F 02 00 02 20 2D 9F 02 24 4C 43 +10 01 DF 92 B3 1E 13 00 04 24 D2 C3 36 1F 4C 43 +10 01 EF C2 1A 00 B0 13 7C CB 5C 43 10 01 4F 4C +48 18 0F 5F 7C 90 40 00 1A 28 7C 90 4F 00 17 2C +92 B3 44 01 FD 23 32 C2 03 43 B2 40 00 A5 44 01 +B2 40 02 A5 40 01 8F 43 00 00 B2 40 40 A5 40 01 +B2 40 00 A5 40 01 B2 40 10 A5 44 01 32 D2 10 01 +A2 D2 24 03 7F 40 80 00 3E 42 B2 C2 22 03 CD 0C +4D FF 4D 9F 03 24 A2 C2 22 03 02 3C A2 D2 22 03 +12 C3 4F 10 B0 13 32 F5 B2 D2 22 03 B0 13 32 F5 +1E 83 EB 23 B2 C2 22 03 A2 D2 22 03 A2 C2 24 03 +10 01 4C 93 1D 20 4C 43 B0 13 10 ED 0C 93 04 24 +1C 83 09 24 1C 83 14 20 C2 43 3C 1F C2 43 3D 1F +82 43 3E 1F 10 01 1F 42 7A FA D2 4F 0E 00 3C 1F +1E 4F 04 00 1F 4F 06 00 C2 4F 3D 1F 82 4E 3E 1F +10 01 0A 14 1A 43 5A 52 31 1F D2 53 31 1F B0 13 +88 CC 4C 4C 0C 9A 11 34 1F 43 5F 52 32 1F 7F 90 +0D 00 05 2C D2 53 32 1F D2 43 31 1F 06 3C D2 43 +31 1F D2 43 32 1F 92 53 34 1F 92 D3 14 1D 0A 16 +10 01 0A 14 0A 43 0F 93 05 34 3E E3 3F E3 1E 53 +0F 63 1A D3 0D 93 05 34 3C E3 3D E3 1C 53 0D 63 +3A E3 B0 13 B2 D8 1A B3 04 24 3C E3 3D E3 1C 53 +0D 63 2A B3 04 24 3E E3 3F E3 1E 53 0F 63 0A 16 +10 01 0A 14 CA 0D CB 0E 4C 4C 3D 40 1C 00 B0 13 +1A F2 1F 42 7A FA 0F 5C 8F 93 18 00 0F 20 8F 4A +00 00 8F 4B 02 00 0B 93 06 20 0A 93 04 20 1C 52 +7A FA EC C2 1A 00 FF 40 7F 00 10 00 0A 16 10 01 +0A 14 5A 42 B9 1E 3C 40 B0 1E B0 13 40 E5 4C 4C +0C EA 47 18 0C 5C 8C 10 4C 4C CA 0C C2 4A B9 1E +3A 90 21 00 05 20 D2 D3 36 1F B0 13 DE F4 05 3C +F2 F0 EF 00 36 1F B0 13 90 CD 0A 16 10 01 1A 14 +C2 93 2A 1E 16 24 3C 40 02 1E 29 42 3A 40 7E FA +3B 40 2C 1E 4E 43 4F 43 7D 4C 7D 9B 01 20 5E 53 +7D 9A 01 20 5F 53 19 83 F7 23 6F 92 02 24 6E 92 +02 20 4C 43 01 3C 5C 43 19 16 10 01 5C 02 0D 6D +5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D +5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D +5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D +5C 02 0D 6D 5C 02 0D 6D 10 01 5D 03 5C 00 5D 03 +5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 +5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 +5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 +5C 00 5D 03 5C 00 10 01 0A 14 3F 40 41 1E 2E 43 +0C 43 2D 43 6D 9F 05 20 3F 50 0C 00 1C 53 1E 83 +F8 23 6C 93 02 20 0C 43 0C 3C 4C 4C 3D 40 0C 00 +B0 13 1A F2 3A 40 41 1E 0A 5C CC 0A B0 13 9C E4 +CC 0A 0A 16 10 01 82 43 BA 1E 4C 43 B0 13 D8 F4 +B0 13 56 F3 C2 43 C2 1E 92 D3 14 1D 7C 40 13 00 +6D 42 B0 13 30 F0 7C 40 17 00 6D 42 B0 13 30 F0 +7C 40 18 00 6D 42 B0 13 30 F0 7C 40 19 00 6D 42 +80 00 30 F0 92 C3 44 03 82 93 FC 1E 0E 24 B0 13 +9A A0 92 93 FC 1E 03 24 B0 13 44 E6 02 3C B0 13 +90 CD 1C 42 F6 1E 80 00 12 F0 F2 C2 36 1F B0 13 +90 CD 1C 42 F8 1E B0 13 12 F0 92 43 FC 1E 10 01 +3A 14 C8 0D C7 0C 3A 40 41 1E 29 43 2F 43 6F 9A +0E 20 3D 40 03 00 0D 5A CC 07 2E 42 B0 13 7C ED +0C 93 05 20 58 9A 0A 00 02 20 CC 0A 05 3C 3A 50 +0C 00 19 83 EB 23 0C 43 37 16 10 01 3A 14 C8 0D +C7 0C 3A 40 41 1E 49 43 2F 43 6F 9A 0E 20 3C 40 +03 00 0C 5A CD 07 2E 42 B0 13 7C ED 0C 93 05 20 +CA 98 0A 00 02 20 CC 0A 05 3C 3A 50 0C 00 59 53 +EB 27 0C 43 37 16 10 01 D2 B3 8D 1C 0A 24 B0 13 +FA F3 4C 93 06 20 B0 13 F4 B1 4C 93 02 20 B0 13 +C6 E2 F2 B0 06 00 8D 1C 02 24 B0 13 F8 D6 7C 40 +15 00 7D 40 03 00 B0 13 30 F0 0C 43 4D 43 5E 43 +80 00 64 B6 82 43 AE 1E B0 13 E4 F4 F2 40 21 00 +AA 1E F2 40 06 00 AC 1E C2 43 AB 1E D2 43 AD 1E +7C 43 5D 43 B0 13 3E D1 B0 13 CE D0 B0 13 0A D9 +7C 40 0C 00 5D 42 94 1E 80 00 2C E4 21 83 0F 42 +32 C2 03 43 B2 B0 10 00 02 0F FC 27 4C 4C 47 18 +0C 5C 3C D0 00 40 4D 4D 0C 5D 82 4C 10 0F B2 B0 +20 00 02 0F FC 27 5E 42 20 0F 81 4E 00 00 02 4F +21 53 10 01 5F 14 1A 42 38 0F 4A 4A B0 13 12 F4 +4C 93 10 20 7A 90 14 00 04 24 4A 93 0D 20 03 43 +0B 3C 1F 42 BA 1E 1F 93 02 24 2F 93 05 20 B0 13 +A8 F2 02 3C B0 13 10 D4 5A 16 00 13 21 83 CC 43 +0A 00 EC 43 00 00 DC 42 40 1E 0B 00 D2 53 40 1E +02 3C D2 53 40 1E C2 93 40 1E FB 27 F2 93 40 1E +F8 27 5C 42 40 1E CD 01 B0 13 42 EB 4C 93 F1 23 +21 53 10 01 0A 14 CA 0C 5D 42 4A 1F B0 13 A0 E7 +4C 93 0E 24 B0 13 DE F2 CD 0C 1C 43 0C 5A 2E 42 +B0 13 7C ED 0C 93 02 20 0C 43 05 3C 2C 43 03 3C +B0 13 BE F3 1C 43 0A 16 10 01 0E 4C 0D 4C 0D 93 +16 24 03 34 3D E3 1D 53 0F 30 3B 40 8F 00 1B 83 +5D 02 FD 2B 4C 4D 8C 10 8D 10 4D 4D 8B 10 0D DB +5E 02 5D 00 5C 00 10 01 3D 40 00 C7 0C 43 10 01 +0A 14 3A 40 09 00 0F 43 6D 4C 3B 42 4E 4D 0E EF +3E 90 80 00 04 38 4F 5F 7F E0 97 00 02 3C 4F 5F +4F 4F 4D 5D 1B 83 F2 23 1C 53 1A 83 ED 23 CC 0F +0A 16 10 01 1D 42 26 1E 0F 42 32 C2 03 43 D2 43 +24 1E 02 4F 0D 93 07 24 B0 13 F4 EF C2 93 23 1E +02 20 1D 83 F9 23 0F 42 32 C2 03 43 C2 43 23 1E +C2 43 24 1E 02 4F 10 01 B0 13 9E F4 1F 42 A6 1E +FF 90 7F 00 10 00 0A 24 2C 93 05 34 3C 93 0D 34 +DF 83 10 00 10 01 DF 53 10 00 10 01 CF 4C 10 00 +1F 42 A6 1E FF 50 0C 00 10 00 10 01 7C 90 2F 00 +06 28 7C 90 3E 00 03 24 32 C2 03 43 FF 3F 0F 42 +32 C2 03 43 B2 B0 10 00 02 0F FC 27 C2 4C 11 0F +B2 B0 20 00 02 0F FC 27 C2 4D 10 0F 02 4F 10 01 +4D 93 03 20 32 C2 03 43 FF 3F 0F 42 32 C2 03 43 +B2 B0 10 00 02 0F FC 27 F2 40 7F 00 11 0F 4D 4D +B2 B0 20 00 02 0F FC 27 F2 4C 10 0F 1D 83 F8 23 +02 4F 10 01 B2 F0 FE FD 36 0F B2 F0 FE FD 32 0F +7C 40 36 00 B0 13 2E C8 7C 40 3A 00 B0 13 2E C8 +7C 40 36 00 B0 13 2E C8 7C 40 32 00 B0 13 2E C8 +82 43 1E 1F 10 01 B0 13 0C C0 B0 13 D0 D4 B0 13 +EE F3 82 93 D8 1E 03 20 82 93 86 1E 02 24 B0 13 +42 B4 82 93 88 1E 02 24 B0 13 C4 EC 82 93 14 1D +EE 27 B0 13 DA AC EB 3F 21 83 7C 40 30 00 B0 13 +2E C8 81 43 00 00 02 3C 91 53 00 00 B1 90 64 00 +00 00 FA 2B 7C 40 36 00 B0 13 2E C8 7C B0 70 00 +F9 23 82 43 06 0F 21 53 10 01 0C 93 02 20 0D 93 +14 24 3B 40 9F 00 1B 83 5C 02 0D 6D FC 2B 12 C3 +5D 00 5C 00 3E 40 06 00 5D 01 5C 00 1E 83 FC 37 +8B 10 0D DB 12 C3 5D 00 5C 00 10 01 D2 B3 8D 1C +06 24 B0 13 FA F3 4C 93 02 24 B0 13 C6 E2 0C 43 +4D 43 6E 43 B0 13 64 B6 F2 B0 06 00 8D 1C 02 24 +B0 13 EE EA 7C 40 15 00 6D 42 80 00 30 F0 B2 B0 +20 00 86 1E 14 20 B0 13 12 F4 4C 93 10 20 A2 B2 +D8 1E 0D 24 1F 42 BA 1E 0F 93 05 20 B0 13 F4 B1 +4C 93 03 24 10 01 2F 93 02 20 80 00 C6 E2 10 01 +4D 93 03 20 32 C2 03 43 FF 3F 0F 42 32 C2 03 43 +4D 4D B2 B0 10 00 02 0F FC 27 F2 40 BF 00 13 0F +1C 53 DC 42 22 0F FF FF 1D 83 F3 23 02 4F 10 01 +CF 0C FF B0 80 FF 0C 00 02 20 6C 43 10 01 CF 9D +0D 00 0C 20 B0 13 DE F2 CD 0C 1C 43 0C 5F 2E 42 +B0 13 7C ED 0C 93 02 20 4C 43 10 01 5C 43 10 01 +82 93 D0 1E 09 20 82 93 CE 1E 06 20 B2 40 04 03 +CE 1E B2 40 02 01 D0 1E B0 13 AC F1 C2 4C D7 1E +4C 93 FA 27 3C 40 D4 1E 0D 43 1E 43 80 00 CC F2 +31 80 06 00 81 43 02 00 D1 4C 05 00 04 00 CF 0C +3F 50 06 00 81 4F 00 00 1D 4C 02 00 2E 42 0E 5C +2F 4C CC 01 2C 53 B0 13 FA C6 31 50 06 00 10 01 +0A 14 CA 0C 3F 40 CF 00 5F FA 0C 00 5F D2 C8 1E +CA 4F 0C 00 2C 43 0C 5A B0 13 46 BF 4C 93 02 20 +0C 43 02 3C 3C 40 09 00 CA 43 00 00 0A 16 10 01 +7C 40 40 00 B0 13 0E E0 5C 53 7C 90 4F 00 FA 2B +C2 43 8C 1C F2 40 06 00 8D 1C F2 40 05 00 8E 1C +C2 43 8F 1C B2 40 00 80 90 1C C2 43 92 1C 10 01 +7C 90 80 00 09 28 4C 4C 3C 80 00 01 2D 43 B0 13 +9C E9 3C 80 4A 00 04 3C 4C 4C 5C 03 3C 80 4A 00 +3C 90 80 FF 02 34 3C 40 80 FF 8C 11 10 01 92 C3 +22 03 F2 F0 DF 00 03 02 F2 F0 1F 00 02 02 A2 C3 +22 03 F2 D0 20 00 05 02 F2 D0 E0 00 04 02 A2 D3 +24 03 92 D3 24 03 D2 43 F5 1E 10 01 B2 F0 FF FD +36 0F 7C 40 36 00 B0 13 EA CF 7C 40 3D 00 B0 13 +EA CF 7C B0 F0 FF F9 23 7C 40 3A 00 B0 13 EA CF +B2 F0 FF FD 32 0F 10 01 C2 93 59 1E 0E 20 B0 13 +86 A8 B0 13 0E CD 0C 93 0C 20 B0 13 2E EE B0 13 +DE F2 B0 13 34 ED B0 13 B8 EF D2 43 59 1E 80 00 +6C B7 10 01 4D 93 13 24 4D 4D 0E 43 5F 42 92 1C +7F 90 80 00 09 2C CB 0F 5B 53 C2 4B 92 1C CB 0E +0B 5C 4F 4F EF 4B 93 1C 1E 53 1D 83 EF 23 10 01 +5C 93 13 20 0C 42 32 C2 03 43 2E 43 3F 40 00 1C +CF 93 00 00 05 24 5D 9F 01 00 02 2C DF 83 01 00 +3F 50 23 00 1E 83 F4 23 02 4C 10 01 0B 43 0D 93 +03 34 3D E3 1D 53 1B D3 0C 93 03 34 3C E3 1C 53 +3B E3 B0 13 04 F2 1B B3 02 24 3C E3 1C 53 2B B3 +02 24 3E E3 1E 53 10 01 4C 4C 3D 40 1C 00 B0 13 +1A F2 CF 0C 1F 52 7A FA EF B2 1A 00 03 24 0F 43 +0D 43 05 3C 1C 52 7A FA 2F 4C 1D 4C 02 00 CC 0F +10 01 C2 93 AC 1E 09 24 1F 42 A6 1E DF 83 13 00 +1F 42 A6 1E CF 93 13 00 02 24 5C 43 10 01 8F 43 +18 00 5D 43 B0 13 92 E0 4C 43 10 01 82 4C 1A 1F +82 93 50 03 02 20 0F 43 05 3C 1F 42 50 03 1F 92 +50 03 FB 23 0F 5C 82 4F 58 03 92 C3 48 03 B2 D0 +10 00 48 03 10 01 31 40 FC 2B 00 18 F2 40 36 F5 +06 1F 00 18 F2 40 36 F5 0A 1F B0 13 12 F5 0C 93 +02 24 B0 13 EA DD 0C 43 B0 13 76 E6 B0 13 16 F5 +5D 93 12 20 C2 93 EB 1E 0A 24 E2 93 EB 1E 0C 2C +7C 40 5A 00 3D 40 F2 F8 5E 43 80 00 D6 BC 7C 40 +5A 00 3D 40 F8 F8 F8 3F 10 01 92 B3 44 01 FD 23 +32 C2 03 43 B2 40 00 A5 44 01 B2 40 40 A5 40 01 +8C 4D 00 00 B2 40 00 A5 40 01 B2 40 10 A5 44 01 +32 D2 10 01 B2 D0 06 00 06 0A B2 40 1D 7B 00 0A +B2 40 ED 00 04 0A F2 D0 E0 00 4A 02 F2 D0 E0 00 +44 02 B2 43 0A 0A B2 40 FF 00 0C 0A 10 01 C2 93 +FE 1D 11 24 C2 93 76 1E 0E 24 B0 13 B6 F4 4C 93 +0A 20 B0 13 76 F4 C2 43 76 1E F2 F0 BF 00 1B 02 +F2 F0 BF 00 1D 02 10 01 F2 C2 03 02 F2 C2 05 02 +D2 B3 8C 1C 0B 20 E2 B3 8C 1C 02 20 80 00 B8 E3 +92 D3 8A 1E B2 D0 00 01 8A 1E 10 01 80 00 0C E7 +10 01 3F 40 41 1E 0E 43 2B 43 6B 9F 07 20 CF 9C +0B 00 04 20 CD 4E 00 00 5C 43 10 01 3F 50 0C 00 +1E 53 2E 93 F1 3B 4C 43 10 01 21 83 CD 01 B0 13 +42 EB 4C 93 0B 24 6C 41 3D 40 0C 00 B0 13 1A F2 +EC 93 41 1E 03 20 3C 50 41 1E 01 3C 0C 43 21 53 +10 01 82 93 EE 1E 09 20 82 93 EC 1E 06 20 B2 40 +08 07 EC 1E B2 40 06 05 EE 1E 00 18 C2 43 F0 1E +B0 13 AC F1 C2 4C F4 1E 10 01 3C 40 03 00 5C F2 +20 01 7C 90 03 00 03 2C 5C 53 B0 13 A4 DD 6C 92 +03 28 5C 83 B0 13 E0 EB 7C 90 03 00 EE 23 10 01 +F2 40 A5 00 21 01 4E 4C 4F 4E 8F 10 0E 5F 3E 50 +00 44 82 4E 26 01 92 B3 2C 01 FD 27 C2 4C 20 01 +C2 43 21 01 10 01 3F 40 13 00 6F 9C 09 24 5F 4C +0C 00 1F 83 07 24 1F 83 07 20 B0 13 10 D2 04 3C +DC 43 0C 00 B0 13 78 AF 0C 43 10 01 F2 F0 E0 00 +05 02 F2 F0 E0 00 03 02 F2 D0 1F 00 07 02 F2 F0 +E0 00 19 02 F2 F0 E0 00 1D 02 F2 D0 1F 00 1B 02 +10 01 1A 14 39 40 11 00 3F 40 BA 1D 3A 40 36 FA +3C 4A B0 13 E8 ED 2F 52 8F 4C FC FF 8F 4D FE FF +19 83 F6 23 19 16 10 01 4D 93 03 24 5F 4C 0A 00 +02 3C 5F 4C 09 00 4F 93 06 24 CC 93 00 00 03 24 +7F 90 20 00 02 2C 2C 43 10 01 0C 43 10 01 3C 40 +E2 1E 0D 43 2E 42 B0 13 CC F2 C2 93 EA 1E 09 20 +3C 40 E6 1E 3D 40 70 FA 2E 42 B0 13 BA F2 D2 43 +EA 1E 10 01 A2 B3 88 1E 03 24 5C 43 B0 13 AE C5 +B2 B2 88 1E 02 24 B0 13 54 B9 92 B3 88 1E 02 24 +B0 13 A8 D1 82 43 88 1E 10 01 B2 B0 20 00 86 1E +0E 20 B0 13 FA F3 4C 93 0A 20 F2 C2 03 02 F2 C2 +05 02 F2 C2 1B 02 B0 13 F4 CA F2 D2 1B 02 10 01 +4C 4C 3D 40 1C 00 B0 13 1A F2 CF 0C 1F 52 7A FA +EF B2 1A 00 02 24 2C 43 10 01 1C 52 7A FA 1C 4C +18 00 10 01 CE 0C 6D 4E 5D 92 7E FA 0C 24 7C 40 +09 00 B0 13 DC E5 2D 42 3F 40 2C 1E 1F 53 FF 4E +FF FF 1D 83 FB 23 10 01 0A 14 0A 42 32 C2 03 43 +D2 93 00 1E 08 24 B0 13 F8 EE 7C 40 32 00 B0 13 +EA CF D2 43 00 1E 02 4A 0A 16 10 01 0E 93 02 20 +0C 43 10 01 1D 83 1C 83 1D 53 6B 4D 1C 53 6F 4C +4F 9B 02 20 1E 83 F8 23 4B 4B 4C 4F 0C 8B 10 01 +0A 14 CA 0C 5D 42 95 1E B0 13 A0 E7 4C 93 04 20 +B0 13 BE F3 1C 43 04 3C CC 0A B0 13 E2 F3 0C 43 +0A 16 10 01 82 43 96 1E 82 43 98 1E E2 42 A0 1E +F2 40 1E 00 A1 1E C2 43 A2 1E C2 43 9F 1E 82 43 +9A 1E 82 43 9C 1E 10 01 0D 4C 0D 93 0E 24 3B 40 +8F 00 1B 83 5D 02 FD 2B 4C 4D 8C 10 8D 10 4D 4D +8B 10 0D DB 12 C3 5D 00 5C 00 10 01 82 43 90 03 +B2 40 C0 00 92 03 B2 D0 10 00 80 03 92 B3 82 03 +FD 27 B2 F0 EF FF 80 03 92 C3 82 03 10 01 D2 93 +00 1E 0D 20 7C 40 36 00 B0 13 EA CF 7C 40 3D 00 +B0 13 EA CF 7C B0 F0 FF F9 23 E2 43 00 1E 10 01 +5F 42 A0 1E 4F 93 09 24 7F 90 0D 00 02 2C CC 0F +10 01 CC 0F 7C 80 0C 00 10 01 3C 40 0C 00 4C 5F +10 01 4C 43 B0 13 10 ED 0C 93 09 24 1C 83 09 20 +B0 13 C6 F4 C2 4C C2 1E 92 43 BC 1E 10 01 80 00 +C6 E2 10 01 0A 14 CA 0C 5D 42 D7 1E B0 13 A0 E7 +4C 93 04 20 B0 13 BE F3 1C 43 03 3C CC 0A B0 13 +06 EC 0A 16 10 01 02 12 32 C2 03 43 82 4C D0 04 +82 4D D2 04 82 4E E0 04 82 4F E2 04 1C 42 E4 04 +1D 42 E6 04 32 41 10 01 0A 14 5C 43 B0 13 02 CF +CA 0C 0A 93 07 24 2C 43 0C 5A B0 13 CA F3 CC 0A +B0 13 52 C9 0A 16 10 01 D2 93 00 1E 09 24 F2 90 +03 00 00 1E 08 20 B0 13 EC E8 E2 43 00 1E 10 01 +32 C2 03 43 FF 3F 10 01 D2 93 00 1E 09 24 F2 90 +03 00 00 1E 08 24 F2 40 03 00 00 1E 80 00 C2 F1 +32 C2 03 43 FF 3F 10 01 1C 42 82 1E 3C B0 00 80 +0D 7D 3D E3 3E 40 52 00 0F 43 B0 13 B6 EE 3E 40 +19 00 0F 43 80 00 12 E1 B0 13 FA F3 4C 93 0A 24 +4C 43 1F 42 54 03 1F 82 50 03 3F 90 F5 01 03 28 +5C 43 10 01 5C 43 10 01 C2 43 C8 1E 00 18 C2 43 +CA 1E B0 13 DE F2 82 4C C6 1E B0 13 AC F1 C2 4C +C4 1E 4C 93 FA 27 10 01 B2 F0 CF FF 80 03 F2 F0 +7F 00 03 02 F2 F0 7F 00 0B 02 B2 F0 EF FF 82 03 +B0 13 AE F4 80 00 80 F4 D2 92 7E FA 2C 1E 08 24 +D2 43 2A 1E 7C 40 07 00 7D 40 07 00 80 00 DC E5 +32 C2 03 43 FF 3F B0 13 EC E8 7C 40 0A 00 5D 42 +82 FA B0 13 DC E5 F2 90 03 00 00 1E 02 20 80 00 +C2 F1 10 01 3F 40 3E 00 0E 42 32 C2 03 43 B0 13 +0C EE 02 4E C2 93 23 1E 03 20 1F 83 3F 93 F4 23 +10 01 CF 0C 82 4F 54 03 92 C3 44 03 B0 13 B2 F3 +2F 83 0F 8C 3F 90 00 80 02 28 92 D3 44 03 10 01 +CF 0D 7C 90 2A 00 0A 2C 4E 4C 5D 4E C2 F9 4C 4C +5C 02 1C 4C 16 1D CE 0D 80 00 2E D5 10 01 0C 9D +02 2C 80 00 BA F2 0C 5E 0D 5E 0E 93 06 24 1D 83 +1C 83 EC 4D 00 00 1E 83 FA 23 10 01 CD 0C C2 93 +EA 1E 02 24 4C 43 10 01 3C 40 E6 1E 2E 42 B0 13 +BA F2 D2 43 EA 1E 5C 43 10 01 B0 13 96 F3 4C 93 +08 20 4C 43 4D 43 B0 13 30 F0 5C 43 5D 43 80 00 +30 F0 4C 43 FB 3F 3C 40 00 1C 0D 43 3E 40 46 00 +B0 13 CC F2 3C 40 46 1C 0D 43 3E 40 46 00 80 00 +CC F2 0A 14 CF 0C CC 0D 2A 43 0F 93 05 20 B0 13 +6C F0 4C 93 01 24 0A 43 CC 0A 0A 16 10 01 21 82 +CF 0C CC 0D A1 4F 00 00 91 4F 02 00 02 00 CD 01 +2E 42 B0 13 4E F0 21 52 10 01 1F 42 A6 1E 5C 4F +11 00 6C 93 02 2C 3C 42 10 01 5C 53 4C 5C 4C 5C +4C 4C 10 01 7C 90 03 00 07 2C 4C 4C 5D 4C 86 FA +7C 40 3E 00 80 00 DC E5 32 C2 03 43 FF 3F 0C 93 +0A 24 5C 0F 1C 53 0F 42 32 C2 03 43 B0 13 0C EE +02 4F 1C 83 F8 23 10 01 B0 13 AC F1 7C F0 0F 00 +5C 53 4E 4C 1C 42 28 1E B0 13 2E F1 1E 83 FA 23 +10 01 B2 90 06 00 0E 07 08 20 92 42 20 07 44 1F +D2 43 46 1F B1 C0 D0 00 00 00 00 13 1C 42 7E 1E +CF 0C 5F 0A 0C 5F 3D 40 05 00 B0 13 9C E9 3C 50 +40 01 10 01 5D 42 F4 1E B0 13 A0 E7 4C 93 02 24 +0C 43 10 01 B0 13 BE F3 1C 43 10 01 5C 42 22 1E +3D 40 6D 00 B0 13 1A F2 7C 50 43 00 C2 4C 22 1E +10 01 B2 F0 FF FD 32 0F 7C 40 34 00 B0 13 EA CF +B2 D0 00 02 36 0F 10 01 0F 42 32 C2 03 43 7C D0 +C0 00 C2 4C 13 0F 5C 42 22 0F 02 4F 10 01 82 43 +BA 1E 82 43 BE 1E 82 43 C0 1E 82 43 BC 1E C2 43 +C2 1E 10 01 0E 43 0F 4C 1C 43 5F 02 0E 6E 0E 9D +01 28 0E 8D 0C 6C F9 2B 10 01 02 12 32 C2 03 43 +82 4C C0 04 82 4D C8 04 1C 42 CA 04 32 41 10 01 +B2 40 FF 7F 52 03 B2 D0 10 00 42 03 B2 D0 24 01 +40 03 10 01 5F 42 FE 1E 5F 83 D2 83 FE 1E 0F 93 +02 20 80 00 98 EF 10 01 5D 93 07 20 7C 40 5B 00 +3D 40 08 F9 5E 43 80 00 D6 BC 10 01 5D 93 07 20 +7C 40 5A 00 3D 40 00 F9 5E 43 80 00 D6 BC 10 01 +3C 80 05 00 05 24 3C 80 05 00 02 24 4C 43 10 01 +5C 43 10 01 B2 40 D9 07 34 1F F2 42 32 1F D2 43 +31 1F C2 43 30 1F 10 01 1F 42 50 03 82 4F 22 1F +1F 92 50 03 F9 23 80 00 72 D4 CF 0C 0E 93 05 24 +1F 53 FF 4D FF FF 1E 83 FB 23 10 01 0E 93 06 24 +4D 4D 1C 53 CC 4D FF FF 1E 83 FB 23 10 01 C2 93 +EA 1E 03 24 3C 40 E6 1E 10 01 3C 40 70 FA 10 01 +0D 93 02 20 0C 93 04 24 82 4C EC 1E 82 4D EE 1E +10 01 0D 93 02 20 0C 93 04 24 82 4C CE 1E 82 4D +D0 1E 10 01 B0 13 A8 E6 B2 F0 EF FF 32 0F B2 D0 +10 00 36 0F 10 01 A2 43 FC 1E 92 C3 44 03 B2 D0 +10 00 44 03 10 01 A2 D2 80 03 82 43 80 03 B2 D0 +00 02 80 03 10 01 CE 0C 3C 40 E8 03 B0 13 2E F1 +1E 83 FA 23 10 01 82 43 32 0F 82 43 36 0F B0 13 +A8 E6 80 00 66 F3 7C 40 36 00 B0 13 2E C8 7C 40 +39 00 80 00 2E C8 4F 43 C2 93 30 1F 01 20 5F 43 +C2 4F 30 1F 10 01 4F 43 C2 93 9F 1E 01 20 5F 43 +C2 4F 9F 1E 10 01 4C 43 F2 90 0C 00 A0 1E 01 2C +5C 43 10 01 F2 40 0F 00 2A 1F B2 40 2C 01 2C 1F +10 01 1C 42 50 03 1C 92 50 03 FB 23 10 01 C2 93 +24 1E 02 24 D2 43 23 1E 10 01 3D 40 01 1E 3E 40 +21 00 80 00 BA F2 5C 43 B0 13 44 D6 6C 43 80 00 +44 D6 DC 93 0C 00 02 20 80 00 88 DF 10 01 B0 13 +BE F4 B2 40 2B 5A 5C 01 10 01 4C 43 A2 93 BA 1E +01 20 5C 43 10 01 4C 43 92 93 BA 1E 01 20 5C 43 +10 01 4C 43 82 93 72 1D 01 24 5C 43 10 01 CF 0C +CC 0D CD 0F 2E 42 80 00 4E F0 CD 0C 3C 40 E2 1E +2E 42 80 00 BA F2 7C 40 03 00 7D 40 0B 00 80 00 +5A D8 5C 93 02 20 CC 0D 10 01 CC 0E 10 01 1C 42 +44 03 7C F0 10 00 10 01 B2 F0 EF FF 44 03 80 00 +44 E6 B0 13 AC F1 C2 4C 4A 1F 10 01 B0 13 AC F1 +C2 4C 95 1E 10 01 7C 40 03 00 4D 43 80 00 5A D8 +C2 43 FE 1E C2 43 04 1F 10 01 1C 42 14 1D 8C 10 +5C F3 10 01 1C 42 14 1D 5C 0F 5C F3 10 01 5C 42 +20 1F 8C 11 10 01 4C 5C C2 4C AB 1E 10 01 B2 F0 +EF FF 48 03 10 01 1C 43 5C F2 8C 1C 10 01 32 D0 +D8 00 03 43 10 01 5C 42 3C 1F 10 01 C2 4C AA 1E +10 01 C2 4C AC 1E 10 01 4D 43 80 00 3E D1 92 D3 +44 03 10 01 92 C3 44 03 10 01 5C 42 00 1E 10 01 +5C 42 76 1E 10 01 82 43 D8 1E 10 01 CC 43 00 00 +10 01 3C 40 7E FA 10 01 82 43 72 1D 10 01 80 00 +2C AE 1C 43 10 01 03 43 FF 3F 2C 43 10 01 2C 43 +10 01 4C 43 10 01 6C 43 10 01 0C 43 10 01 0C 43 +10 01 03 43 10 01 10 01 10 01 30 30 30 30 30 31 +30 30 32 30 30 33 30 30 34 30 30 35 30 30 36 30 +30 37 30 30 38 30 30 39 30 31 30 30 31 31 30 31 +32 30 31 33 30 31 34 30 31 35 30 31 36 30 31 37 +30 31 38 30 31 39 30 32 30 30 32 31 30 32 32 30 +32 33 30 32 34 30 32 35 30 32 36 30 32 37 30 32 +38 30 32 39 30 33 30 30 33 31 30 33 32 30 33 33 +30 33 34 30 33 35 30 33 36 30 33 37 30 33 38 30 +33 39 30 34 30 30 34 31 30 34 32 30 34 33 30 34 +34 30 34 35 30 34 36 30 34 37 30 34 38 30 34 39 +30 35 30 30 35 31 30 35 32 30 35 33 30 35 34 30 +35 35 30 35 36 30 35 37 30 35 38 30 35 39 30 36 +30 30 36 31 30 36 32 30 36 33 30 36 34 30 36 35 +30 36 36 30 36 37 30 36 38 30 36 39 30 37 30 30 +37 31 30 37 32 30 37 33 30 37 34 30 37 35 30 37 +36 30 37 37 30 37 38 30 37 39 30 38 30 30 38 31 +30 38 32 30 38 33 30 38 34 30 38 35 30 38 36 30 +38 37 30 38 38 30 38 39 30 39 30 30 39 31 30 39 +32 30 39 33 30 39 34 30 39 35 30 39 36 30 39 37 +30 39 38 30 39 39 31 30 30 31 30 31 31 30 32 31 +30 33 31 30 34 31 30 35 31 30 36 31 30 37 31 30 +38 31 30 39 31 31 30 31 31 31 31 31 32 31 31 33 +31 31 34 31 31 35 31 31 36 31 31 37 31 31 38 31 +31 39 31 32 30 31 32 31 31 32 32 31 32 33 31 32 +34 31 32 35 31 32 36 31 32 37 31 32 38 31 32 39 +31 33 30 31 33 31 31 33 32 31 33 33 31 33 34 31 +33 35 31 33 36 31 33 37 31 33 38 31 33 39 31 34 +30 31 34 31 31 34 32 31 34 33 31 34 34 31 34 35 +31 34 36 31 34 37 31 34 38 31 34 39 31 35 30 31 +35 31 31 35 32 31 35 33 31 35 34 31 35 35 31 35 +36 31 35 37 31 35 38 31 35 39 31 36 30 31 36 31 +31 36 32 31 36 33 31 36 34 31 36 35 31 36 36 31 +36 37 31 36 38 31 36 39 31 37 30 31 37 31 31 37 +32 31 37 33 31 37 34 31 37 35 31 37 36 31 37 37 +31 37 38 31 37 39 31 38 30 00 01 80 40 20 10 08 +84 42 21 90 48 A4 52 29 14 0A 85 C2 61 B0 58 AC +D6 6B 35 9A CD 66 33 99 4C A6 53 A9 54 2A 95 CA +E5 F2 79 3C 9E CF 67 B3 D9 6C B6 5B 2D 16 0B 05 +82 41 A0 50 28 94 4A A5 D2 69 34 1A 8D 46 23 91 +C8 E4 72 39 1C 8E C7 E3 F1 F8 FC FE FF 7F 3F 1F +0F 07 83 C1 E0 70 38 9C CE E7 F3 F9 7C BE DF 6F +37 9B 4D 26 13 89 44 22 11 88 C4 62 31 98 CC E6 +73 B9 5C AE D7 EB 75 BA DD 6E B7 DB 6D 36 1B 0D +06 03 81 C0 60 30 18 8C C6 63 B1 D8 EC F6 7B 3D +1E 8F 47 A3 D1 E8 F4 7A BD 5E AF 57 AB 55 AA D5 +EA F5 FA FD 7E BF 5F 2F 17 8B 45 A2 51 A8 D4 6A +B5 DA ED 76 3B 1D 0E 87 C3 E1 F0 78 BC DE EF 77 +BB 5D 2E 97 CB 65 B2 59 2C 96 4B 25 92 49 24 12 +09 04 02 01 80 40 20 10 08 84 42 21 90 48 A4 52 +29 14 0A 85 C2 61 B0 58 AC D6 6B 35 9A CD 66 33 +99 4C A6 53 A9 54 2A 95 CA E5 86 F3 00 00 38 F5 +00 00 86 AB 00 00 94 F4 00 00 6C F8 38 F5 00 00 +38 F5 00 00 00 BC 00 00 94 F4 00 00 7E F8 38 F5 +00 00 38 F5 00 00 42 BA 00 00 94 F4 00 00 90 F8 +3E E7 00 00 F6 F4 00 00 44 D3 00 00 94 F4 00 00 +5A F8 76 F3 00 00 38 F5 00 00 7C BE 00 00 8A F4 +00 00 B4 F8 18 EB 00 00 38 F5 00 00 58 F2 00 00 +94 F4 00 00 C6 F8 EA EC 00 00 38 F5 00 00 6C F2 +00 00 94 F4 00 00 D8 F8 B4 D9 00 00 38 F5 00 00 +70 EA 00 00 94 F4 00 00 A2 F8 20 20 44 4F 4E 45 +00 00 20 43 4F 4E 46 00 20 52 46 42 53 4C 00 00 +20 20 53 59 4E 43 00 00 20 44 4C 4F 47 00 46 41 +49 4C 00 00 45 52 52 00 30 30 30 30 30 30 30 00 +2D 2D 2D 00 20 52 41 4D 00 00 20 4F 46 46 00 00 +20 20 4F 4E 00 00 20 4E 4F 4D 45 4D 00 00 4C 4F +42 41 54 54 00 00 20 20 4F 50 45 4E 00 00 20 20 +4C 4F 3F 54 00 00 02 1B 01 1E 17 3C 18 10 06 1E +08 05 03 47 0B 08 0C 00 0D 21 0E 71 0F 7A 10 7B +11 83 12 13 13 22 14 F8 15 42 19 1D 1A 1C 1B C7 +1C 00 1D B2 21 B6 22 10 23 EA 24 2A 25 00 26 1F +2C 81 2D 35 2E 09 F5 60 B6 F2 63 D3 D7 70 F7 F3 +00 00 00 00 00 86 00 77 C7 95 E6 97 17 F3 67 05 +F0 87 85 75 46 C6 37 F5 06 D3 87 C4 C4 02 67 E3 +B6 00 03 01 04 08 10 80 80 80 80 20 40 02 01 80 +04 02 10 20 40 08 08 80 08 08 08 08 F7 F7 F7 F7 +20 40 04 80 7F 7F 7F 7F 7F 10 01 80 2F 1E 1B 07 +37 B2 0A 04 00 00 00 0C 00 21 64 EC 4D 3B 15 11 +F8 57 07 0C 10 1D 1C C7 10 B0 FF FF F9 B6 10 EA +2A 00 1F 00 67 FF 00 00 6F 00 1C 02 DD 03 B1 05 +9D 07 A2 09 C4 0B 07 0E 6E 10 01 13 C6 15 C8 18 +11 1C B5 1F CC 23 07 04 F5 03 E8 03 B6 03 84 03 +52 03 20 03 EE 02 BC 02 8A 02 58 02 26 02 F4 01 +C2 01 90 01 5E 01 2C 01 A0 ED 00 00 94 EE 00 00 +94 F1 00 00 2E F5 00 00 2A F5 00 00 D4 E4 00 00 +79 56 34 12 02 01 01 01 00 00 5A 1E 5A 1E FF FF +FF FF 00 32 50 6E 0F 27 8C 00 02 00 00 +@fa8e +01 00 1C 1F 00 00 01 00 E0 1E 00 00 01 00 E1 1E +0A 00 54 00 16 1D 20 0A 20 0A 20 0A 20 0A 24 0A +2A 0A 29 0A 27 0A 26 0A 24 0A 24 0A 26 0A 26 0A +24 0A 26 0A 24 0A 26 0A 26 0A 26 0A 21 0A 22 0A +20 0A 23 0A 24 0A 25 0A 26 0A 21 0A 22 0A 23 0A +25 0A 20 0A 20 0A 24 0A 2B 0A 2B 0A 2A 0A 29 0A +28 0A 27 0A 20 0A 24 0A 28 0A 02 00 40 1F 00 00 +02 00 42 1F 00 00 01 00 59 1E 00 00 01 00 00 1E +00 00 01 00 22 1E 00 00 01 00 23 1E 00 00 01 00 +24 1E 00 00 02 00 26 1E 00 00 02 00 28 1E 00 00 +01 00 2A 1E 00 00 01 00 2C 1E FF 00 04 00 30 1E +00 00 00 00 04 00 34 1E 00 00 00 00 04 00 38 1E +00 00 00 00 01 00 EA 1E 00 00 01 00 C4 1E 00 00 +02 00 C6 1E 00 00 01 00 C8 1E 00 00 04 00 CA 1E +00 00 00 00 01 00 3C 1E 01 00 01 00 95 1E 00 00 +02 00 48 1F 00 00 01 00 4A 1F 00 00 04 00 CE 1E +00 00 00 00 01 00 D2 1E 00 00 01 00 D6 1E 00 00 +01 00 D7 1E 00 00 04 00 EC 1E 00 00 00 00 04 00 +F0 1E 00 00 00 00 01 00 F4 1E 00 00 01 00 AA 1E +00 00 01 00 AB 1E 00 00 01 00 AC 1E 00 00 01 00 +AD 1E 00 00 02 00 F6 1E 00 00 02 00 F8 1E 00 00 +01 00 FA 1E 00 00 01 00 FB 1E 00 00 01 00 20 1F +00 00 02 00 22 1F 00 00 02 00 38 1F 00 00 01 00 +3A 1F 00 00 00 00 +@ffe0 +F6 A4 +@ffea +64 E4 60 D9 C4 A6 62 F1 +@fffe +46 EA +q diff --git a/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_datalogger_915MHz.txt b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_datalogger_915MHz.txt new file mode 100755 index 0000000..8511b06 --- /dev/null +++ b/chronos-ti/Recovery/Chronos Watch/Applications/Recovery_ez430_chronos_datalogger_915MHz.txt @@ -0,0 +1,1513 @@ +@9e00 +5A 14 31 80 1A 00 CA 0E B0 13 B2 E6 0E 43 3F 40 +C8 42 B0 13 CE C8 81 4C 12 00 81 4D 14 00 CC 0A +B0 13 C0 ED 0E 43 3F 40 20 41 B0 13 CE C8 81 4C +16 00 81 4D 18 00 36 40 11 00 37 40 BA 1D 0A 43 +28 47 19 47 02 00 CC 08 CD 09 1E 41 12 00 1F 41 +14 00 B0 13 16 DC 0C 93 0A 38 81 48 08 00 81 49 +0A 00 27 52 1A 53 16 83 EB 23 4A 4A 03 3C 4A 4A +0A 93 7E 24 3A 90 0F 00 3D 38 3A 90 0F 00 23 24 +B0 13 86 A0 1E 42 FA 1D 1F 42 FC 1D B0 13 BC B0 +C9 0C CA 0D 1C 42 FA 1D 1D 42 FC 1D 1E 42 F6 1D +1F 42 F8 1D B0 13 3A A0 1C 42 1E FA 1C 82 1C FA +B0 13 4C A0 1C 42 1E FA B0 13 60 A0 81 4C 00 00 +81 4D 02 00 73 3C B0 13 24 A0 C9 0C CA 0D 1C 42 +F6 1D 1D 42 F8 1D 1E 41 08 00 1F 41 0A 00 B0 13 +3A A0 1C 42 1C FA 1C 82 1A FA B0 13 4C A0 1C 42 +1A FA E2 3F C9 0A 59 02 16 49 FC F9 5A 06 17 4A +BA 1D 18 4A BC 1D B0 13 24 A0 C5 0C CA 0D B0 13 +86 A0 CE 07 CF 08 B0 13 BC B0 3E 40 34 80 3F 40 +37 3A B0 13 10 A0 CC 05 CD 0A B0 13 4A C2 C5 0C +CA 0D CC 07 CD 08 1E 41 08 00 1F 41 0A 00 B0 13 +90 A0 CC 05 CD 0A B0 13 CE C8 C8 0C CA 0D 1C 49 +FE F9 0C 86 B0 13 E2 E4 CE 0C CF 0D CC 08 CD 0A +B0 13 4A C2 C9 0C CA 0D CC 06 B0 13 60 A0 A6 3F +B0 13 86 A0 1E 42 BA 1D 1F 42 BC 1D B0 13 BC B0 +C9 0C CA 0D 1C 42 BE 1D 1D 42 C0 1D 1E 42 BA 1D +1F 42 BC 1D B0 13 3A A0 1C 42 00 FA 1C 82 FE F9 +B0 13 56 A0 81 4C 00 00 81 4D 02 00 2C 41 1D 41 +02 00 B0 13 6A A0 3E 40 F4 FD 3F 40 D4 3B B0 13 +10 A0 1C 41 16 00 1D 41 18 00 B0 13 CE C8 81 4C +04 00 81 4D 06 00 1C 41 04 00 1D 41 06 00 B0 13 +6A A0 2E 41 1F 41 02 00 B0 13 4A C2 81 4C 0C 00 +81 4D 0E 00 1C 41 0C 00 1D 41 0E 00 B0 13 54 DE +81 4C 10 00 1C 41 10 00 31 50 1A 00 55 16 10 01 +B0 13 4A C2 CE 0C CF 0D 0C 43 3D 40 80 3F B0 13 +90 A0 10 01 1C 41 16 00 1D 41 18 00 1E 41 0C 00 +1F 41 0E 00 B0 13 BC B0 10 01 B0 13 90 A0 CC 09 +CD 0A B0 13 CE C8 C9 0C CA 0D 10 01 B0 13 56 A0 +C9 0C CA 0D 10 01 B0 13 78 A0 B0 13 4A C2 10 01 +B0 13 78 A0 B0 13 C2 B0 10 01 3E 40 E7 6F 3F 40 +63 3B B0 13 4A C2 10 01 B0 13 E2 E4 CE 0C CF 0D +CC 09 CD 0A 10 01 1C 41 16 00 1D 41 18 00 10 01 +B0 13 BC B0 CE 0C CF 0D 10 01 4A 14 31 82 B0 13 +9C F3 C8 0C CF 08 3F 50 FF 7F 81 4F 06 00 91 41 +06 00 04 00 82 43 A8 1E 4A 43 49 43 4C 49 B0 13 +04 A3 1F 4C 18 00 1F 83 1D 24 1F 83 14 24 D2 B3 +36 1F 47 24 1E 42 B0 1E 1F 42 B2 1E 3E F3 3F F0 +FF 00 1F 9C 02 00 3D 20 2E 9C 3B 20 D2 C3 36 1F +82 43 A8 1E 36 3C 5A 53 B0 13 32 DB 4C 93 31 24 +C7 09 2F 3C B0 13 D2 F0 C6 0C CC 09 B0 13 A6 E1 +4C 93 0C 20 CC 09 CD 06 CE 08 B0 13 1C B3 1F 42 +A6 1E AF 93 18 00 09 20 5A 53 07 3C 82 43 A8 1E +E2 B2 36 1F 02 20 B0 13 80 E5 1F 42 A6 1E 9F 93 +18 00 0F 20 CF 01 3F 50 03 00 81 4F 00 00 CC 06 +CD 01 3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 +EA D9 59 53 AB 27 4A 93 50 24 92 93 A8 1E 18 38 +4C 47 B0 13 04 A3 CC 07 B0 13 94 C1 4C 93 10 24 +5A 83 CF 01 3F 50 03 00 81 4F 00 00 7C 42 CD 01 +3D 50 06 00 CE 01 2E 52 CF 01 2F 53 B0 13 EA D9 +4A 93 33 24 1F 42 A4 1E 0F 88 1F 93 2C 34 E2 B2 +36 1F 0D 20 E2 D2 36 1F C2 93 AD 1E 04 20 B2 50 +E0 7F A4 1E 20 3C B2 50 C0 53 A4 1E 1C 3C E2 C2 +36 1F C2 93 AD 1E 03 24 3F 40 40 6C 02 3C 3F 40 +20 00 82 5F A4 1E 49 43 4C 49 B0 13 04 A3 AC 93 +18 00 07 20 CC 09 B0 13 CA E9 4C 93 02 20 5A 83 +04 24 59 53 F1 27 4A 93 0E 20 F2 F0 F9 00 36 1F +91 91 06 00 04 00 02 24 0E 43 08 3C B0 13 42 F4 +A2 43 FC 1E 6C 3C E2 D3 36 1F 1E 43 1F 41 06 00 +0F 88 0F 93 50 38 0E 93 38 24 E2 B2 36 1F 15 20 +1F 41 06 00 1F 82 A4 1E 3F 80 42 00 0F 93 2D 38 +C2 43 FA 1E C2 43 FB 1E F2 D0 18 00 36 1F 92 42 +A4 1E F6 1E A2 43 FC 1E 48 3C 1F 41 06 00 0F 88 +3F 80 42 00 1F 93 19 38 C2 43 FA 1E C2 43 FB 1E +F2 D0 18 00 36 1F 1F 41 06 00 1F 82 A4 1E 3F 80 +42 00 0F 93 05 34 1F 41 06 00 3F 80 42 00 02 3C +1F 42 A4 1E 82 4F F6 1E 26 3C D2 41 02 00 FA 1E +D2 41 03 00 FB 1E 5F 42 36 1F 7F C2 7F D0 10 00 +C2 4F 36 1F 92 41 06 00 F6 1E 92 41 04 00 F8 1E +82 43 FC 1E 12 3C D2 91 02 00 FA 1E 09 24 D2 41 +02 00 FA 1E D2 41 03 00 FB 1E F2 D0 10 00 36 1F +92 41 04 00 F6 1E 92 43 FC 1E D2 C3 36 1F 31 52 +46 16 10 01 3D 40 1C 00 B0 13 F2 F1 1C 52 64 FA +82 4C A6 1E 10 01 6A 14 31 80 20 00 C8 0F C9 0D +CA 0E 81 43 0C 00 81 43 0E 00 B0 13 E2 E4 81 4C +14 00 81 4D 16 00 CC 09 CD 0A B0 13 B2 E6 0E 43 +3F 40 C8 42 B0 13 CE C8 81 4C 18 00 81 4D 1A 00 +CC 08 B0 13 C0 ED 0E 43 3F 40 20 41 B0 13 CE C8 +81 4C 1C 00 81 4D 1E 00 1C 41 14 00 1D 41 16 00 +3E 40 F4 FD 3F 40 D4 3B B0 13 4A C2 1E 41 1C 00 +1F 41 1E 00 B0 13 C2 B0 81 4C 10 00 81 4D 12 00 +1C 41 10 00 1D 41 12 00 3E 40 E7 6F 3F 40 63 3B +B0 13 4A C2 CE 0C CF 0D 1C 41 14 00 1D 41 16 00 +B0 13 CE C8 81 4C 08 00 81 4D 0A 00 36 40 10 00 +37 40 FE F9 0A 43 2C 47 B0 13 BC A4 CE 08 CF 09 +B0 13 16 DC 0C 93 08 38 81 48 0C 00 81 49 0E 00 +27 53 1A 53 16 83 EF 23 4A 4A 5A 02 1C 4A 1E FA +B0 13 C0 ED C6 0C C7 0D 1C 4A FE F9 B0 13 BC A4 +B0 13 E0 A4 C4 0C C5 0D 1C 41 08 00 1D 41 0A 00 +CE 08 CF 09 B0 13 BC B0 3E 40 82 A8 3F 40 7B 38 +B0 13 4A C2 CE 0C CF 0D 0C 43 3D 40 80 3F B0 13 +CE A4 C4 0C C5 0D 1C 4A 20 FA B0 13 C0 ED CE 06 +CF 07 B0 13 CE A4 C5 0C CA 0D CC 08 CD 09 B0 13 +E0 A4 CE 0C CF 0D CC 05 CD 0A B0 13 CE C8 CE 06 +CF 07 B0 13 C2 B0 81 4C 04 00 81 4D 06 00 1C 41 +18 00 1D 41 1A 00 1E 41 04 00 1F 41 06 00 B0 13 +CE C8 81 4C 00 00 81 4D 02 00 38 40 11 00 3A 40 +BA 1D 39 40 20 FA 3C 49 B0 13 C0 ED 2E 41 1F 41 +02 00 B0 13 4A C2 2A 52 8A 4C FC FF 8A 4D FE FF +18 83 F1 23 31 50 20 00 64 16 10 01 B0 13 E2 E4 +C8 0C C9 0D 1C 41 0C 00 1D 41 0E 00 10 01 B0 13 +BC B0 CE 0C CF 0D CC 04 CD 05 B0 13 4A C2 10 01 +1E 41 10 00 1F 41 12 00 B0 13 BC B0 10 01 4F 14 +5D 42 1B 02 B2 B0 20 00 D8 1E D4 20 B2 B0 40 00 +D8 1E D0 20 82 43 D8 1E 5E 42 1D 02 4E FD 4B 43 +B0 13 FC F3 4C 93 62 20 7E B0 1F 00 0F 24 32 C2 +03 43 C2 43 1B 02 32 D2 3C 40 A3 00 B0 13 3C DA +92 42 96 1E 9A 1E 92 42 98 1E 9C 1E 6E B2 39 20 +6E B3 22 20 7E B0 10 00 17 20 5E B3 0E 20 7E B2 +6C 24 F2 B2 01 02 69 24 D2 43 DD 1E C2 43 DC 1E +F2 D2 03 02 F2 D2 05 02 60 3C D2 B3 01 02 5D 24 +B2 D2 D8 1E 5B 43 59 3C F2 B0 10 00 01 02 55 24 +A2 D2 D8 1E 5B 43 51 3C E2 B3 01 02 0B 20 E2 B3 +19 02 4B 24 A2 D3 D8 1E B2 F0 FF FE D8 1E E2 C3 +19 02 43 3C A2 D3 D8 1E B2 F0 FF FE D8 1E 5B 43 +3C 3C E2 B2 01 02 0B 20 E2 B2 19 02 36 24 92 D3 +D8 1E B2 F0 7F FF D8 1E E2 C2 19 02 2E 3C 92 D3 +D8 1E B2 F0 7F FF D8 1E 5B 43 27 3C D2 53 E0 1E +5F 42 E0 1E 5F 83 7F 90 07 00 05 28 F2 F0 0F 00 +7A 1D C2 43 E0 1E 6E B2 13 20 6E B3 0D 20 7E B0 +10 00 06 20 5E B3 11 24 F2 D0 20 00 78 1D 0D 3C +F2 D0 30 00 7A 1D 07 3C F2 D0 20 00 7A 1D 03 3C +F2 D0 10 00 7A 1D F2 D2 78 1D A2 B3 D8 1E 03 24 +B2 B2 D8 1E 0D 20 4B 93 0D 24 B2 B0 10 00 86 1E +02 20 B0 13 60 DC 3C 40 00 20 B0 13 3C DA 02 3C +82 43 D8 1E 7E B0 20 00 02 24 A2 D2 88 1E 7E B0 +40 00 02 24 A2 D3 88 1E 92 B3 D8 1E 03 20 A2 B3 +D8 1E 18 24 3C 40 66 06 B0 13 3C DA E2 B2 01 02 +07 24 E2 D2 19 02 92 C3 D8 1E B2 D0 80 00 D8 1E +E2 B3 01 02 07 24 E2 D3 19 02 A2 C3 D8 1E B2 D0 +00 01 D8 1E 32 C2 03 43 C2 43 1D 02 C2 4D 1B 02 +32 D2 B1 C0 F0 00 14 00 4B 16 00 13 4F 14 B2 F0 +EF FF 42 03 92 C3 42 03 B2 80 00 80 52 03 B2 D0 +10 00 42 03 B0 13 1E D5 B2 D0 10 00 14 1D B0 13 +F0 F3 4C 93 C7 20 B0 13 FC F3 4C 93 11 24 B2 90 +03 00 72 1D 0D 20 C2 93 76 1D 08 20 7C 40 5A 00 +3D 40 EA F8 5E 43 B0 13 E0 BC 02 3C D2 83 76 1D +E2 93 9E 1E 02 28 92 D3 88 1E B0 13 A0 F4 4C 93 +02 24 B2 D2 88 1E B0 13 DA F4 4C 93 02 24 A2 D3 +88 1E B0 13 E4 F3 4C 93 02 24 B0 13 4A EE B2 B0 +20 00 86 1E 10 24 5E 42 2A 1F CF 0E 5F 83 C2 4F +2A 1F 4E 93 08 20 92 D3 8A 1E B2 D0 20 00 8A 1E +F2 40 0F 00 2A 1F 82 93 8A 1E 0F 24 92 B3 8A 1E +08 20 A2 B2 8A 1E 09 24 A2 C2 8A 1E 92 D3 14 1D +04 3C 92 C3 8A 1E A2 D3 8A 1E A2 B3 86 1E 0E 24 +1F 42 96 1E 1E 42 98 1E 1F 82 9A 1E 1E 72 9C 1E +03 20 3F 90 1F 00 02 28 92 D3 86 1E D2 93 DD 1E +0E 20 E2 92 DC 1E 03 2C D2 53 DC 1E 08 3C F2 C2 +03 02 F2 C2 05 02 C2 43 DC 1E C2 43 DD 1E E2 B3 +01 02 03 24 D2 B3 01 02 2F 20 C2 43 1C 1F E2 B2 +01 02 11 24 D2 53 DA 1E F2 90 03 00 DA 1E 0D 28 +B2 D0 20 00 D8 1E B2 F0 7F FF D8 1E C2 43 DA 1E +E2 C2 19 02 02 3C C2 43 DA 1E E2 B3 01 02 11 24 +D2 53 DB 1E F2 90 03 00 DB 1E 2C 28 B2 D0 40 00 +D8 1E B2 F0 FF FE D8 1E C2 43 DB 1E E2 C3 19 02 +21 3C C2 43 DB 1E 1E 3C D2 53 1C 1F 5F 42 1C 1F +5F 83 7F 90 03 00 16 28 1F 42 86 1E 2F C2 2E 42 +1E C2 86 1E 0E DF 82 4E 86 1E 92 D3 8A 1E A2 B2 +86 1E 04 20 B2 D0 10 00 8A 1E 02 3C B2 D2 8A 1E +C2 43 1C 1F B1 C0 D0 00 14 00 4B 16 00 13 3C 40 +01 1E 0D 43 3E 40 21 00 B0 13 B6 F2 7C 40 30 00 +B0 13 6C CF 7C 40 30 00 B0 13 0E DE 4C 93 AF 20 +7C 40 31 00 B0 13 0E DE 7C 90 06 00 A5 20 7C 40 +36 00 B0 13 6C CF B0 13 04 AA FD 23 B2 40 01 02 +34 0F 0F 42 32 C2 03 43 B2 B0 10 00 02 0F FC 27 +B2 40 51 7E 10 0F B2 B0 10 00 02 0F FC 27 F2 40 +3D 00 11 0F B2 B0 10 00 02 0F FC 27 F2 40 FE 00 +11 0F B2 B0 20 00 02 0F FC 27 C2 43 10 0F B2 B0 +80 00 02 0F FC 27 F2 90 51 00 20 0F 72 20 B2 B0 +10 00 02 0F FC 27 F2 40 3D 00 11 0F 02 4F 3B 40 +40 F9 4E 43 6C 4B 4F 4E 5F 02 5D 4F 41 F9 B0 13 +B4 E5 2B 53 5E 53 7E 90 20 00 F4 2B 3D 40 40 F9 +4E 43 6C 4D B0 13 0E DE 4F 4E 5F 02 CF 9C 41 F9 +4D 20 2D 53 5E 53 7E 90 20 00 F3 2B 7C 40 36 00 +B0 13 6C CF B0 13 04 AA FD 23 7C 40 0C 00 5D 42 +94 1E B0 13 B4 E5 B0 13 AE EF 6C 43 B0 13 EC F0 +7C 40 34 00 B0 13 6C CF A2 B3 30 0F FD 27 3E 40 +10 00 7C 40 34 00 B0 13 0E DE 5C F3 5F 42 22 1E +4F 5F 4C DF C2 4C 22 1E 1E 83 F3 23 F2 D0 80 00 +22 1E B0 13 C4 E8 7C 40 32 00 B0 13 6C CF D2 43 +00 1E B2 40 36 00 26 1E B2 40 E2 04 28 1E 3C 40 +01 1E 0D 43 3E 40 1F 00 B0 13 B6 F2 3C 40 20 1E +0D 43 2E 43 B0 13 B6 F2 32 D2 10 01 32 C2 03 43 +FF 3F 32 C2 03 43 FF 3F 32 C2 03 43 FF 3F 32 C2 +03 43 FF 3F 7C 40 3D 00 B0 13 6C CF 7C B0 F0 FF +10 01 C2 43 9E 1D 5F 42 7A 1D 2F 83 AA 24 1F 83 +50 24 1F 83 33 24 1F 83 16 24 1F 83 06 24 1F 83 +A5 20 F2 D0 20 00 78 1D 10 01 7C 40 40 00 B0 13 +AA DF 5C 53 7C 90 4F 00 FA 2B B2 40 00 80 90 1C +E2 C3 8C 1C 10 01 E2 43 7A 1D 3C 40 A4 1D 4D 43 +4E 4D 5E 02 5F 4E 7B 1D 47 18 0F 5F 5E 4E 7C 1D +0E 5F 2C 53 8C 4E FE FF 5D 53 7D 90 09 00 F0 2B +E2 43 9F 1D F2 40 09 00 9E 1D 10 01 E2 43 7A 1D +5E 42 7B 1D 47 18 0E 5E 5F 42 7C 1D 0E 5F 82 4E +A0 1D 5F 42 7D 1D 47 18 0F 5F 5D 42 7E 1D 0F 5D +82 4F A2 1D D2 43 9F 1D 4F 8E 5F 53 C2 4F 9E 1D +10 01 3E 40 BF FF 1E F2 86 1E 5F 42 7B 1D 5F 03 +3F F0 C0 FF 0E DF 82 4E 86 1E 3F 40 7F 00 5F F2 +7B 1D C2 4F A0 1E D2 42 7C 1D A1 1E D2 42 7D 1D +A2 1E 5F 42 7E 1D 47 18 0F 5F 5E 42 7F 1D 0E 5F +82 4E 34 1F D2 42 80 1D 32 1F D2 42 81 1D 31 1F +5F 42 84 1D 47 18 0F 5F 5E 42 85 1D 0E 5F CF 0E +1F 52 80 1E 1F 82 7E 1E 82 4F 80 1E 82 4E 7E 1E +5F 42 86 1D 47 18 0F 5F 5C 42 87 1D 0C 5F 82 4C +82 1E 1D 42 78 1E 1E 42 7A 1E 1F 42 7C 1E B0 13 +16 A3 D2 42 88 1D 8D 1C D2 42 89 1D 8E 1C 7C 40 +5A 00 3D 40 D4 F8 5E 43 B0 13 E0 BC D2 43 76 1D +10 01 F2 40 03 00 7A 1D D2 43 9E 1D 10 01 1A 14 +CA 0C 6D 93 3A 24 5D 93 0E 24 6D 92 5C 20 B0 13 +B6 AC 6D 42 B0 13 08 F0 C2 43 9F 1E 4C 43 4D 43 +B0 13 08 F0 50 3C C2 93 9F 1E 18 20 B2 B0 40 00 +86 1E 07 20 B0 13 4A AC 5A 93 05 20 B0 13 62 F0 +02 3C B0 13 5E AC B0 13 90 AC C9 0C 5C 42 A1 1E +B0 13 6C AC B0 13 B6 AC 6D 43 E2 3F B0 13 A8 AC +C9 0C 5C 42 A2 1E B0 13 6C AC 7D 40 1F 00 7E 40 +29 00 B0 13 2C F4 5D 43 D3 3F 5F 42 9E 1E 4F 93 +22 24 C2 93 9F 1E 18 20 4F 4F 2F 83 0D 24 1F 83 +1A 20 B2 B0 40 00 86 1E 05 20 B0 13 4A AC B0 13 +62 F0 02 3C B0 13 5E AC B0 13 90 AC CA 0C 5C 42 +A1 1E B0 13 82 AC 07 3C B0 13 A8 AC CA 0C 5C 42 +A2 1E B0 13 82 AC 19 16 10 01 B0 13 28 EE CF 0C +CC 0A B0 13 98 AC 4C 4F B0 13 74 AC 10 01 B0 13 +98 AC 5C 42 A0 1E B0 13 74 AC 10 01 B0 13 74 AC +CC 0A 10 01 B0 13 C4 AC CC 09 5E 43 B0 13 E0 BC +10 01 B0 13 C4 AC CC 0A 5E 43 B0 13 E0 BC 10 01 +CC 0A B0 13 A8 AC 10 01 7D 40 4A 00 7E 40 60 00 +B0 13 2C F4 C9 0C 10 01 7D 40 48 00 7E 40 5E 00 +B0 13 2C F4 10 01 7D 40 1E 00 7E 40 28 00 B0 13 +2C F4 10 01 0D 43 6E 43 4F 43 B0 13 DC C0 CD 0C +10 01 0A 14 31 82 92 B3 14 1D 0F 20 A2 B2 14 1D +0C 20 3F 40 0C 00 1F 52 40 1F 6F 13 4C 93 0C 24 +5C 43 6D 43 80 13 8C 1E 07 3C 5C 43 B0 13 D4 D5 +5C 43 5D 43 80 13 8C 1E A2 B3 8A 1E 1B 20 92 B3 +14 1D 12 20 B2 B2 14 1D 0F 20 3F 40 0C 00 1F 52 +42 1F 6F 13 4C 93 61 24 82 93 8A 1E 5E 20 6C 43 +6D 43 80 13 90 1E 59 3C 6C 43 B0 13 D4 D5 6C 43 +5D 43 F7 3F 6A 43 B2 B2 8A 1E 2E 20 B2 B0 10 00 +8A 1E 26 20 B2 B0 20 00 8A 1E 1E 20 B2 B0 00 01 +8A 1E 14 20 5A 43 B2 B0 40 00 8A 1E 0B 20 B2 B0 +80 00 8A 1E 20 24 CC 01 3D 40 14 F9 2E 42 B0 13 +A4 F2 19 3C CC 01 3D 40 1A F9 F8 3F CC 01 3D 40 +20 F9 3E 40 06 00 F3 3F CC 01 3D 40 28 F9 F9 3F +CC 01 3D 40 30 F9 F5 3F CC 01 3D 40 38 F9 3E 40 +06 00 B0 13 A4 F2 CC 0A B0 13 D4 D5 CC 0A 6D 42 +80 13 90 1E 6A 93 07 24 7C 40 46 00 CD 01 5E 43 +B0 13 E0 BC 06 3C 7C 40 5A 00 CD 01 5E 43 B0 13 +E0 BC 82 43 8A 1E A2 D2 8A 1E 92 B3 14 1D 10 24 +B0 13 E4 F3 6C 93 0C 20 7C 40 17 00 B0 13 1A AE +7C 40 18 00 B0 13 1A AE 7C 40 19 00 B0 13 1A AE +82 43 14 1D 31 52 0A 16 10 01 7D 40 03 00 B0 13 +08 F0 10 01 1A 14 31 80 16 00 B0 13 60 E2 CA 0C +0A 93 03 20 3C 40 03 00 97 3C 5C 43 CD 0A B0 13 +B4 BD 4C 93 04 20 CC 0A B0 13 E6 F4 F3 3F B0 13 +EC F4 CD 0C C9 01 39 52 CC 09 2E 42 B0 13 A4 F2 +81 49 00 00 CF 01 3F 50 0C 00 81 4F 02 00 F1 40 +09 00 04 00 E1 43 05 00 CD 01 3D 50 0E 00 3C 40 +CE 1E B0 13 B6 F0 D1 4A 09 00 12 00 D1 42 D7 1E +0D 00 B0 13 0C F5 C1 4C 13 00 D1 43 0C 00 B0 13 +10 F5 C1 4C 14 00 2C 43 3D 40 03 00 CE 01 B0 13 +00 C3 0C 93 59 20 B0 13 D4 F4 C9 0C E1 43 05 00 +CF 01 3F 50 0C 00 81 4F 02 00 CF 0A 3F 50 03 00 +81 4F 00 00 79 90 03 00 06 24 59 93 02 20 B0 13 +06 EE B0 13 F0 EE B0 13 4C E5 79 90 03 00 07 24 +59 93 03 24 B0 13 D0 EE 02 3C B0 13 30 ED 2C 43 +2D 43 CE 01 B0 13 00 C3 0C 93 05 24 CC 0A B0 13 +E6 F4 1C 43 29 3C 3F 40 7F 00 5F F1 0C 00 5F 93 +09 24 7F 90 03 00 06 24 CC 0A B0 13 E6 F4 3C 40 +05 00 1A 3C EA 43 00 00 DA 41 0E 00 0A 00 D2 4A +0B 00 FF 1D F1 90 40 00 0F 00 02 20 5F 43 02 3C +7F 40 03 00 CA 4F 01 00 D2 53 D7 1E C2 93 D7 1E +02 20 D2 43 D7 1E 0C 43 31 50 16 00 19 16 10 01 +3A 14 31 82 C9 0C F9 90 14 00 00 00 05 28 B0 13 +10 F5 C9 9C 14 00 74 20 3C 40 0E 00 0C 59 CD 01 +B0 13 08 F4 91 92 D0 1E 02 00 6A 20 91 92 CE 1E +00 00 66 20 58 49 12 00 3A 40 05 00 0A 59 3C 40 +05 00 0C 59 CD 08 B0 13 54 E3 0C 93 48 20 C2 93 +D2 1E 56 24 B0 13 60 E2 C7 0C 07 93 51 24 3C 40 +03 00 0C 57 CD 0A 2E 42 B0 13 A4 F2 6C 43 CD 07 +B0 13 B4 BD 4C 93 03 24 D2 93 D6 1E 04 20 CC 07 +B0 13 E6 F4 3D 3C 5F 42 D6 1E CE 0F 5E 53 C2 4E +D6 1E 4F 4F DF 47 0B 00 D4 1E C7 48 0A 00 E7 43 +00 00 F9 90 40 00 13 00 02 20 5F 43 02 3C 7F 40 +03 00 C7 4F 01 00 D1 47 09 00 06 00 B0 13 0C F5 +C1 4C 07 00 B0 13 A0 B0 B0 13 8E B0 CD 01 B0 13 +AE B0 D5 27 B0 13 76 B0 0C 93 12 24 D0 3F B0 13 +A0 B0 D1 4C 09 00 06 00 B0 13 0C F5 C1 4C 07 00 +B0 13 8E B0 CD 01 B0 13 AE B0 02 24 B0 13 76 B0 +31 52 37 16 10 01 3C 40 03 00 0C 59 CD 0A 2E 42 +B0 13 A4 F2 CC 09 4D 43 B0 13 08 E8 10 01 3E 40 +07 00 5E F9 0A 00 3F 40 03 00 4F 8E 6C 43 10 01 +F1 40 81 00 08 00 D1 49 0D 00 09 00 10 01 2D 52 +6E 42 B0 13 74 CA C9 0C 09 93 10 01 3B 40 80 00 +01 3C 0B 43 0A 14 09 14 08 14 07 14 21 83 3F B0 +80 7F 7B 24 3D B0 80 7F 05 20 0C 4E 0D 4F 8B 10 +0D EB 73 3C 5D 02 08 4D 4D 10 38 F0 00 FF 0D D8 +5F 02 08 4F 4F 10 38 F0 00 FF 0F D8 09 4C 0A 4D +3D F0 80 00 C1 4D 00 00 0B EA 0B EF 3B C0 7F FF +3A D0 80 00 3F D0 80 00 0A 9F 02 20 09 9E 0A 24 +0B 2C 0D 4F 0F 4A 0A 4D 0C 4E 0E 49 09 4C 81 EB +00 00 02 3C 0B 93 4F 20 0C 43 08 4A 88 10 47 48 +8F 10 48 8F 8F 10 0E 24 38 90 19 00 34 2C 12 C3 +4F 10 5E 00 5C 00 3C B0 00 10 02 24 3C D0 00 20 +18 83 F5 23 0B 93 0C 24 08 8C 09 7E 4A 7F 0C 48 +4A 93 12 30 5C 02 09 69 4A 6A 17 83 2C 24 F8 3F +09 5E 4A 6F 09 28 4A 10 59 00 5C 00 3C B0 00 10 +02 24 3C D0 00 20 17 53 3C B0 00 80 07 24 09 63 +4A 63 07 63 3C B0 00 60 01 20 19 C3 17 93 13 38 +37 90 FF 00 13 34 7A C0 80 00 87 10 D1 51 00 00 +00 00 57 00 0A D7 0C 49 0D 4A 21 53 07 16 08 16 +09 16 0A 16 10 01 0D 43 0C 43 F7 3F 3D 40 FF FE +D1 61 00 00 00 00 5D 00 3C 43 EF 3F 0A 14 B0 13 +FE F2 B0 13 CC E3 7C 40 0A 00 B0 13 B6 F4 7C 40 +06 00 B0 13 BC F4 82 43 BE 1E 82 43 C0 1E 7C 40 +05 00 B0 13 90 F4 7C 40 0C 00 5D 42 94 1E B0 13 +04 E4 92 43 BA 1E 7C 40 17 00 6D 43 B0 13 08 B3 +6D 43 B0 13 12 B3 6D 43 B0 13 08 F0 4C 43 B0 13 +E8 EC 0C 93 2A 20 4C 43 1D 42 BE 1E 1E 42 C0 1E +B0 13 AE E0 4C 43 B0 13 E2 D6 7A 40 28 00 04 3C +3C 40 99 19 B0 13 3C DA 4C 43 B0 13 E8 EC 2C 93 +04 20 CF 0A 5A 83 4F 93 F3 23 4A 93 0E 20 7C 40 +46 00 3D 40 F8 F8 5E 43 B0 13 E0 BC 2E 42 3C 40 +00 40 B0 13 3C DA 1E 83 FA 23 4C 43 B0 13 E8 EC +1C 93 0D 24 7C 40 17 00 6D 42 B0 13 08 B3 6D 42 +B0 13 12 B3 6D 42 B0 13 08 F0 4C 43 23 3C A2 43 +BA 1E 82 93 C0 1E 0A 20 82 93 BE 1E 07 20 4C 43 +B0 13 A0 E9 82 4C BE 1E 82 4D C0 1E 7C 40 17 00 +7D 40 03 00 B0 13 08 B3 7D 40 03 00 B0 13 12 B3 +7D 40 03 00 B0 13 08 F0 7C 40 13 00 6D 43 B0 13 +08 F0 5C 43 0A 16 10 01 B0 13 08 F0 7C 40 18 00 +10 01 B0 13 08 F0 7C 40 19 00 10 01 1A 14 C9 0C +1A 42 A6 1E 4D 4D 1D 5A 0C 00 0D 8E 3D 80 13 00 +0D 93 81 34 3E 40 1A 00 1E 52 A6 1E 6F 4E 3F F0 +03 00 1F 83 4E 24 1F 83 2C 20 CA 43 12 00 2F 42 +6F BE 1A 20 1C 42 A6 1E D2 9C 11 00 AA 1E 09 2C +C2 93 AC 1E 03 20 B0 13 98 D9 09 3C 8C 43 18 00 +06 3C B0 13 7A D5 1F 42 A6 1E DF 53 11 00 CC 09 +5D 43 B0 13 2A E1 57 3C EE C2 00 00 1F 42 A6 1E +8F 43 00 00 8F 43 02 00 1C 42 A6 1E B0 13 98 D9 +4A 3C 3C 40 80 00 5C 8A 13 00 CF 0A 2D 4F 1E 4F +02 00 3F 40 00 02 B0 13 3C DD 1C 5A 0C 00 3C 50 +00 02 8A 4C 0C 00 1F 42 A6 1E FF 40 22 00 0F 00 +3E 40 1A 00 1E 52 A6 1E 3F 40 FC 00 6F FE 5F D3 +28 3C 3C 40 40 00 5C 8A 13 00 2D 4A 1E 4A 02 00 +3F 40 80 1C B0 13 3C DD 1F 42 A6 1E 1C 5F 0A 00 +3C 50 00 06 8F 4C 0C 00 1F 42 A6 1E DF 43 0F 00 +1A 42 A6 1E CF 0A 5C 4F 13 00 2D 4F B0 13 80 F2 +CA 5C 0F 00 3E 40 1A 00 1E 52 A6 1E 6F 4E 5F C3 +6F D3 CE 4F 00 00 19 16 10 01 1D 42 90 1C 3D 80 +00 80 1D C3 5F 42 7A 1D 2F 83 03 24 1F 83 2D 24 +10 01 D2 93 9F 1D 15 24 E2 93 9F 1D 6A 20 5C 02 +1F 4C A4 1D B0 13 4A B5 5F 0E 3F 80 00 80 82 4F +B8 1D 3E 40 7D 1D 7F 40 03 00 B0 13 34 B5 FD 2B +10 01 1F 42 A0 1D 0F 5C B0 13 4A B5 1C 52 A0 1D +5C 0E 3C 80 00 80 82 4C B8 1D 3E 40 7D 1D 7F 40 +03 00 B0 13 34 B5 FD 2B 10 01 1F 42 86 1E 7F F0 +C0 00 4F 5F 3E 40 7F 00 5E F2 A0 1E 4E DF C2 4E +7B 1D D2 42 A1 1E 7C 1D D2 42 A2 1E 7D 1D 1E 42 +34 1F CF 0E 8F 10 C2 4F 7E 1D C2 4E 7F 1D D2 42 +32 1F 80 1D D2 42 31 1F 81 1D C2 43 82 1D C2 43 +83 1D 1E 42 7E 1E CF 0E 8F 10 8F 11 C2 4F 84 1D +C2 4E 85 1D 1E 42 82 1E CF 0E 8F 10 8F 11 C2 4F +86 1D C2 4E 87 1D D2 42 8D 1C 88 1D D2 42 8E 1C +89 1D CF 0D 8F 10 C2 4F 8A 1D C2 4D 8B 1D C2 43 +8C 1D 10 01 1E 53 1D 42 B8 1D EE 4D FF FF 92 53 +B8 1D 5F 53 7F 90 13 00 10 01 CE 0F 8E 10 C2 4E +7B 1D C2 4F 7C 1D 10 01 A2 D3 86 1E 82 93 D8 1E +03 24 A2 B2 86 1E 68 20 B2 B0 20 00 D8 1E 5B 20 +B2 B0 40 00 D8 1E 4B 20 82 93 D8 1E 69 24 92 B3 +D8 1E 32 20 A2 B3 D8 1E 1A 20 A2 B2 D8 1E 0D 20 +B2 B2 D8 1E 5D 24 1F 42 42 1F 0F 0F 6C 43 4F 13 +B2 D2 14 1D B2 C2 D8 1E 53 3C 1F 42 40 1F 0F 0F +5C 43 4F 13 A2 D2 14 1D A2 C2 D8 1E 49 3C C2 43 +EB 1E 6C 43 6D 42 80 13 90 1E 1F 42 42 1F 1F 4F +10 00 82 4F 42 1F 00 18 D2 4F 08 00 90 1E B2 D2 +14 1D A2 C3 D8 1E 34 3C 5C 43 6D 42 80 13 8C 1E +1F 42 40 1F 1F 4F 10 00 82 4F 40 1F 00 18 D2 4F +08 00 8C 1E A2 D2 14 1D 92 C3 D8 1E 21 3C B2 F0 +BF FF D8 1E 1F 42 42 1F 3F 0F 04 00 6C 43 4F 13 +92 D3 14 1D 15 3C B2 F0 DF FF D8 1E 1F 42 40 1F +3F 0F 04 00 5C 43 F3 3F E2 B3 01 02 03 24 D2 B3 +01 02 04 20 92 D3 8A 1E B2 D2 8A 1E 82 43 D8 1E +82 93 86 1E 09 24 92 B3 86 1E 06 24 92 C3 86 1E +B0 13 C0 F3 92 D3 14 1D A2 C3 86 1E 10 01 21 83 +4E 4E 1E 83 48 24 1E 83 2C 24 2E 83 1E 24 2E 82 +13 24 3E 82 72 20 D2 B3 8C 1C 6F 24 E2 B3 8C 1C +6C 20 F2 90 65 00 92 1C 68 28 B0 13 30 EF 4C 93 +64 24 B0 13 0E C5 61 3C D2 B3 8C 1C 5E 24 E2 B3 +8C 1C 5B 20 B0 13 1C E9 58 3C D2 B3 8C 1C 55 20 +7C 40 40 00 B0 13 AA DF 5C 53 7C 90 4F 00 FA 2B +4C 3C D2 B3 8C 1C 14 24 E2 B3 8C 1C 11 20 D2 B3 +92 1C 05 24 81 43 00 00 CC 01 B0 13 6E B7 B1 40 +FE FF 00 00 CC 01 6D 43 B0 13 1C E9 B0 13 0E C5 +D2 C3 8C 1C 32 3C 5F 42 8C 1C 1F F3 5E 42 8C 1C +2E F3 0E DF 0E 93 29 20 C2 43 92 1C D2 42 8E 1C +8F 1C B1 40 FB FF 00 00 CC 01 6D 43 B0 13 1C E9 +3C 40 8D 1C B0 13 6E B7 3C 40 8E 1C B0 13 6E B7 +3C 40 31 1F B0 13 6E B7 3C 40 32 1F B0 13 6E B7 +3C 40 34 1F 6D 43 B0 13 1C E9 3C 40 A0 1E 7D 40 +03 00 B0 13 1C E9 D2 D3 8C 1C 21 53 10 01 5D 43 +B0 13 1C E9 10 01 1A 14 31 80 18 00 B0 13 D4 F4 +C9 0C B0 13 EC F4 81 4C 10 00 CF 01 2F 52 81 4F +12 00 F1 42 14 00 7A 40 03 00 C1 4A 15 00 CD 01 +3D 50 06 00 3C 40 EC 1E B0 13 B6 F0 D1 43 04 00 +D1 42 F4 1E 05 00 D1 43 0A 00 B0 13 10 F5 C1 4C +0B 00 2C 43 3D 40 03 00 CE 01 3E 50 10 00 B0 13 +00 C3 C1 4A 15 00 CF 01 2F 52 81 4F 12 00 CF 01 +3F 50 0C 00 81 4F 10 00 79 90 03 00 06 24 59 93 +02 20 B0 13 06 EE B0 13 F0 EE B0 13 4C E5 3A 40 +06 00 79 90 03 00 07 24 59 93 03 24 B0 13 D0 EE +02 3C B0 13 30 ED 2C 43 2D 43 CE 01 3E 50 10 00 +B0 13 00 C3 0C 93 1D 20 3F 40 7F 00 5F F1 04 00 +5F 93 03 24 7F 90 06 00 14 20 CC 01 CD 01 3D 50 +06 00 2E 42 B0 13 A4 F2 2C 41 1D 41 02 00 B0 13 +EC F2 CC 01 3C 50 0C 00 B0 13 14 F4 D2 53 F4 1E +0A 43 CC 0A 31 50 18 00 19 16 10 01 0A 14 21 83 +C1 43 00 00 F2 90 03 00 00 1E 6B 20 7C 40 3B 00 +B0 13 0E DE CE 0C 7C 40 3B 00 B0 13 0E DE 4E 9C +F9 23 4E 93 61 24 CC 01 5D 43 B0 13 48 E7 6F 41 +3F 50 03 00 4E 4E 0E 9F 38 20 F1 90 1F 00 00 00 +34 2C F1 90 0B 00 00 00 30 28 3C 40 01 1E 0D 43 +3E 40 1F 00 B0 13 B6 F2 E2 41 01 1E 3C 40 02 1E +6D 41 B0 13 48 E7 3C 40 20 1E 6D 43 B0 13 48 E7 +F2 B0 80 FF 21 1E 14 24 92 53 34 1E 82 63 36 1E +B0 13 68 E1 4C 93 30 20 5C 42 20 1E B0 13 68 E8 +C2 4C 20 1E F2 F0 7F 00 21 1E B0 13 B0 EE 24 3C +92 53 30 1E 82 63 32 1E 1F 3C 92 53 38 1E 82 63 +3A 1E 0A 42 32 C2 03 43 7C 40 36 00 B0 13 6C CF +7C 40 3D 00 B0 13 6C CF 7C B0 F0 FF F9 23 7C 40 +3A 00 B0 13 6C CF 7C 40 34 00 B0 13 6C CF 02 4A +03 3C 32 C2 03 43 FF 3F 21 53 0A 16 10 01 21 82 +D2 83 8F 1C 66 20 5F 42 8D 1C 5F 93 51 24 6F 93 +4C 24 6F 92 3F 24 7F 90 07 00 2B 24 7F 90 03 00 +22 24 7F 90 05 00 12 24 7F 90 06 00 45 20 1E 42 +7E 1E CF 0E 5F 0D C1 4F 00 00 B0 13 36 BA C1 4E +01 00 C1 4D 02 00 7D 40 03 00 36 3C D1 42 C2 1E +00 00 1E 42 82 1E CF 0E 8F 10 8F 11 C1 4F 01 00 +C1 4E 02 00 F0 3F D1 42 C2 1E 00 00 1E 42 7E 1E +F2 3F D1 42 C2 1E 00 00 1E 42 7E 1E CF 0E 5F 0D +C1 4F 01 00 B0 13 36 BA C1 4E 02 00 C1 4D 03 00 +6D 42 12 3C 1E 42 82 1E CF 0E 8F 10 8F 11 C1 4F +00 00 C1 4E 01 00 6D 43 07 3C 1E 42 7E 1E F4 3F +D1 42 C2 1E 00 00 5D 43 CC 01 7E 42 B0 13 6E B6 +D2 42 8E 1C 8F 1C 0C 43 4D 43 7E 40 10 00 B0 13 +6E B6 21 52 10 01 1D 42 82 1E 43 18 4E 5E CF 0D +8F 10 8F 11 7F F0 0F 00 4E DF 10 01 0A 14 4A 4D +10 3C B2 B0 40 00 86 1E 06 20 7C 40 09 00 5D 43 +B0 13 08 F0 05 3C 7C 40 0B 00 5D 43 B0 13 08 F0 +2A 43 B0 13 88 D6 1A 93 EC 27 2A 93 13 24 2A 92 +3A 20 B0 13 C6 EA 7C 40 0B 00 4D 43 B0 13 08 F0 +7C 40 09 00 4D 43 B0 13 08 F0 6C 43 4D 43 B0 13 +1E BB 29 3C B2 B0 40 00 86 1E 19 20 B0 13 10 EF +3C 90 10 27 0F 34 0C 93 0F 34 3C E3 1C 53 B0 13 +06 BB 4D 43 B0 13 08 F0 7C 40 03 00 5D 43 B0 13 +08 F0 0B 3C 3C 40 0F 27 B0 13 FA BA 06 3C 1C 42 +82 1E 0C 93 EA 3B B0 13 FA BA 7C 40 46 00 CD 0B +5E 43 B0 13 E0 BC 0A 16 10 01 B0 13 06 BB 5D 43 +B0 13 1E BB 10 01 3C B0 00 80 0D 7D 3D E3 6E 42 +7F 40 03 00 B0 13 DC C0 CB 0C 6C 43 10 01 B0 13 +08 F0 7C 40 03 00 4D 43 B0 13 08 F0 10 01 6A 14 +31 80 06 00 C6 0C 09 43 3A 40 00 1C 7F 40 03 00 +81 4F 00 00 2F 46 1F 93 06 24 0F 93 0B 20 58 46 +02 00 C7 09 10 3C 5C 46 02 00 B0 13 42 EB C7 0C +07 93 02 20 0C 43 4D 3C 58 47 09 00 3F 40 03 00 +0F 57 81 4F 02 00 24 43 0F 42 32 C2 03 43 1E 43 +6E 9A 39 20 EA 42 00 00 02 4F 3F 40 0B 00 0F 5A +6F 4F 3F F0 3F 00 4E 48 0F 9E 2A 20 25 46 15 93 +0E 20 78 90 3F 00 06 20 3F 40 03 00 0F 57 81 4F +04 00 05 3C 3F 40 07 00 0F 5A 81 4F 04 00 1C 41 +04 00 1D 41 02 00 2E 42 B0 13 54 ED 4C 4C 05 93 +02 24 0C 93 0D 20 5F 4A 01 00 2E 41 4F 9E 08 2C +09 93 02 24 D9 43 00 00 81 4F 00 00 C9 0A 04 3C +DA 43 00 00 01 3C 02 4F 3A 50 23 00 14 83 BC 23 +CC 09 31 50 06 00 64 16 10 01 4D 4D 1D 93 14 24 +2D 93 31 24 2D 92 5B 20 B0 13 C6 EA 6C 43 4D 43 +B0 13 D0 BC 7C 40 0F 00 4D 43 B0 13 08 F0 7C 40 +1F 00 4D 43 80 00 08 F0 B0 13 88 D6 7C 40 1F 00 +5D 43 B0 13 08 F0 7C 40 0F 00 5D 43 B0 13 08 F0 +B2 B0 40 00 86 1E 08 20 7C 40 1D 00 7D 40 46 00 +5E 43 B0 13 FA CE 07 3C 7C 40 1D 00 7D 40 43 00 +5E 43 B0 13 FA CE B2 B0 40 00 86 1E 04 20 B0 13 +54 F1 CB 0C 02 3C 1B 42 7E 1E 0B 93 05 38 6C 43 +5D 43 B0 13 D0 BC 0B 3C 3B E3 1B 53 6C 43 4D 43 +B0 13 08 F0 7C 40 03 00 5D 43 B0 13 08 F0 CC 0B +3C B0 00 80 0D 7D 3D E3 7E 40 03 00 5F 43 B0 13 +DC C0 CD 0C 7C 40 49 00 5E 43 80 00 E0 BC 10 01 +B0 13 08 F0 7C 40 03 00 4D 43 B0 13 08 F0 10 01 +4A 14 C9 0E 4C 4C 3C 80 46 00 53 24 1C 83 4C 24 +1C 83 46 24 1C 83 41 24 1C 83 3B 24 3C 80 10 00 +3C 90 09 00 55 2C 5C 06 00 18 50 4C 0E BD 6C BD +00 00 66 BD 00 00 62 BD 00 00 58 BD 00 00 50 BD +00 00 4C BD 00 00 44 BD 00 00 3C BD 00 00 32 BD +00 00 7A 40 03 00 78 40 22 00 2E 3C 6A 43 78 40 +21 00 2A 3C 6A 43 78 40 23 00 26 3C 6A 42 F7 3F +6A 43 78 40 25 00 20 3C 7A 40 03 00 78 40 24 00 +1B 3C 6A 42 F0 3F 7A 40 05 00 E5 3F 7A 40 06 00 +E6 3F 6A 43 78 40 1A 00 0F 3C 7A 40 03 00 FA 3F +6A 43 78 40 1C 00 08 3C 7A 40 03 00 78 40 1B 00 +03 3C 6A 42 78 40 1A 00 C7 0D 4A 4A 06 43 CC 08 +4C 56 7D 47 CE 09 B0 13 FA CE 16 53 1A 83 F7 23 +46 16 10 01 4A 14 21 83 C8 0D C7 0C 39 40 41 1E +CC 01 0D 43 1E 43 B0 13 B6 F2 46 43 09 98 25 24 +2F 43 6F 99 22 20 5A 49 09 00 7A 90 3E 00 1D 2C +57 93 13 24 3C 40 03 00 0C 59 3D 40 03 00 0D 58 +2E 42 B0 13 54 ED 0C 93 10 20 4F 4A CA 01 3A 50 +E0 FF 0A 5F DA 43 00 00 08 3C C2 9A 3E 1E 05 2C +4A 4A CF 01 0F 8A DF 43 3D 00 39 50 0C 00 56 53 +D5 27 CE 01 0F 43 4C 43 CE 93 00 00 04 24 1E 53 +5C 53 FA 27 09 3C 67 93 04 20 7C 50 20 00 4F 4C +03 3C 3F 40 3D 00 4F 8C 67 93 0B 24 5E 42 3F 1E +0F 9E 12 38 5E 42 3E 1E 0F 9E 0F 20 D2 83 3E 1E +0C 3C 5E 42 3E 1E 0E 9F 07 38 5E 42 3F 1E 0E 9F +04 34 C2 4F 3F 1E 01 3C 0F 43 C8 4F 09 00 CC 0F +21 53 46 16 10 01 0A 14 CA 0C 5D 93 05 24 6D 92 +34 20 C2 43 30 1F 31 3C C2 93 30 1F 1A 20 5C 42 +31 1F B0 13 1E BF 03 20 B0 13 FE BE 02 3C B0 13 +0E BF 5C 42 32 1F B0 13 1E BF 03 20 B0 13 0E BF +02 3C B0 13 FE BE B0 13 32 BF 5D 43 B0 13 08 F0 +14 3C 1C 42 34 1F 0D 43 6E 42 4F 43 B0 13 DC C0 +CF 0C CC 0A 7D 40 46 00 7E 40 5C 00 B0 13 42 BF +B0 13 32 BF 4D 43 B0 13 08 F0 0A 16 10 01 CC 0A +7D 40 48 00 7E 40 5E 00 B0 13 42 BF 10 01 CC 0A +7D 40 4A 00 7E 40 60 00 B0 13 42 BF 10 01 0D 43 +6E 43 4F 43 B0 13 DC C0 CF 0C B2 B0 40 00 86 1E +10 01 CC 0A 7D 40 1F 00 7E 40 29 00 B0 13 2C F4 +10 01 B0 13 2C F4 CD 0F 5E 43 B0 13 E0 BC 10 01 +1A 14 CA 0D C9 0C D2 93 00 1E 58 24 B0 13 C4 E8 +1D 43 6D 59 CC 09 B0 13 E8 E5 49 43 4A 93 37 24 +5A 93 32 20 6A 42 16 3C 7C 40 36 00 B0 13 6C CF +7C 40 3D 00 B0 13 6C CF 7C B0 F0 FF F9 23 7C 40 +3A 00 B0 13 6C CF 4A 93 02 20 59 43 2B 3C B0 13 +20 F1 5A 83 7C 40 34 00 B0 13 6C CF A2 B3 30 0F +FD 27 92 C3 32 0F 7C 40 35 00 B0 13 6C CF 3C 40 +19 00 B0 13 06 F1 92 B3 32 0F D6 27 92 C3 32 0F +92 B3 30 0F FD 27 0E 3C 32 C2 03 43 FF 3F 7C 40 +35 00 B0 13 6C CF B2 B0 00 02 32 0F FC 27 B2 F0 +FF FD 32 0F 7C 40 3B 00 B0 13 6C CF F2 90 03 00 +00 1E 02 20 B0 13 9A F1 CC 09 03 3C 32 C2 03 43 +FF 3F 19 16 10 01 B2 40 23 5A 5C 01 B0 13 92 EB +F2 40 A5 00 21 01 F2 D0 80 00 20 01 C2 43 21 01 +F2 D0 03 00 4A 02 92 C3 6C 01 B2 D0 0C 00 6C 01 +82 43 66 01 B2 40 44 00 68 01 32 D0 40 00 82 43 +60 01 B2 40 50 00 62 01 B2 40 6E 11 64 01 32 C0 +40 00 1E 14 3D 40 41 D1 0E 43 1D 83 0E 73 FD 23 +0D 93 FB 23 1D 16 00 3C B2 F0 F0 FF 6E 01 A2 C3 +02 01 A2 B3 02 01 F8 23 32 C2 03 43 B2 40 52 2D +C0 01 A2 43 C2 01 F2 40 0E 00 D7 01 F2 F0 7F 00 +03 02 F2 D0 80 00 05 02 F2 40 11 00 CD 01 F2 40 +12 00 CE 01 F2 40 13 00 CF 01 82 43 C0 01 32 D2 +B0 13 80 E6 B0 13 50 F3 B0 13 96 E8 B0 13 9C EA +B0 13 04 EC B0 13 08 F2 80 00 0C CE 4A 14 C8 0F +C6 0E C9 0C CA 0D C7 06 3C 40 6A 1D 3D 40 02 F9 +3E 40 07 00 B0 13 A4 F2 0A 93 1C 20 39 90 B5 00 +19 2C 77 90 03 00 0B 2C CD 09 59 02 0D 59 3D 50 +25 F5 3C 40 6A 1D 2E 43 B0 13 A4 F2 22 3C 4C 46 +3C 50 67 1D CD 09 59 02 0D 59 3D 50 24 F5 3E 40 +03 00 F2 3F CC 09 CD 0A 3E 40 0A 00 0F 43 B0 13 +42 D8 7E 50 30 00 4F 46 CF 4E 69 1D CC 09 CD 0A +3E 40 0A 00 0F 43 B0 13 42 D8 C9 0C CA 0D 56 83 +E9 23 3F 40 6A 1D 4D 43 08 3C 48 93 04 24 FF 40 +20 00 00 00 58 83 1F 53 5D 53 3E 40 30 00 6E 9F +05 20 4E 47 1E 83 4C 4D 0C 9E EF 3B 3C 40 6A 1D +46 16 10 01 0A 14 CA 0C 1F 42 A6 1E 8F 93 02 00 +10 20 8F 93 00 00 0D 20 C2 93 AB 1E 0A 24 5E 42 +AB 1E 3E 50 64 00 5D 42 3A 1F 0D 9E 02 34 4C 43 +42 3C BF 40 00 70 08 00 5C 42 B3 1E 1D 42 B0 1E +1E 42 B2 1E 3D F3 3E F0 FF 00 3F 40 00 08 B0 13 +3C DD 1C 52 38 1F 1F 42 A6 1E 8F 4C 0A 00 1F 42 +A6 1E 9F 42 38 1F 0C 00 1F 42 A6 1E CF 43 14 00 +1F 42 A6 1E CF 43 15 00 1F 42 A6 1E 8F 93 02 00 +05 20 8F 93 00 00 02 20 EF D2 1A 00 1D 42 A6 1E +1E 42 B0 1E 1F 42 B2 1E 3E F3 3F F0 FF 00 8D 4E +00 00 8D 4F 02 00 1F 42 A6 1E 9F 43 18 00 CC 0A +B0 13 86 CB 5C 43 0A 16 10 01 3A 14 07 4F 07 ED +0A 4F 5A 02 8A 10 4A 4A 0A 93 49 24 7F D0 80 00 +0B 4D 5B 02 8B 10 4B 4B 0B 93 3F 24 7D D0 80 00 +0B 5A 3B 80 7F 00 08 43 09 43 0E 93 09 24 1A 43 +5E 00 02 28 08 5C 09 6D 59 00 58 00 5A 02 F8 2B +0E 43 1A 43 5F 00 02 28 08 5C 09 6D 59 00 58 00 +5E 00 3E B0 00 10 02 24 3E D0 00 20 4A 5A F2 23 +49 93 02 34 1B 53 03 3C 0E 6E 08 68 49 69 3E B0 +00 80 07 24 08 63 49 63 0B 63 3E B0 00 60 01 20 +18 C3 1B 93 0C 38 3B 90 FF 00 0C 34 49 59 8B 10 +09 DB 57 02 59 00 0D 49 0C 48 37 16 10 01 0C 43 +0D 43 FB 3F 3D 40 FF FE 3C 43 57 02 5D 00 F5 3F +CF 0D CD 0E CE 0C C2 93 59 1E 06 20 B0 13 58 F2 +4C 93 02 20 2C 43 10 01 2E 83 2C 24 1E 83 43 24 +2E 83 20 24 1E 83 3B 24 3E 80 03 00 34 24 1E 83 +30 20 0E 43 8D 93 00 00 09 20 0F 93 2A 20 1C 4D +02 00 1D 4D 04 00 B0 13 EC F2 31 3C 1C 43 2C 9D +20 20 0F 93 1E 20 1C 4D 02 00 1D 4D 04 00 B0 13 +DA F2 25 3C 3F B0 FE FF 14 20 CC 0F B0 13 9A F0 +CE 0C 1D 3C 3F 90 03 00 07 24 2F 93 0A 20 CC 0D +B0 13 D8 E7 CE 0C 13 3C CC 0D B0 13 8E DA CE 0C +0E 3C 2E 43 0C 3C B0 13 04 F5 CE 0C 08 3C B0 13 +08 F5 CE 0C 04 3C CC 0F B0 13 2E D6 CE 0C CC 0E +10 01 0A 14 31 80 06 00 B0 13 20 F3 2E 42 CF 01 +1F 53 3D 40 9A 1D 1F 53 FF 4D FF FF 1E 83 FB 23 +3C 40 05 00 0D 43 CE 01 1E 53 B0 13 00 C3 D2 43 +78 1D 4A 43 B0 13 F0 E8 0C 93 08 24 B0 13 48 C4 +1A 2C F2 B0 20 00 78 1D F5 27 1F 3C E1 43 00 00 +3C 40 03 00 3D 40 0A 00 CE 01 B0 13 00 C3 4A 43 +B0 13 F8 F4 0C 93 04 20 E2 43 78 1D 5C 43 10 3C +B0 13 48 C4 06 28 C2 43 59 1E E2 42 78 1D 4C 43 +07 3C F2 B0 20 00 78 1D EB 27 C2 43 59 1E 4C 43 +31 50 06 00 0A 16 10 01 3C 40 E8 03 B0 13 30 F3 +B2 40 2B 5A 5C 01 CF 0A 1A 43 4A 5F 7F 90 0B 00 +10 01 31 80 0E 00 CE 01 3D 40 00 18 4F 43 1E 53 +FE 4D FF FF 5F 53 7F 90 0D 00 F9 2B F1 93 00 00 +30 24 5F 41 01 00 C2 4F 94 1E 3F 90 15 00 05 38 +3F 90 EC 00 02 34 C2 43 94 1E 5F 41 04 00 47 18 +0F 5F 5E 41 05 00 0E 5F 82 4E 2E 1F D2 41 06 00 +9A 1D D2 41 07 00 9B 1D D2 41 08 00 9C 1D D2 41 +09 00 9D 1D F1 93 0C 00 08 24 5F 41 0A 00 47 18 +0F 5F 5E 41 0B 00 0E 5F 01 3C 0E 43 82 4E 84 1E +13 3C E2 42 94 1E B2 40 F6 FF 2E 1F F2 40 79 00 +9A 1D F2 40 56 00 9B 1D F2 40 34 00 9C 1D F2 40 +12 00 9D 1D 82 43 84 1E 31 50 0E 00 10 01 21 83 +5F 42 92 1C 1D 42 90 1C 4C 4F 3E 40 FE 9D 0E 8C +0D 9E 02 2C 4B 43 09 3C 81 4D 00 00 2E 41 3F 40 +FE 00 4F 8E C2 4F 92 1C 5B 43 4E 43 15 3C 4F 4E +5D 4F 93 1C 5E 53 4F 4E 5F 4F 93 1C 47 18 0F 5F +0D 5F 5E 53 1C 42 90 1C CF 0C 2F 53 82 4F 90 1C +B0 13 72 EA 5F 42 92 1C 4D 4F 1D 83 4C 4E 0C 9D +E6 3B 4B 93 0C 20 5F B3 03 20 C2 43 92 1C 1A 3C +4F 4F D2 4F 92 1C 93 1C D2 43 92 1C 13 3C 3C 40 +FE 9D 3D 40 FE FF B0 13 72 EA C2 43 92 1C 5F 42 +8C 1C 5F C3 6F D3 C2 4F 8C 1C 7C 40 15 00 6D 42 +B0 13 08 F0 21 53 10 01 1A 14 21 82 CA 0C F2 B0 +40 00 01 02 42 24 B0 13 7E DB 82 4C 7C 1E 1C 52 +80 1E 3C 80 A1 0A 82 4C 7E 1E B0 13 9A D3 81 4C +00 00 81 4D 02 00 4A 93 03 20 B0 13 50 C6 27 3C +2C 41 1D 41 02 00 B0 13 B2 E6 3E 40 CD CC 3F 40 +4C 3E B0 13 4A C2 C9 0C CA 0D 1C 42 78 1E 1D 42 +7A 1E B0 13 B2 E6 3E 40 CD CC 3F 40 4C 3F B0 13 +4A C2 CE 0C CF 0D CC 09 CD 0A B0 13 C2 B0 B0 13 +CA DB 81 4C 00 00 81 4D 02 00 B0 13 50 C6 1E 42 +7C 1E B0 13 00 9E 82 4C 82 1E 21 52 19 16 10 01 +1C 41 04 00 1D 41 06 00 82 4C 78 1E 82 4D 7A 1E +10 01 1A 14 21 82 39 40 CB 00 3C 40 00 40 B0 13 +3C DA 3C 40 03 00 3D 40 05 00 0E 43 B0 13 00 C3 +D1 43 02 00 C1 49 03 00 CC 01 2C 53 6D 43 B0 13 +68 D2 3C 40 03 00 3D 42 0E 43 B0 13 00 C3 3C 40 +0A 00 B0 13 30 F3 CC 01 B0 13 F4 DC 0C 93 18 20 +C1 93 00 00 F8 27 B0 13 12 AA 4A 43 5A 92 9E 1D +F2 2F 3C 40 0A 00 B0 13 30 F3 4C 4A B0 13 3A B4 +3C 40 7A 1D 7D 40 13 00 B0 13 68 D2 5A 53 EE 3F +3C 40 03 00 2D 42 0E 43 B0 13 00 C3 B2 40 2B 5A +5C 01 F2 B0 20 00 78 1D B8 27 C2 43 59 1E 21 52 +19 16 10 01 5A 14 C6 0F C7 0E C5 0D C9 0C 18 41 +1C 00 C7 43 00 00 B0 13 2E BB CA 0C 0A 93 02 20 +2C 42 3C 3C 1F 43 2F 99 02 24 09 43 09 3C 5C 49 +02 00 B0 13 42 EB C9 0C 09 93 02 20 2C 43 2E 3C +5E 4A 02 00 7E 80 0B 00 C7 4E 00 00 3D 40 0E 00 +0D 5A 4E 4E CC 05 B0 13 A4 F2 09 93 06 24 D9 4A +21 00 07 00 D9 4A 22 00 08 00 06 93 07 24 3D 40 +07 00 0D 5A CC 06 2E 42 B0 13 A4 F2 08 93 06 24 +3F 40 07 00 5F FA 0C 00 C8 4F 00 00 5D 4A 01 00 +5C 43 B0 13 48 E9 CA 43 00 00 0C 43 55 16 10 01 +4F 43 4C 93 2D 24 5C 93 20 24 6C 93 13 24 7C 90 +03 00 2A 20 A2 D2 22 03 A2 C2 24 03 B2 C2 22 03 +B0 13 1C F5 B0 13 2E C8 1F 42 20 03 6F F2 B2 C2 +22 03 1A 3C A2 D2 24 03 B0 13 1C C8 B0 13 2E C8 +A2 D2 22 03 B0 13 1C F5 0F 3C A2 D2 24 03 B2 C2 +22 03 A2 D2 22 03 B0 13 1C F5 B0 13 12 C8 04 3C +A2 D2 24 03 B0 13 12 C8 4C 43 4F 93 01 20 5C 43 +10 01 B0 13 2E C8 B0 13 1C C8 10 01 A2 C2 22 03 +B0 13 1C F5 B2 C2 22 03 B0 13 1C F5 10 01 B2 D2 +22 03 B0 13 1C F5 10 01 1A 14 CB 0C 7B 90 BD 00 +07 24 4C 43 7B 90 31 00 40 28 7B 90 3D 00 3D 2C +0A 42 32 C2 03 43 B2 F0 BF FF 02 0F B2 B0 10 00 +02 0F FC 27 7B 90 3D 00 26 2C 4C 43 B0 13 B0 F1 +C9 0C 4C 43 7D 40 29 00 B0 13 04 E4 C2 4B 11 0F +A2 B2 30 0F 13 24 7B 90 32 00 10 24 7B 90 39 00 +0D 24 7B 90 38 00 0A 24 A2 B2 30 0F FD 23 0D 14 +3D 40 BF 0C 1D 83 FE 23 0D 16 03 43 4C 43 CD 09 +B0 13 04 E4 03 3C F2 40 BD 00 11 0F 5C 42 21 0F +B2 B0 40 00 02 0F FC 27 02 4A 19 16 10 01 3A 14 +07 4F 07 ED 0A 4F 5A 02 8A 10 4A 4A 0A 93 38 24 +7F D0 80 00 0B 4D 5B 02 8B 10 4B 4B 0B 93 2B 24 +7D D0 80 00 0B 8A 3B 50 7F 00 3A 40 18 00 08 43 +09 43 0C 8E 0D 7F 03 2C 0C 5E 0D 6F 12 C3 08 68 +09 69 5C 02 0D 6D 1A 83 F4 23 49 93 03 30 1A 53 +1B 83 EF 3F 0C 7E 0D 7F 08 63 49 63 0B 63 1B 93 +0C 38 3B 90 FF 00 0C 34 49 59 8B 10 09 DB 57 02 +59 00 0D 49 0C 48 37 16 10 01 0C 43 0D 43 FB 3F +3C 40 FF FE 3D 43 57 02 5D 00 F5 3F 2A 14 21 83 +C9 0C 3F 40 0B 00 0F 59 68 4F 3A 40 3F 00 4A F8 +3C 40 07 00 0C 59 1D 42 C6 1E 2E 42 B0 13 54 ED +0C 93 2D 24 78 B0 40 00 2A 20 4A 93 10 24 7A 90 +07 00 0D 2C 4A 4A 5A 06 00 18 5F 4A 3E FA 2C 43 +0C 59 4F 13 1C 93 1B 20 D9 43 00 00 1A 3C 7A 90 +3F 00 03 24 7A 90 20 00 12 28 2C 43 0C 59 CD 01 +B0 13 E8 C9 4C 93 0B 24 D9 43 00 00 00 18 C2 93 +CA 1E 07 24 6C 41 80 13 CA 1E 4C 93 02 24 C9 43 +00 00 21 53 28 16 10 01 4A 14 C7 0D C8 0C 39 40 +41 1E 3A 40 3F 00 5A F8 09 00 26 43 2F 43 6F 99 +32 20 5A 99 09 00 2F 20 7A 90 3F 00 0B 24 3C 40 +03 00 0C 59 3D 40 05 00 0D 58 2E 42 B0 13 54 ED +0C 93 21 20 D7 49 0B 00 00 00 57 43 7A 90 3F 00 +16 24 3F 40 0A 00 0F 58 6F 4F 7F B0 80 FF 0A 20 +7F B2 0D 24 D9 98 0B 00 02 00 02 20 C9 43 02 00 +47 43 05 3C 5D 49 0A 00 CC 08 B0 13 90 CD B0 13 +A8 F3 CC 07 05 3C 39 50 0C 00 16 83 C7 23 4C 43 +46 16 10 01 4A 14 C9 0F C7 0E C6 0D CA 0C 6C 43 +B0 13 84 CE C8 0C 08 93 02 20 0C 43 36 3C CF 07 +7F 50 0B 00 C8 4F 02 00 3E 40 0B 00 0E 58 3F 40 +80 00 6F FE 4F DA CE 4F 00 00 D8 42 C4 1E 0D 00 +D2 53 C4 1E FD 27 F8 F0 BF 00 0C 00 5F 48 0C 00 +7F F0 F8 00 4F D9 C8 4F 0C 00 F8 F0 7F 00 0C 00 +F8 C2 0C 00 FE F0 7F 00 00 00 3C 40 0E 00 0C 58 +4E 47 CD 06 B0 13 A4 F2 3C 40 07 00 0C 58 1D 42 +C6 1E 2E 42 B0 13 A4 F2 CC 08 46 16 10 01 5C 43 +B0 13 D4 D5 5C 43 6D 42 80 13 8C 1E B0 13 E4 E6 +7C 40 17 00 6D 43 B0 13 08 F0 7C 40 18 00 6D 43 +B0 13 08 F0 7C 40 19 00 6D 43 B0 13 08 F0 B0 13 +FE F2 B2 40 03 00 72 1D B2 40 10 0E 74 1D B0 13 +B2 C3 4C 93 02 24 B0 13 62 C6 82 43 72 1D B0 13 +40 F3 3C 40 00 20 B0 13 3C DA C2 43 1D 02 82 43 +D8 1E 7C 40 17 00 6D 42 B0 13 08 F0 7C 40 18 00 +6D 42 B0 13 08 F0 7C 40 19 00 6D 42 B0 13 08 F0 +92 D3 14 1D 10 01 1F 42 A6 1E CF 43 11 00 1F 42 +A6 1E DF 42 B3 1E 13 00 1F 42 A6 1E 5E 42 38 1F +5E 8F 0C 00 CF 4E 16 00 1F 42 A6 1E 5E 4F 16 00 +8E 11 8F 5E 0A 00 1F 42 A6 1E DF 5F 16 00 15 00 +1F 42 A6 1E DF 42 3A 1F 12 00 1F 42 A6 1E FF 92 +12 00 02 2C FF 42 12 00 1F 42 A6 1E 9F 42 B4 1E +04 00 9F 42 B6 1E 06 00 1F 42 A6 1E DF 42 B8 1E +0E 00 1F 42 A6 1E EF B2 1A 00 03 20 4D 43 B0 13 +2A E1 B0 13 7A D5 D2 C3 36 1F 10 01 0A 14 5F 42 +32 1F 3F 90 07 00 0E 34 3F 90 06 00 31 24 1F 83 +32 24 1F 83 14 24 1F 83 2E 24 1F 83 29 24 1F 83 +2A 24 2C 3C 3F 80 07 00 2F 93 25 28 2F 83 20 24 +1F 83 21 24 1F 83 1C 24 1F 83 1D 24 1F 3C 1A 42 +34 1F 3A B0 03 00 0E 20 CC 0A 3D 40 64 00 B0 13 +DC F1 0E 93 0A 20 CC 0A 3D 40 90 01 B0 13 DC F1 +0E 93 03 24 7C 40 1C 00 0A 3C 7C 40 1D 00 07 3C +7C 40 1E 00 04 3C 7C 40 1F 00 01 3C 4C 43 0A 16 +10 01 3C 40 3D 1E 0D 43 3E 40 1C 00 B0 13 B6 F2 +E2 43 3D 1E F2 40 3D 00 3E 1E F2 40 20 00 3F 1E +D2 43 40 1E B0 13 76 EC B0 13 50 EF B0 13 7E F0 +B0 13 56 F4 B0 13 6A EB B0 13 4C F4 B0 13 A8 E7 +3F 40 41 1E CF 43 00 00 3F 50 0C 00 CF 43 00 00 +C2 93 4D 1E 15 20 E2 43 4D 1E F2 40 03 00 4E 1E +7F 40 3F 00 C2 4F 56 1E C2 4F 57 1E F2 43 58 1E +B0 13 EC F4 CD 0C 3C 40 50 1E 2E 42 B0 13 A4 F2 +0C 43 10 01 1E 42 A6 1E 5F 4E 15 00 8F 11 3F 90 +40 00 0B 34 3F 90 C1 FF 14 34 FE 50 40 00 15 00 +1F 42 A6 1E 9F 83 08 00 07 3C FE 80 40 00 15 00 +1F 42 A6 1E 9F 53 08 00 1F 42 A6 1E 5F 4F 15 00 +8F 11 1E 42 A6 1E CE 5F 14 00 1E 42 A6 1E 5F 4E +14 00 8F 11 3F 90 40 00 0B 34 3F 90 C1 FF 0F 34 +FE 50 40 00 14 00 1F 42 A6 1E 9F 83 0A 00 10 01 +FE 80 40 00 14 00 1F 42 A6 1E 9F 53 0A 00 10 01 +1A 14 31 80 22 00 C9 0D 5A 4C 0B 00 3F 40 CF 00 +5F F1 0A 00 5F D2 C8 1E 7F F0 BF 00 C1 4F 0A 00 +3D 40 05 00 0D 5C CC 01 1C 53 2E 42 B0 13 A4 F2 +CC 01 3C 50 05 00 1D 42 C6 1E 2E 42 B0 13 A4 F2 +3D 40 C0 00 5D F1 09 00 4D D9 F1 40 0B 00 00 00 +C1 4A 0B 00 3F 40 70 00 5F F1 0A 00 7F D0 0B 00 +C1 4F 0A 00 7D F0 3F 00 C1 4D 09 00 CC 01 4D 43 +B0 13 50 BF 31 50 22 00 19 16 10 01 21 82 F2 F0 +BF 00 05 02 F2 F0 BF 00 19 02 B2 D0 0C 00 22 03 +B2 D0 0C 00 24 03 C2 43 FE 1D 3C 40 CC 0C B0 13 +3C DA 7C 40 06 00 5D 43 B0 13 EA D7 C1 4C 00 00 +3C 40 CC 0C B0 13 3C DA 7C 40 07 00 4D 43 B0 13 +DE CF C1 4C 01 00 D1 B3 01 00 12 20 C1 93 01 00 +0F 24 7C 40 7F 00 4D 43 B0 13 DE CF C1 4C 02 00 +D1 93 02 00 03 24 C2 43 FE 1D 02 3C D2 43 FE 1D +21 52 10 01 2A 14 5C 93 03 20 3F 40 00 1C 02 3C +3F 40 46 1C 2D 43 08 43 CB 08 4E 43 79 40 03 00 +CF 93 00 00 06 20 6C 93 02 20 CC 0F 24 3C CB 0F +0C 3C 5C 93 0A 20 5E 53 2A 42 6A 9F 06 24 5A 4F +01 00 4A 99 02 2C C8 0F C9 0A 3F 50 23 00 1D 83 +E7 23 0B 93 0C 20 08 93 02 20 0C 43 0C 3C CB 08 +5D 4B 01 00 B0 13 48 E9 EB 43 01 00 03 3C 5E 53 +CB 4E 01 00 CC 0B 28 16 10 01 1A 14 CF 0E CA 0C +7A 90 1A 00 31 28 7A 90 2A 00 2E 2C 4E 4A 5E 02 +1C 4E 16 1D 4E 4A 5E 4E AC F9 7D 90 30 00 05 2C +7D 90 2D 00 05 20 6B 43 08 3C 7D 90 5B 00 02 28 +4B 43 03 3C 4B 4D 5B 4B 50 F9 7A 90 21 00 11 28 +C9 0B 43 18 49 59 43 19 4B 10 4B D9 7A 90 21 00 +08 20 7D 90 31 00 03 24 7D 90 4C 00 02 20 7B 40 +80 00 CD 0B B0 13 C0 D4 19 16 10 01 0A 14 CE 0C +0B 42 32 C2 03 43 B2 F0 BF FF 02 0F B2 B0 10 00 +02 0F FC 27 7E 90 31 00 23 28 7E 90 3D 00 20 2C +4C 43 B0 13 0E DE CA 0C 4C 43 7D 40 29 00 B0 13 +B4 E5 C2 4E 11 0F A2 B2 30 0F 0D 24 7E 90 32 00 +0A 24 7E 90 38 00 07 24 A2 B2 30 0F FD 23 3C 40 +F8 02 B0 13 06 F1 4C 43 CD 0A B0 13 B4 E5 02 3C +C2 4E 11 0F 5C 42 21 0F 02 4B 0A 16 10 01 0A 14 +CB 0D CA 0C 4C 43 B0 13 A0 C7 7C 40 22 00 B0 13 +40 D0 0C 24 CC 0A B0 13 40 D0 08 24 5C 43 B0 13 +A0 C7 7C 40 23 00 B0 13 40 D0 02 20 0C 43 16 3C +5B 93 05 24 4C 43 B0 13 E0 DA 4D 4C 0B 3C 5C 43 +B0 13 E0 DA 4C 4C 4D 4C 8D 10 4C 43 B0 13 E0 DA +4C 4C 0D DC 6C 43 B0 13 A0 C7 CC 0D 0A 16 10 01 +B0 13 EC DF 7C 40 03 00 B0 13 A0 C7 4C 93 10 01 +7C 40 36 00 B0 13 38 C8 4C 43 3D 40 D6 F9 7E 40 +27 00 B0 13 DE DE 7C 40 2C 00 7D 40 88 00 B0 13 +04 E4 7C 40 2D 00 7D 40 31 00 B0 13 04 E4 7C 40 +2E 00 7D 40 09 00 B0 13 04 E4 7C 40 36 00 B0 13 +38 C8 7C 40 33 00 B0 13 38 C8 7C 40 3D 00 B0 13 +38 C8 7C B0 70 00 F9 23 7C 40 36 00 B0 13 38 C8 +82 43 1E 1F B2 D0 01 02 34 0F 82 43 32 0F 10 01 +7C 40 36 00 B0 13 38 C8 F2 B0 10 00 36 1F 1F 24 +7C 40 0A 00 5D 42 FA 1E B0 13 04 E4 F2 90 7F 00 +FB 1E 03 38 7D 40 0C 00 02 3C 5D 42 FB 1E 7C 40 +0C 00 B0 13 04 E4 F2 B2 36 1F 03 20 7D 40 11 00 +02 3C 7D 40 15 00 7C 40 12 00 B0 13 04 E4 7C 40 +34 00 B0 13 38 C8 B2 F0 FE FD 32 0F B2 F0 FE FD +32 0F B2 D0 01 02 36 0F A2 43 1E 1F 10 01 0A 14 +CA 0D CB 0C 7B 93 02 24 CF 0B 02 3C 4B 43 4F 43 +4E 4B 4F 4F 0F 8E 1F 53 4C 4B 3D 40 1C 00 B0 13 +F2 F1 1C 52 64 FA 4A 93 09 24 8C 43 00 00 8C 43 +02 00 CC 43 1A 00 FC 40 7F 00 10 00 8C 43 18 00 +FC F0 FC 00 1A 00 8C 43 04 00 8C 43 06 00 CC 43 +0E 00 CC 43 12 00 CC 43 0F 00 CC 43 11 00 5B 53 +1F 83 DA 23 0A 16 10 01 B0 13 3A D7 5C 06 3D 40 +29 00 B0 13 DC F1 1F 42 2E 1F 0F 5C 3F 90 69 01 +03 2C 1C 42 2C 1F 03 3C 1C 42 2C 1F CF 0C 5C 06 +0C 5F 5C 02 3D 40 0A 00 B0 13 DC F1 82 4C 2C 1F +3C 90 F0 00 08 28 B2 F0 DF FF 86 1E 7C 42 4D 43 +B0 13 08 F0 07 3C B2 D0 20 00 86 1E 7C 42 5D 43 +B0 13 08 F0 B2 D2 14 1D B2 D0 80 00 14 1D 10 01 +1A 14 21 82 CA 0C 3C 40 05 00 0C 5A 5D 4A 0E 00 +B0 13 18 E3 0C 93 02 20 3F 42 03 3C B0 13 E6 F4 +0F 43 F1 40 82 00 00 00 D1 4A 0D 00 01 00 C1 4F +02 00 6C 43 CD 01 7E 40 03 00 7F 40 03 00 B0 13 +74 CA C9 0C 09 93 0D 24 3C 40 03 00 0C 59 3D 40 +05 00 0D 5A 2E 42 B0 13 A4 F2 CC 09 4D 43 B0 13 +08 E8 21 52 19 16 10 01 2A 14 C8 0D C9 0C 5C 42 +FF 1D B0 13 42 EB CA 0C B0 13 D4 F4 0A 93 24 24 +CC 0A 5D 43 B0 13 50 EC 0C 93 1F 20 09 93 1D 24 +5C 4A 0A 00 5F 4A 01 00 CD 09 CE 08 B0 13 74 CA +C9 0C 09 93 0E 24 3C 40 03 00 0C 59 3D 40 03 00 +0D 5A 2E 42 B0 13 A4 F2 CC 09 5D 43 B0 13 08 E8 +04 3C 3C 40 03 00 01 3C 2C 43 28 16 10 01 0E 42 +32 C2 03 43 4C 93 2C 24 4F 4C 3F 50 00 7E B2 B0 +10 00 02 0F FC 27 82 4F 10 0F B2 B0 10 00 02 0F +FC 27 F2 40 3D 00 11 0F B2 B0 10 00 02 0F FC 27 +F2 40 FE 00 11 0F B2 B0 20 00 02 0F FC 27 C2 43 +10 0F B2 B0 80 00 02 0F FC 27 5D 42 20 0F B2 B0 +10 00 02 0F FC 27 F2 40 3D 00 11 0F 4D 9C D7 23 +02 4E 10 01 0A 14 CA 0D 6A 92 1A 24 B0 13 E4 F3 +4C 93 08 20 7C 40 47 00 3D 40 0A F9 5E 43 B0 13 +E0 BC 0E 3C 5C 42 C2 1E 0D 43 7E 40 03 00 6F 43 +B0 13 DC C0 CD 0C 7C 40 47 00 5E 43 B0 13 E0 BC +B0 13 E4 F3 4C 93 0F 20 5A 93 08 24 6A 92 0B 20 +7C 40 13 00 4D 43 B0 13 08 F0 05 3C 7C 40 13 00 +5D 43 B0 13 08 F0 0A 16 10 01 21 82 81 43 00 00 +81 43 02 00 7C 40 7F 00 4D 43 B0 13 DE CF 81 4C +00 00 81 43 02 00 2C 41 1F 41 02 00 47 18 0C 5C +0D 43 3C F0 00 07 0D F3 B0 13 00 E2 81 4C 00 00 +81 4D 02 00 7C 40 80 00 5D 43 B0 13 DE CF 81 DC +00 00 12 C3 11 10 02 00 11 10 00 00 12 C3 11 10 +02 00 11 10 00 00 2C 41 1D 41 02 00 21 52 10 01 +1F 42 38 0F 1E 42 0E 0F 0E 93 14 20 0F 93 28 24 +3F 90 14 00 0C 20 B2 B0 00 02 36 0F 03 20 32 C2 +03 43 FF 3F B2 F0 FF FD 32 0F 80 00 6C B8 32 C2 +03 43 FF 3F 2E 93 11 20 1F 42 0C 0F 2F 93 0A 24 +2F 92 08 24 3F 90 06 00 05 24 3F 92 03 24 32 C2 +03 43 FF 3F 32 C2 03 43 FF 3F 32 C2 03 43 FF 3F +10 01 B2 F0 FE FD 36 0F B2 F0 FE FD 32 0F B2 F0 +FE FD 32 0F 92 43 1E 1F 7C 40 32 00 B0 13 B0 F1 +C2 4C 20 1F 7C 43 3D 40 B0 1E 7E 40 0A 00 B0 13 +9A DE 7C 43 B0 13 B0 F1 C2 4C 3A 1F 7C B0 80 FF +04 20 F2 80 80 00 3A 1F 03 3C F2 F0 7F 00 3A 1F +1F 42 22 1F 3F 80 10 00 82 4F 38 1F 80 00 EC E0 +5F 93 20 24 4F 93 1B 24 6F 93 12 24 7F 90 03 00 +05 24 6F 92 1C 20 B0 13 10 D5 10 01 4E 4E 3E E3 +CF 0E 6F FC 4D DF CC 4D 00 00 CC FE 20 00 10 01 +B0 13 10 D5 CC DD 00 00 CC DD 20 00 10 01 CC CE +00 00 10 01 6F 4C 4F CE 4D DF CC 4D 00 00 10 01 +4E 4E 3E E3 CC FE 00 00 CC FE 20 00 10 01 92 53 +96 1E 82 63 98 1E 1F 43 5F 52 A2 1E 3F 90 3C 00 +1F 20 C2 43 A2 1E 1F 43 5F 52 A1 1E 3F 90 3C 00 +12 20 C2 43 A1 1E 1F 43 5F 52 A0 1E F2 40 03 00 +9E 1E 3F 90 18 00 03 24 C2 4F A0 1E 10 01 C2 43 +A0 1E 80 00 2E E0 C2 4F A1 1E E2 43 9E 1E 10 01 +C2 4F A2 1E D2 43 9E 1E 10 01 0A 14 1F 42 A6 1E +DF 53 13 00 B0 13 14 CD 1F 42 A6 1E 1E 4F 08 00 +1E 5F 0A 00 8F 4E 0C 00 1F 42 A6 1E 9F 4F 0C 00 +0A 00 1A 42 A6 1E CF 0A 5C 4F 13 00 2D 4F 1E 4F +02 00 3F 40 00 08 B0 13 3C DD 8A 8C 0C 00 1F 42 +A6 1E CF 43 0F 00 1F 42 A6 1E FF F0 FC 00 1A 00 +0A 16 10 01 0A 14 CA 0C 7D 40 46 00 7E 40 5A 00 +B0 13 2C F4 0D 43 4E 43 B0 13 E0 BC 5A 93 0D 24 +7C 40 29 00 B0 13 26 D6 7C 40 27 00 B0 13 26 D6 +7C 40 28 00 B0 13 26 D6 0C 3C 7C 40 1F 00 B0 13 +26 D6 7C 40 20 00 B0 13 26 D6 7C 40 1E 00 B0 13 +26 D6 0A 16 10 01 4D 43 B0 13 08 F0 10 01 0A 14 +0A 43 2C 92 22 24 3C 90 05 00 1C 24 3C 92 17 24 +3C 90 0A 00 12 20 2F 4D 0F 93 0A 24 1F 83 06 24 +1F 83 02 24 2C 43 16 3C 6C 43 03 3C 5C 43 01 3C +4C 43 B0 13 EC F0 0C 43 0D 3C 2A 43 0A 3C B0 13 +F0 EE 07 3C B0 13 06 EE 04 3C B0 13 D0 EE B0 13 +30 ED CC 0A 0A 16 10 01 C2 93 76 1E 29 20 C2 93 +FE 1D 07 20 7C 40 47 00 3D 40 FE F8 5E 43 80 00 +E0 BC F2 F0 BF 00 1D 02 F2 D0 40 00 1B 02 B0 13 +20 F4 D2 43 76 1E 7E 40 0F 00 07 3C 4E 93 0B 24 +3C 40 CC 0C B0 13 3C DA 5E 83 F2 B0 40 00 01 02 +F5 27 4E 93 02 20 C2 43 76 1E 4C 43 80 00 B8 C5 +10 01 1A 14 C9 0C 79 93 02 24 CA 09 02 3C 49 43 +4A 43 4F 49 4A 4A 0A 8F 1A 53 CC 09 B0 13 E8 EC +0C 93 09 20 4C 49 3D 40 1C 00 B0 13 F2 F1 1C 52 +64 FA B0 13 98 D9 59 53 1A 83 EF 23 E2 B3 36 1F +0A 24 B0 13 38 F4 4C 93 06 20 D2 C3 36 1F B0 13 +10 F3 B0 13 C8 F4 19 16 10 01 B2 D0 91 00 B0 01 +B2 40 10 0A 00 07 B2 40 00 02 02 07 F2 40 1B 00 +10 07 92 43 0C 07 2C 43 B0 13 3C DA A2 D3 00 07 +C2 43 46 1F 92 D3 00 07 3C 40 05 00 B0 13 3C DA +C2 93 46 1F FD 27 B2 F0 FC F5 00 07 B2 F0 EF FF +00 07 B2 F0 6E FF B0 01 82 43 0C 07 1C 42 44 1F +10 01 B2 40 44 F8 40 1F B2 40 9E F8 42 1F 00 18 +D2 42 4C F8 8C 1E 00 18 D2 42 A6 F8 90 1E 82 43 +D8 1E 82 43 86 1E 82 43 88 1E 82 43 14 1D 82 43 +8A 1E 92 D3 14 1D B0 13 62 C4 B0 13 9C ED B0 13 +6C F2 B0 13 6A F4 B0 13 22 DF B0 13 C6 F1 B0 13 +F2 F4 B0 13 8E F3 80 00 38 E8 0A 14 21 83 CA 0D +CB 0C 4C 43 B0 13 A0 C7 7C 40 22 00 B0 13 26 D8 +0E 24 CC 0B B0 13 26 D8 0A 24 CC 0A B0 13 34 D8 +C1 4C 00 00 6C 43 B0 13 A0 C7 5C 43 01 3C 4C 43 +21 53 0A 16 10 01 B0 13 34 D8 C1 4C 04 00 C1 93 +04 00 10 01 B0 13 EC DF 7C 40 03 00 B0 13 A0 C7 +10 01 0A 14 09 14 09 43 0A 43 1B 43 0F 93 04 24 +09 4D 0D 4C 0C 43 0D 3C 5C 02 0D 6D 09 69 09 8E +04 28 1C D3 5B 02 F8 2B 03 3C 09 5E 5B 02 F4 2B +1B 43 5C 02 0D 6D 09 69 0A 6A 09 8E 0A 7F 04 28 +1C D3 5B 02 F6 2B 04 3C 09 5E 0A 6F 5B 02 F1 2B +0E 49 0F 4A 09 16 0A 16 10 01 0A 14 7C 40 23 00 +B0 13 B0 F1 CA 0C 7A D0 20 00 CD 0A 7C 40 23 00 +B0 13 04 E4 7C 40 C4 00 B0 13 CE D2 7C 40 33 00 +B0 13 38 C8 7C 40 3D 00 B0 13 38 C8 7C B0 70 00 +F9 23 3D 40 DF 00 4D FA 7C 40 23 00 B0 13 04 E4 +7C 40 36 00 B0 13 38 C8 82 43 1E 1F 0A 16 10 01 +4F 14 1F 42 6E 03 2F 83 1E 24 2F 82 0B 24 2F 83 +1C 20 B2 F0 EF FF 4A 03 92 C3 4A 03 B2 D0 80 00 +86 1E 13 3C B2 F0 EF FF 48 03 92 C3 48 03 1F 42 +50 03 1F 52 1A 1F 82 4F 58 03 B2 D0 10 00 48 03 +80 13 16 1F 02 3C B0 13 DC E2 B1 C0 D0 00 14 00 +4B 16 00 13 B2 B0 20 00 86 1E 25 20 B0 13 E4 F3 +4C 93 21 20 B0 13 FC F3 4C 93 1D 20 D2 53 EB 1E +E2 93 EB 1E 18 20 4C 43 4D 43 B0 13 08 F0 5C 43 +B0 13 D4 D5 7C 40 5A 00 3D 40 E2 F8 5E 43 B0 13 +E0 BC 7C 40 46 00 3D 40 0E F9 5E 43 B0 13 E0 BC +3F 40 00 10 C0 0F 10 01 AC 43 18 00 FC F0 FC 00 +1A 00 CC 43 12 00 5F 42 AC 1E C2 93 AD 1E 06 24 +5E 42 AC 1E 12 C3 4E 10 4E 11 4F 8E CC 4F 13 00 +E2 B3 36 1F 11 20 F2 D0 06 00 36 1F B0 13 9C F3 +82 4C A4 1E C2 93 AD 1E 04 20 B2 50 E0 7F A4 1E +10 01 B2 50 C0 53 A4 1E 10 01 2A 14 1A 41 10 00 +49 4C 1B 42 A6 1E 1B 4B 0C 00 0B 89 3B 80 32 00 +28 4D C9 0B 09 88 09 93 02 38 28 9E 15 20 8D 4B +00 00 1D 42 A6 1E 4C 4C 1C 5D 0C 00 3C 50 10 00 +8E 4C 00 00 1E 42 A6 1E DF 4E 0F 00 00 00 1F 42 +A6 1E DA 4F 10 00 00 00 28 16 10 01 B2 B0 30 00 +40 03 24 24 B2 F0 EF FF 4A 03 B2 F0 7F FF 86 1E +82 93 50 03 02 20 0F 43 05 3C 1F 42 50 03 1F 92 +50 03 FB 23 0F 5C 82 4F 5A 03 92 C3 4A 03 B2 D0 +10 00 4A 03 B0 13 A8 F4 B2 40 2B 5A 5C 01 32 C2 +03 43 B2 B0 80 00 86 1E F5 27 32 D2 10 01 1A 14 +CA 0C 5C 4A 05 00 CF 0C 3F 80 03 00 06 24 2F 83 +2F 93 03 28 7F 40 03 00 01 3C 5F 43 4C 4C 1D 4A +02 00 5E 4A 04 00 B0 13 74 CA C9 0C 09 93 0C 24 +3C 40 03 00 0C 59 2D 4A 2E 42 B0 13 A4 F2 CC 09 +5D 43 B0 13 08 E8 02 3C 3C 40 03 00 19 16 10 01 +A2 D2 22 03 A2 C2 24 03 3E 42 4F 43 B2 C2 22 03 +B0 13 24 DB 4F 5F A2 B2 20 03 01 24 5F D3 1E 83 +F5 23 A2 D2 24 03 B2 C2 22 03 5C 93 03 24 A2 D2 +22 03 02 3C A2 C2 22 03 B0 13 24 DB B2 C2 22 03 +CC 0F 10 01 B0 13 1C F5 B2 D2 22 03 B0 13 1C F5 +10 01 D2 B3 36 1F 1D 24 A2 93 A8 1E 1A 24 1F 42 +A6 1E 2C 4F 1D 4F 02 00 0D 93 08 20 0C 93 06 20 +82 93 A8 1E 0E 20 92 43 A8 1E 0F 3C 1E 42 B0 1E +1F 42 B2 1E 3E F3 3F F0 FF 00 0F 9D 02 20 0E 9C +02 24 4C 43 10 01 A2 43 A8 1E 5C 43 10 01 21 83 +81 43 00 00 7C 40 81 00 5D 43 B0 13 DE CF 81 4C +00 00 B1 B0 00 20 00 00 02 20 4E 43 08 3C B1 D0 +00 C0 00 00 B1 E3 00 00 91 53 00 00 5E 43 2C 41 +5C 03 CF 0C 4E 93 04 24 3C 40 AC 0A 0C 8F 03 3C +3C 40 AC 0A 0C 5F 21 53 10 01 0B 4D 0E 4B 0D 93 +1F 30 3B F0 80 7F 1C 24 5B 02 8B 10 7E D0 80 00 +3B 80 7F 00 15 30 3B 90 20 00 0F 34 3B 80 17 00 +05 30 1B 83 08 30 5C 02 0E 6E FB 3F 5E 01 5C 00 +1B 53 01 24 FB 3F 0D 4E 10 01 3C 43 3D 43 10 01 +0C 43 0D 43 10 01 0B 4D 0B EF 0A 30 0D 93 12 30 +0D 9F 02 24 19 34 16 3C 0C 9E 18 24 13 28 14 3C +3D B0 80 7F 04 20 3F B0 80 7F 01 20 0F 24 0D 9F +0B 34 08 3C 0F 9D 02 24 07 34 04 3C 0E 9C EC 27 +01 28 02 3C 3C 43 10 01 1C 43 10 01 0C 43 10 01 +C2 93 FE 1E 21 20 D2 43 FE 1E B2 40 8F 02 00 1F +B2 40 33 13 02 1F B2 40 14 01 80 03 B2 40 05 00 +92 03 B2 40 80 00 82 03 F2 D0 80 00 0B 02 00 18 +F2 40 AA DC 16 1F 3C 40 8F 02 B0 13 F4 E9 92 42 +02 1F 1A 1F E2 43 04 1F 10 01 E2 93 04 1F 13 24 +B0 13 1C F2 C2 93 04 1F 1C 24 82 43 90 03 B2 D0 +10 00 80 03 F2 D0 80 00 0B 02 E2 43 04 1F 92 42 +02 1F 1A 1F 10 01 B2 F0 CF FF 80 03 F2 F0 7F 00 +03 02 F2 F0 7F 00 0B 02 D2 43 04 1F 92 42 00 1F +1A 1F 10 01 1A 14 31 80 06 00 C9 0C 5A 42 FF 1D +CC 0A B0 13 42 EB 0C 93 02 20 2C 43 13 3C 4D 43 +B0 13 50 EC 0C 93 0E 20 91 43 02 00 C1 4A 04 00 +81 43 00 00 CC 01 2C 53 3D 40 7A 1D CE 09 0F 43 +B0 13 04 C7 31 50 06 00 19 16 10 01 1A 14 CA 0D +CB 0C CC 0A CD 0E B0 13 3E E2 4D 4C CC 0A 49 4B +5C E9 44 F7 47 18 0C 5C 4B ED 5B 4B 44 F7 0B 5C +4A 4A 47 18 0A 5A CC 0E 4C DD 0C 5A 0C EB 0F 9C +06 2C 3E 40 FF 7F 0C FE 5E 03 0F 9C FC 2B 19 16 +10 01 F2 40 A5 00 21 01 4E 4C 4F 4E 8F 10 0E 5F +3E 50 00 44 82 4E 24 01 4F 4C 3F 50 00 44 82 4F +26 01 92 B3 2C 01 FD 27 C2 4C 20 01 B2 F0 F9 FF +2C 01 A2 B3 2C 01 03 24 A2 B2 2C 01 FD 27 82 4E +26 01 C2 43 21 01 10 01 1A 14 3F 40 78 FA 9F 00 +FF FF 12 24 3D 40 78 FA 0C 3C 4F 13 2A 52 12 3C +3C 4D CA 0D CE 09 B0 13 A4 F2 0A 59 CD 0A 1D 53 +1D C3 39 4D 09 93 F4 23 3F 40 FF FF 3F 93 05 24 +3A 40 FF FF 0F 0A DF 03 E8 23 19 16 10 01 7C 90 +3C 00 06 28 7C 90 3E 00 03 24 32 C2 03 43 FF 3F +0F 42 32 C2 03 43 B2 B0 10 00 02 0F FC 27 7C 90 +2F 00 08 28 7C 90 3E 00 05 24 7C D0 C0 00 C2 4C +13 0F 04 3C 7C D0 80 00 C2 4C 13 0F 5C 42 22 0F +02 4F 10 01 0B 4D 0E 4B 3B F0 80 7F 1C 24 5B 02 +8B 10 7E D0 80 00 3B 80 7F 00 15 30 3B 90 10 00 +10 34 5E 01 5C 00 1E 93 01 24 FB 3F 1B 83 03 30 +5C 02 0E 6E FB 3F 0D 93 02 34 3E E3 1E 53 0C 4E +10 01 3C 43 10 01 0C 43 10 01 0A 14 CB 0D 0A 42 +32 C2 03 43 B2 B0 10 00 02 0F FC 27 7C D0 C0 00 +C2 4C 13 0F 4F 4E 1F 83 0A 24 B2 B0 80 00 02 0F +FC 27 1D 53 DD 42 22 0F FF FF 1F 83 F6 23 4D 4E +0D 5B DD 42 20 0F FF FF 02 4A 0A 16 10 01 0B 42 +32 C2 03 43 B2 B0 10 00 02 0F FC 27 4C 4C 47 18 +0C 5C 3C D0 00 40 6F 4D 0F 5C 82 4F 10 0F 6E 93 +0C 28 1D 53 4E 4E 1E 83 E2 4D 10 0F B2 B0 20 00 +02 0F FC 27 1D 53 1E 83 F7 23 5F 42 20 0F 02 4B +10 01 C2 43 76 1E 82 43 82 1E 82 43 7E 1E 82 43 +80 1E C2 93 FE 1D 16 24 B0 13 2A EC B0 13 88 D6 +B0 13 C6 EA 1C 42 84 1E 0C 93 0C 24 1C 52 82 1E +82 4C 82 1E 1D 42 78 1E 1E 42 7A 1E 1F 42 7C 1E +80 00 16 A3 10 01 1A 14 C9 0C 3D 40 0C 00 0D 59 +6E 49 7E 80 0B 00 5C 43 7F 40 03 00 B0 13 74 CA +CA 0C 0A 93 10 24 3C 40 03 00 0C 5A 3D 40 05 00 +0D 59 2E 42 B0 13 A4 F2 FA D0 80 00 0E 00 CC 0A +4D 43 B0 13 08 E8 19 16 10 01 4F 4C 48 18 0F 5F +7C 90 40 00 1A 28 7C 90 4F 00 17 2C 92 B3 44 01 +FD 23 32 C2 03 43 B2 40 00 A5 44 01 B2 40 02 A5 +40 01 8F 43 00 00 B2 40 40 A5 40 01 B2 40 00 A5 +40 01 B2 40 10 A5 44 01 32 D2 10 01 A2 D2 24 03 +7F 40 80 00 3E 42 B2 C2 22 03 CD 0C 4D FF 4D 9F +03 24 A2 C2 22 03 02 3C A2 D2 22 03 12 C3 4F 10 +B0 13 1C F5 B2 D2 22 03 B0 13 1C F5 1E 83 EB 23 +B2 C2 22 03 A2 D2 22 03 A2 C2 24 03 10 01 0A 14 +1A 43 5A 52 31 1F D2 53 31 1F B0 13 0C CC 4C 4C +0C 9A 11 34 1F 43 5F 52 32 1F 7F 90 0D 00 05 2C +D2 53 32 1F D2 43 31 1F 06 3C D2 43 31 1F D2 43 +32 1F 92 53 34 1F 92 D3 14 1D 0A 16 10 01 0A 14 +0A 43 0F 93 05 34 3E E3 3F E3 1E 53 0F 63 1A D3 +0D 93 05 34 3C E3 3D E3 1C 53 0D 63 3A E3 B0 13 +42 D8 1A B3 04 24 3C E3 3D E3 1C 53 0D 63 2A B3 +04 24 3E E3 3F E3 1E 53 0F 63 0A 16 10 01 0A 14 +CA 0D CB 0E 4C 4C 3D 40 1C 00 B0 13 F2 F1 1F 42 +64 FA 0F 5C 8F 93 18 00 0F 20 8F 4A 00 00 8F 4B +02 00 0B 93 06 20 0A 93 04 20 1C 52 64 FA EC C2 +1A 00 FF 40 7F 00 10 00 0A 16 10 01 0A 14 5A 42 +B9 1E 3C 40 B0 1E B0 13 18 E5 4C 4C 0C EA 47 18 +0C 5C 8C 10 4C 4C CA 0C C2 4A B9 1E 3A 90 21 00 +05 20 D2 D3 36 1F B0 13 C8 F4 05 3C F2 F0 EF 00 +36 1F B0 13 C0 D0 0A 16 10 01 4C 93 1C 20 4C 43 +B0 13 E8 EC 0C 93 04 24 1C 83 09 24 1C 83 13 20 +C2 43 3C 1F C2 43 3D 1F 82 43 3E 1F 10 01 1F 42 +64 FA D2 4F 0E 00 3C 1F 1E 4F 06 00 92 4F 04 00 +3E 1F C2 4E 3D 1F 10 01 1A 14 C2 93 2A 1E 16 24 +3C 40 02 1E 29 42 3A 40 68 FA 3B 40 2C 1E 4E 43 +4F 43 7D 4C 7D 9B 01 20 5E 53 7D 9A 01 20 5F 53 +19 83 F7 23 6F 92 02 24 6E 92 02 20 4C 43 01 3C +5C 43 19 16 10 01 D2 B3 36 1F 14 24 1D 42 B0 1E +1E 42 B2 1E 3D F3 3E F0 FF 00 1F 42 A6 1E 1E 9F +02 00 08 20 2D 9F 06 20 DF 92 B3 1E 13 00 04 24 +D2 C3 36 1F 4C 43 10 01 EF C2 1A 00 B0 13 86 CB +5C 43 10 01 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D +5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D +5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D +5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D 5C 02 0D 6D +10 01 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 +5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 +5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 +5C 00 5D 03 5C 00 5D 03 5C 00 5D 03 5C 00 10 01 +0A 14 3F 40 41 1E 2E 43 0C 43 2D 43 6D 9F 05 20 +3F 50 0C 00 1C 53 1E 83 F8 23 6C 93 02 20 0C 43 +0C 3C 4C 4C 3D 40 0C 00 B0 13 F2 F1 3A 40 41 1E +0A 5C CC 0A B0 13 74 E4 CC 0A 0A 16 10 01 82 43 +BA 1E 4C 43 B0 13 C2 F4 B0 13 40 F3 C2 43 C2 1E +92 D3 14 1D 7C 40 13 00 6D 42 B0 13 08 F0 7C 40 +17 00 6D 42 B0 13 08 F0 7C 40 18 00 6D 42 B0 13 +08 F0 7C 40 19 00 6D 42 80 00 08 F0 92 C3 44 03 +82 93 FC 1E 0E 24 B0 13 9A A0 92 93 FC 1E 03 24 +B0 13 1C E6 02 3C B0 13 C0 D0 1C 42 F6 1E 80 00 +EA EF F2 C2 36 1F B0 13 C0 D0 1C 42 F8 1E B0 13 +EA EF 92 43 FC 1E 10 01 3A 14 C8 0D C7 0C 3A 40 +41 1E 29 43 2F 43 6F 9A 0E 20 3D 40 03 00 0D 5A +CC 07 2E 42 B0 13 54 ED 0C 93 05 20 58 9A 0A 00 +02 20 CC 0A 05 3C 3A 50 0C 00 19 83 EB 23 0C 43 +37 16 10 01 3A 14 C8 0D C7 0C 3A 40 41 1E 49 43 +2F 43 6F 9A 0E 20 3C 40 03 00 0C 5A CD 07 2E 42 +B0 13 54 ED 0C 93 05 20 CA 98 0A 00 02 20 CC 0A +05 3C 3A 50 0C 00 59 53 EB 27 0C 43 37 16 10 01 +D2 B3 8D 1C 0A 24 B0 13 E4 F3 4C 93 06 20 B0 13 +EC B1 4C 93 02 20 B0 13 9E E2 F2 B0 06 00 8D 1C +02 24 B0 13 88 D6 7C 40 15 00 7D 40 03 00 B0 13 +08 F0 0C 43 4D 43 5E 43 80 00 6E B6 82 43 AE 1E +B0 13 CE F4 F2 40 21 00 AA 1E F2 40 06 00 AC 1E +C2 43 AB 1E D2 43 AD 1E 7C 43 5D 43 B0 13 2E D1 +B0 13 50 D0 B0 13 9A D8 7C 40 0C 00 5D 42 94 1E +80 00 04 E4 21 83 0F 42 32 C2 03 43 B2 B0 10 00 +02 0F FC 27 4C 4C 47 18 0C 5C 3C D0 00 40 4D 4D +0C 5D 82 4C 10 0F B2 B0 20 00 02 0F FC 27 5E 42 +20 0F 81 4E 00 00 02 4F 21 53 10 01 5F 14 1A 42 +38 0F 4A 4A B0 13 FC F3 4C 93 10 20 7A 90 14 00 +04 24 4A 93 0D 20 03 43 0B 3C 1F 42 BA 1E 1F 93 +02 24 2F 93 05 20 B0 13 92 F2 02 3C B0 13 00 D4 +5A 16 00 13 21 83 CC 43 0A 00 EC 43 00 00 DC 42 +40 1E 0B 00 D2 53 40 1E 02 3C D2 53 40 1E C2 93 +40 1E FB 27 F2 93 40 1E F8 27 5C 42 40 1E CD 01 +B0 13 1A EB 4C 93 F1 23 21 53 10 01 0A 14 CA 0C +5D 42 4A 1F B0 13 78 E7 4C 93 0E 24 B0 13 C8 F2 +CD 0C 1C 43 0C 5A 2E 42 B0 13 54 ED 0C 93 02 20 +0C 43 05 3C 2C 43 03 3C B0 13 A8 F3 1C 43 0A 16 +10 01 0E 4C 0D 4C 0D 93 16 24 03 34 3D E3 1D 53 +0F 30 3B 40 8F 00 1B 83 5D 02 FD 2B 4C 4D 8C 10 +8D 10 4D 4D 8B 10 0D DB 5E 02 5D 00 5C 00 10 01 +3D 40 00 C7 0C 43 10 01 0A 14 3A 40 09 00 0F 43 +6D 4C 3B 42 4E 4D 0E EF 3E 90 80 00 04 38 4F 5F +7F E0 97 00 01 3C 4F 5F 4F 4F 4D 5D 1B 83 F2 23 +1C 53 1A 83 ED 23 CC 0F 0A 16 10 01 1D 42 26 1E +0F 42 32 C2 03 43 D2 43 24 1E 02 4F 0D 93 07 24 +B0 13 CC EF C2 93 23 1E 02 20 1D 83 F9 23 0F 42 +32 C2 03 43 C2 43 23 1E C2 43 24 1E 02 4F 10 01 +B0 13 88 F4 1F 42 A6 1E FF 90 7F 00 10 00 0A 24 +2C 93 05 34 3C 93 0D 34 DF 83 10 00 10 01 DF 53 +10 00 10 01 CF 4C 10 00 1F 42 A6 1E FF 50 0C 00 +10 00 10 01 7C 90 2F 00 06 28 7C 90 3E 00 03 24 +32 C2 03 43 FF 3F 0F 42 32 C2 03 43 B2 B0 10 00 +02 0F FC 27 C2 4C 11 0F B2 B0 20 00 02 0F FC 27 +C2 4D 10 0F 02 4F 10 01 4D 93 03 20 32 C2 03 43 +FF 3F 0F 42 32 C2 03 43 B2 B0 10 00 02 0F FC 27 +F2 40 7F 00 11 0F 4D 4D B2 B0 20 00 02 0F FC 27 +F2 4C 10 0F 1D 83 F8 23 02 4F 10 01 B2 F0 FE FD +36 0F B2 F0 FE FD 32 0F 7C 40 36 00 B0 13 38 C8 +7C 40 3A 00 B0 13 38 C8 7C 40 36 00 B0 13 38 C8 +7C 40 32 00 B0 13 38 C8 82 43 1E 1F 10 01 B0 13 +16 C0 B0 13 92 D7 B0 13 D8 F3 82 93 D8 1E 03 20 +82 93 86 1E 02 24 B0 13 58 B5 82 93 88 1E 02 24 +B0 13 9C EC 82 93 14 1D EE 27 B0 13 D2 AC EB 3F +21 83 7C 40 30 00 B0 13 38 C8 81 43 00 00 02 3C +91 53 00 00 B1 90 64 00 00 00 FA 2B 7C 40 36 00 +B0 13 38 C8 7C B0 70 00 F9 23 82 43 06 0F 21 53 +10 01 0C 93 02 20 0D 93 14 24 3B 40 9F 00 1B 83 +5C 02 0D 6D FC 2B 12 C3 5D 00 5C 00 3E 40 06 00 +5D 01 5C 00 1E 83 FC 37 8B 10 0D DB 12 C3 5D 00 +5C 00 10 01 D2 B3 8D 1C 06 24 B0 13 E4 F3 4C 93 +02 24 B0 13 9E E2 0C 43 4D 43 6E 43 B0 13 6E B6 +F2 B0 06 00 8D 1C 02 24 B0 13 C6 EA 7C 40 15 00 +6D 42 80 00 08 F0 B2 B0 20 00 86 1E 14 20 B0 13 +FC F3 4C 93 10 20 A2 B2 D8 1E 0D 24 1F 42 BA 1E +0F 93 05 20 B0 13 EC B1 4C 93 03 24 10 01 2F 93 +02 20 80 00 9E E2 10 01 4D 93 03 20 32 C2 03 43 +FF 3F 0F 42 32 C2 03 43 4D 4D B2 B0 10 00 02 0F +FC 27 F2 40 BF 00 13 0F 1C 53 DC 42 22 0F FF FF +1D 83 F3 23 02 4F 10 01 CF 0C FF B0 80 FF 0C 00 +02 20 6C 43 10 01 CF 9D 0D 00 0C 20 B0 13 C8 F2 +CD 0C 1C 43 0C 5F 2E 42 B0 13 54 ED 0C 93 02 20 +4C 43 10 01 5C 43 10 01 82 93 D0 1E 09 20 82 93 +CE 1E 06 20 B2 40 04 03 CE 1E B2 40 02 01 D0 1E +B0 13 84 F1 C2 4C D7 1E 4C 93 FA 27 3C 40 D4 1E +0D 43 1E 43 80 00 B6 F2 31 80 06 00 81 43 02 00 +D1 4C 05 00 04 00 CF 0C 3F 50 06 00 81 4F 00 00 +1D 4C 02 00 2E 42 0E 5C 2F 4C CC 01 2C 53 B0 13 +04 C7 31 50 06 00 10 01 0A 14 CA 0C 3F 40 CF 00 +5F FA 0C 00 5F D2 C8 1E CA 4F 0C 00 2C 43 0C 5A +B0 13 50 BF 4C 93 02 20 0C 43 02 3C 3C 40 09 00 +CA 43 00 00 0A 16 10 01 7C 40 40 00 B0 13 AA DF +5C 53 7C 90 4F 00 FA 2B C2 43 8C 1C F2 40 06 00 +8D 1C F2 40 05 00 8E 1C C2 43 8F 1C B2 40 00 80 +90 1C C2 43 92 1C 10 01 7C 90 80 00 09 28 4C 4C +3C 80 00 01 2D 43 B0 13 74 E9 3C 80 4A 00 04 3C +4C 4C 5C 03 3C 80 4A 00 3C 90 80 FF 02 34 3C 40 +80 FF 8C 11 10 01 92 C3 22 03 F2 F0 DF 00 03 02 +F2 F0 1F 00 02 02 A2 C3 22 03 F2 D0 20 00 05 02 +F2 D0 E0 00 04 02 A2 D3 24 03 92 D3 24 03 D2 43 +F5 1E 10 01 B2 F0 FF FD 36 0F 7C 40 36 00 B0 13 +6C CF 7C 40 3D 00 B0 13 6C CF 7C B0 F0 FF F9 23 +7C 40 3A 00 B0 13 6C CF B2 F0 FF FD 32 0F 10 01 +C2 93 59 1E 0E 20 B0 13 7E A8 B0 13 92 CC 0C 93 +0C 20 B0 13 06 EE B0 13 C8 F2 B0 13 0C ED B0 13 +90 EF D2 43 59 1E 80 00 76 B7 10 01 4D 93 13 24 +4D 4D 0E 43 5F 42 92 1C 7F 90 80 00 09 2C CB 0F +5B 53 C2 4B 92 1C CB 0E 0B 5C 4F 4F EF 4B 93 1C +1E 53 1D 83 EF 23 10 01 5C 93 13 20 0C 42 32 C2 +03 43 2E 43 3F 40 00 1C CF 93 00 00 05 24 5D 9F +01 00 02 2C DF 83 01 00 3F 50 23 00 1E 83 F4 23 +02 4C 10 01 0B 43 0D 93 03 34 3D E3 1D 53 1B D3 +0C 93 03 34 3C E3 1C 53 3B E3 B0 13 DC F1 1B B3 +02 24 3C E3 1C 53 2B B3 02 24 3E E3 1E 53 10 01 +4C 4C 3D 40 1C 00 B0 13 F2 F1 CF 0C 1F 52 64 FA +EF B2 1A 00 03 24 0F 43 0D 43 05 3C 1C 52 64 FA +2F 4C 1D 4C 02 00 CC 0F 10 01 C2 93 AC 1E 09 24 +1F 42 A6 1E DF 83 13 00 1F 42 A6 1E CF 93 13 00 +02 24 5C 43 10 01 8F 43 18 00 5D 43 B0 13 2A E1 +4C 43 10 01 82 4C 1A 1F 82 93 50 03 02 20 0F 43 +05 3C 1F 42 50 03 1F 92 50 03 FB 23 0F 5C 82 4F +58 03 92 C3 48 03 B2 D0 10 00 48 03 10 01 31 40 +FC 2B 00 18 F2 40 20 F5 06 1F 00 18 F2 40 20 F5 +0A 1F B0 13 FC F4 0C 93 02 24 B0 13 C8 DD 0C 43 +B0 13 4E E6 B0 13 00 F5 5D 93 12 20 C2 93 EB 1E +0A 24 E2 93 EB 1E 0C 2C 7C 40 5A 00 3D 40 DC F8 +5E 43 80 00 E0 BC 7C 40 5A 00 3D 40 E2 F8 F8 3F +10 01 92 B3 44 01 FD 23 32 C2 03 43 B2 40 00 A5 +44 01 B2 40 40 A5 40 01 8C 4D 00 00 B2 40 00 A5 +40 01 B2 40 10 A5 44 01 32 D2 10 01 B2 D0 06 00 +06 0A B2 40 1D 7B 00 0A B2 40 ED 00 04 0A F2 D0 +E0 00 4A 02 F2 D0 E0 00 44 02 B2 43 0A 0A B2 40 +FF 00 0C 0A 10 01 C2 93 FE 1D 11 24 C2 93 76 1E +0E 24 B0 13 A0 F4 4C 93 0A 20 B0 13 60 F4 C2 43 +76 1E F2 F0 BF 00 1B 02 F2 F0 BF 00 1D 02 10 01 +F2 C2 03 02 F2 C2 05 02 D2 B3 8C 1C 0B 20 E2 B3 +8C 1C 02 20 80 00 90 E3 92 D3 8A 1E B2 D0 00 01 +8A 1E 10 01 80 00 E4 E6 10 01 3F 40 41 1E 0E 43 +2B 43 6B 9F 07 20 CF 9C 0B 00 04 20 CD 4E 00 00 +5C 43 10 01 3F 50 0C 00 1E 53 2E 93 F1 3B 4C 43 +10 01 21 83 CD 01 B0 13 1A EB 4C 93 0B 24 6C 41 +3D 40 0C 00 B0 13 F2 F1 EC 93 41 1E 03 20 3C 50 +41 1E 01 3C 0C 43 21 53 10 01 82 93 EE 1E 09 20 +82 93 EC 1E 06 20 B2 40 08 07 EC 1E B2 40 06 05 +EE 1E 00 18 C2 43 F0 1E B0 13 84 F1 C2 4C F4 1E +10 01 3C 40 03 00 5C F2 20 01 7C 90 03 00 03 2C +5C 53 B0 13 82 DD 6C 92 03 28 5C 83 B0 13 B8 EB +7C 90 03 00 EE 23 10 01 F2 40 A5 00 21 01 4E 4C +4F 4E 8F 10 0E 5F 3E 50 00 44 82 4E 26 01 92 B3 +2C 01 FD 27 C2 4C 20 01 C2 43 21 01 10 01 3F 40 +13 00 6F 9C 09 24 5F 4C 0C 00 1F 83 07 24 1F 83 +07 20 B0 13 00 D2 04 3C DC 43 0C 00 B0 13 70 AF +0C 43 10 01 F2 F0 E0 00 05 02 F2 F0 E0 00 03 02 +F2 D0 1F 00 07 02 F2 F0 E0 00 19 02 F2 F0 E0 00 +1D 02 F2 D0 1F 00 1B 02 10 01 1A 14 39 40 11 00 +3F 40 BA 1D 3A 40 20 FA 3C 4A B0 13 C0 ED 2F 52 +8F 4C FC FF 8F 4D FE FF 19 83 F6 23 19 16 10 01 +4D 93 03 24 5F 4C 0A 00 02 3C 5F 4C 09 00 4F 93 +06 24 CC 93 00 00 03 24 7F 90 20 00 02 2C 2C 43 +10 01 0C 43 10 01 3C 40 E2 1E 0D 43 2E 42 B0 13 +B6 F2 C2 93 EA 1E 09 20 3C 40 E6 1E 3D 40 5A FA +2E 42 B0 13 A4 F2 D2 43 EA 1E 10 01 A2 B3 88 1E +03 24 5C 43 B0 13 B8 C5 B2 B2 88 1E 02 24 B0 13 +5E B9 92 B3 88 1E 02 24 B0 13 98 D1 82 43 88 1E +10 01 B2 B0 20 00 86 1E 0E 20 B0 13 E4 F3 4C 93 +0A 20 F2 C2 03 02 F2 C2 05 02 F2 C2 1B 02 B0 13 +FE CA F2 D2 1B 02 10 01 4C 4C 3D 40 1C 00 B0 13 +F2 F1 CF 0C 1F 52 64 FA EF B2 1A 00 02 24 2C 43 +10 01 1C 52 64 FA 1C 4C 18 00 10 01 CE 0C 6D 4E +5D 92 68 FA 0C 24 7C 40 09 00 B0 13 B4 E5 2D 42 +3F 40 2C 1E 1F 53 FF 4E FF FF 1D 83 FB 23 10 01 +0A 14 0A 42 32 C2 03 43 D2 93 00 1E 08 24 B0 13 +D0 EE 7C 40 32 00 B0 13 6C CF D2 43 00 1E 02 4A +0A 16 10 01 0E 93 02 20 0C 43 10 01 1D 83 1C 83 +1D 53 6B 4D 1C 53 6F 4C 4F 9B 02 20 1E 83 F8 23 +4B 4B 4C 4F 0C 8B 10 01 0A 14 CA 0C 5D 42 95 1E +B0 13 78 E7 4C 93 04 20 B0 13 A8 F3 1C 43 04 3C +CC 0A B0 13 CC F3 0C 43 0A 16 10 01 82 43 96 1E +82 43 98 1E E2 42 A0 1E F2 40 1E 00 A1 1E C2 43 +A2 1E C2 43 9F 1E 82 43 9A 1E 82 43 9C 1E 10 01 +0D 4C 0D 93 0E 24 3B 40 8F 00 1B 83 5D 02 FD 2B +4C 4D 8C 10 8D 10 4D 4D 8B 10 0D DB 12 C3 5D 00 +5C 00 10 01 82 43 90 03 B2 40 C0 00 92 03 B2 D0 +10 00 80 03 92 B3 82 03 FD 27 B2 F0 EF FF 80 03 +92 C3 82 03 10 01 D2 93 00 1E 0D 20 7C 40 36 00 +B0 13 6C CF 7C 40 3D 00 B0 13 6C CF 7C B0 F0 FF +F9 23 E2 43 00 1E 10 01 5F 42 A0 1E 4F 93 09 24 +7F 90 0D 00 02 2C CC 0F 10 01 CC 0F 7C 80 0C 00 +10 01 3C 40 0C 00 4C 5F 10 01 4C 43 B0 13 E8 EC +0C 93 09 24 1C 83 09 20 B0 13 B0 F4 C2 4C C2 1E +92 43 BC 1E 10 01 80 00 9E E2 10 01 0A 14 CA 0C +5D 42 D7 1E B0 13 78 E7 4C 93 04 20 B0 13 A8 F3 +1C 43 03 3C CC 0A B0 13 DE EB 0A 16 10 01 02 12 +32 C2 03 43 82 4C D0 04 82 4D D2 04 82 4E E0 04 +82 4F E2 04 1C 42 E4 04 1D 42 E6 04 32 41 10 01 +0A 14 5C 43 B0 13 84 CE CA 0C 0A 93 07 24 2C 43 +0C 5A B0 13 B4 F3 CC 0A B0 13 5C C9 0A 16 10 01 +D2 93 00 1E 09 24 F2 90 03 00 00 1E 08 20 B0 13 +C4 E8 E2 43 00 1E 10 01 32 C2 03 43 FF 3F 10 01 +D2 93 00 1E 09 24 F2 90 03 00 00 1E 08 24 F2 40 +03 00 00 1E 80 00 9A F1 32 C2 03 43 FF 3F 10 01 +1C 42 82 1E 3C B0 00 80 0D 7D 3D E3 3E 40 52 00 +0F 43 B0 13 8E EE 3E 40 19 00 0F 43 80 00 6E E0 +B0 13 E4 F3 4C 93 0A 24 4C 43 1F 42 54 03 1F 82 +50 03 3F 90 F5 01 03 28 5C 43 10 01 5C 43 10 01 +C2 43 C8 1E 00 18 C2 43 CA 1E B0 13 C8 F2 82 4C +C6 1E B0 13 84 F1 C2 4C C4 1E 4C 93 FA 27 10 01 +B2 F0 CF FF 80 03 F2 F0 7F 00 03 02 F2 F0 7F 00 +0B 02 B2 F0 EF FF 82 03 B0 13 98 F4 80 00 6A F4 +D2 92 68 FA 2C 1E 08 24 D2 43 2A 1E 7C 40 07 00 +7D 40 07 00 80 00 B4 E5 32 C2 03 43 FF 3F B0 13 +C4 E8 7C 40 0A 00 5D 42 6C FA B0 13 B4 E5 F2 90 +03 00 00 1E 02 20 80 00 9A F1 10 01 3F 40 3E 00 +0E 42 32 C2 03 43 B0 13 E4 ED 02 4E C2 93 23 1E +03 20 1F 83 3F 93 F4 23 10 01 CF 0C 82 4F 54 03 +92 C3 44 03 B0 13 9C F3 2F 83 0F 8C 3F 90 00 80 +02 28 92 D3 44 03 10 01 CF 0D 7C 90 2A 00 0A 2C +4E 4C 5D 4E AC F9 4C 4C 5C 02 1C 4C 16 1D CE 0D +80 00 C0 D4 10 01 0C 9D 02 2C 80 00 A4 F2 0C 5E +0D 5E 0E 93 06 24 1D 83 1C 83 EC 4D 00 00 1E 83 +FA 23 10 01 CD 0C C2 93 EA 1E 02 24 4C 43 10 01 +3C 40 E6 1E 2E 42 B0 13 A4 F2 D2 43 EA 1E 5C 43 +10 01 B0 13 80 F3 4C 93 08 20 4C 43 4D 43 B0 13 +08 F0 5C 43 5D 43 80 00 08 F0 4C 43 FB 3F 3C 40 +00 1C 0D 43 3E 40 46 00 B0 13 B6 F2 3C 40 46 1C +0D 43 3E 40 46 00 80 00 B6 F2 0A 14 CF 0C CC 0D +2A 43 0F 93 05 20 B0 13 44 F0 4C 93 01 24 0A 43 +CC 0A 0A 16 10 01 21 82 CF 0C CC 0D A1 4F 00 00 +91 4F 02 00 02 00 CD 01 2E 42 B0 13 26 F0 21 52 +10 01 1F 42 A6 1E 5C 4F 11 00 6C 93 02 2C 3C 42 +10 01 5C 53 4C 5C 4C 5C 4C 4C 10 01 7C 90 03 00 +07 2C 4C 4C 5D 4C 70 FA 7C 40 3E 00 80 00 B4 E5 +32 C2 03 43 FF 3F 0C 93 0A 24 5C 0F 1C 53 0F 42 +32 C2 03 43 B0 13 E4 ED 02 4F 1C 83 F8 23 10 01 +B0 13 84 F1 7C F0 0F 00 5C 53 4E 4C 1C 42 28 1E +B0 13 06 F1 1E 83 FA 23 10 01 B2 90 06 00 0E 07 +08 20 92 42 20 07 44 1F D2 43 46 1F B1 C0 D0 00 +00 00 00 13 1C 42 7E 1E CF 0C 5F 0A 0C 5F 3D 40 +05 00 B0 13 74 E9 3C 50 40 01 10 01 5D 42 F4 1E +B0 13 78 E7 4C 93 02 24 0C 43 10 01 B0 13 A8 F3 +1C 43 10 01 5C 42 22 1E 3D 40 6D 00 B0 13 F2 F1 +7C 50 43 00 C2 4C 22 1E 10 01 B2 F0 FF FD 32 0F +7C 40 34 00 B0 13 6C CF B2 D0 00 02 36 0F 10 01 +0F 42 32 C2 03 43 7C D0 C0 00 C2 4C 13 0F 5C 42 +22 0F 02 4F 10 01 82 43 BA 1E 82 43 BE 1E 82 43 +C0 1E 82 43 BC 1E C2 43 C2 1E 10 01 0E 43 0F 4C +1C 43 5F 02 0E 6E 0E 9D 01 28 0E 8D 0C 6C F9 2B +10 01 02 12 32 C2 03 43 82 4C C0 04 82 4D C8 04 +1C 42 CA 04 32 41 10 01 B2 40 FF 7F 52 03 B2 D0 +10 00 42 03 B2 D0 24 01 40 03 10 01 5F 42 FE 1E +5F 83 D2 83 FE 1E 0F 93 02 20 80 00 70 EF 10 01 +5D 93 07 20 7C 40 5B 00 3D 40 F2 F8 5E 43 80 00 +E0 BC 10 01 5D 93 07 20 7C 40 5A 00 3D 40 EA F8 +5E 43 80 00 E0 BC 10 01 3C 80 05 00 05 24 3C 80 +05 00 02 24 4C 43 10 01 5C 43 10 01 B2 40 D9 07 +34 1F F2 42 32 1F D2 43 31 1F C2 43 30 1F 10 01 +4C ED 4F 4C CC 0D 8C 10 5C EF 44 F7 7C F0 1F 00 +10 01 1F 42 50 03 82 4F 22 1F 1F 92 50 03 F9 23 +80 00 62 D4 CF 0C 0E 93 05 24 1F 53 FF 4D FF FF +1E 83 FB 23 10 01 0E 93 06 24 4D 4D 1C 53 CC 4D +FF FF 1E 83 FB 23 10 01 C2 93 EA 1E 03 24 3C 40 +E6 1E 10 01 3C 40 5A FA 10 01 0D 93 02 20 0C 93 +04 24 82 4C EC 1E 82 4D EE 1E 10 01 0D 93 02 20 +0C 93 04 24 82 4C CE 1E 82 4D D0 1E 10 01 B0 13 +80 E6 B2 F0 EF FF 32 0F B2 D0 10 00 36 0F 10 01 +A2 43 FC 1E 92 C3 44 03 B2 D0 10 00 44 03 10 01 +A2 D2 80 03 82 43 80 03 B2 D0 00 02 80 03 10 01 +CE 0C 3C 40 E8 03 B0 13 06 F1 1E 83 FA 23 10 01 +82 43 32 0F 82 43 36 0F B0 13 80 E6 80 00 50 F3 +7C 40 36 00 B0 13 38 C8 7C 40 39 00 80 00 38 C8 +4F 43 C2 93 30 1F 01 20 5F 43 C2 4F 30 1F 10 01 +4F 43 C2 93 9F 1E 01 20 5F 43 C2 4F 9F 1E 10 01 +4C 43 F2 90 0C 00 A0 1E 01 2C 5C 43 10 01 F2 40 +0F 00 2A 1F B2 40 2C 01 2C 1F 10 01 1C 42 50 03 +1C 92 50 03 FB 23 10 01 C2 93 24 1E 02 24 D2 43 +23 1E 10 01 3D 40 01 1E 3E 40 21 00 80 00 A4 F2 +5C 43 B0 13 D4 D5 6C 43 80 00 D4 D5 DC 93 0C 00 +02 20 80 00 66 DF 10 01 B0 13 A8 F4 B2 40 2B 5A +5C 01 10 01 4C 43 A2 93 BA 1E 01 20 5C 43 10 01 +4C 43 92 93 BA 1E 01 20 5C 43 10 01 4C 43 82 93 +72 1D 01 24 5C 43 10 01 CF 0C CC 0D CD 0F 2E 42 +80 00 26 F0 CD 0C 3C 40 E2 1E 2E 42 80 00 A4 F2 +7C 40 03 00 7D 40 0B 00 80 00 EA D7 5C 93 02 20 +CC 0D 10 01 CC 0E 10 01 1C 42 44 03 7C F0 10 00 +10 01 B2 F0 EF FF 44 03 80 00 1C E6 B0 13 84 F1 +C2 4C 4A 1F 10 01 B0 13 84 F1 C2 4C 95 1E 10 01 +7C 40 03 00 4D 43 80 00 EA D7 C2 43 FE 1E C2 43 +04 1F 10 01 1C 42 14 1D 8C 10 5C F3 10 01 1C 42 +14 1D 5C 0F 5C F3 10 01 5C 42 20 1F 8C 11 10 01 +4C 5C C2 4C AB 1E 10 01 B2 F0 EF FF 48 03 10 01 +1C 43 5C F2 8C 1C 10 01 32 D0 D8 00 03 43 10 01 +5C 42 3C 1F 10 01 C2 4C AA 1E 10 01 C2 4C AC 1E +10 01 4D 43 80 00 2E D1 92 D3 44 03 10 01 92 C3 +44 03 10 01 5C 42 00 1E 10 01 5C 42 76 1E 10 01 +82 43 D8 1E 10 01 CC 43 00 00 10 01 3C 40 68 FA +10 01 82 43 72 1D 10 01 80 00 24 AE 1C 43 10 01 +03 43 FF 3F 2C 43 10 01 2C 43 10 01 4C 43 10 01 +6C 43 10 01 0C 43 10 01 0C 43 10 01 03 43 10 01 +10 01 10 01 30 30 30 30 30 31 30 30 32 30 30 33 +30 30 34 30 30 35 30 30 36 30 30 37 30 30 38 30 +30 39 30 31 30 30 31 31 30 31 32 30 31 33 30 31 +34 30 31 35 30 31 36 30 31 37 30 31 38 30 31 39 +30 32 30 30 32 31 30 32 32 30 32 33 30 32 34 30 +32 35 30 32 36 30 32 37 30 32 38 30 32 39 30 33 +30 30 33 31 30 33 32 30 33 33 30 33 34 30 33 35 +30 33 36 30 33 37 30 33 38 30 33 39 30 34 30 30 +34 31 30 34 32 30 34 33 30 34 34 30 34 35 30 34 +36 30 34 37 30 34 38 30 34 39 30 35 30 30 35 31 +30 35 32 30 35 33 30 35 34 30 35 35 30 35 36 30 +35 37 30 35 38 30 35 39 30 36 30 30 36 31 30 36 +32 30 36 33 30 36 34 30 36 35 30 36 36 30 36 37 +30 36 38 30 36 39 30 37 30 30 37 31 30 37 32 30 +37 33 30 37 34 30 37 35 30 37 36 30 37 37 30 37 +38 30 37 39 30 38 30 30 38 31 30 38 32 30 38 33 +30 38 34 30 38 35 30 38 36 30 38 37 30 38 38 30 +38 39 30 39 30 30 39 31 30 39 32 30 39 33 30 39 +34 30 39 35 30 39 36 30 39 37 30 39 38 30 39 39 +31 30 30 31 30 31 31 30 32 31 30 33 31 30 34 31 +30 35 31 30 36 31 30 37 31 30 38 31 30 39 31 31 +30 31 31 31 31 31 32 31 31 33 31 31 34 31 31 35 +31 31 36 31 31 37 31 31 38 31 31 39 31 32 30 31 +32 31 31 32 32 31 32 33 31 32 34 31 32 35 31 32 +36 31 32 37 31 32 38 31 32 39 31 33 30 31 33 31 +31 33 32 31 33 33 31 33 34 31 33 35 31 33 36 31 +33 37 31 33 38 31 33 39 31 34 30 31 34 31 31 34 +32 31 34 33 31 34 34 31 34 35 31 34 36 31 34 37 +31 34 38 31 34 39 31 35 30 31 35 31 31 35 32 31 +35 33 31 35 34 31 35 35 31 35 36 31 35 37 31 35 +38 31 35 39 31 36 30 31 36 31 31 36 32 31 36 33 +31 36 34 31 36 35 31 36 36 31 36 37 31 36 38 31 +36 39 31 37 30 31 37 31 31 37 32 31 37 33 31 37 +34 31 37 35 31 37 36 31 37 37 31 37 38 31 37 39 +31 38 30 00 01 80 40 20 10 08 84 42 21 90 48 A4 +52 29 14 0A 85 C2 61 B0 58 AC D6 6B 35 9A CD 66 +33 99 4C A6 53 A9 54 2A 95 CA E5 F2 79 3C 9E CF +67 B3 D9 6C B6 5B 2D 16 0B 05 82 41 A0 50 28 94 +4A A5 D2 69 34 1A 8D 46 23 91 C8 E4 72 39 1C 8E +C7 E3 F1 F8 FC FE FF 7F 3F 1F 0F 07 83 C1 E0 70 +38 9C CE E7 F3 F9 7C BE DF 6F 37 9B 4D 26 13 89 +44 22 11 88 C4 62 31 98 CC E6 73 B9 5C AE D7 EB +75 BA DD 6E B7 DB 6D 36 1B 0D 06 03 81 C0 60 30 +18 8C C6 63 B1 D8 EC F6 7B 3D 1E 8F 47 A3 D1 E8 +F4 7A BD 5E AF 57 AB 55 AA D5 EA F5 FA FD 7E BF +5F 2F 17 8B 45 A2 51 A8 D4 6A B5 DA ED 76 3B 1D +0E 87 C3 E1 F0 78 BC DE EF 77 BB 5D 2E 97 CB 65 +B2 59 2C 96 4B 25 92 49 24 12 09 04 02 01 80 40 +20 10 08 84 42 21 90 48 A4 52 29 14 0A 85 C2 61 +B0 58 AC D6 6B 35 9A CD 66 33 99 4C A6 53 A9 54 +2A 95 CA E5 70 F3 00 00 22 F5 00 00 7E AB 00 00 +7E F4 00 00 56 F8 22 F5 00 00 22 F5 00 00 0A BC +00 00 7E F4 00 00 68 F8 22 F5 00 00 22 F5 00 00 +4C BA 00 00 7E F4 00 00 7A F8 16 E7 00 00 E0 F4 +00 00 34 D3 00 00 7E F4 00 00 44 F8 60 F3 00 00 +22 F5 00 00 86 BE 00 00 74 F4 00 00 9E F8 F0 EA +00 00 22 F5 00 00 30 F2 00 00 7E F4 00 00 B0 F8 +C2 EC 00 00 22 F5 00 00 44 F2 00 00 7E F4 00 00 +C2 F8 44 D9 00 00 22 F5 00 00 48 EA 00 00 7E F4 +00 00 8C F8 20 20 44 4F 4E 45 00 00 20 43 4F 4E +46 00 20 52 46 42 53 4C 00 00 20 20 53 59 4E 43 +00 00 20 44 4C 4F 47 00 46 41 49 4C 00 00 45 52 +52 00 30 30 30 30 30 30 30 00 2D 2D 2D 00 20 52 +41 4D 00 00 20 4F 46 46 00 00 20 20 4F 4E 00 00 +20 4E 4F 4D 45 4D 00 00 4C 4F 42 41 54 54 00 00 +20 20 4F 50 45 4E 00 00 20 20 4C 4F 3F 54 00 00 +02 1B 01 1E 17 3C 18 10 06 1E 08 05 03 47 0B 08 +0C 00 0D 22 0E B1 0F 3B 10 7B 11 83 12 13 13 22 +14 F8 15 42 19 1D 1A 1C 1B C7 1C 00 1D B2 21 B6 +22 10 23 EA 24 2A 25 00 26 1F 2C 81 2D 35 2E 09 +F5 60 B6 F2 63 D3 D7 70 F7 F3 00 00 00 00 00 86 +00 77 C7 95 E6 97 17 F3 67 05 F0 87 85 75 46 C6 +37 F5 06 D3 87 C4 C4 02 67 E3 B6 00 03 01 04 08 +10 80 80 80 80 20 40 02 01 80 04 02 10 20 40 08 +08 80 08 08 08 08 F7 F7 F7 F7 20 40 04 80 7F 7F +7F 7F 7F 10 01 80 2F 1E 1B 07 37 B2 0A 04 00 00 +00 0C 00 23 2A D4 4D 3B 15 11 F8 57 07 0C 10 1D +1C C7 10 B0 FF FF F9 B6 10 EA 2A 00 1F 00 67 FF +00 00 6F 00 1C 02 DD 03 B1 05 9D 07 A2 09 C4 0B +07 0E 6E 10 01 13 C6 15 C8 18 11 1C B5 1F CC 23 +07 04 F5 03 E8 03 B6 03 84 03 52 03 20 03 EE 02 +BC 02 8A 02 58 02 26 02 F4 01 C2 01 90 01 5E 01 +2C 01 78 ED 00 00 6C EE 00 00 6C F1 00 00 18 F5 +00 00 14 F5 00 00 AC E4 00 00 79 56 34 12 02 01 +01 01 00 00 5A 1E 5A 1E FF FF FF FF 14 32 50 6E +0F 27 8B 00 02 00 00 +@fa78 +01 00 1C 1F 00 00 01 00 E0 1E 00 00 01 00 E1 1E +0A 00 54 00 16 1D 20 0A 20 0A 20 0A 20 0A 24 0A +2A 0A 29 0A 27 0A 26 0A 24 0A 24 0A 26 0A 26 0A +24 0A 26 0A 24 0A 26 0A 26 0A 26 0A 21 0A 22 0A +20 0A 23 0A 24 0A 25 0A 26 0A 21 0A 22 0A 23 0A +25 0A 20 0A 20 0A 24 0A 2B 0A 2B 0A 2A 0A 29 0A +28 0A 27 0A 20 0A 24 0A 28 0A 02 00 40 1F 00 00 +02 00 42 1F 00 00 01 00 59 1E 00 00 01 00 00 1E +00 00 01 00 22 1E 00 00 01 00 23 1E 00 00 01 00 +24 1E 00 00 02 00 26 1E 00 00 02 00 28 1E 00 00 +01 00 2A 1E 00 00 01 00 2C 1E FF 00 04 00 30 1E +00 00 00 00 04 00 34 1E 00 00 00 00 04 00 38 1E +00 00 00 00 01 00 EA 1E 00 00 01 00 C4 1E 00 00 +02 00 C6 1E 00 00 01 00 C8 1E 00 00 04 00 CA 1E +00 00 00 00 01 00 3C 1E 01 00 01 00 95 1E 00 00 +02 00 48 1F 00 00 01 00 4A 1F 00 00 04 00 CE 1E +00 00 00 00 01 00 D2 1E 00 00 01 00 D6 1E 00 00 +01 00 D7 1E 00 00 04 00 EC 1E 00 00 00 00 04 00 +F0 1E 00 00 00 00 01 00 F4 1E 00 00 01 00 AA 1E +00 00 01 00 AB 1E 00 00 01 00 AC 1E 00 00 01 00 +AD 1E 00 00 02 00 F6 1E 00 00 02 00 F8 1E 00 00 +01 00 FA 1E 00 00 01 00 FB 1E 00 00 01 00 20 1F +00 00 02 00 22 1F 00 00 02 00 38 1F 00 00 01 00 +3A 1F 00 00 00 00 +@ffe0 +EE A4 +@ffea +3C E4 F0 D8 BC A6 3A F1 +@fffe +1E EA +q diff --git a/chronos-ti/Recovery/Chronos Watch/Wireless Updater/Recovery_eZ430_Chronos_rfbsl_433MHz_1_0.txt b/chronos-ti/Recovery/Chronos Watch/Wireless Updater/Recovery_eZ430_Chronos_rfbsl_433MHz_1_0.txt new file mode 100755 index 0000000..15a747e --- /dev/null +++ b/chronos-ti/Recovery/Chronos Watch/Wireless Updater/Recovery_eZ430_Chronos_rfbsl_433MHz_1_0.txt @@ -0,0 +1,133 @@ +@1000 +14 3C 01 3C FF 3F D0 B3 15 F2 03 28 B1 C0 F0 00 +00 00 C0 43 09 F2 00 13 0C 43 B2 D0 03 80 82 01 +B2 93 FE FF 01 20 2C D3 10 01 31 40 7A 2B 3C 40 +0E 1C 3D 40 1A 01 B0 13 3A 17 3C 40 00 1C 3D 40 +AC 10 3E 40 0E 00 B0 13 DC 17 B0 13 04 15 B0 13 +E0 17 02 1B 01 1E 00 29 16 07 17 3C 18 18 04 D3 +05 91 06 FE 07 05 08 45 09 AD 03 07 1E 87 1F 6B +20 F8 0A 00 0B 0C 0C 00 0D 10 0E B0 0F 71 10 2D +11 3B 12 13 13 22 14 F8 15 62 19 1D 1A 1C 1B C7 +1C 00 1D B0 21 B6 22 10 23 EA 24 2A 25 00 26 1F +2B 88 2A 7F 29 59 2C 88 2D 31 2E 09 07 00 AD 00 +BA 5E BA 11 05 00 AD 00 00 00 1B 15 4A 43 D2 53 +26 1D F2 90 05 00 26 1D 05 28 F2 40 20 00 21 1D +4C 43 5F 3C B0 13 66 15 3B 40 1E 1D D2 93 23 1D +07 24 C2 93 27 1D 04 24 2D 4B 3D 53 5C 43 4E 3C +D2 93 23 1D 4D 20 C2 43 23 1D 5F 42 16 1C 5F 4F +18 1C 7F F0 80 00 D2 92 25 1D 18 1C 41 20 5E 42 +19 1C C2 93 27 1D 14 20 4F 93 10 24 C2 43 26 1D +5F 42 1A 1C 47 18 0F 5F 0E 5F 82 4E 1C 1D 3D 43 +5C 43 B0 13 D2 14 D2 43 27 1D 2A 3C 3D 43 25 3C +4F 93 22 24 5F 42 1A 1C 47 18 0E 5E 0F 5E 2F 9B +CB 23 B0 13 1C 12 5C 93 17 20 C2 43 26 1D 2D 4B +5C 43 B0 13 D2 14 92 53 1E 1D 2C 4B 5C 06 0F 4C +5C 0A 0F 5C 0C 5C 0C 5F 1E 42 1C 1D B0 13 84 16 +C2 4C 24 1D 5A 43 04 3C 2D 4B 4C 43 B0 13 D2 14 +4C 4A 1A 17 10 01 3B 15 4B 4C 4C 43 7B 90 BD 00 +06 24 7B 90 31 00 38 28 7B 90 3D 00 35 2C 08 42 +32 C2 03 43 B2 C0 40 00 02 0F B0 13 D2 17 7B 90 +31 00 25 28 7B 90 3D 00 22 2C B0 13 C2 15 4A 4C +7D 40 29 00 4C 43 B0 13 40 16 C2 4B 11 0F A2 B2 +30 0F 10 28 7B 90 32 00 0D 24 7B 90 39 00 0A 24 +7B 90 38 00 07 24 A2 B2 30 0F FD 2F 3F 40 C1 0C +3F 53 FE 2F 4D 4A 4C 43 B0 13 40 16 02 3C C2 4B +11 0F 5C 42 21 0F 02 48 38 17 10 01 2A 15 5C 43 +5A 42 16 1C 3A 50 FB FF 7D 40 06 00 D2 93 1B 1C +18 20 5E 42 1C 1C 47 18 0E 5E 5F 42 1D 1C 0E 5F +82 4E 18 1D 2A 83 7D 42 3E 90 FE FF 0A 20 5E 42 +1E 1C 5F 42 1F 1C 47 18 0F 5F 0E 5F 82 4E 1A 1D +2A 83 0A 93 19 24 1C 42 18 1D 3C 90 30 1D 08 28 +08 4C 09 43 08 5A 09 63 03 20 38 90 FF 2A 02 28 +4C 43 0A 3C 4E 4D 3E 50 16 1C 4D 4A B0 13 94 15 +5C 93 02 20 82 5A 18 1D 28 17 10 01 1B 15 0B 4C +4A 4D B0 13 E8 16 4E 4A 0D 4B 7C 40 7F 00 B0 13 +36 15 6A 42 05 3C 3C 40 0F 00 B0 13 A0 17 7A 53 +7C 40 34 00 B0 13 96 11 A2 B3 30 0F FD 2B 92 C3 +32 0F 7C 40 35 00 B0 13 96 11 3C 40 19 00 B0 13 +A0 17 92 B3 32 0F 0A 28 92 C3 32 0F 92 B3 30 0F +FD 2B 7C 40 3B 00 B0 13 96 11 0D 3C 7C 40 36 00 +B0 13 96 11 7C B0 70 00 F9 23 7C 40 3A 00 B0 13 +96 11 4A 93 D0 23 1A 17 10 01 3B 15 82 93 38 0F +B2 C0 00 02 32 0F E2 93 22 1D 33 20 3E 40 02 01 +0D 43 3C 40 16 1C B0 13 4C 17 7A 40 3B 00 B0 13 +D0 16 4C 93 26 24 7C 40 3F 00 B0 13 C2 15 C2 4C +16 1C 39 40 17 1C 4E 4C 6E 53 C2 4E 20 1D 7B 90 +41 00 05 28 B0 13 E8 16 B0 13 80 17 12 3C E2 93 +20 1D 0B 28 B0 13 D0 16 6B 93 F9 2B B0 13 AE 17 +19 53 F2 53 20 1D 7B 53 F7 3F B0 13 AE 17 D2 43 +23 1D 38 17 10 01 B0 13 62 16 82 43 34 0F B0 13 +EE 15 B0 13 12 17 D2 43 0E 1C D2 43 21 1D B0 13 +94 14 5C 93 16 20 E2 43 21 1D 92 92 1C 1D 1E 1D +03 28 C2 93 27 1D 0D 20 B0 13 BA 10 F2 90 20 00 +21 1D 07 24 92 92 1C 1D 1E 1D EF 2B C2 93 27 1D +F3 27 C2 43 0E 1C 92 92 1C 1D 1E 1D 05 28 C2 93 +27 1D 02 24 10 42 1A 1D 10 01 F2 D0 03 00 4A 02 +B2 F0 3E FF 6C 01 B2 D0 0C 00 6C 01 82 43 66 01 +B2 40 44 00 68 01 32 D0 40 00 82 43 60 01 B2 40 +50 00 62 01 B2 40 6E 11 64 01 32 C0 40 00 3F 40 +22 F4 03 43 0E 43 3F 53 3E 63 FD 2F B2 F0 F0 FF +6E 01 A2 C3 02 01 A2 B3 02 01 F8 2F 10 01 4E 43 +0F 42 32 C2 03 43 1A 3C B0 13 D2 17 4E 4C 3E 50 +00 7E 82 4E 10 0F B0 13 BC 17 B0 13 D2 17 F2 40 +FE 00 11 0F B0 13 C8 17 C2 43 10 0F B2 B0 80 00 +02 0F FC 2B 5E 42 20 0F B0 13 BC 17 4E 9C E4 23 +02 4F 10 01 0A 12 4A 43 7D 42 3C 40 00 1C B0 13 +9C 12 B0 13 66 15 D2 93 23 1D 10 20 C2 43 23 1D +D2 93 19 1C 05 20 5F 42 16 1C CF 93 18 1C 02 38 +4C 43 05 3C D2 42 18 1C 25 1D 5A 43 4C 4A 3A 41 +10 01 4E 4C 3C 40 09 00 B0 13 A0 17 D2 42 25 1D +09 1C C2 4E 0B 1C 0F 4D 47 19 0F 10 7F F0 7F 00 +C2 4F 0C 1C C2 4D 0D 1C 7D 40 06 00 3C 40 08 1C +80 00 9C 12 B2 40 80 5A 5C 01 B2 93 FE FF 09 20 +B2 40 02 10 E0 2B 92 D3 80 01 B0 13 B6 16 32 D0 +F8 00 32 C2 03 43 B0 13 FA 13 B0 13 96 13 B2 40 +04 A5 20 01 FA 3F 0A 12 0A 42 B0 13 FE 16 6F 4D +0C 5F 82 4C 10 0F 5F 43 07 3C B0 13 C8 17 0C 4D +0C 5F E2 4C 10 0F 5F 53 4F 9E F7 2B C2 93 20 0F +02 4A 3A 41 10 01 B0 13 80 17 3C 40 00 40 B0 13 +9C 16 06 3C B2 B0 00 02 32 0F 02 28 B0 13 1A 13 +92 B3 44 03 03 2C D2 93 23 1D F4 23 B0 13 70 17 +80 00 E8 16 5B 15 08 4C 4A 4D 06 4E 0C 48 0D 43 +04 3C FC 46 00 00 1C 53 0D 63 0E 48 0F 43 0E 5A +0F 63 0D 9F F6 2B 02 20 0C 9E F3 2B 5C 43 56 17 +10 01 0F 42 32 C2 03 43 B0 13 D2 17 7C 90 2F 00 +03 28 7C 90 3E 00 03 20 7C D0 80 00 02 3C 7C D0 +C0 00 C2 4C 13 0F 5C 42 20 0F 02 4F 10 01 21 83 +82 43 32 0F 7C 40 30 00 B0 13 96 11 81 43 00 00 +02 3C 91 53 00 00 B1 90 64 00 00 00 FA 2B B0 13 +90 17 82 43 06 0F 21 53 10 01 3B 15 0B 4C 48 4D +4A 43 0A 3C 4E 4A 0E 5E 0F 4B 0F 5E 5D 4F 01 00 +6C 4F B0 13 40 16 5A 53 4A 98 F4 2B 38 17 10 01 +21 83 0E 42 B0 13 FE 16 4D 4D 0C 5D 82 4C 10 0F +B0 13 C8 17 5F 42 20 0F 81 4F 00 00 02 4E 21 53 +10 01 C2 43 0E 1C C2 43 24 1D 82 43 1E 1D 82 43 +1C 1D C2 43 26 1D C2 43 27 1D 82 43 32 0F 10 01 +7C F3 7E F3 0F 4E 0D 4C 0E 43 1C 43 0D 5D 0E 6E +0E 9F 01 28 0E 8F 0C 6C F9 2B 10 01 3C 90 00 80 +02 28 3C 40 FF 7F 82 4C 54 03 92 C3 44 03 B2 D0 +24 01 40 03 10 01 D2 C3 05 02 D2 C3 03 02 D2 D3 +07 02 D2 C3 19 02 D2 C3 1D 02 D2 D3 1B 02 10 01 +4C 4A B0 13 C2 15 4B 4C 48 4B 4C 4A B0 13 C2 15 +4B 4C 48 9C F9 23 10 01 D2 43 22 1D B0 13 90 17 +7C 40 3A 00 B0 13 96 11 82 43 32 0F 10 01 32 C2 +03 43 B0 13 D2 17 4C 4C 3C D0 40 00 47 18 0C 5C +10 01 7C 40 8D 00 B0 13 4E 14 7D 40 2D 00 3C 40 +52 10 80 00 1A 16 0A 12 21 83 0A 4C 81 4A 00 00 +0D 41 5C 43 B0 13 E8 17 F9 3F 0F 4C 0F 5D 03 3C +CC 43 00 00 1C 53 0C 9F FB 23 10 01 0F 4C 04 3C +CF 4D 00 00 1F 53 3E 53 0E 93 FA 23 10 01 0F 4C +04 3C FF 4D 00 00 1F 53 3E 53 0E 93 FA 23 10 01 +92 C3 44 03 B2 F0 CF FF 40 03 82 43 50 03 10 01 +82 43 32 0F E2 43 22 1D 7C 40 34 00 80 00 96 11 +7C 40 36 00 B0 13 96 11 7C B0 70 00 F9 23 10 01 +B0 13 9C 16 92 B3 44 03 FD 2B 80 00 70 17 7C 40 +3F 00 B0 13 C2 15 C9 4C 00 00 10 01 B0 13 D2 17 +F2 40 3D 00 11 0F 10 01 B2 B0 20 00 02 0F FC 2B +10 01 B2 B0 10 00 02 0F FC 2B 10 01 80 00 5E 17 +80 00 E4 17 80 00 26 17 10 01 +@17F0 +FF FF 18 10 A5 3C 5A C3 FF FF 00 10 +@17FC +FF FF FF FF +q diff --git a/chronos-ti/Recovery/Chronos Watch/Wireless Updater/Recovery_eZ430_Chronos_rfbsl_868MHz_1_0.txt b/chronos-ti/Recovery/Chronos Watch/Wireless Updater/Recovery_eZ430_Chronos_rfbsl_868MHz_1_0.txt new file mode 100755 index 0000000..eb14f89 --- /dev/null +++ b/chronos-ti/Recovery/Chronos Watch/Wireless Updater/Recovery_eZ430_Chronos_rfbsl_868MHz_1_0.txt @@ -0,0 +1,133 @@ +@1000 +14 3C 01 3C FF 3F D0 B3 15 F2 03 28 B1 C0 F0 00 +00 00 C0 43 09 F2 00 13 0C 43 B2 D0 03 80 82 01 +B2 93 FE FF 01 20 2C D3 10 01 31 40 7A 2B 3C 40 +0E 1C 3D 40 1A 01 B0 13 3A 17 3C 40 00 1C 3D 40 +AC 10 3E 40 0E 00 B0 13 DC 17 B0 13 04 15 B0 13 +E0 17 02 1B 01 1E 00 29 16 07 17 3C 18 18 04 D3 +05 91 06 FE 07 05 08 45 09 AD 03 07 1E 87 1F 6B +20 F8 0A 00 0B 0C 0C 00 0D 21 0E 71 0F 7A 10 2D +11 3B 12 13 13 22 14 F8 15 62 19 1D 1A 1C 1B C7 +1C 00 1D B0 21 B6 22 10 23 EA 24 2A 25 00 26 1F +2B 88 2A 7F 29 59 2C 88 2D 31 2E 09 07 00 AD 00 +BA 5E BA 11 05 00 AD 00 00 00 1B 15 4A 43 D2 53 +26 1D F2 90 05 00 26 1D 05 28 F2 40 20 00 21 1D +4C 43 5F 3C B0 13 66 15 3B 40 1E 1D D2 93 23 1D +07 24 C2 93 27 1D 04 24 2D 4B 3D 53 5C 43 4E 3C +D2 93 23 1D 4D 20 C2 43 23 1D 5F 42 16 1C 5F 4F +18 1C 7F F0 80 00 D2 92 25 1D 18 1C 41 20 5E 42 +19 1C C2 93 27 1D 14 20 4F 93 10 24 C2 43 26 1D +5F 42 1A 1C 47 18 0F 5F 0E 5F 82 4E 1C 1D 3D 43 +5C 43 B0 13 D2 14 D2 43 27 1D 2A 3C 3D 43 25 3C +4F 93 22 24 5F 42 1A 1C 47 18 0E 5E 0F 5E 2F 9B +CB 23 B0 13 1C 12 5C 93 17 20 C2 43 26 1D 2D 4B +5C 43 B0 13 D2 14 92 53 1E 1D 2C 4B 5C 06 0F 4C +5C 0A 0F 5C 0C 5C 0C 5F 1E 42 1C 1D B0 13 84 16 +C2 4C 24 1D 5A 43 04 3C 2D 4B 4C 43 B0 13 D2 14 +4C 4A 1A 17 10 01 3B 15 4B 4C 4C 43 7B 90 BD 00 +06 24 7B 90 31 00 38 28 7B 90 3D 00 35 2C 08 42 +32 C2 03 43 B2 C0 40 00 02 0F B0 13 D2 17 7B 90 +31 00 25 28 7B 90 3D 00 22 2C B0 13 C2 15 4A 4C +7D 40 29 00 4C 43 B0 13 40 16 C2 4B 11 0F A2 B2 +30 0F 10 28 7B 90 32 00 0D 24 7B 90 39 00 0A 24 +7B 90 38 00 07 24 A2 B2 30 0F FD 2F 3F 40 C1 0C +3F 53 FE 2F 4D 4A 4C 43 B0 13 40 16 02 3C C2 4B +11 0F 5C 42 21 0F 02 48 38 17 10 01 2A 15 5C 43 +5A 42 16 1C 3A 50 FB FF 7D 40 06 00 D2 93 1B 1C +18 20 5E 42 1C 1C 47 18 0E 5E 5F 42 1D 1C 0E 5F +82 4E 18 1D 2A 83 7D 42 3E 90 FE FF 0A 20 5E 42 +1E 1C 5F 42 1F 1C 47 18 0F 5F 0E 5F 82 4E 1A 1D +2A 83 0A 93 19 24 1C 42 18 1D 3C 90 30 1D 08 28 +08 4C 09 43 08 5A 09 63 03 20 38 90 FF 2A 02 28 +4C 43 0A 3C 4E 4D 3E 50 16 1C 4D 4A B0 13 94 15 +5C 93 02 20 82 5A 18 1D 28 17 10 01 1B 15 0B 4C +4A 4D B0 13 E8 16 4E 4A 0D 4B 7C 40 7F 00 B0 13 +36 15 6A 42 05 3C 3C 40 0F 00 B0 13 A0 17 7A 53 +7C 40 34 00 B0 13 96 11 A2 B3 30 0F FD 2B 92 C3 +32 0F 7C 40 35 00 B0 13 96 11 3C 40 19 00 B0 13 +A0 17 92 B3 32 0F 0A 28 92 C3 32 0F 92 B3 30 0F +FD 2B 7C 40 3B 00 B0 13 96 11 0D 3C 7C 40 36 00 +B0 13 96 11 7C B0 70 00 F9 23 7C 40 3A 00 B0 13 +96 11 4A 93 D0 23 1A 17 10 01 3B 15 82 93 38 0F +B2 C0 00 02 32 0F E2 93 22 1D 33 20 3E 40 02 01 +0D 43 3C 40 16 1C B0 13 4C 17 7A 40 3B 00 B0 13 +D0 16 4C 93 26 24 7C 40 3F 00 B0 13 C2 15 C2 4C +16 1C 39 40 17 1C 4E 4C 6E 53 C2 4E 20 1D 7B 90 +41 00 05 28 B0 13 E8 16 B0 13 80 17 12 3C E2 93 +20 1D 0B 28 B0 13 D0 16 6B 93 F9 2B B0 13 AE 17 +19 53 F2 53 20 1D 7B 53 F7 3F B0 13 AE 17 D2 43 +23 1D 38 17 10 01 B0 13 62 16 82 43 34 0F B0 13 +EE 15 B0 13 12 17 D2 43 0E 1C D2 43 21 1D B0 13 +94 14 5C 93 16 20 E2 43 21 1D 92 92 1C 1D 1E 1D +03 28 C2 93 27 1D 0D 20 B0 13 BA 10 F2 90 20 00 +21 1D 07 24 92 92 1C 1D 1E 1D EF 2B C2 93 27 1D +F3 27 C2 43 0E 1C 92 92 1C 1D 1E 1D 05 28 C2 93 +27 1D 02 24 10 42 1A 1D 10 01 F2 D0 03 00 4A 02 +B2 F0 3E FF 6C 01 B2 D0 0C 00 6C 01 82 43 66 01 +B2 40 44 00 68 01 32 D0 40 00 82 43 60 01 B2 40 +50 00 62 01 B2 40 6E 11 64 01 32 C0 40 00 3F 40 +22 F4 03 43 0E 43 3F 53 3E 63 FD 2F B2 F0 F0 FF +6E 01 A2 C3 02 01 A2 B3 02 01 F8 2F 10 01 4E 43 +0F 42 32 C2 03 43 1A 3C B0 13 D2 17 4E 4C 3E 50 +00 7E 82 4E 10 0F B0 13 BC 17 B0 13 D2 17 F2 40 +FE 00 11 0F B0 13 C8 17 C2 43 10 0F B2 B0 80 00 +02 0F FC 2B 5E 42 20 0F B0 13 BC 17 4E 9C E4 23 +02 4F 10 01 0A 12 4A 43 7D 42 3C 40 00 1C B0 13 +9C 12 B0 13 66 15 D2 93 23 1D 10 20 C2 43 23 1D +D2 93 19 1C 05 20 5F 42 16 1C CF 93 18 1C 02 38 +4C 43 05 3C D2 42 18 1C 25 1D 5A 43 4C 4A 3A 41 +10 01 4E 4C 3C 40 09 00 B0 13 A0 17 D2 42 25 1D +09 1C C2 4E 0B 1C 0F 4D 47 19 0F 10 7F F0 7F 00 +C2 4F 0C 1C C2 4D 0D 1C 7D 40 06 00 3C 40 08 1C +80 00 9C 12 B2 40 80 5A 5C 01 B2 93 FE FF 09 20 +B2 40 02 10 E0 2B 92 D3 80 01 B0 13 B6 16 32 D0 +F8 00 32 C2 03 43 B0 13 FA 13 B0 13 96 13 B2 40 +04 A5 20 01 FA 3F 0A 12 0A 42 B0 13 FE 16 6F 4D +0C 5F 82 4C 10 0F 5F 43 07 3C B0 13 C8 17 0C 4D +0C 5F E2 4C 10 0F 5F 53 4F 9E F7 2B C2 93 20 0F +02 4A 3A 41 10 01 B0 13 80 17 3C 40 00 40 B0 13 +9C 16 06 3C B2 B0 00 02 32 0F 02 28 B0 13 1A 13 +92 B3 44 03 03 2C D2 93 23 1D F4 23 B0 13 70 17 +80 00 E8 16 5B 15 08 4C 4A 4D 06 4E 0C 48 0D 43 +04 3C FC 46 00 00 1C 53 0D 63 0E 48 0F 43 0E 5A +0F 63 0D 9F F6 2B 02 20 0C 9E F3 2B 5C 43 56 17 +10 01 0F 42 32 C2 03 43 B0 13 D2 17 7C 90 2F 00 +03 28 7C 90 3E 00 03 20 7C D0 80 00 02 3C 7C D0 +C0 00 C2 4C 13 0F 5C 42 20 0F 02 4F 10 01 21 83 +82 43 32 0F 7C 40 30 00 B0 13 96 11 81 43 00 00 +02 3C 91 53 00 00 B1 90 64 00 00 00 FA 2B B0 13 +90 17 82 43 06 0F 21 53 10 01 3B 15 0B 4C 48 4D +4A 43 0A 3C 4E 4A 0E 5E 0F 4B 0F 5E 5D 4F 01 00 +6C 4F B0 13 40 16 5A 53 4A 98 F4 2B 38 17 10 01 +21 83 0E 42 B0 13 FE 16 4D 4D 0C 5D 82 4C 10 0F +B0 13 C8 17 5F 42 20 0F 81 4F 00 00 02 4E 21 53 +10 01 C2 43 0E 1C C2 43 24 1D 82 43 1E 1D 82 43 +1C 1D C2 43 26 1D C2 43 27 1D 82 43 32 0F 10 01 +7C F3 7E F3 0F 4E 0D 4C 0E 43 1C 43 0D 5D 0E 6E +0E 9F 01 28 0E 8F 0C 6C F9 2B 10 01 3C 90 00 80 +02 28 3C 40 FF 7F 82 4C 54 03 92 C3 44 03 B2 D0 +24 01 40 03 10 01 D2 C3 05 02 D2 C3 03 02 D2 D3 +07 02 D2 C3 19 02 D2 C3 1D 02 D2 D3 1B 02 10 01 +4C 4A B0 13 C2 15 4B 4C 48 4B 4C 4A B0 13 C2 15 +4B 4C 48 9C F9 23 10 01 D2 43 22 1D B0 13 90 17 +7C 40 3A 00 B0 13 96 11 82 43 32 0F 10 01 32 C2 +03 43 B0 13 D2 17 4C 4C 3C D0 40 00 47 18 0C 5C +10 01 7C 40 8C 00 B0 13 4E 14 7D 40 2D 00 3C 40 +52 10 80 00 1A 16 0A 12 21 83 0A 4C 81 4A 00 00 +0D 41 5C 43 B0 13 E8 17 F9 3F 0F 4C 0F 5D 03 3C +CC 43 00 00 1C 53 0C 9F FB 23 10 01 0F 4C 04 3C +CF 4D 00 00 1F 53 3E 53 0E 93 FA 23 10 01 0F 4C +04 3C FF 4D 00 00 1F 53 3E 53 0E 93 FA 23 10 01 +92 C3 44 03 B2 F0 CF FF 40 03 82 43 50 03 10 01 +82 43 32 0F E2 43 22 1D 7C 40 34 00 80 00 96 11 +7C 40 36 00 B0 13 96 11 7C B0 70 00 F9 23 10 01 +B0 13 9C 16 92 B3 44 03 FD 2B 80 00 70 17 7C 40 +3F 00 B0 13 C2 15 C9 4C 00 00 10 01 B0 13 D2 17 +F2 40 3D 00 11 0F 10 01 B2 B0 20 00 02 0F FC 2B +10 01 B2 B0 10 00 02 0F FC 2B 10 01 80 00 5E 17 +80 00 E4 17 80 00 26 17 10 01 +@17F0 +FF FF 18 10 A5 3C 5A C3 FF FF 00 10 +@17FC +FF FF FF FF +q diff --git a/chronos-ti/Recovery/Chronos Watch/Wireless Updater/Recovery_eZ430_Chronos_rfbsl_915MHz_1_0.txt b/chronos-ti/Recovery/Chronos Watch/Wireless Updater/Recovery_eZ430_Chronos_rfbsl_915MHz_1_0.txt new file mode 100755 index 0000000..5fbac7c --- /dev/null +++ b/chronos-ti/Recovery/Chronos Watch/Wireless Updater/Recovery_eZ430_Chronos_rfbsl_915MHz_1_0.txt @@ -0,0 +1,133 @@ +@1000 +14 3C 01 3C FF 3F D0 B3 15 F2 03 28 B1 C0 F0 00 +00 00 C0 43 09 F2 00 13 0C 43 B2 D0 03 80 82 01 +B2 93 FE FF 01 20 2C D3 10 01 31 40 7A 2B 3C 40 +0E 1C 3D 40 1A 01 B0 13 3A 17 3C 40 00 1C 3D 40 +AC 10 3E 40 0E 00 B0 13 DC 17 B0 13 04 15 B0 13 +E0 17 02 1B 01 1E 00 29 16 07 17 3C 18 18 04 D3 +05 91 06 FE 07 05 08 45 09 AD 03 07 1E 87 1F 6B +20 F8 0A 14 0B 0C 0C 00 0D 22 0E B1 0F 3B 10 2D +11 3B 12 13 13 22 14 F8 15 62 19 1D 1A 1C 1B C7 +1C 00 1D B0 21 B6 22 10 23 EA 24 2A 25 00 26 1F +2B 88 2A 7F 29 59 2C 88 2D 31 2E 09 07 00 AD 00 +BA 5E BA 11 05 00 AD 00 00 00 1B 15 4A 43 D2 53 +26 1D F2 90 05 00 26 1D 05 28 F2 40 20 00 21 1D +4C 43 5F 3C B0 13 66 15 3B 40 1E 1D D2 93 23 1D +07 24 C2 93 27 1D 04 24 2D 4B 3D 53 5C 43 4E 3C +D2 93 23 1D 4D 20 C2 43 23 1D 5F 42 16 1C 5F 4F +18 1C 7F F0 80 00 D2 92 25 1D 18 1C 41 20 5E 42 +19 1C C2 93 27 1D 14 20 4F 93 10 24 C2 43 26 1D +5F 42 1A 1C 47 18 0F 5F 0E 5F 82 4E 1C 1D 3D 43 +5C 43 B0 13 D2 14 D2 43 27 1D 2A 3C 3D 43 25 3C +4F 93 22 24 5F 42 1A 1C 47 18 0E 5E 0F 5E 2F 9B +CB 23 B0 13 1C 12 5C 93 17 20 C2 43 26 1D 2D 4B +5C 43 B0 13 D2 14 92 53 1E 1D 2C 4B 5C 06 0F 4C +5C 0A 0F 5C 0C 5C 0C 5F 1E 42 1C 1D B0 13 84 16 +C2 4C 24 1D 5A 43 04 3C 2D 4B 4C 43 B0 13 D2 14 +4C 4A 1A 17 10 01 3B 15 4B 4C 4C 43 7B 90 BD 00 +06 24 7B 90 31 00 38 28 7B 90 3D 00 35 2C 08 42 +32 C2 03 43 B2 C0 40 00 02 0F B0 13 D2 17 7B 90 +31 00 25 28 7B 90 3D 00 22 2C B0 13 C2 15 4A 4C +7D 40 29 00 4C 43 B0 13 40 16 C2 4B 11 0F A2 B2 +30 0F 10 28 7B 90 32 00 0D 24 7B 90 39 00 0A 24 +7B 90 38 00 07 24 A2 B2 30 0F FD 2F 3F 40 C1 0C +3F 53 FE 2F 4D 4A 4C 43 B0 13 40 16 02 3C C2 4B +11 0F 5C 42 21 0F 02 48 38 17 10 01 2A 15 5C 43 +5A 42 16 1C 3A 50 FB FF 7D 40 06 00 D2 93 1B 1C +18 20 5E 42 1C 1C 47 18 0E 5E 5F 42 1D 1C 0E 5F +82 4E 18 1D 2A 83 7D 42 3E 90 FE FF 0A 20 5E 42 +1E 1C 5F 42 1F 1C 47 18 0F 5F 0E 5F 82 4E 1A 1D +2A 83 0A 93 19 24 1C 42 18 1D 3C 90 30 1D 08 28 +08 4C 09 43 08 5A 09 63 03 20 38 90 FF 2A 02 28 +4C 43 0A 3C 4E 4D 3E 50 16 1C 4D 4A B0 13 94 15 +5C 93 02 20 82 5A 18 1D 28 17 10 01 1B 15 0B 4C +4A 4D B0 13 E8 16 4E 4A 0D 4B 7C 40 7F 00 B0 13 +36 15 6A 42 05 3C 3C 40 0F 00 B0 13 A0 17 7A 53 +7C 40 34 00 B0 13 96 11 A2 B3 30 0F FD 2B 92 C3 +32 0F 7C 40 35 00 B0 13 96 11 3C 40 19 00 B0 13 +A0 17 92 B3 32 0F 0A 28 92 C3 32 0F 92 B3 30 0F +FD 2B 7C 40 3B 00 B0 13 96 11 0D 3C 7C 40 36 00 +B0 13 96 11 7C B0 70 00 F9 23 7C 40 3A 00 B0 13 +96 11 4A 93 D0 23 1A 17 10 01 3B 15 82 93 38 0F +B2 C0 00 02 32 0F E2 93 22 1D 33 20 3E 40 02 01 +0D 43 3C 40 16 1C B0 13 4C 17 7A 40 3B 00 B0 13 +D0 16 4C 93 26 24 7C 40 3F 00 B0 13 C2 15 C2 4C +16 1C 39 40 17 1C 4E 4C 6E 53 C2 4E 20 1D 7B 90 +41 00 05 28 B0 13 E8 16 B0 13 80 17 12 3C E2 93 +20 1D 0B 28 B0 13 D0 16 6B 93 F9 2B B0 13 AE 17 +19 53 F2 53 20 1D 7B 53 F7 3F B0 13 AE 17 D2 43 +23 1D 38 17 10 01 B0 13 62 16 82 43 34 0F B0 13 +EE 15 B0 13 12 17 D2 43 0E 1C D2 43 21 1D B0 13 +94 14 5C 93 16 20 E2 43 21 1D 92 92 1C 1D 1E 1D +03 28 C2 93 27 1D 0D 20 B0 13 BA 10 F2 90 20 00 +21 1D 07 24 92 92 1C 1D 1E 1D EF 2B C2 93 27 1D +F3 27 C2 43 0E 1C 92 92 1C 1D 1E 1D 05 28 C2 93 +27 1D 02 24 10 42 1A 1D 10 01 F2 D0 03 00 4A 02 +B2 F0 3E FF 6C 01 B2 D0 0C 00 6C 01 82 43 66 01 +B2 40 44 00 68 01 32 D0 40 00 82 43 60 01 B2 40 +50 00 62 01 B2 40 6E 11 64 01 32 C0 40 00 3F 40 +22 F4 03 43 0E 43 3F 53 3E 63 FD 2F B2 F0 F0 FF +6E 01 A2 C3 02 01 A2 B3 02 01 F8 2F 10 01 4E 43 +0F 42 32 C2 03 43 1A 3C B0 13 D2 17 4E 4C 3E 50 +00 7E 82 4E 10 0F B0 13 BC 17 B0 13 D2 17 F2 40 +FE 00 11 0F B0 13 C8 17 C2 43 10 0F B2 B0 80 00 +02 0F FC 2B 5E 42 20 0F B0 13 BC 17 4E 9C E4 23 +02 4F 10 01 0A 12 4A 43 7D 42 3C 40 00 1C B0 13 +9C 12 B0 13 66 15 D2 93 23 1D 10 20 C2 43 23 1D +D2 93 19 1C 05 20 5F 42 16 1C CF 93 18 1C 02 38 +4C 43 05 3C D2 42 18 1C 25 1D 5A 43 4C 4A 3A 41 +10 01 4E 4C 3C 40 09 00 B0 13 A0 17 D2 42 25 1D +09 1C C2 4E 0B 1C 0F 4D 47 19 0F 10 7F F0 7F 00 +C2 4F 0C 1C C2 4D 0D 1C 7D 40 06 00 3C 40 08 1C +80 00 9C 12 B2 40 80 5A 5C 01 B2 93 FE FF 09 20 +B2 40 02 10 E0 2B 92 D3 80 01 B0 13 B6 16 32 D0 +F8 00 32 C2 03 43 B0 13 FA 13 B0 13 96 13 B2 40 +04 A5 20 01 FA 3F 0A 12 0A 42 B0 13 FE 16 6F 4D +0C 5F 82 4C 10 0F 5F 43 07 3C B0 13 C8 17 0C 4D +0C 5F E2 4C 10 0F 5F 53 4F 9E F7 2B C2 93 20 0F +02 4A 3A 41 10 01 B0 13 80 17 3C 40 00 40 B0 13 +9C 16 06 3C B2 B0 00 02 32 0F 02 28 B0 13 1A 13 +92 B3 44 03 03 2C D2 93 23 1D F4 23 B0 13 70 17 +80 00 E8 16 5B 15 08 4C 4A 4D 06 4E 0C 48 0D 43 +04 3C FC 46 00 00 1C 53 0D 63 0E 48 0F 43 0E 5A +0F 63 0D 9F F6 2B 02 20 0C 9E F3 2B 5C 43 56 17 +10 01 0F 42 32 C2 03 43 B0 13 D2 17 7C 90 2F 00 +03 28 7C 90 3E 00 03 20 7C D0 80 00 02 3C 7C D0 +C0 00 C2 4C 13 0F 5C 42 20 0F 02 4F 10 01 21 83 +82 43 32 0F 7C 40 30 00 B0 13 96 11 81 43 00 00 +02 3C 91 53 00 00 B1 90 64 00 00 00 FA 2B B0 13 +90 17 82 43 06 0F 21 53 10 01 3B 15 0B 4C 48 4D +4A 43 0A 3C 4E 4A 0E 5E 0F 4B 0F 5E 5D 4F 01 00 +6C 4F B0 13 40 16 5A 53 4A 98 F4 2B 38 17 10 01 +21 83 0E 42 B0 13 FE 16 4D 4D 0C 5D 82 4C 10 0F +B0 13 C8 17 5F 42 20 0F 81 4F 00 00 02 4E 21 53 +10 01 C2 43 0E 1C C2 43 24 1D 82 43 1E 1D 82 43 +1C 1D C2 43 26 1D C2 43 27 1D 82 43 32 0F 10 01 +7C F3 7E F3 0F 4E 0D 4C 0E 43 1C 43 0D 5D 0E 6E +0E 9F 01 28 0E 8F 0C 6C F9 2B 10 01 3C 90 00 80 +02 28 3C 40 FF 7F 82 4C 54 03 92 C3 44 03 B2 D0 +24 01 40 03 10 01 D2 C3 05 02 D2 C3 03 02 D2 D3 +07 02 D2 C3 19 02 D2 C3 1D 02 D2 D3 1B 02 10 01 +4C 4A B0 13 C2 15 4B 4C 48 4B 4C 4A B0 13 C2 15 +4B 4C 48 9C F9 23 10 01 D2 43 22 1D B0 13 90 17 +7C 40 3A 00 B0 13 96 11 82 43 32 0F 10 01 32 C2 +03 43 B0 13 D2 17 4C 4C 3C D0 40 00 47 18 0C 5C +10 01 7C 40 8B 00 B0 13 4E 14 7D 40 2D 00 3C 40 +52 10 80 00 1A 16 0A 12 21 83 0A 4C 81 4A 00 00 +0D 41 5C 43 B0 13 E8 17 F9 3F 0F 4C 0F 5D 03 3C +CC 43 00 00 1C 53 0C 9F FB 23 10 01 0F 4C 04 3C +CF 4D 00 00 1F 53 3E 53 0E 93 FA 23 10 01 0F 4C +04 3C FF 4D 00 00 1F 53 3E 53 0E 93 FA 23 10 01 +92 C3 44 03 B2 F0 CF FF 40 03 82 43 50 03 10 01 +82 43 32 0F E2 43 22 1D 7C 40 34 00 80 00 96 11 +7C 40 36 00 B0 13 96 11 7C B0 70 00 F9 23 10 01 +B0 13 9C 16 92 B3 44 03 FD 2B 80 00 70 17 7C 40 +3F 00 B0 13 C2 15 C9 4C 00 00 10 01 B0 13 D2 17 +F2 40 3D 00 11 0F 10 01 B2 B0 20 00 02 0F FC 2B +10 01 B2 B0 10 00 02 0F FC 2B 10 01 80 00 5E 17 +80 00 E4 17 80 00 26 17 10 01 +@17F0 +FF FF 18 10 A5 3C 5A C3 FF FF 00 10 +@17FC +FF FF FF FF +q diff --git a/chronos-ti/Recovery/RF Access Point/Recovery_eZ430-Chronos_AP_433MHz_1_2.hex b/chronos-ti/Recovery/RF Access Point/Recovery_eZ430-Chronos_AP_433MHz_1_2.hex new file mode 100755 index 0000000..44e3e4d --- /dev/null +++ b/chronos-ti/Recovery/RF Access Point/Recovery_eZ430-Chronos_AP_433MHz_1_2.hex @@ -0,0 +1,1714 @@ +:020000040000FA +:060000000200E90211D923 +:03000B0002127965 +:030013000212884E +:03001B0002129737 +:030023000212A620 +:03002B000212B509 +:0300330002500375 +:03003B000212C4EA +:030043000212D3D3 +:03004B000211F9A6 +:030053000212E2B4 +:030063000212275F +:03006B000250A898 +:030073000212F185 +:03007B000213006D +:030083000211A3C4 +:10008B0002130F00000080FB1200F8B900030200FE +:10009B00E3E479217812B800028004F709D8FCE474 +:1000AB0090F3FF78AC79068002F0A3D8FCD9FA90D4 +:1000BB00F9AAAA82AB839000FB78AA79028015E497 +:1000CB0093A3AC82AD838A828B83F0A3AA82AB838A +:1000DB008C828D83D8E9D9E7120A2512008E75D050 +:1000EB000075814F7510FF7511F302009379012292 +:1000FB0087D6120000C201000000000001000000C2 +:10010B00F1490200FFFFFFFF0032506E0E278DFFFB +:10011B0000000001000000000000000000000000D3 +:10012B0000000000000000000000000000000000C4 +:10013B0000000000000000000000000000000000B4 +:10014B00B242873F183B0543FC34B4407856341019 +:10015B00020101010008070605040302010055AA6C +:10016B0055AA55AA55AA556CDC0200A402470347B1 +:10017B0003470347034F03200700CABA5EBA1109AE +:10018B000300CA000500CA000000010001000000C6 +:10019B000000FFFFFFFF0001804020100884422178 +:1001AB009048A45229140A85C261B058ACD66B355D +:1001BB009ACD6633994CA653A9542A95CAE5F27980 +:1001CB003C9ECF67B3D96CB65B2D160B058241A055 +:1001DB005028944AA5D269341A8D462391C8E472EB +:1001EB00391C8EC7E3F1F8FCFEFF7F3F1F0F07831F +:1001FB00C1E070389CCEE7F3F97CBEDF6F379B4DC7 +:10020B0026138944221188C4623198CCE673B95CF9 +:10021B00AED7EB75BADD6EB7DB6D361B0D06038102 +:10022B00C06030188CC663B1D8ECF67B3D1E8F478F +:10023B00A3D1E8F47ABD5EAF57AB55AAD5EAF5FA70 +:10024B00FD7EBF5F2F178B45A251A8D46AB5DAED9F +:10025B00763B1D0E87C3E1F078BCDEEF77BB5D2EDE +:10026B0097CB65B2592C964B25924924120904025F +:10027B000180402010088442219048A45229140A7E +:10028B0085C261B058ACD66B359ACD6633994CA606 +:10029B0053A9542A95CAE5013C1201100102000032 +:1002AB00205104A6160900010203010902430002B2 +:1002BB00010080190904000001020201000524005D +:1002CB00100104240202052406000105240100018B +:1002DB000705820340004009040100020A000000E8 +:1002EB0007058402400001070504024000010403D6 +:1002FB00090424035400650078006100730020009A +:10030B0049006E0073007400720075006D0065008B +:10031B006E00740073001E03430043003100310074 +:10032B0031003100200055005300420020004300F3 +:10033B00440043000803300030003100BF020000CE +:10034B00E2020000E066701008A3E066700A08A3E2 +:10035B00E066700408A3E06622C3E09608A3E0966B +:10036B0008A3E09608A3E09622BB0102E722C08215 +:10037B00C08389828A83BB0003E08002E493D0832D +:10038B00D08222BB000EC082C0838A838982F0D0C8 +:10039B0083D08222BB0101F722080808EAC0E0EBF8 +:1003AB00C0E086F0E7A4FA180986F0E7A42AFA1849 +:1003BB000986F0E7A42AFA180986F0E7A42AFA19A5 +:1003CB0086F0E7A4FBE5F02AFA190886F0E7A42BE0 +:1003DB00FBE5F03AFA190886F0E7A42BFBE5F03AB7 +:1003EB00FA18180986F0E7A4C5F02BFBE43AFA19C2 +:1003FB0008E7C5F0C6A426F6E5F03BFBE43AFA188D +:10040B0086F0E7A4F6E5F00826F6E43B08F6E43AB6 +:10041B0008F6D0E0FBD0E0FA22E4CFC0E0E4CEC097 +:10042B00E0E4CDC0E0E4CCC0E075F020C3E633F6E9 +:10043B0008E633F608E633F608E633F6181818EC38 +:10044B0033FCED33FDEE33FEEF33FFC3EC9709EDD9 +:10045B009709EE9709EF97191919400FFFEC97FCC5 +:10046B0009ED97FD09EE97FE191906D5F0BEECF7CD +:10047B0009EDF709EEF709EFF7191919D0E0FCD0E0 +:10048B00E0FDD0E0FED0E0FF226016080808C6C3EE +:10049B0013C618C613C618C613C618C613C6D5E09E +:1004AB00EA227009080808226016181818C6C33308 +:1004BB00C608C633C608C633C608C633C6D5E0EA77 +:1004CB0022E627F60809E637F60809E637F60809A3 +:1004DB00E637F622E026F608A3E036F608A3E03668 +:1004EB00F608A3E036F622E056F608A3E056F60827 +:1004FB00A3E056F608A3E056F622E647F60809E60F +:10050B0047F60809E647F60809E647F622E046F003 +:10051B0008A3E046F008A3E046F008A3E046F0226B +:10052B00E0F608A3E0F608A3E0F608A3E0F622E65F +:10053B00F008A3E6F008A3E6F008A3E6F022CAC091 +:10054B00E0E6F0A308DAFAD0E0FA22CAC0E0E0A3B2 +:10055B00C582CCC582C583CDC583F0A3C582CCC56E +:10056B0082C583CDC583DAE6D0E0CA22C3E498F80E +:10057B00E499F91205B88026C3E49AFAE49BFBE9E7 +:10058B0020E7E91205B8E498F8E499F922C3E49856 +:10059B00F8E499F91205B8E498F8E499F9C3E49AE8 +:1005AB00FAE49BFB22EB20E7CFE920E7E0B9001050 +:1005BB00BB0008E88AF084F8AAF022E4FBC8FA2210 +:1005CB00EB70227B10C833C8C933C9335007C39AA9 +:1005DB00C3DBF280069A50012ADBEAC833F4C8C9A0 +:1005EB0033F4C9FA2275F008E4C833C8C933C933E8 +:1005FB00C99AC99B5004C92AC93BD5F0ECFBC83337 +:10060B00F4C8E4C9FA22600C08C6C313C618C61393 +:10061B00C6D5E0F422700422600D18C6C333C60899 +:10062B00C633C6D5E0F41822251010AF08F51040DC +:10063B000215118008F51040021511D2AF22C0D05F +:10064B00251010AF08F510500205118008F5105059 +:10065B00020511D2AFD0D0222510F58210AF08F5CC +:10066B0010400215118008F51040021511D2AF850C +:10067B001183222510F582E43511F58322E47325CD +:10068B0010C582C0E0E51134FFC583C0E0E510C39F +:10069B00958224F9F8E4C5A8858311858210C5A835 +:1006AB00E8CEF0A3E520F0A37808E608F0A3DEFA85 +:1006BB00EFF0A3E58124FBF8E608F0A3E608F0A32E +:1006CB000808E608F0A3E608F0A315811581D0E031 +:1006DB00FED0E0F815811581E8C0E0EEC0E0228580 +:1006EB001183851082E0A3FEE0A3F5207808E0A338 +:1006FB00F608DFFAE0A3FFE0A3C0E0E0A3C0E0E070 +:10070B00A3C0E0E0A3C0E0E4C5A8858210858311F7 +:10071B00C5A8D083D08222C0D02510C582C0E0E509 +:10072B001134FFC583C0E0E510C3958224F310AFED +:10073B00088583118582108008858311858210D2EC +:10074B00AFC8F0A3E9F0A3EAF0A3EBF0A37908E7B5 +:10075B0009F0A3D8FAECF0A3EDF0A3EEF0A3EFF0C1 +:10076B00A3D0E0F0A3D0E0F0A3D0E0F0A3E520F01D +:10077B00A3E5F0F0A322851183851082E0C0E0A3EE +:10078B00E0F9A3E0FAA3E0FBA37808E0F608A3DF07 +:10079B00FAE0FCA3E0FDA3E0FEA3E0FFA3E0C0E0D2 +:1007AB00A3E0C0E0A3E0F5D0A3E0F520A3E0A3F520 +:1007BB00F0E4C5A8858311858210C5A8D082D083AB +:1007CB00D0E0F8D0E0327403800474028000C0E003 +:1007DB00F404120663D0E0120549227403800474FA +:1007EB00028000CCC0E0EDC0E0E510C39CCCAD11A5 +:1007FB0050011D10AF068C108D1180068C108D11C1 +:10080B00D2AF120556D0E0FDD0E0FC22D083D082CF +:10081B00C5F0E493A3C5F0C395F0F5F0E493A3C33F +:10082B0095F04005E5F0048001E475F002A4258203 +:10083B00F582E5F03583F583E493A3C0E0E493C040 +:10084B00E022D083D082CCC0E0E493A360061208F0 +:10085B00771470FAE493A360061208961470FAD01A +:10086B00E0FCE493A3C0E0E493C0E022C0E0E49397 +:10087B00A3D39C5010E493A3C39C400AD0E0D0E0D8 +:10088B00D0E002086AA3A3A3D0E022C0E0E493A3C4 +:10089B006C7009D0E0D0E0D0E002086AA3A3D0E0EE +:1008AB002253CBEFC2D843CB0475F00CEAA4F5CDA1 +:1008BB0074FC55CB4402F5CB43CB10A2D850FC5360 +:1008CB00CBEFC2D822C082C08353A8C0E5A853B8CF +:1008DB00F0E5B8539AC2E59A7422C0E0740755C686 +:1008EB00F8D0E0B800028004C313D8FCF5AB7475E4 +:1008FB0090FC00F074AE90FC01F0740290FC02F0DE +:10090B00E490FC03F090FC04F0747490FC05F0741C +:10091B00FF90FC06F074F590FC07F074AF90FC08A8 +:10092B00F0E490FC09F090FC0AF0747490FC0BF06E +:10093B0074FF90FC0CF074F590FC0DF074AF90FC10 +:10094B000EF0E490FC0FF090FC10F074E590FC11AD +:10095B00F074AE90FC12F0745490FC13F074409051 +:10096B00FC14F0747090FC15F074FA90FC16F07493 +:10097B002290FC17F0740190F3FFF0D083D0822209 +:10098B00C082C0838A828B83E493F9D083D0822286 +:10099B00C082C0838A828B83E493F9A3E4932400FF +:1009AB00FAE439FBD083D0822274F712068AECFE6C +:1009BB00EDFF740912067EE0FCA3E0FD74326C704F +:1009CB000374576D600479008045C2AFE5AEA2E7B2 +:1009DB0040FA8A088B0974097808120611E508F5A4 +:1009EB00ADEAFCEBC313EC13F5ACEF90FC06F0EEA9 +:1009FB0090FC0CF012FC00D2AFE9601112099B8A3B +:100A0B00088B09EE65087003EF650970B979017FF2 +:100A1B00020206EAD2AF22C2AF22750C00750D009E +:100A2B007E0043FE01D29043FE10C29443FD3FE58E +:100A3B00FD43FEE0E5FE43FF19E5FF53BEF8E5BEBF +:100A4B0000746055BE60FA780079008008E82401D4 +:100A5B0008E93400F9C3E89420E9944E40EF53C6FB +:100A6B00BF53C6C0E5C643C638E5C6746055BE6005 +:100A7B00FA780079008008E8240108E93400F9C30A +:100A8B00E89420E9944E40EF90F9AA780812052BD0 +:100A9B00AA08AB09AC0AAD0B12647374FF90F4187F +:100AAB00F07AF07B7F12098BE9700C7AF27B7F1264 +:100ABB00098BE990F412F090F412E0C3941F4008F4 +:100ACB00E0C394E25002E4F043B933E5B943A92300 +:100ADB00E5A990F9AE780812052BAA08AB09AC0A68 +:100AEB00AD0B12593B800F125993E50C2401F50CF9 +:100AFB00E50D3400F50DC3E50C9420E50D944E4047 +:100B0B00E6C29075EC4475ED0475EBDED2BCD2AF4A +:100B1B00800E12115A740590F400F0E490F404F076 +:100B2B0090F404E0600C90F401E0700690F403E0A4 +:100B3B0060E090F402E0602990F60EE06008EE7041 +:100B4B000553EBEF7E0190F608E060D412664FEE92 +:100B5B006009E490F60EF0FE43EB10E490F608808B +:100B6B00BE90F405E0603490F403E0702ED290E474 +:100B7B0090F405F012111D740390F400F0740190C1 +:100B8B00F401F012131E740190F400F0E490F401E0 +:100B9B00F074FF90F418F0C290808590F406E0603A +:100BAB003D90F401E07037D290E490F406F0125BC4 +:100BBB0019740A90F400F0740190F403F01260D0F1 +:100BCB0090F67AE0A2E25004740B8002740C90F45D +:100BDB0000F0E490F403F074FF90F67C80B890F48E +:100BEB000DE07003020B2B90F40FE06003020B2B54 +:100BFB0090F40EE01208170102190C0C0C110C16D4 +:100C0B000C12434B800812486F80031248957401F5 +:100C1B0090F40F020B2A74F112068A90F653E064DB +:100C2B00FF600302111890F654E012084D001900F2 +:100C3B00A20C01A80C02BD0C03E10C04460D058DA2 +:100C4B000D06DA0C07B10D08D10D09900E0A970DA0 +:100C5B0020870C310D0E32480E33580E40990E4141 +:100C6B00D20E46C60E47F00E48D80E49E90E705804 +:100C7B0010718F1072C01073A8100C11741290F6B3 +:100C8B0059F0743490F658F0745690F657F0747817 +:100C9B0090F656F002110C90F400E080F3121187DD +:100CAB00E490F402F090F401F090F403F090F4006F +:100CBB0080E190F401E0600790F417E0D2E5F0904A +:100CCB00F402E0600302110C740190F40480C4126E +:100CDB001187740480D790F659E0F50875090075F3 +:100CEB000A00750B00741878081204AD90F658E0E2 +:100CFB00F50C750D00750E00750F007410780C1245 +:100D0B0004AD7808790C1204CC90F657E0F50C750D +:100D1B000E007408780C1204AD7808790C1204CC10 +:100D2B0090F656E0F50C750D007808790C1204CC92 +:100D3B0090F98A780812053A02110C90F98A780C0E +:100D4B0012052B850C08850D09850E0A850F0B7472 +:100D5B00187808120494E50890F659F0850C08856C +:100D6B000D09850E0AF50B74107808120494E5082A +:100D7B0090F658F0850D09E50990F657F0E50C0251 +:100D8B000C9B90F656E090FB52020C9E90F656E0B0 +:100D9B0090F9A5F090F658E0F990F657E090F9A687 +:100DAB00F0A3E9020C9E90F402E06003121187900D +:100DBB00F401E0600302110C740290F400F0740172 +:100DCB0090F405020C9E90F417E0A2E4502F90F4DF +:100DDB001BE090F659F090F41AE090F658F090F46E +:100DEB0019E090F657F090F418E090F656F074FF77 +:100DFB0090F418F090F417E0C2E4020C9E74FF021A +:100E0B000C9B90F401E0700302110C7A00801F8A96 +:100E1B0082A882E82456F582E434F6F583E0C0E03C +:100E2B00E82418F582E434F4F583D0E0F00AEAC341 +:100E3B00941340DB90F417E0D2E6020C9E90F4077B +:100E4B00E090F656F0740490F655020C9E90F40761 +:100E5B00E0602E7A00801F8A82A882E82418F5822F +:100E6B00E434F4F583E0C0E0E82456F582E434F68C +:100E7B00F583D0E0F00AEAC3941340DBE490F40767 +:100E8B00F0741680C290F417E0D2E5020C9E90F439 +:100E9B0002E0600312118790F401E0600790F417F1 +:100EAB00E0D2E5F090F403E0600302110C740990BA +:100EBB00F400F0740190F406020C9E90F67AE0D2E6 +:100ECB00E5F0C29002110C90F977020CA590F40397 +:100EDB00E0600690F67B020CA57480020C9B74F705 +:100EEB0090F65680A6740290F67BF090F773E06450 +:100EFB00016003020FD6E490F40AF090F655E0245B +:100F0B00FB90F409F090F656E090F40BF090F65746 +:100F1B00E0F50890F40BE07035E50890F77AF09067 +:100F2B00F658E090F77BF0F9E50890F983F0A3E928 +:100F3B00F090F983E090FA41F090F984E090FA4256 +:100F4B00F0740490F773F0E490F408020C9EE5083B +:100F5B0090F40CF090F40BE06401700474018002C7 +:100F6B00740290F779F090F40CE0240590F774F08C +:100F7B007A00801F8A82A882E82458F582E434F62E +:100F8B00F583E0C0E0E8247AF582E434F7F583D00A +:100F9B00E0F00AEAC0E090F409E0FBD0E0C39B402C +:100FAB00D3740290F773F090F409E090F408F0908A +:100FBB00F409E090F40AF0E0C0E090F40CE0FAD011 +:100FCB00E0C39A500302110C020F4CE06402600361 +:100FDB0002110C90F655E024FD90F409F07A008094 +:100FEB002B8A82A882E82456F582E434F6F583E056 +:100FFB00C0E090F408E0FCE82CF8E43400F9E824B5 +:10100B007AF582E934F7F583D0E0F00AEAC0E09094 +:10101B00F409E0FBD0E0C39B40C7E0FA90F408E092 +:10102B002AF090F409E0FA90F40AE02AF090F40820 +:10103B00E0C394F7509290F40AE0C0E090F40CE017 +:10104B00FAD0E0C39A500302110C020FD390F6575B +:10105B00E0F990F656E0F874AB68700374AB697006 +:10106B001C740190F40DF0E490F40EF0740190F404 +:10107B000FF0E490F402F090F401020C9EE490F473 +:10108B000D020C9E90F40DE0607790F410E4F0A349 +:10109B00F090F40FF090F40EE004020C9E90F40D1F +:1010AB00E0605E90F410E090F656F090F411E09052 +:1010BB00F657020C9E90F40DE0604690F656E0F564 +:1010CB000890F657E0FA90F658E0F9EAFEE9FF12BD +:1010DB0008D0EEFAEFFB12098BE964FF7023750A57 +:1010EB0032750B57780A1207D57900AB0874FF24B9 +:1010FB0000FCE43BFDEEFAEFFB1209B4740212069E +:10110B0049740190F677F0740690F654F07F08025C +:10111B0006EAC082C08375C6B074D390DF00F0744A +:10112B009190DF01F0740490DF03F0E490DF05F0A1 +:10113B0090DF06F0740790DF12F0E490DF2FF09051 +:10114B00DF30F090DF31F0759100D083D08222C078 +:10115B0082C08375C6B8439190E59175E25575E5EC +:10116B004475E402D2B912686390F412E090DF0880 +:10117B00F0740190F402F0D083D08222C082C0833D +:10118B0012645EC2B975E40075E255124899E49099 +:10119B00F402F0D083D08222C0E074F212072290C6 +:1011AB00F402E060051263BD801F90F401E060055E +:1011BB00121793801490F40DE0600512483D8009DE +:1011CB0090F403E06003125C2C7F01020781C0E006 +:1011DB0074F212072290F402E0600512636B80092F +:1011EB0090F40DE060031247307F01020781C0E0ED +:1011FB0074F2120722C2C153E40FE5E490F607E044 +:10120B00601590F608E0700F1248C3E97003740183 +:10121B00F090F60FE004F07F01020781C0E074F25A +:10122B0012072290F403E0603990F873E0F8A3E022 +:10123B00F9E87001E9602B90F871E02401F0A3E06C +:10124B003400F090F871E0687003A3E069701390BC +:10125B00F871E4F0A3F090F873F0A3F0740190F838 +:10126B0075F0C2DB1259937F010207810022C0E0A7 +:10127B0074F21207221212777F01020781C0E07409 +:10128B00F21207221212777F01020781C0E074F27B +:10129B001207221212777F01020781C0E074F2124B +:1012AB0007221212777F01020781C0E074F2120746 +:1012BB00221212777F01020781C0E074F21207221B +:1012CB001212777F01020781C0E074F2120722121B +:1012DB0012777F01020781C0E074F212072212120B +:1012EB00777F01020781C0E074F212072212127796 +:1012FB007F01020781C0E074F21207221212777F7E +:10130B0001020781C0E074F21207221212777F01EB +:10131B0002078174F112068A74FA12063390F9B23D +:10132B00780812052B740190F417F07AFD7B1412D8 +:10133B0027B97402C0E0740112067ED0E0F0AC82D3 +:10134B00AD837A0A7903122AA0C290805390F414C9 +:10135B00E0704D740212067E780812053A74021280 +:10136B00067EC082C08390F9B6780812052BD08315 +:10137B00D08278081204DF740212067EC082C0830A +:10138B0090F9BA780C12052BD083D082780C12030B +:10139B0064400D639001E59090F9B2780812052B2B +:1013AB0090F416E0603190F414E0702B7A137BF418 +:1013BB001227E6E970F6740290F417F0D29090F4CD +:1013CB0014E004F0A2AFE492E0FAC2AF90F416E09E +:1013DB0014F0EAA2E092AF90F415E070030214C887 +:1013EB00851082851183AC82AD837A387BF490F4BF +:1013FB0013E0F9122A36E960030214C885108285BE +:10140B001183E064047029639001E590750C0475F9 +:10141B000D00780C1207D57C387DF47A187BF4120A +:10142B006958740212064990F417E0D2E40214C70B +:10143B00E064026008E0641360030214C863900167 +:10144B00E59090F438E01208170102C8145E14936B +:10145B0014931490F417E0A2E65008E0C2E6F0747F +:10146B0013800E740190F418F0745590F419F07405 +:10147B0002851082851183F0E0FC7A187BF490F4DE +:10148B0013E0F912285C803590F407E0702F7A0096 +:10149B00801F8A82A882E82438F582E434F4F5832D +:1014AB00E0C0E0E82418F582E434F4F583D0E0F0F2 +:1014BB000AEAC3941340DB740190F407F090F4171D +:1014CB00E0A2E54003021358539AFE75910075E9AB +:1014DB0000E490F413F090F414F090F416F090F400 +:1014EB0015F090F5A1F0C29074061206497F080220 +:1014FB0006EAC082C083E9600590F415800390F47E +:10150B0016E004F07900D083D0822274F712068A99 +:10151B0075082175090078081207D57C007D007AC3 +:10152B00597BF4126A3F740212064990DF36E0547D +:10153B00EF64016004C2AF80FE90DF37E0C3940319 +:10154B005004C2AF80FE53BEFBE5BEA2E650FA5379 +:10155B00C6BF43BE0474F4F5D575D480743C90DFDC +:10156B0013F0741490DF14F0741E90DF02F0740506 +:10157B0090DF04F0745090DF2EF0740990DF25F0AB +:10158B0090DF07F090F412E090DF08F0741290DF18 +:10159B0009F0741490DF0AF0747A90DF0BF0746B1F +:1015AB0090DF0CF074A390DF0DF0741390DF0EF04E +:1015BB00742390DF0FF0741190DF10F0744390DF01 +:1015CB0011F0741D90DF15F0741C90DF16F074C7CA +:1015DB0090DF17F0E490DF18F074B090DF19F0741F +:1015EB00B690DF1AF0741090DF1BF074EA90DF1CDA +:1015FB00F0742A90DF1DF0E490DF1EF0741F90DF73 +:10160B001FF0748190DF23F0743590DF24F07402A7 +:10161B0090F458F07900121B8D7E007F0075E1026B +:10162B0075081475090590DF3CE0545070237A401F +:10163B007B001219A5E50824C0F508E50934FFF570 +:10164B0009C3E5089401E5099400A2D265D0335093 +:10165B00D57A008013EEC333FEEF33FF90DF3AE011 +:10166B00A2E0E492E04EFE0AEAC3941040E77480D5 +:10167B004EF5BCEFF5BC12196090F47C7436F0A3F8 +:10168B00E4F090F47E74E2F0A37404F0439A01D278 +:10169B00AF7F020206EA74F712068AEAFEEBFF89B5 +:1016AB000975080090F458E064017004C2AF80FE25 +:1016BB00121960EF90F480F0EE90F481F074DF90EB +:1016CB00F482F074D990F483F0742090F484F07465 +:1016DB002190F485F0741390F486F0744190F487A4 +:1016EB00F0E509701143D60175E103E5E9A2E45079 +:1016FB00FA53E9EF8068740165096004C2AF80FE9C +:10170B007509048008121960121ACA150943D6010B +:10171B0075E10290DF3BE0640D70F87E147F05905D +:10172B00DF3CE05450701D7A407B001219A5EE246B +:10173B00C0FEEF34FFFFC3EE9401EF9400A2D2651D +:10174B00D03350DB75E10390DF3BE0640D6008E5BF +:10175B00E9A2E450FA809AE50970AA7508011219FA +:10176B006090F458E0640370031218D7A9087F0245 +:10177B000206EAC082C08390F459EAFCEBFD7421A7 +:10178B00120556D083D0822274F712068A90F45831 +:10179B00E064036004C2AF80FEE5E9A2E45035E5E6 +:1017AB00E9A2E6502F53E9EF53E9BF539BFCE59BAE +:1017BB0012196075081F75090078081207D57C008F +:1017CB007D007A597BF4126A3F7402120649121893 +:1017DB00D702186A53E9EF539BFCE59B750802751A +:1017EB00090078081207D590F459E0042459FCE459 +:1017FB0034F4FD7A787BF41269A07402120649E086 +:10180B00FA90F479E0A2E7503B8A0874012508F8B6 +:10181B00E43400F9E89420E99400C365D0335024F4 +:10182B00EAC3940B401E7A5A7BF4121BF5E9701431 +:10183B0090F478E0F9121B38E9F090F479E0C2E704 +:10184B00F0122D5E75081F78081207D57C007D00FD +:10185B007A597BF4126A3F740212064943D6017F10 +:10186B00020206EA74F812068A90F458E0640160EA +:10187B0013A2AFE492E0FEC2AF1219857401F0EE31 +:10188B00A2E092AF7F010206EAC082C083E5C6A246 +:10189B00E65004C2AF80FE90F458E06401702274ED +:1018AB00EA90DF1CF0742A90DF1DF0E490DF1EF04D +:1018BB00740290F458F075E10490DF3BE064017022 +:1018CB00F8D083D0822243B404A9BC2274F7120649 +:1018DB008A74DF90F480F074D990F481F074F490F2 +:1018EB00F482F0745990F483F0748090F484F07463 +:1018FB002190F485F0741390F486F0741190F487B2 +:10190B00F075D68175081F75090078081207D57C0C +:10191B00007D007A597BF4126A3F74021206494328 +:10192B00D601539BFCE59B53E9EF75E10243911004 +:10193B007F020206EAC082C08390F458E064017013 +:10194B0004C2AF80FEE0640360067403F01218D784 +:10195B00D083D08222C082C0835391EF75E1049073 +:10196B00DF3BE0640170F875D68153D1FE539BFCCD +:10197B00E59B53E9EFD083D08222C082C08390F4E1 +:10198B0058E064017004C2AF80FEE064037006127D +:10199B0019607402F0D083D0822274F712068A8AFF +:1019AB00088B0974047808120611AE08AF09EA70A7 +:1019BB0001EB6028A2AFE492E0F508C2AF7A107B8E +:1019CB00001208ACE508A2E092AFEEF8EFF974FF55 +:1019DB00281E74FF39FFE87001E970D87F020206F8 +:1019EB00EA74F712068A8A088B09740478081206BF +:1019FB0011AE08AF09EA7001EB602EA2AFE492E0E2 +:101A0B00F508C2AF7A107B001208ACE508A2E09291 +:101A1B00AF90F47AE07012EEF8EFF974FF281E74B1 +:101A2B00FF39FFE87001E970D27F020206EA74F811 +:101A3B0012068AEAFEEB800E7AF47B011219A5EEF0 +:101A4B0024FF1EEF34FFFFEE7001EF70EB7F0102FE +:101A5B0006EA74F812068A90F47CE0FEA3E0FFA27B +:101A6B00AFE492E0FAC2AF740190F47BF0EAA2E02B +:101A7B0092AF8008EE24FF1EEF34FFFFEE7001EFF4 +:101A8B00600D7AF47B011219EC90F47AE060E5A218 +:101A9B00AFE492E0FAC2AFE490F47AF090F47BF00A +:101AAB00EAA2E092AF7F010206EAC082C08390F403 +:101ABB007BE06006740190F47AF0D083D0822274BC +:101ACB00F812068A1218D1E9540F04FF7E00800C1D +:101ADB0090F47EE0FAA3E0FB1219A50EEEC39F4033 +:101AEB00EF7F010206EA74F812068A90F458E0645C +:101AFB00036004C2AF80FE7E147F0590DF3CE05490 +:101B0B0050701D7A407B001219A5EE24C0FEEF34F5 +:101B1B00FFFFC3EE9401EF9400A2D265D03350DBEC +:101B2B0090DF3AE0F9121B387F010206EAC008C0C9 +:101B3B0009E9C39480E94019F879FF7A027B001216 +:101B4B0005B08808890974B72508F874FF35098032 +:101B5B000BC313F874B728F874FF3400F9C3E89477 +:101B6B0080E994FFA2D265D03350027880E8F9D097 +:101B7B0009D00822C082C08390F458E0F9D083D0FA +:101B8B00822274F712068A8908E9C394044004C2BE +:101B9B00AF80FE121960E50824C2F582E434F9F532 +:101BAB0083E090DF06F090F458E0640370031218A2 +:101BBB00D77F020206EA74F712068A8908E9C394F2 +:101BCB00034004C2AF80FE121960E50824C6F582FB +:101BDB00E434F9F583E090DF2EF090F458E06403E1 +:101BEB0070031218D77F020206EA74F812068A9065 +:101BFB00F488E07004790080487E007D007C0080D2 +:101C0B002E8C82A882EA28F582EB3400F583E0FF64 +:101C1B00E824C9F582E434F9F583E06F70010EE82E +:101C2B0024BEF582E434F9F583E06F70010D0CEC02 +:101C3B00C3940440CC74046D60BB74046E60B679BD +:101C4B00017F010206EA74F712068AEAFEEBFF75C2 +:101C5B00082C75090078081207D57C007D007ACE18 +:101C6B007BF9126A3F7402120649740290F9CEF0A6 +:101C7B00743D90F9CFF0742090F9D0F0740190F985 +:101C8B00D1F01234FFEEFAEFFB122C0112244112A9 +:101C9B0034FB124232EEFAEFFB1237D512408712A9 +:101CAB003B5F12430490F9EEE070347402F074035E +:101CBB0090F9EFF0743F90F9F7F090F9F8F074FFAA +:101CCB0090F9F9F075080478081207D5123599EADE +:101CDB00FCEBFD7AF17BF912695874021206497913 +:101CEB00007F020206EAC082C0837B0080010BEBFF +:101CFB00C394025014EB75F00CA424E2F582E5F0CA +:101D0B0034F9F583E0640260E574026B70067A00C7 +:101D1B007B00801AEB75F00CA424E2F582E5F0341D +:101D2B00F9F583AA82AB83121D3EAA82AB83D083C3 +:101D3B00D08222C082C08374FF120633E48A828B66 +:101D4B0083A3A3A3A3A3A3A3A3A3A3F074028A8235 +:101D5B008B83F090F9D1E0C0E0EA240BF582EB34F1 +:101D6B0000F583D0E0F090F9D1E004F0E0F960F6F3 +:101D7B0074FF6960F1851082851183AA82AB83128F +:101D8B002284E970E17401120649D083D08222C00B +:101D9B0082C083E48A828B83F0D083D08222C0827C +:101DAB00C08374FF120633851082851183AA82AB20 +:101DBB0083122284E96014E075F00CA424E2F5820E +:101DCB00E5F034F9F583E0640260067582007583F3 +:101DDB0000AA82AB837401120649D083D08222748D +:101DEB00F312068A8A088B09890A7EE27FF97A0048 +:101DFB00800A7A01EE240CFEEF3400FFEA70478E66 +:101E0B00828F83E0640270EA750C04750D00780C08 +:101E1B001207D5AC08AD09EE2403FAEF3400FB1220 +:101E2B0068FF7402120649EA7001EB70C58E828F4F +:101E3B0083A3A3A3A3A3A3A3A3A3A3E0650A70B245 +:101E4B00EEFAEFFB80047A007B007F060206EA7A4B +:101E5B00D27BF92274F312068A8A0A8B0B7508005F +:101E6B007509007EE27FF97A00800E8E088F097A61 +:101E7B0001EE240CFEEF3400FFEA703D8E828F835F +:101E8B00E064026005E0640170E1750C04750D00FF +:101E9B00780C1207D5E50A2405FCE50B3400FDEEA2 +:101EAB002403FAEF3400FB1268FF7402120649EAAE +:101EBB007001EB70BA7900803AE5087002E50960B1 +:101ECB00F47401850882850983F0750C04750D0087 +:101EDB00780C1207D5E50A2405FCE50B3400FDE56B +:101EEB00082403FAE5093400FB1269587402120640 +:101EFB004979017F060206EA74F512068A8A088B75 +:101F0B00097EE27FF97A00800A7A01EE240CFEEF5B +:101F1B003400FFEA70418E828F83E0640170EA75B2 +:101F2B000A04750B00780A1207D5E5082405FCE5B1 +:101F3B00093400FDEE2403FAEF3400FB1268FF7442 +:101F4B0002120649EA7001EB70BFEEFAEFFB121DAD +:101F5B003EEEFAEFFB80047A007B007F040206EA78 +:101F6B00C082C083E98A828B836001A3A3A3A3A34E +:101F7B00A3A3A3A3A3E0FCEC60078A828B83E0708E +:101F8B000479028008ECC3942040F67900D083D00A +:101F9B00822274F112068A8A0C8B0D8C0E8D0F7EA9 +:101FAB00E27FF98A828B83A3A3A3A3A3A3A3A3A3F7 +:101FBB00E0543FF509750800800A0508EE240CFE75 +:101FCB00EF3400FFE508C3940240030220998E8290 +:101FDB008F83E0640270E3A3A3A3A3A3A3A3A3A390 +:101FEB00E0650970D5743F6509602B750A04750BA4 +:101FFB0000780A1207D5E50C2405FCE50D3400FD2D +:10200B00EE2403FAEF3400FB1268FF740212064948 +:10201B00EA7001EB70A4750801EE240BF582EF3426 +:10202B0000F583E0850E82850F83F0743F650960B0 +:10203B0056E50C240AF582E50D3400F583E0A2E7A2 +:10204B0050198E828F83A3A3A3A3A3A3A3A3A3A39C +:10205B00E0F9AA0CAB0D123115802CE0A2E350274E +:10206B00EE2402F8EF3400F988828983E0FAE50C5C +:10207B00240BF582E50D3400F583E06A7006E488E5 +:10208B00828983F0750800121AB5A90880027900BD +:10209B007F080206EA74F112068A74FF120633896E +:1020AB00088A0E8B0F7EE27FF9750A01750B00789B +:1020BB000A1207D57C007D00740212067EAA82AB41 +:1020CB0083126A3F74021206497A00805D750C0414 +:1020DB00750D00780C1207D5E50E2403FCE50F34C3 +:1020EB0000FDEE2403FAEF3400FB1268FF740212BA +:1020FB000649EA7001EB70287401C0E0850A8285FD +:10210B000B83E0F8851082851183E58228F8E5833F +:10211B003400F974E028F58274FF39F583D0E0F0D0 +:10212B007A01EE240CFEEF3400FFEA7069E50E6EC7 +:10213B007003E50F6F60E98E828F83E0640270E0BD +:10214B00EE2409F50AEF3400F50B850A82F583E0DE +:10215B00C3943E50CB7401650860030220D890F9FC +:10216B00CFE0C0E0850A82850B83E0FAD0E0C39A0A +:10217B0050AE7401C0E0E0F8C3E498F8E49400F9C1 +:10218B00851082851183E58228F8E58339F9743D42 +:10219B0028F582E4808479007A0080027A01EA7063 +:1021AB0015851082851183E070F274026508700446 +:1021BB0079208002793D74026508701790F9CFE0A1 +:1021CB00C399400B90F9D0E0C399501FE9801B795C +:1021DB00008018E9C0E090F9D0E0FAD0E0C39A4053 +:1021EB00EE90F9CFE0697003E014F0E9850E82857B +:1021FB000F83A3A3A3A3A3A3A3A3A3F0740112060A +:10220B00497F080206EA74F512068AEAFEEBFF75AF +:10221B0008028C0AEE250AFAEF3400FB740C2AF53F +:10222B0082E43BF583E0A2E750488D08EE2508FADF +:10223B00EF3400FB740C2AF582E43BF583E0697004 +:10224B002E75080475090078081207D5123545EA72 +:10225B00FCEBFD8E828F83A3AA82AB831268FF7483 +:10226B0002120649EA7001EB7005750800800375D0 +:10227B000801A9087F040206EA74F812068A7CE2B8 +:10228B007DF97E0080090EEC240CFCED3400FDEE94 +:10229B00C3940250218C828D83E0640270E8EC249D +:1022AB000BF582ED3400F583E06970DAEE8A828BF0 +:1022BB0083F07901800279007F010206EA74F31240 +:1022CB00068A8A0C8B0D89097EE27FF975080080DE +:1022DB000A0508EE240CFEEF3400FFE508C3940258 +:1022EB0050478E828F83E0640270E6750A04750B8B +:1022FB0000780A1207D5EE2403FCEF3400FDAA0C7C +:10230B00AB0D1268FF7402120649EA7001EB70C143 +:10231B008E828F83A3A3A3A3A3A3A3A3A3A3E065ED +:10232B000970AEEEFAEFFB80047A007B007F0602A9 +:10233B0006EAE9FB7900EA6B601FEBC39A500EEAE1 +:10234B00C394FD4006EBC39403400E0922EBC394E8 +:10235B00FD4006EAC3940340F22274F512068AECA0 +:10236B00FEEDFF890A890875090078081207D5EA7E +:10237B00FCEBFDEEFAEFFB1269A07402120649E5C5 +:10238B000A1208170202BF239923BF23AD238E82A3 +:10239B008F83E0F8A3E0F98E828F83E8F0A3E9F056 +:1023AB0080128E828F83780812052B8E828F837812 +:1023BB000812053A7F040206EA74F512068A74FACB +:1023CB00120633EAFEEBFFECFAEDFBE912081702FB +:1023DB0002E423EA23E4230624EEFCEFFD80388E8F +:1023EB00828F83E0FCA3E0FD851082851183ECF0E6 +:1023FB00A3EDF085108285118380188E828F8378F0 +:10240B000812052B740212067E780812053A740224 +:10241B0012067EAC82AD8389087509007808120715 +:10242B00D51269A0740212064974061206497F047C +:10243B000206EA79022274F712068A7508D2750928 +:10244B000078081207D57C007D007A897BF4126A2C +:10245B003F740212064975084678081207D57C00AE +:10246B007D007A5B7BF5126A3F74021206497F028C +:10247B000206EA74F512068A7C007D007E007F005E +:10248B00780074016970097A897BF47509068007F5 +:10249B007A5B7BF575090274012509F50A880880BA +:1024AB000EEAFEEBFF0508EA2423FAEB3400FBE50A +:1024BB0008C3950950298A828B83E0601B740169DC +:1024CB0070E308E0640460DDA3E0C3950A50D6EA2C +:1024DB00FCEBFDE0F50A80CD74026970C48031EE2F +:1024EB007001EF701EEC7001ED70067A007B0080BE +:1024FB001FECFEEDFF8E828F83A3E0FA122520E501 +:10250B000880087401288E828F83A3F0EEFAEFFB0C +:10251B007F040206EAC082C083740169703A78892D +:10252B0079F4A2AFE492E0FDC2AF7B00801F8882FA +:10253B008983E0600FA3EAC0E0E0FCD0E0C39C50CD +:10254B0003E014F00BE82423F8E93400F9EBC3940F +:10255B000640DBEDA2E092AFD083D0822274F11261 +:10256B00068A74F61206338A0C8B0D8C09740412CE +:10257B00067EE4F0A3F0851082851183F0A3F0743E +:10258B000212067EE4F0A3F0740169702E7E897F3F +:10259B00F4750E078A828B83E064017052A3E0F915 +:1025AB00121DA9851082851183EAF0A3EBF085102B +:1025BB0082851183E07002A3E070077A007B000232 +:1025CB0027A0851082851183E0F8A3E0F58388822C +:1025DB00A3A3A3A3A3A3A3A3A3E0F50885108285BC +:1025EB001183E02403F8A3E03400F974088049E078 +:1025FB007006A3E0F5088048E0640270BEA3A882D1 +:10260B00A983E0240EFAA3E03400FB8A828B83E0DB +:10261B00F50888828983E02405FAA3E03400FB7473 +:10262B000812067EEAF0A3EBF088828983E0240F80 +:10263B00F8A3E03400F9740212067EE8F0A3E9F087 +:10264B007401650970057509018003750903750F20 +:10265B0000800FEAA2E092AF050FEE2423FEEF34C9 +:10266B0000FFE50FC394064003022796A2AFE49246 +:10267B00E0FAC2AF8E828F83E0650970D67404F0E6 +:10268B00EAA2E092AFEE240BF582EF3400F583E083 +:10269B00543F6508600302278E850C82850D83E00D +:1026AB0064017019743F6508700E85108285118363 +:1026BB00E02403F8A3E0800FEE24078008E0640217 +:1026CB007012EE2403F8EF3400F9740612067EE85C +:1026DB00F0A3E9F0750A04750B00780A1207D5749C +:1026EB000A12067EE0FCA3E0FD740812067EE0FAF7 +:1026FB00A3E0FB1268FF7402120649850C82850D5C +:10270B0083E06040740212067EE07002A3E0700367 +:10271B00EA6031740212067EE07002A3E060647816 +:10272B000A1207D5EE2407FCEF3400FD74041206E1 +:10273B007EE0FAA3E0FB1268FF7402120649EA700E +:10274B0001EB703F8E828F83A3AA82AB83E0C3958C +:10275B000E5030740412067EE07002A3E060107419 +:10276B000412067EE0F8A3E0F5838882E509F08A7F +:10277B00828B83E0F50E740412067EEEF0A3EFF06D +:10278B000226638E828F83E50980F4740412067E21 +:10279B00E0FAA3E0FB740A1206497F080206EA740A +:1027AB00016970057A897BF4227A5B7BF52274F8D8 +:1027BB0012068AEAFEEBFF90F5A1E07013121516D4 +:1027CB00EEFAEFFB121C51E9700C1218941219401F +:1027DB007401F0123A4F7F010206EA74F712068A6F +:1027EB008A828B83121B7FE9F509790012401574DD +:1027FB00036509600C7401650970031218941219B2 +:10280B00407E007F00800F7A0A7B00121A39EE247B +:10281B00010EEF3400FFC3EE94F4EF940150091254 +:10282B003FBCE9FA8A0860DF74036509600E740126 +:10283B006509700512186F8003121985E508700978 +:10284B00790112401579018003F079007F020206AD +:10285B00EA74F712068A75080075090078081207E2 +:10286B00D512287974021206497F020206EA74F126 +:10287B0012068A74FC120633740212067EEAF0A367 +:10288B00EBF089088C09741312067EE0FEA3E0FFBF +:10289B00121DA98A0C8B0D750B02121B7FE985107B +:1028AB0082851183F0750A00E50C7002E50D600F4F +:1028BB007901AA0CAB0D121F6BE9FA8A0B600302AC +:1028CB002A2A740212067EE07002A3E060F1E50989 +:1028DB00C3941450EAEE7001EF703D850C82850DA8 +:1028EB0083A3E0FDAC09740212067EE0FAA3E0FBC1 +:1028FB00850C82850D83A3A3A3A3A3A3A3A3A3A347 +:10290B00E0F9122C328A088B09AE08AF09EE700180 +:10291B00EF70627903022A2CEEA2E0505374FF652C +:10292B0008604DE50C2402F50AE50D3400F50B7833 +:10293B000A1207D5850C82850D83A3E0FDAC0974C3 +:10294B000412067EE0FAA3E0FB850C82850D83A3BF +:10295B00A3A3A3A3A3A3A3A3A3E0F9122D1D740206 +:10296B001206498A088B09AE08AF09750A01809DCA +:10297B007902022A2CEE2403F50EEF3400F50F75C5 +:10298B00080475090078081207D5E50C2403FCE54B +:10299B000D3400FDAA0EAB0F1269587402120649D2 +:1029AB00740112067EAC82AD83AA0EAB0F123A52A3 +:1029BB00EA7001EB600B74038E828F83F0790080D9 +:1029CB00607901EEFAEFFB1230B9E9F50B7050E5C7 +:1029DB000A604C851082851183E06403600BE06410 +:1029EB00017003121894121940121A5DE06403600F +:1029FB000DE06401700512186F8003121985A2AFE8 +:102A0B00E492E0FAC2AFE50C2402F582E50D340046 +:102A1B00F583E06005E4F0750B0CEAA2E092AFA938 +:102A2B000B74041206497F080206EA74F312068A35 +:102A3B0074FD120633890AEAFEEBFF8C088D09122E +:102A4B001DA97902EA7001EB60411919121F6BE99C +:102A5B0070397401851082851183F012067EE50AA8 +:102A6B00F0750A00750B00780A1207D5780A120761 +:102A7B00D578081207D5EEFCEFFD740612067EAA78 +:102A8B0082AB83122D927406120649740312064907 +:102A9B007F060206EA74F112068A89088A09ECFE9F +:102AAB00EDFF90F5A1E0700B122BE4E970057902B4 +:102ABB00022BDFE50812081702080C2B6F2B8D2B4E +:102ACB00982B5A2B4F2B9F2BC82B402BD92A750891 +:102ADB00008E828F83E0702FE5097014A3780C129F +:102AEB00052BAA0CAB0DAC0EAD0F123BB8022BDDB8 +:102AFB0074016509700BA3AA82AB83123BDC022B1A +:102B0B00DD750802022BDDE0640170F5E509701438 +:102B1B00A3780C12052BAA0CAB0DAC0EAD0F123813 +:102B2B0030022BDD7401650970D7A3AA82AB831227 +:102B3B003854022BDDEEFAEFFBA90912243EE9F51E +:102B4B0008022BDDEEFAEFFBA9091237A780EF7411 +:102B5B000165096004E50970A8EEFAEFFBA90912FB +:102B6B00376380DA740365097009EEFAEFFB1235EF +:102B7B009E80CB740265097088EEFAEFFB12362A41 +:102B8B0080BCEEFAEFFBA90912369B80B1A90912A2 +:102B9B00375280AA740165096003022B0C75080477 +:102BAB0075090078081207D512355EEAFCEBFDEECD +:102BBB00FAEFFB1269587402120649801274016510 +:102BCB00096003022B0C123563E98E828F83F0753B +:102BDB000800A9087F080206EAC082C083E9120830 +:102BEB004D000205F62B0AF62BFA2B7901800279A0 +:102BFB0000D083D08222C082C083E490F5A5F0740C +:102C0B002090F5A6F090F5A7EAF0A3EBF01235456E +:102C1B0090F5A3EAF0A3EBF01218D1E990F5A2F02E +:102C2B0060F6D083D0822274F112068A89088A0E4C +:102C3B008B0F8C0A8D09790212247E8A0C8B0DA8BE +:102C4B000CA90DE8FEE9FFE87001E970077A007B3B +:102C5B0000022D18740B250A8E828F83A3A3F0EE2E +:102C6B00240BF8EF3400F988828983E0C2E6F0E0A8 +:102C7B0054C04508F090F5A2E0C0E0EE240DF582BB +:102C8B00EF3400F583D0E0F090F5A2E004F0E060C3 +:102C9B00F7EE240CFAEF3400FB90F5A5C082C0834D +:102CAB008A828B83E054BFD083D082FCE04C8A8233 +:102CBB008B83F0E054F84509F0E0C2E7F0E0C2E3A3 +:102CCB00F088828983E0C2E7F0750B00780A12075F +:102CDB00D5AC0EAD0FEE240E0A0AEF3400FB1269D1 +:102CEB005874021206497508047509007808120712 +:102CFB00D590F5A3E0FCA3E0FDEE2407FAEF34003A +:102D0B00FB1269587402120649EEFAEFFB7F0802B8 +:102D1B0006EA74F712068A740912067EE0FEA3E037 +:102D2B00FF122C32EA7001EB70067A007B00801EDA +:102D3B00EA240DF582EB3400F583E08E828F83F06D +:102D4B00EA240CF582EB3400F583E0D2E7F07F0246 +:102D5B000206EA74F712068A790112247E8A088B1E +:102D6B0009A808A909E8FEE9FFE87001E96013EE7C +:102D7B0024020A0AEF3400FB12177EEEFAEFFB1265 +:102D8B002EE77F020206EA74F112068A74FE12061F +:102D9B0033851082851183ECF0A3EDF08A0C8B0D3B +:102DAB00741112067EE0F50AA3E0F50B74151206FA +:102DBB007EE0F50EA3E0F50FE4850A82850B83F028 +:102DCB007C0179011225688A088B09AE08AF09EEE0 +:102DDB007001EF7003022EDB750800750900850C7E +:102DEB0082850D83E064017015A3E0F9121DA98A99 +:102DFB00088B09EA7001EB70057902022EDD8E82D9 +:102E0B008F83A3A3E024F5850A82850B83F0E0F57D +:102E1B000A750B00780A1207D5EE240EFCEF34006E +:102E2B00FD740212067EE0FAA3E0FB1269587402ED +:102E3B00120649E5087002E5096033EE2421F5829C +:102E4B00EF3400F583E0850882850983A3A3A3A350 +:102E5B00A3A3A3F0EE2422F582EF3400F583E085E3 +:102E6B000882850983A3A3A3A3A3A3A3A3F074132D +:102E7B0012067EE07002A3E0602575080475090058 +:102E8B0078081207D5EE2407FCEF3400FD741512F9 +:102E9B00067EE0FAA3E0FB1269587402120649E5BC +:102EAB000E7002E50F6014EE240CF582EF3400F582 +:102EBB0083E05407850E82850F83F08E828F83A368 +:102ECB00E0FA7901122520E48E828F83F0F98002DB +:102EDB00790474021206497F080206EA74F312069B +:102EEB008A74FE120633EAFEEBFFEE240BF582EF3B +:102EFB003400F583E0543FF509750A04750B00782F +:102F0B000A1207D590F5A3E0FCA3E0FDEE2407FA27 +:102F1B00EF3400FB1268FF7402120649EA7001EBF2 +:102F2B007010E48E828F83F074021206497F0602C2 +:102F3B0006EAEE240BF582EF3400F583E0A2E640BF +:102F4B00E1E509603EC394075039EE2402FAEF34F1 +:102F5B0000FBE509C33324F8F582E434F9F583E08B +:102F6B00F8A3E0F5838882120688E9FA74016A7087 +:102F7B0004740180AE74026A70A8EEFAEFFB123192 +:102F8B00EC80A5743F6509600EE509C3942040925F +:102F9B00E509C3943F508BEE2403F50AEF3400F59B +:102FAB000B750C04750D00780C1207D5AC0AAD0B24 +:102FBB0090F5A3E0FAA3E0FB1268FF740212064936 +:102FCB00EA7001EB70057508018003750800E508D0 +:102FDB007020743F65097073780C1207D512359900 +:102FEB00AD0BAC0A1268FF7402120649EA7001EBD2 +:102FFB007059851082851183AC82AD83EE2402FA61 +:10300B00EF3400FB121F9DE97003022F2DE50870B2 +:10301B0007EEFAEFFB1231EC74018E828F83F09086 +:10302B00F5A7E07002A3E07003022F3385108285B1 +:10303B001183E0F990F5A7E0F8A3E0F583888212FD +:10304B000688E96003022F2D022F33740112067ECE +:10305B00AC82AD83AA0AAB0B123A52EA7001EB6059 +:10306B0036EE2402FAEF3400FB1233DFE960030281 +:10307B002F2DEE240BF582EF3400F583E0A2E75001 +:10308B0003022F2DEE240CF582EF3400F583E0C202 +:10309B00E7F07403022F2EEE240CF582EF3400F5CB +:1030AB0083E0543064206003022F85022F2D74F8C7 +:1030BB0012068AEAFEEBFFE9FAEE240CF8EF340075 +:1030CB00F990F5A6C082C08388828983E054CFD063 +:1030DB0083D082FBE04B88828983F0EAF9EE2402ED +:1030EB00FAEF3400FB1216A1E97004790080027923 +:1030FB0009E48E828F83F07F010206EAC082C083CF +:10310B0090F5A5E0F9D083D0822274F712068A7469 +:10311B00DF120633E9FEEA240BF582EB3400F5836C +:10312B00E0FF90F5A5C082C08390F5A6C082C08356 +:10313B00740A12067EE054CFD083D082FCE04C544C +:10314B00BFD083D082FCE04CC0E0740A12067ED064 +:10315B00E0F075080475090078081207D5EA240514 +:10316B00FCEB3400FD740312067EAA82AB8312695A +:10317B0058740212064978081207D590F5A3E0FCA3 +:10318B00A3E0FD740712067EAA82AB831269587402 +:10319B0002120649740912067EE054C04EF0740BFD +:1031AB00851082851183F0EFC0E0740B12067ED080 +:1031BB00E0F0740A12067EE05478F0E0440BF074F1 +:1031CB000912067EE0543FF0790085108285118349 +:1031DB00AA82AB831216A174211206497F02020642 +:1031EB00EA74F812068AEAFEEBFFEE240CF582EF86 +:1031FB003400F583E05407FA74FF2AFBEA6017E00A +:10320B0054F84BF07A017B00121A397901EEFAEF80 +:10321B00FB1230B98006E48E828F83F07F010206A9 +:10322B00EA74F312068A74FD1206338A0C8B0D892D +:10323B0008EA2508F8EB3400F9740C28F582E43918 +:10324B00F583E0F5097402851082851183F0740112 +:10325B0012067EEAF0A3EBF07C02851082851183C7 +:10326B00AA82AB8379011225688A0A8B0BA80AA95B +:10327B000BE8FEE9FFE87001E96006EEFAEFFB8070 +:10328B006C79021227AA8A0A8B0BAE0AAF0B750850 +:10329B0000804F8E828F83E06403703C750A047547 +:1032AB000B00780A1207D5E50C2405FCE50D34005C +:1032BB00FDEE2403FAEF3400FB1268FF74021206D2 +:1032CB0049EA7001EB7011EE240BF582EF3400F537 +:1032DB0083E0543F650960A30508EE2423FEEF3419 +:1032EB0000FFE508C3940240AA7A007B0074031226 +:1032FB0006497F060206EA74F512068A74DF120687 +:10330B0033EAFEEBFFEE240EF582EF3400F583E09B +:10331B00F50890F5A5C082C083740A12067EE054AE +:10332B008FD083D082FAE04A4420C0E0740A1206A0 +:10333B007ED0E0F0750A04750B00780A1207D5EE03 +:10334B002405FCEF3400FD740312067EAA82AB83C6 +:10335B001269587402120649780A1207D5EE240F27 +:10336B00FCEF3400FD740712067EAA82AB83126950 +:10337B00587402120649740912067EE054C04508BF +:10338B00FAF0740B851082851183F090F5A2E0C0E2 +:10339B00E0740B12067ED0E0F090F5A2E004F0741E +:1033AB000A12067EE05471F0E0D2E0F074BF5A448A +:1033BB0080C0E0740912067ED0E0F079008510829F +:1033CB00851183AA82AB831216A174211206497F41 +:1033DB00040206EA74F112068A8A0C8B0D8A828B20 +:1033EB0083E024F8F50979011227AA8A0A8B0BAE20 +:1033FB000AAF0B750800800A0508EE2423FEEF3494 +:10340B0000FFE508C3940640030234F48E828F83D9 +:10341B00E0640370E385098285820E8E82A3A3E0AC +:10342B00F874F828F874FF3400F9E50E687001E9B8 +:10343B0070C6750A04750B00780A1207D5850C82C5 +:10344B00850D83A3AC82AD83EE2403FAEF3400FB2E +:10345B001268FF7402120649EA7001EB709A780A3F +:10346B001207D5E50C2405FCE50D3400FDEE240711 +:10347B00FAEF3400FB1268FF7402120649EA70017E +:10348B00EB6003023403750A01780A1207D5E50CC9 +:10349B002409FCE50D3400FDEE240BFAEF3400FBA0 +:1034AB001268FF7402120649EA7001EB60030234E2 +:1034BB000374FE250EF50A74FF3400F50B780A121F +:1034CB0007D5E50C240BFCE50D3400FDEE240DFABD +:1034DB00EF3400FB1268FF7402120649EA7001EB2D +:1034EB0060030234037901800279007F080206EA47 +:1034FB002279002274F712068A7508047509007880 +:10350B00081207D57C007D007AA97BF5126A3F74FF +:10351B000212064990F5B1E0701B78081207D57CB2 +:10352B00067DFA7AAD7BF51269587402120649745E +:10353B000190F5B1F07F020206EAC082C08390F5DC +:10354B00B1E060067AAD7BF580047A067BFAD08316 +:10355B00D082227A0B7BFA2279022274F712068A26 +:10356B00790090F5B1E0702175080489097808128B +:10357B0007D5EAFCEBFD7AAD7BF5126958740212A4 +:10358B000649740190F5B1F0F97F020206EA7ABEA2 +:10359B007BF92274F512068AEAFEEBFFEE2405F89E +:1035AB00EF3400F988828983E012084D010506C2C9 +:1035BB00350103C235C6357D0180027D038E828FB6 +:1035CB0083A3A3A3A3E0FC8E828F83A3A3E0FAA320 +:1035DB00E0FB88828983E0F9122C328A088B09A9D7 +:1035EB0009EA7001E96031750A04750B00780A125B +:1035FB0007D58E828F83E0FCA3E0FDEA24030A0A41 +:10360B000AE93400FB12695874021206497901AABF +:10361B0008AB091230B9800279037F040206EA7401 +:10362B00F712068A74FD120633E485108285118326 +:10363B00F08A828B83A3A3A3A3A3E0C0E07401123F +:10364B00067ED0E0F0EA2406F508EB3400F50978A5 +:10365B00081207D58A828B831207EAEA2404F5083D +:10366B00EB3400F50978081207D58A828B83A3A364 +:10367B00E0FCA3E0FD740612067EAA82AB83122D3A +:10368B0092740612064974031206497F020206EA77 +:10369B0074F512068AEAFEEBFF7508007404697074 +:1036AB000912198512186F02374B740569700912CC +:1036BB00189412194002374B74066970398E828F39 +:1036CB0083E0F9121DA9EA7001EB70047902807294 +:1036DB00750A02750B00780A1207D5EA2407FCEB72 +:1036EB003400FD8E828F83A3AA82AB831269587438 +:1036FB0002120649804A740769700B121AF1E98E9F +:10370B00828F83F0803A74086960A7740969700529 +:10371B00121985802B740A6970238E828F83E012B5 +:10372B0008170002D7363F373B3737377902800609 +:10373B00790180027900121BC1790080057508029E +:10374B00A9087F040206EA740B69700479018002F0 +:10375B007902123AC679002274F712068AEAFEEB56 +:10376B00FF750802740169702075080475090078EB +:10377B00081207D5123545EAFCEBFDEEFAEFFB120A +:10378B00695874021206498009E97009123566E915 +:10379B006003750800A9087F020206EA74F7120697 +:1037AB008AE9FC8A828B83E0F9740E6C60047902DF +:1037BB00801374FF6960F7121DA9EA7001EB60EECC +:1037CB00121D9A79007F020206EA74F512068A909E +:1037DB00F5B2C082C08390F9B2780812052BD08362 +:1037EB00D082780812034F701090FA0F78081205E8 +:1037FB002B90F5B2780812053A90F5B6EAF0A3EBE8 +:10380B00F01218D1E990F5B8F0123875123BB87474 +:10381B000190F5BBF0121E5A90F5B9EAF0A3EBF04C +:10382B007F040206EA74F512068A8A088B098C0A51 +:10383B008D0B90F9B2780812034F600890F5B278AF +:10384B000812053A7F040206EA74F512068AEA703A +:10385B0001EB601190F5B2780812052B8A828B83ED +:10386B00780812053A7F040206EA7AEF7BBE7CAD3C +:10387B007DDE2274F312068A74F4120633EAFEEB31 +:10388B00FF8E828F83E0F874F528F874FF3400F90B +:10389B00C3E89408E99400A2D265D0334018EE2413 +:1038AB0013F582EF3400F583E0F508123563E96513 +:1038BB00086003023A457904740112067EAC82ADAE +:1038CB0083EE240EFAEF3400FB122365C082C08313 +:1038DB0090F5B2780812052BD083D08278081203AA +:1038EB004F6003023A45740112067EAA82AB831223 +:1038FB003BDC7904740712067EAC82AD8374011233 +:10390B00067EAA82AB831223C4E4C0E0740B1206BA +:10391B007ED0E0F07481C0E0740512067ED0E0F03A +:10392B00EE240DF582EF3400F583E0C0E07406124F +:10393B00067ED0E0F07D017C07740512067EAA821C +:10394B00AB837903122C328A088B09A808A9098842 +:10395B000A890BE87001E97003023A45EE2405F57C +:10396B0008EF3400F509750C04750D00780C12077F +:10397B00D5AC08AD09EA24030A0A0AE93400FB12A4 +:10398B0069587402120649EE2412F582EF3400F5E1 +:10399B0083E06024EEFAEFFB121E5FE9601A90F5EC +:1039AB00B6E07002A3E06010790090F5B6E0F8A3E2 +:1039BB00E0F58388821206888E828F83A3A3A3A34C +:1039CB00A3A3A3A3A3A3E0A2E6506685108285114F +:1039DB0083AC82AD83AA08AB09123A52EA7001EBB1 +:1039EB00704A90F5B9E0FEA3E0FF8E828F83E0C3AF +:1039FB0094035046780C1207D5AC08AD098E828F14 +:103A0B0083E075F005A4F8A9F090F5B9E028FAA3C6 +:103A1B00E0398A82F583A3AA82AB831269587402B8 +:103A2B001206498E828F83E004F08005E0F9124282 +:103A3B00187900AA0AAB0B1230B9740C1206497F25 +:103A4B00060206EA79002274F112068A8A0E8B0F9F +:103A5B008C088D0990F5B9E02401FEA3E03400FF3A +:103A6B00750A00800A050AEE2405FEEF3400FF906C +:103A7B00F5B9E0F8A3E0F5838882E0FAE50AC39A8A +:103A8B005030750C04750D00780C1207D5AC0EADCB +:103A9B000FEEFAEFFB1268FF7402120649EA70018F +:103AAB00EB70C2850882850983E50AF0EEFAEFFB1D +:103ABB0080047A007B007F080206EAC082C0837410 +:103ACB000169700474018001E490F5BBF0D083D0E0 +:103ADB008222C082C083EA240CF8EB3400F98A827C +:103AEB008B83E0FC74F52CFC74FF3400FD74076CC5 +:103AFB007001ED7007740188828983F08882898355 +:103B0B00E06401700312387ED083D0822274F812E5 +:103B1B00068AEAFEEBFF7508007D017C0090F5B884 +:103B2B00E0F9122211E9FB7008121AB57508018031 +:103B3B001C74016B7005750802801274026B700D9A +:103B4B0090F5BBE06007EEFAEFFB123ADDA9087FB8 +:103B5B00010206EA74F512068A90F5BCC082C08396 +:103B6B0090F9B2780812052BD083D0827808120313 +:103B7B004F701090FA13780812052B90F5BC78084B +:103B8B0012053A1218D1E990F5C3F060F6750801E9 +:103B9B0075090078081207D57C007D007AC17BF58A +:103BAB00126A3F74021206497F040206EA74F51288 +:103BBB00068A8A088B098C0A8D0B90F9B278081249 +:103BCB00034F600890F5BC780812053A7F04020693 +:103BDB00EA74F512068AEA7001EB601190F5BC7875 +:103BEB000812052B8A828B83780812053A7F040210 +:103BFB0006EA74F312068A74FD120633EAFEEBFF33 +:103C0B00750A08EE2405F508EF3400F509EE240ECD +:103C1B00F582EF3400F583E0F9AA08AB091222C84C +:103C2B00EA7001EB6006121D9A750A00748285100A +:103C3B0082851183F0EE240DF582EF3400F583E0DD +:103C4B00C0E0740112067ED0E0F0740212067EE52D +:103C5B000AF07D037C03851082851183AA82AB83D6 +:103C6B007902122C328A0A8B0BA80AA90BE8FEE9FF +:103C7B00FFE87001E9602A750A04750B00780A12D7 +:103C8B0007D5AC08AD09EE24030A0A0AEF3400FB92 +:103C9B0012695874021206497900EEFAEFFB1230E2 +:103CAB00B974031206497F060206EA74F112068AFA +:103CBB0074F81206338A088B098A828B83E0F874B6 +:103CCB00F528F874FF3400F9C3E89409E99400A2CD +:103CDB00D265D033401FEA2414F582EB3400F58310 +:103CEB00E0FE123563E96E600C7902740812064926 +:103CFB007F080206EA7904E912067EAC82AD83E501 +:103D0B0008240EFAE5093400FB122365C082C08338 +:103D1B0090F5BC780C12052BD083D082780C120353 +:103D2B004F70C6E5082412F582E5093400F583E0EF +:103D3B00F50AE5082405F50EE5093400F50FA90A87 +:103D4B00AA0EFB121DEA8A0C8B0DA80CA90DE8FE1E +:103D5B00E9FFE87001E97003023E1174818510825E +:103D6B00851183F0E508240DF582E5093400F58310 +:103D7B00E0C0E0740112067ED0E0F08E828F83A348 +:103D8B00A3A3A3A3A3A3A3A3E0C0E0740212067E84 +:103D9B00D0E0F0123107E9C0E0740312067ED0E0E8 +:103DAB00F0850882850983A3A3A3A3A3A3A3A3A33D +:103DBB00A3E05407FA7403C39AFD7C048510828533 +:103DCB001183AA82AB837902122C328A088B09A940 +:103DDB0009EA7001E9602A750A04750B00780A126A +:103DEB0007D5AC0EAD0FEA24030A0A0AE93400FB2F +:103DFB0012695874021206497900AA08AB091230ED +:103E0B00B97901023CF690F5C0E07003023CF4AACC +:103E1B0008AB09121F038A0C8B0DAE0CAF0DEE70A5 +:103E2B0001EF700B121CF18A0C8B0DAE0CAF0DEE6B +:103E3B007001EF60CC750C04750D00780C1207D572 +:103E4B00AC0EAD0FEE2403FAEF3400FB126958747D +:103E5B0002120649EEFAEFFB79021220A0E9700973 +:103E6B00EEFAEFFB121D9A809890F5C2E0640160A8 +:103E7B00EFE0F50C7401250CF0EE240BF582EF341A +:103E8B0000F583E0C0E0E50C24C1F582E434F5F5E0 +:103E9B0083D0E0F08E828F83A3A3A3A3A3A3A3A3BA +:103EAB00A3A3E50AF074028E828F83F0A3A882A9E4 +:103EBB0083E5082413F582E5093400F583E06440BB +:103ECB00700474018002740388828983F08E828F60 +:103EDB0083A3A3A3A3A3A3A3A3A3E0C0E074021291 +:103EEB00067ED0E0F0123107E9C0E0740312067EC3 +:103EFB00D0E0F07481851082851183F0E508240DE4 +:103F0B00F582E5093400F583E0C0E0740112067E0A +:103F1B00D0E0F0850882850983A3A3A3A3A3A3A361 +:103F2B00A3A3A3E05407FA7403C39AFD7C04851082 +:103F3B0082851183AA82AB837902122C328A088B79 +:103F4B0009A909EA7001E96030750A04750B00785C +:103F5B000A1207D5AC0EAD0FEA24030A0A0AE9349C +:103F6B0000FB12695874021206497900AA08AB09C2 +:103F7B001230B9E97003023E0C023E6B74F8120664 +:103F8B008AEAFEEBFF7D017C0090F5C3E0F912227B +:103F9B0011E9FB7007121AB57901801074016B706F +:103FAB000479028007EEFAEFFB12402C7F01020628 +:103FBB00EA74F712068A7900A2AFE492E0FAC2AF74 +:103FCB0090F5C2E0603AE014F0EAA2E092AF091279 +:103FDB00401590F5C1E0F97C00ECC0E090F5C2E033 +:103FEB00FAD0E0C39A501E8C08E50824C1FAE434D9 +:103FFB00F5FB8A828B83A3E08A828B83F00C80D9BA +:10400B00EAA2E092AF7F020206EAC082C083E970A7 +:10401B00047A0180027A00EA90F5C0F0D083D08256 +:10402B002274F812068A7E00EA240CF8EB3400F9AD +:10403B008A828B83E0FC74F52CFC74FF3400FD74D6 +:10404B00086C7001ED7007740188828983F0888297 +:10405B008983E01208170101804069407D40123CC2 +:10406B00B6E9FA90F5C0E0700C74016A60070E0EA9 +:10407B008003123BFDEEF97F010206EA74F712068C +:10408B008A1218D1E990F5C7F07508037509007805 +:10409B00081207D57C007D007AC47BF5126A3F7449 +:1040AB00021206497F020206EA74F712068AEAFE3A +:1040BB00EBFF7D017C0090F5C7E0F9122211E9FBC3 +:1040CB007007121AB57901803B74016B7004790289 +:1040DB00803275080475090078081207D51235452A +:1040EB00EAFCEBFD8E828F83A3AA82AB831268FF5F +:1040FB007402120649EA7001EB70D3EEFAEFFB1271 +:10410B00411479007F020206EAC082C083EA240CC4 +:10411B00F582EB3400F583E06401700312412FD07C +:10412B0083D0822274F612068A74FF120633EAFEDB +:10413B00EBFFEE240DF582EF3400F583E0F50A85F5 +:10414B001082851183AC82AD83EE2405FAEF340027 +:10415B00FB123A52EAF8EBF9EA7001EB70030242F8 +:10416B000EE82404F508E93400F509E024C4F582CF +:10417B00E434F5F583E07021850882850983E50A2F +:10418B00F07401C0E0851082851183E024C4F582B0 +:10419B00E434F5F583D0E08012AA0A8508828509FC +:1041AB0083E0F912233DE9605AE50AF07902EEFA51 +:1041BB00EFFB12322C8A088B09A808A909E87001B9 +:1041CB00E9603988828983A3E0FA7901122520E519 +:1041DB0008240CF582E5093400F583E054F844011A +:1041EB00F0E508240BF582E5093400F583E0D2E70E +:1041FB00F07900AA08AB091230B98007EEFAEFFB91 +:10420B0012330274011206497F030206EA74F71295 +:10421B00068AE4C0E0E924C4F582E434F5F583D0E2 +:10422B00E0F07F020206EAC082C0831218D1E99047 +:10423B00F5C8F0D083D0822274F512068AEAFEEB21 +:10424B00FF7D038E828F83E024F5FCEE240CFAEFC6 +:10425B003400FB7901122C328A088B09A909EA7008 +:10426B0001E9603E750A04750B00780A1207D5EE5A +:10427B002405FCEF3400FDEA24030A0A0AE93400A2 +:10428B00FB1269587402120649E508240EF582E503 +:10429B00093400F583E0D2E7F07900AA08AB0912E4 +:1042AB0030B97F040206EA74F812068AEAFEEBFFC5 +:1042BB007D017C0090F5C8E0F9122211E9FA700734 +:1042CB00121AB57901801274016A7004790280099F +:1042DB00EEFAEFFB1242E979007F010206EAC08297 +:1042EB00C083EA240CF582EB3400F583E0640170A3 +:1042FB0003124243D083D0822222790022C082C093 +:10430B0083124638E490F5D4F0FB8029EB75F00569 +:10431B00A424D5F8E5F034F5F9E488828983F0A379 +:10432B00F0A3F088828983A3A3A3F088828983A357 +:10433B00A3A3A3F00BEBC3940A40D1D083D082226A +:10434B0074F112068A74FB12063374018510828590 +:10435B001183F01243081248997A007BC0124971FD +:10436B0075E54475E402539BFCE59B53E9EF4391E0 +:10437B0010D2A8439A01D2B990F410E4F0A3F080C4 +:10438B000B90DF3BE06401700375E10290F5D4E024 +:10439B00C3940A500690F608E060E675E10490F6C7 +:1043AB0008E0700990F5D4E0C39405500B90F4101D +:1043BB00E4F0A374800245857A0080010AEAC39475 +:1043CB000A5031EA75F005A424D5F8E5F034F5F977 +:1043DB0088828983E060E5A3E0FAA3E0FB74031213 +:1043EB00067EEAF0A3EBF088828983A3A3A3E0F512 +:1043FB000C750D007A0980011AEA602E75F005A480 +:10440B0024D5F8E5F034F5F988828983E060E9A3D7 +:10441B00E0FAA3E0FB740112067EEAF0A3EBF0884E +:10442B00828983A3A3A3E0FE7F00750800750900B2 +:10443B007C007D007A008015E508250AF508E50962 +:10444B003400F509EC24010CED3400FD0AEAC394A9 +:10445B000A5033EA75F005A424D5F582E5F034F55E +:10446B00F583E060E7E5822404F582E5833400F50B +:10447B0083E0F50AE0A2E750BFA80AE50828F50893 +:10448B00E50934FF80BCA808A909ECFAEDFB12057D +:10449B00B0880EC3E894E7E994FFA2D265D033400D +:1044AB000EC3E8941AE99400A2D265D033400B9066 +:1044BB00F410E8F0A37420024585EEC3950CF8EFD9 +:1044CB00950DF9E875F0CCA4C8AAF075F00CA42AE8 +:1044DB00FA75F0CCE9A42AF9740112067EC082C0E9 +:1044EB0083740312067EE0FAA3E0FBD083D082E054 +:1044FB00C39AFEA3E09BFFE8C39EFAE99FFBC3EAC6 +:10450B009404EB94005036740F5AF990F410E4F0C5 +:10451B00A3E9F0C3E5099400A2D265D0335046C39A +:10452B00E49508F8E49509F9ECFAEDFB1205B8E807 +:10453B00F404F890F410E048F0A3E08045EEC39843 +:10454B00F8EF99F9C3E89404E994005025740F58D7 +:10455B00F990F410E4F0A3E9F0C3E5099400A2D2BA +:10456B0065D03340BAA808A909ECFAEDFB1205B8DF +:10457B0080C190F410E4F0A37440F0E485108285C0 +:10458B001183F0851082851183E06401600302467C +:10459B001EE490F5D4F0FA8029EA75F005A424D531 +:1045AB00F8E5F034F5F9E488828983F0A3F0A3F001 +:1045BB0088828983A3A3A3F088828983A3A3A3A35F +:1045CB00F00AEAC3940A40D1E50E90DF08F01248D6 +:1045DB00997A007B40124971800B90DF3BE06401BC +:1045EB00700375E10290F5D4E0700690F608E06078 +:1045FB00E975E10490F5D4E0601090F5D9E0FAC3C9 +:10460B0094FE500FEAC39403400990F410E4F0A316 +:10461B007410F0C2A8539AFEC2B975E40075E25546 +:10462B0012489974051206497F080206EAC082C037 +:10463B008374CA90DF00F074BA90DF01F0740A90B3 +:10464B00DF02F0E490DF03F090DF04F090DF05F081 +:10465B0090DF06F0741290DF07F0E490DF08F0743F +:10466B001290DF09F0740A90DF0AF074AA90DF0B46 +:10467B00F0743D90DF0CF0745590DF0DF0741590D5 +:10468B00DF0EF0741290DF0FF0741190DF10F074E6 +:10469B006090DF11F0740790DF12F0740290DF135B +:1046AB00F0741890DF14F0741D90DF15F0741C90EB +:1046BB00DF16F074C790DF17F0741090DF18F074EA +:1046CB00B290DF19F074B690DF1AF0741090DF1B04 +:1046DB00F074EA90DF1CF0742A90DF1DF0E490DF99 +:1046EB001EF0741F90DF1FF0E490DF2FF090DF308F +:1046FB00F090DF31F0743190DF24F090DF1CE04458 +:10470B0020F0745A90DF2EF075E10475E10190DF13 +:10471B003BE0640170F890DF1CE054CFF075E104CE +:10472B00D083D0822274F112068AE5D990F5C9F0B4 +:10473B00740190F5D3F07890F9801DA2895019E59A +:10474B00D9C0E0E024C9F582E434F5F583D0E0F07C +:10475B0090F5D3E004F0C289E0C3940A5012E8FA52 +:10476B00E9FB74FF2A1874FF3BF9EA7001EB70CB7D +:10477B00E0640A600302483875E104AAE28A828584 +:10478B008208E5E3F8E4C8F50990F60FE0FA75F056 +:10479B00BDA4CAACF075F02CA42CFB880A880B7452 +:1047AB000F78081204AD90FA21780C12052B7808BB +:1047BB00790C120424E5082AF508E5093BF5097C78 +:1047CB00017B0180218B82A882E824C9F582E43425 +:1047DB00F5F583E0FAE82417F582E434FAF583E083 +:1047EB006A60027C000BEBC3940A40D9EC603E90EC +:1047FB00F5D4E075F005A424D5F8E5F034F5F9749B +:10480B000188828983F0A3E508F0A3E509F090F510 +:10481B00C9E088828983A3A3A3F090DF38E0888264 +:10482B008983A3A3A3A3F090F5D4E004F07F08023F +:10483B0006EAC082C083E5E9FA539BFCE59BEAA23A +:10484B00E7500575E1048014A2E6501075E1049061 +:10485B00DF3BE0640170F8E490F5D3F075E900D02C +:10486B0083D08222C082C083C2A8539AFE74FF9069 +:10487B00DF06F074C090DF2EF0740190DF02F0754C +:10488B00D95575E103D083D0822275E10422C08211 +:10489B00C083E490F607F090F608F090F609F0A3C9 +:1048AB00F090F60BF090F60CF0A3F090F60EF09063 +:1048BB00F60FF0D083D0822274F712068A7C009018 +:1048CB00F60BE0603E53E5BF75DBFF75DAFFE5DB0A +:1048DB00F9E5DAF874FF68700374FF69601375DB30 +:1048EB00FF75DAFFE5DBF9E5DAF8EC0CC3940B4066 +:1048FB00E3E014F053E40FE5E443E54079017F0274 +:10490B000206EA90F60CC3E09406A3E09400405232 +:10491B0053E5BF90F60CE024FFA3E034FFF5DB90EA +:10492B00F60CE014F5DAE5DBF9E5DAF8E024FFFA4A +:10493B00A3E034FFFBEA687002EB696017EBF5DB71 +:10494B0090F60CE014F5DAE5DBF9E5DAF8EC0CC3DC +:10495B00940B40D890F60CE4F0A3F0740190F60E93 +:10496B0080917900809874F112068A53E5BFE49028 +:10497B00F607F090F60B800AEA2443FAEB34D3FBEC +:10498B00E004F0C3EA94BDEB942C50EC8A088B093D +:10499B00750A00750B0090FA21780C12052B78081C +:1049AB00790C1203A4740F780812049490F60CE59A +:1049BB0008F0A3E509F01248C353E40FE5E443E51F +:1049CB0040740190F607F07F080206EAC082C083AC +:1049DB0090F609E0F8A3E0F9C3E89AE99B5009EADD +:1049EB00C398F8EB99F9800CE86A7002E96B70EFE9 +:1049FB0078FF79FF90F609EAF0A3EBF0E8FAE9FB10 +:104A0B00124971D083D08222C082C083740190F688 +:104A1B0007F0D083D08222C082C083E490F607F0E7 +:104A2B00D083D08222C082C083E490F608F0D0837A +:104A3B00D08222C082C08390F62CE0FA74226A7076 +:104A4B001A90F619E0703390F62DE0F8A3E0F99088 +:104A5B00F650E8F0A3E9F07402801B74206A70141E +:104A6B0090F619E0701490F6267449F0A374F6F0E2 +:104A7B00A3E480E2740490F619F0D083D08222C0B4 +:104A8B0082C08390F62CE06421702090F619E070C0 +:104A9B002090F6267449F0A374F6F0A3E4F090F698 +:104AAB00297407F0A3E4F074018002740490F619E2 +:104ABB00F0D083D08222C082C083740490F619F0A8 +:104ACB00D083D08222C082C083740490F619F0D0B8 +:104ADB0083D08222C082C083740490F619F0D083F5 +:104AEB00D08222C082C083740490F619F0D083D098 +:104AFB0082222222C082C08390FA25E0F8A3E0F93B +:104B0B0090F610E8F0A3E9F0D083D0822274F8126B +:104B1B00068AE9FCEAFD7A007B00802190F610E022 +:104B2B00F8A3E0F5838882E493F890F610E028F878 +:104B3B00A3E03400F990F610E8F0A3E9F090F6103A +:104B4B00E0F8A3E0F990FA27E0687003A3E069604E +:104B5B004890F610E02401F8A3E03400F98882892C +:104B6B0083E4936C702B90F610E0FAA3E0FB90F6C5 +:104B7B0010E0F8A3E0F5838882E493F890F610E058 +:104B8B0028F8A3E03400F990F610E8F0A3E9F080E0 +:104B9B0008E4936D7086ED60837F010206EA124A8A +:104BAB00FF7A007901124B182274F712068AE9FE7C +:104BBB00EAFF124AFF800E8A828B83A3A3A3A3A3CF +:104BCB00E4936E60147A007902124B18EA7001EBD1 +:104BDB006007EE70E2EF1F70EC7F020206EA74F7DB +:104BEB0012068AEAFEEBFF7A00124BB47A027904C2 +:104BFB00124B18EA7001EB60178A828B83A3A3E434 +:104C0B00936E70E88A828B83A3A3A3E4936F70DC0B +:104C1B007F020206EA74F712068AE9FE124AFF7A4D +:104C2B00007903124B18EE1E70F57F020206EAC0E4 +:104C3B0082C0837A007901124BB48A828B83A3A33F +:104C4B00A3A3A3A3A3E493A2E6500474018001E4FD +:104C5B0090F625F0E490F624F043BE80D2BDD083CD +:104C6B00D08222C082C083740290F612F0E490F6D8 +:104C7B0013F090F619F07903124EF9752100752295 +:104C8B0000D083D0822274F512068A90DE0EE0FEED +:104C9B00E4F090DE11E0FFA2E4501F7480F0740783 +:104CAB0090F619F0E5217002E522600985218285D5 +:104CBB002283120688E490F619F0EFA2E25009E481 +:104CCB0090DE11F090F619F090F619E0FA74026A82 +:104CDB006003024D6790DE16E0F50A90F626120788 +:104CEB00E6A90A7A207BDE124F3F74031206498530 +:104CFB000A0890F629C3E09508F0A3E09400F09021 +:104D0B00F626E0F9A3E0FAA3E0FBE9250AF9EA3479 +:104D1B0000FA90F626E9F0A3EAF0A3EBF090F6295F +:104D2B00E07002A3E060047A4080027A48EA90DEE9 +:104D3B0011F090F629E07002A3E07016E5217002E5 +:104D4B00E5226009852182852283120688E490F68C +:104D5B0019F0EE90DE0EF07F040206EA74066A701C +:104D6B000985218285228312068890F619E060035B +:104D7B00024E6AEFA2E04003024E6A75082B7509DA +:104D8B00F6750A0078081207D179087A207BDE12B3 +:104D9B004F3F740312064975210075220090F62BC4 +:104DAB00E054E012084D000600C74D20434E402D45 +:104DBB004E80024EA04E4EC0384EFA4D90F62CE06F +:104DCB0012084D000501EB4D03E64D05E14D09F0D1 +:104DDB004D0BF54DFA4D1252CC80711252C0806CB6 +:104DEB001252B480671256CF80621257F7805D74EF +:104DFB000490F619F0805590F62CE012084D000443 +:104E0B0000194E061E4E08234E0A284EFA4D12501C +:104E1B00CA80391253258034125686802F12579927 +:104E2B00802A7521C175224A124AC1801F7521D073 +:104E3B0075224A124AD0801475213E75224A124AB5 +:104E4B003E800975218A75224A124A8A90F619E02A +:104E5B00640470047A6080027A40EA90DE11F0906C +:104E6B00F619E0FA74016A70717F0290F629E0F886 +:104E7B00A3E0F9C3E89420E994005007E8F50A7F12 +:104E8B000A8003750A2090F6261207E6A90A7A20F3 +:104E9B007BDE124F797403120649850A0890F626B9 +:104EAB00E0F9A3E0FAA3E0FBE92508F9EA3400FAFC +:104EBB0090F626E9F0A3EAF0A3EBF090F629C3E015 +:104ECB009508F0A3E09400F0EF90DE11F0E50AC333 +:104EDB0094204003024D5D024D4774056A60030246 +:104EEB004D5D852182852283120688024D5D74F704 +:104EFB0012068A7A008014E9C0E08A08E508241AB1 +:104F0B00F582E434F6F583D0E0F00AEAC394054069 +:104F1B00E67A008014E9C0E08A08E508241FF582D0 +:104F2B00E434F6F583D0E0F00AEAC3940540E67F5B +:104F3B00020206EA74F612068AEAFCEBFDE9FE743D +:104F4B000A12067EE0F508A3E0F509A3E0A908AA7A +:104F5B0009FBEE60148C828D83E012038EE9240131 +:104F6B0009EA3400FA1EEE70EC7F030206EA74F6CF +:104F7B0012068AEAFCEBFDE9FE740A12067EE0F5E6 +:104F8B0008A3E0F509A3E0A908AA09FBEE60141237 +:104F9B0003748C828D83F0E9240109EA3400FA1E34 +:104FAB00EE70EC7F030206EA74F712068A75230093 +:104FBB007524007525008A268B27EA90DE0BF08A74 +:104FCB00088B0974047808120611E50890DE07F0C7 +:104FDB008A088B0974097808120611E508543E906B +:104FEB00DE09F0438C10758900C2C5758B00C2E8D1 +:104FFB00439A027F020206EAC0E074F1120722E52F +:10500B00BEA2E650FA90DE06E0FAA2E25036A826DF +:10501B00E890DE0BF08526088527097404780812C2 +:10502B000611E50890DE07F0852608852709740927 +:10503B007808120611E508543E90DE09F090DE0167 +:10504B00E0D2E0F07823EA46F608E6F690DE02E0DE +:10505B00F508750900740478081206207823E50812 +:10506B0046F608E50946F690DE04E0F508750900FA +:10507B00740978081206207823E6F608E50946F647 +:10508B00EAA2E0500375250174065A6003752500EA +:10509B00124AFE758B00C2E87F02020781C0E074E2 +:1050AB00F2120722E5BEA2E650FAE589A2E7500507 +:1050BB00C2BD125921758900C2C57F0102078174D7 +:1050CB00F712068A90F62DE07002A3E0701E90F6A0 +:1050DB002FE0F8A3E0F974FF59FBE47001EB700CBF +:1050EB0090F631E064027002A3E060057404025193 +:1050FB00BC90F62BE0120817800210510D513D5158 +:10510B004D51E86008740490F61902519B90F625F6 +:10511B00E0600478018002780090F633E8F0A3E4B5 +:10512B00F090F624E0606A90F633E04402F0A3E0DE +:10513B00805E90F612E0640470CB90F633E4F0A33B +:10514B00804EE8547FF50890F612E0640470B6E5E3 +:10515B0008C3940650AFE5082412F582E434F6F543 +:10516B0083E854806010A3A3A3A3A3A3A3E06403C9 +:10517B00701578018013E582240CF582E5833400E9 +:10518B00F583E0640360EB780090F633E8F0A3E47A +:10519B00F090F619E06404601C90F6267433F0A3CB +:1051AB0074F6F0A3E4F090F6297402F0A3E4F07423 +:1051BB000190F619F07F020206EA74F712068A9044 +:1051CB00F631E07002A3E0701290F612E064046016 +:1051DB001290F62FE07002A3E06008740490F619A9 +:1051EB000252AC90F62BE0541F1208170002E65146 +:1051FB0001520952235290F62DE0640160057900AB +:10520B000252AFE990F624F060047905800279062A +:10521B007A00124AFD0252AD90F62FE0547FFA90BD +:10522B00F62DE070D9EAC3940650B0EA90DE0EF08A +:10523B0090F62FE054806032E960047B1080027B93 +:10524B0040EB90DE11F0E960047B0380027B00EB06 +:10525B00C0E0EA2419F582E434F6F583D0E0F0E9F6 +:10526B0060047908803479078030E960047B208002 +:10527B00027B80EB90DE14F0E960047B0380027B01 +:10528B0000EBC0E0EA241EF582E434F6F583D0E0AF +:10529B00F0E96004790A80027909124AFDE490DE94 +:1052AB000EF079017F020206EA79001251C5E9700E +:1052BB0003124ADF2279011251C5E97003124AEE3B +:1052CB0022C082C08390F62FE07002A3E070209082 +:1052DB00F631E07002A3E0701690F62DE0F8A3E033 +:1052EB00F9748058FA74FF59FBEA7001EB6007748C +:1052FB000490F619801EE890DE00F090F62DE090F9 +:10530B00F6126009E06402700C74038007E064031A +:10531B0070037402F0D083D0822274F512068A9047 +:10532B00F62DE0FAA3E01208170102D9533E53659C +:10533B0053B053124BA990F626EAF0A3EBF0A374EB +:10534B0080F090F626E0F9A3E0FAA3E0FB120374D9 +:10535B0090F629F0A3E4F00254AB7900124BB49011 +:10536B00F626EAF0A3EBF0A37480F090F626E0F9B2 +:10537B00A3E0FAA3E0FBE924020909EA3400FA12DC +:10538B000374FC90F626E0F9A3E0FAA3E0FBE92412 +:10539B0003090909EA3400FA120374F9EC90F629AF +:1053AB00F0A3E980B1EAF9124C2090F626EAF0A3BB +:1053BB00EBF0A37480F090F626E0F9A3E0FAA3E0FB +:1053CB00FB12037490F629F0A3E4F00254AB90F6B1 +:1053DB0026E4F0A3F0A3F0FC02547C7509007403DF +:1053EB007808120620AE08AF09EA2EF8EB3FF990C9 +:1053FB00F62DE0F508A3E0F50988828983E493AAEA +:10540B00096A706CA3E4936508706590F62FE0F55C +:10541B0008A3E0F50988828983A3A3E493AA096A08 +:10542B00704E88828983A3A3A3E493650870418897 +:10543B00828983A3A3A3A3E493F508740193F509CD +:10544B0090F626E508F0A3E509F0A37480F090FA36 +:10545B0029E02EFAA3E03F8A82F583A3A3A3A3A39B +:10546B00A3E493F8740193F990F629E8F0A3E9F01B +:10547B000C90FA29E0FAA3E0FB8C0890FA2BE0F8E9 +:10548B00A3E0F9E8C39AF50AE99BF50B7403780AD4 +:10549B00120611C3E508950AE4950B50030253E677 +:1054AB0090F626E0FCA3E0FDA3E0FEEC4D4E70066B +:1054BB00740490F619F090F619E06404602590F6E8 +:1054CB0031E0FAA3E0FB90F629E0F8A3E0F9C3EA98 +:1054DB0098EB99500890F629EAF0A3EBF074019041 +:1054EB00F619F07F040206EA74F112068A74FE12B2 +:1054FB000633851082851183EAF0A3EBF0851082C9 +:10550B00851183E0F8A3E0F5838882A3A3A3A3E42A +:10551B0093602B90FA2DE0FEA3E08007EE2404FEAF +:10552B00EF3400FF8E828F83E493F8740193F98537 +:10553B001082851183E0687003A3E06970DE750843 +:10554B0000805A749090DE14F07410F08882898376 +:10555B00E493540364017003750940750A01750BDC +:10556B0000E50C780A1206208E828F83A3A3A393E7 +:10557B00550A6006E509D2E0F509E50990DE15F05C +:10558B00EA90DE13F0E4C0E0E50C241EF582E4346F +:10559B00F6F583D0E0F0E490DE0EF005088510827E +:1055AB00851183E0F8A3E0F5838882A3A3A3A3E48A +:1055BB0093FAE508C39A400302567C7A00790512E8 +:1055CB004B188A0A8B0BAC0AAD0BEC7001ED60CB60 +:1055DB00EC2402F50EED3400F50F850E82F583E415 +:1055EB0093540FF50C90DE0EF07509008C828D83B1 +:1055FB00A3A3A3A3E4932407F50AA3E4933400F530 +:10560B000B7403780A120611AA0AEC2403F8ED3482 +:10561B0000F9850E82850F83E493A2E740030255C0 +:10562B004E744890DE11F07408F088828983E493FD +:10563B00540364017003750940750A01750B00E58D +:10564B000C780A1206208E828F83A3A393550A60CF +:10565B0006E509D2E0F509E50990DE12F0EA90DEE5 +:10566B0010F0E4C0E0E50C2419F582E434F60255A1 +:10567B009C74021206497F080206EAC082C083901E +:10568B00F62DE07002A3E0701690F62FE07002A3E7 +:10569B00E0700C90F631E064017002A3E0600474DA +:1056AB0004801890F6267413F0A374F6F0A3E4F0BC +:1056BB0090F6297401F0A3E4F0740190F619F0D080 +:1056CB0083D0822274F312068A90F612E064026091 +:1056DB001F90F62FE07002A3E0701590F631E0708A +:1056EB0002A3E0700B90F62EE0F9E47001E960097B +:1056FB00740490F619F00257947A007901124AFD5E +:10570B0090F62DE0606E7A00F9124BB48A088B0983 +:10571B00EA7001EB6056740490F612F090F62DE0EF +:10572B0090F613F0750A00850882850983A3A3A35D +:10573B00A3E493FAE50AC39A5048850A0CE50C24B6 +:10574B0014FEE434F6FFE48E828F83F07A00790442 +:10575B00124B188A828B83A3A3A3E493FC8E828FB4 +:10576B0083E06C70E71254F3050A80BB740490F667 +:10577B0019F0800E90F613F0740390F612F0F912F4 +:10578B004EF97A007902124AFD7F060206EA74F698 +:10579B0012068A90F612E06404701E90F62BE064F9 +:1057AB0081701690F62DE07002A3E0700C90F6312C +:1057BB00E064017002A3E060047404802690F62F6D +:1057CB00E02414F508A3E034F6F50990F626E50875 +:1057DB00F0A3E509F0A3E4F090F6297401F0A3E43B +:1057EB00F0740190F619F07F030206EA74F71206C3 +:1057FB008A90F612E06404701290F62BE06401704C +:10580B000A90F631E07002A3E06008740490F61978 +:10581B00F0805890F62DE0FB90F62FE0FA90F613FF +:10582B00E0F9124BE98A088B09A808A909E8FEE9F7 +:10583B00FFE87001E960D490F62FE0FA7903124A81 +:10584B00FD90F62DE0C0E090F62FE02414F8A3E0D5 +:10585B0034F6F988828983D0E0F0EEFAEFFB12542C +:10586B00F390F62FE0FA7904124AFD7F020206EA62 +:10587B00C082C08390F645E07002A3E0600E90F604 +:10588B0045E0F8A3E0F5838882120688745390F6FE +:10589B0035F074BE90F636F074FC90F637F0744326 +:1058AB0090F638F074BE90F639F0740190F63AF039 +:1058BB00747590F63BF0748790F63CF0740190F69B +:1058CB003DF074E590F63EF0742590F63FF0747061 +:1058DB0090F640F074F390F641F0742290F642F09B +:1058EB00758900C2C5D2BD90F6437435F0A374F62A +:1058FB00F0758235F58312068890F647E07002A3A7 +:10590B00E0600E90F647E0F8A3E0F583888212067C +:10591B0088D083D08222C082C083E490F63AF09084 +:10592B00F63BF090F63CF090F63DF0D083D082221F +:10593B0074F512068A8A088B098C0A8D0BE490F693 +:10594B0075F090F676F090F677F090F649780812AD +:10595B00053AE490F64DF090F64EF0740890F64F41 +:10596B00F090F650E4F0A3F0740190F652F0124C64 +:10597B003A7AFF7BFF124FB353F4FDD29143FE02F1 +:10598B00120A1F7F040206EAC082C0831259AB9031 +:10599B00F652E06006125A5A1259F6D083D0822280 +:1059AB00A823E85404600E782374FB56F60874FFA2 +:1059BB0056F6124C6EA823E85410600E782374EF41 +:1059CB0056F60874FF56F6124C91A823E8A2E05045 +:1059DB0019782374FE56F60874FF56F612587B7826 +:1059EB002374FD56F60874FF56F62274F612068AD7 +:1059FB00120A2290DE0EE090F678F0740490DE0E20 +:105A0B00F090DE11E0A2E0403690F677E060307562 +:105A1B0008537509F6750A0078081207D190F655E8 +:105A2B00E0F97A287BDE124F797403120649E49071 +:105A3B00F677F0740490DE0EF0740190DE11F090A6 +:105A4B00F678E090DE0EF0120A1F7F030206EA746E +:105A5B00F612068A7E00120A2290DE0EE090F6788D +:105A6B00F0740490DE0EF090DE14E0A2E04003022E +:105A7B005B0990DE16E0FF90DE17E0742090FA31A0 +:105A8B00F090F675E0F8EF28F8E43400F9E894218B +:105A9B00E994004002E4F0E02453F508E434F6F511 +:105AAB00098E0A78081207D1EFF97A287BDE124F9C +:105ABB003F740312064990F675E02FF0740490DEE4 +:105ACB000EF0E490DE14F090F675E0C394024005FE +:105ADB0090F655E0FE8E0874FF2508F874FF34002D +:105AEB00F990F675E0FAC3E89AE99400A2D265D072 +:105AFB0033500BEEC394034005120C21E4F090F6E7 +:105B0B0078E090DE0EF0120A1F7F030206EAC082D5 +:105B1B00C08375910075E90075C6B874D390DF002A +:105B2B00F0749190DF01F0741290DF07F0E490DFD6 +:105B3B0008F0741290DF09F0741490DF0AF0747A95 +:105B4B0090DF0BF0E490DF06F0748D90DF2EF07495 +:105B5B001D90DF0CF0745590DF0DF0741390DF0E79 +:105B6B00F0742390DF0FF0741190DF10F0746390DA +:105B7B00DF11F074B690DF1AF0741090DF1BF07425 +:105B8B001890DF14F0743C90DF13F0740790DF1261 +:105B9B00F075A48775A36B75A2F8741D90DF15F0D3 +:105BAB00741C90DF16F074C790DF17F0E490DF18C9 +:105BBB00F074B090DF19F074EA90DF1CF0742A9047 +:105BCB00DF1DF0E490DF1EF0741F90DF1FF074599F +:105BDB0090DF20F0748890DF23F0743190DF24F095 +:105BEB00740990DF25F0747F90DF21F0748890DFCB +:105BFB0022F0742990DF2FF0741E90DF30F0741BAD +:105C0B0090DF31F0740690DF03F0744590DF04F001 +:105C1B0074CA90DF05F074FE90DF02F0D083D0825F +:105C2B002274F712068AE5E9FA90F979E0640260CA +:105C3B000575E900804574505A6450702E53E9EF96 +:105C4B0053E9BF539BFCE59B125D3D7508FF75093E +:105C5B000078081207D57C007D007A787BF8126AF1 +:105C6B003F7402120649125CC7801053E910E5E934 +:105C7B00539BFCE59B740190F876F07F020206EAD9 +:105C8B00C082C083E9701190F871E4F0A3F090F832 +:105C9B0073F0A3F090F875F0D083D08222C082C04D +:105CAB0083E9701390F871E4F0A3F090F875F0901D +:105CBB00F873EAF0A3EBF0D083D0822274F71206CC +:105CCB008A74F890F97DF0747890F97EF074DF9017 +:105CDB00F97BF074D990F97CF090F97FE054E044B3 +:105CEB0001F0E490F980F0748190F97FF0741290D8 +:105CFB00F982F0741390F981F075D6817508FF75F0 +:105D0B00090078081207D57C007D007A787BF812A1 +:105D1B006A3F740212064943D601539BFCE59B5321 +:105D2B00E9EF740290F979F075E102439110FF02EB +:105D3B0006EAC082C0835391EF740190F979F07534 +:105D4B00E10490DF3BE0640170F875D68153D1FE1E +:105D5B00539BFCE59B53E9EFD083D0822274F8125E +:105D6B00068AEAFEEBFF125D3D74DF90F97DF0745D +:105D7B00D990F97EF0EF90F97BF0EE90F97CF090F2 +:105D8B00F97FE054E04401F0E490F980F074219045 +:105D9B00F97FF0744290F982F0741390F981F0431B +:105DAB00D601740490F979F075E103E5E9A2E450AA +:105DBB00FA53E9EF125D3D79017F010206EA74F8AF +:105DCB0012068A790090F876E064016003025E5E49 +:105DDB00E4F090F879E0707B90F878E0247AF58223 +:105DEB00E434F8F583E0A2E750697E017D00802161 +:105DFB008D82AA82EA247CF582E434F8F583E0FCF8 +:105E0B00EA2435F582E434FAF583E06C60027E0017 +:105E1B000DEDC3940440D9EE603990F87AE090F917 +:105E2B007AF0E090FA3BF0740190FA3DF0FA7B00C7 +:105E3B00125CA890F875E060FA7900125C8BD29036 +:105E4B0079047A3A7BFA125D68C2907901740290F8 +:105E5B00F67AF07F010206EAC082C08390F97AE0FD +:105E6B0090FA3FF090F877E090FA43F07AB87B0124 +:105E7B007900125CA890F773E06404600690F875E3 +:105E8B00E060F290F773E06404600990F67AE0D278 +:105E9B00E5025F247900125C8BD29079067A3E7B07 +:105EAB00FA125D68C290125CC77AB87B0179001256 +:105EBB005CA890F875E0700890F876E0640170F2D9 +:105ECB007900125C8B125D3D90F876E06401704AAC +:105EDB0090F878E0247AF582E434F8F583E0548086 +:105EEB00FBE490F876F090F879E064CA702C90F8A7 +:105EFB007AE0FA90F97AE06A702090F87BE064011E +:105F0B007018EB6015E490F877F0740190F987F056 +:105F1B0090F773F0740890F67BF0D083D08222C098 +:105F2B0082C08390F986E090F777F090F985E09046 +:105F3B00F778F090F97AE090F775F07AB87B017901 +:105F4B0000125CA890F773E06404600690F875E0AB +:105F5B0060F290F773E06404600990F67AE0D2E5A2 +:105F6B000260477900125C8BD29090F774E004F9D1 +:105F7B007A747BF7125D68C290125CC77AB87B01AA +:105F8B007900125CA890F875E0700890F876E064E0 +:105F9B000170F2125D3D7900125C8B90F876E06433 +:105FAB0001600302604890F878E0247AF582E434CB +:105FBB00F8F583E05480FBE490F876F090F879E004 +:105FCB0064CA707990F87AE0FA90F97AE06A706DA9 +:105FDB0090F87BE06401706590F87CE0FA90F986AC +:105FEB00E0547F6A705790F87DE0C0E090F985E04F +:105FFB00F8D0E0687047EB6044E490F877F090F9E4 +:10600B0085E02401F0A3E03400F090F985E0F8A3DB +:10601B00E0F9E875F064A4F8AAF075F064E9A42A35 +:10602B00F990F983E0FAA3E0FB1205B8E890F97751 +:10603B00F0740890F67BF0740190F773F0D083D076 +:10604B008222C082C08390F877E004F0E0C394060C +:10605B00400D90F67AE0D2E5F0E0D2E2F0802990A4 +:10606B00F987E07005125E63801E90F985C082C0CF +:10607B008390F983E0F8A3E0F9D083D082C3E09852 +:10608B00A3E0995003125F2AD083D08222C082C032 +:10609B0083E490F877F090F977F0740190F67AF04A +:1060AB0090F67BF090F985E4F0A3F090F983F0A3E0 +:1060BB00F0740190F773F0E490F987F090F876F0B4 +:1060CB00D083D08222C082C08374F9F5D575D47B7E +:1060DB0012609874FC90F774F074CA90F776F074B1 +:1060EB000190F67AF0C2A8439A01C290E490F67937 +:1060FB00F090F977F0125D3D806090F985C082C019 +:10610B008390F983E0F8A3E0F9D083D082C3E098C1 +:10611B00A3E099400690F987E0701712604D7A0161 +:10612B007B007900125CA890F875E060FA79001298 +:10613B005C8B90F978E0701B90F985C082C08390DE +:10614B00F983E0F8A3E0F9D083D082C3E098A3E011 +:10615B0099400790F67AE0D2E5F090F679E0702A54 +:10616B00125CC7125DC9E964017017740290F67A6C +:10617B00F090F679E004F0740490F67BF0125D3D3C +:10618B00800890F67AE0A2E550D990F67AE0A2E585 +:10619B004003026105C2A8539AFE5391EF75E900C3 +:1061AB00125D3DE490F679F07A2C7B01F9125CA834 +:1061BB0090F875E060FA7900125C8BD083D0822264 +:1061CB00C082C08374B290DF01F0743790DF00F0AF +:1061DB00740A90DF02F0740090DF03F0740090DF1C +:1061EB0004F0740090DF05F0740090DF06F0741279 +:1061FB0090DF07F0740090DF08F0741290DF09F065 +:10620B00740D90DF0AF074DD90DF0BF0743D90DFBE +:10621B000CF0745590DF0DF0741590DF0EF07412C6 +:10622B0090DF0FF0741190DF10F0746090DF11F0BD +:10623B00740790DF12F0740090DF13F0741890DF86 +:10624B0014F0741D90DF15F0741C90DF16F074C7FA +:10625B0090DF17F0741090DF18F074B290DF19F024 +:10626B0074B690DF1AF0741090DF1BF074EA90DFB5 +:10627B001CF0742A90DF1DF0740090DF1EF0741F69 +:10628B0090DF1FF0740090DF2FF0740090DF30F080 +:10629B00740090DF31F0743190DF24F075E10475F8 +:1062AB00E10190DF3BE0640170F8D083D08222C023 +:1062BB0082C08390DF1CE0442090DF1CF074C690FA +:1062CB00DF2EF075E10475E10190DF3BE0640170B6 +:1062DB00F890DF1CE054CFF075E104D083D082221C +:1062EB0074F712068AE990DF06F07A00EAC3940A83 +:1062FB00501E8A08750900E508249BF582E50934D0 +:10630B00F9F583E0C0E074282AF8D0E0F60A80DCC7 +:10631B00753200D29074FE559AFA8A9AC2A8C28935 +:10632B00539BFCE59B75E900D2A87401459AFC8C44 +:10633B009A740090FA44F075E1037F020206EAC0FA +:10634B0082C083C290C2A874FE559AFA8A9A7401CD +:10635B0090FA44F075E104D083D0822212634A2272 +:10636B007A007B0075320074282532F8E6F5D905E2 +:10637B0032E532C3940A502BEAF8EBF9740128FA90 +:10638B00740039FBC3E89488E994135016A2895022 +:10639B00E074282532F8E6F5D90532C2897A007BFC +:1063AB000080CEC3EA9488EB94134005C28975E94B +:1063BB00002274F812068AE5E9FEEEA2E750027E8F +:1063CB0000EEA2E45009740190FA44F01263677571 +:1063DB00E9007F010206EA74F512068A1261CB12FC +:1063EB0062BA90F9B2780812052B90F98E780812E0 +:1063FB00053A740090F992F07F040206EA74F712E2 +:10640B00068A740090F99AF0740090F999F0740070 +:10641B0090F998F0E5E3F8E4C8F990F995E8F0A362 +:10642B00E9F085E20875090090F995E04508F0A3BD +:10643B00E04509F090F995E024A4F0A3E03400F0D6 +:10644B0090F995E0FAA3E0FB1249D7124A137F02A9 +:10645B000206EAC082C083124A2212634A74009079 +:10646B00F99AF0D083D0822274F512068A8A088BAF +:10647B00098C0A8D0B90F98A780812053A7F040271 +:10648B0006EA74F512068AC0A8C2AF8A088B098C7B +:10649B000A8D0B90F98E780812053AE990F992F073 +:1064AB00D0A87F040206EA74F512068A90F999E0E7 +:1064BB001208170102C8647465CC65246690F993C1 +:1064CB00E02400F0A3E03470F012687490F99AE0C5 +:1064DB00D2E1F090FB51E0C39401A2D265D03350CE +:1064EB002890FA45780812052B90F98E780812053A +:1064FB001890FB51E06488700990F99AE0D2E0F0B3 +:10650B00800790F99AE0C2E0F012666E740790F97A +:10651B0097F075080075090878081207D590F98A65 +:10652B00780812052BAA08AB09AC0AAD0B90F998A9 +:10653B00E0F912676A74021206498A088B09A808E7 +:10654B00A90990F993E0C398F8A3E099F990F98819 +:10655B00E8F0A3E9F090F988E0FAA3E0FB1249D741 +:10656B00740190F999F002664A740090F997F075EE +:10657B00080075090278081207D590F98A78081275 +:10658B00052BAA08AB09AC0AAD0B90F998E0FE7489 +:10659B0080C39EF912676A74021206498A088B0936 +:1065AB00A808A90990F988E028F8A3E039F9740044 +:1065BB0028FA740239FB1249D7740290F999F080CA +:1065CB007E740190F997F075088075091C78081294 +:1065DB0007D590F98A780812052BAA08AB09AC0AE3 +:1065EB00AD0B90F998E0FE7440C39EF912676A7484 +:1065FB00021206498A088B09A808A90990F993E0A9 +:10660B0028F8A3E039F9740028FA740639FB12490B +:10661B00D7740390F999F0802612687390F99AE079 +:10662B00C2E1F090F998E02401F090F993E024B8DE +:10663B00FAA3E03466FB1249D7740090F999F07F06 +:10664B00040206EAC082C08390F99AE0A2E15008E6 +:10665B0090F997E0F91262EB1264B2124A30D083D0 +:10666B00D0822274F112068A90F99BC082C083906B +:10667B00FA49780812052BD083D08278081204F2DD +:10668B0090F98AC082C08390FA4D780C12052BD0FA +:10669B0083D082780C1204F27808790C12050590DD +:1066AB00F99B780812053A90F99BC082C08390FA47 +:1066BB004D780C12052BD083D082780C1204F290FB +:1066CB00F998E0F508E4F509F50AF50B7418780864 +:1066DB001204AD780C790812050590F99B780C1211 +:1066EB00053A90F99F780812052B90F98E780C12C9 +:1066FB00052B90F99F780C12053A90F992E090F9DE +:10670B00A3F07A9B7BF9126722E9FA74216A90F95C +:10671B00A4F07F080206EA74F812068A79007D005D +:10672B00EDC3940950348A828B83E0FE7C00ECC36A +:10673B009408501AE96EC394804008E9C3336497F8 +:10674B00F98004E9C333F9EEC333FE0C80E08A828F +:10675B008B83A3AA82AB830D80C67F010206EA74EA +:10676B00F112068A74FE120633E9FF8A0C8B0D8C2C +:10677B000E8D0F7CFF7D7F851082851183E50CF0DC +:10678B00AE0D850C08850D09850E0A850F0B74104F +:10679B007808120494740112067EE508F08F0875D0 +:1067AB000900E5082451F582E50934FAF583E0F890 +:1067BB00851082851183E0F508E50868F8E4C8F9CF +:1067CB008F0A750B008E08750900E508650AF50838 +:1067DB00E509650BF509E5082451F582E50934FA5D +:1067EB00F583E0F508750900E50828F8E50939F99E +:1067FB00851082851183E0F50AE4C50AF50B8E0836 +:10680B00750900740112067EE0F582758300E5823E +:10681B004508F508E5834509F509E508250AF50856 +:10682B00E509350BF509E50868F8E50969F9E8FAB2 +:10683B00E9FB741112067EC3E09AA3E09B500FECA8 +:10684B005AFAED5BFBEDC313FDEC13FC80E4740211 +:10685B001206497F080206EA43FE01C29012686CD9 +:10686B00221263E2126408222274F112068A74FC6B +:10687B0012063390F9A8E02400F0A3E03470F090F6 +:10688B00F9A8C3E09400A3E09480400C90F9A8E031 +:10689B002400F0A3E03480F090FB52E0FE90F9A5C9 +:1068AB00E0F50CE4F50DF50EF50F7410780C1204F1 +:1068BB00AD90F9A6E0F508A3E0F509E4F50AF50BB0 +:1068CB00780C79081204CC851082851183780C1210 +:1068DB00053AEEF9851082851183780812052BAAEB +:1068EB0008AB09AC0AAD0B12648D74041206497F18 +:1068FB00080206EA74F812068A740812067EE0F89B +:10690B00A3E08015A3AA82AB838C828D83A3AC8278 +:10691B00AD83E824FF18E934FFF9E87001E960243E +:10692B008A828B83E0FE8C828D83E06E8A828B83DE +:10693B0060D2E0F88C828D83E0FAE8C39AFAE49493 +:10694B0000FB80047A007B007F010206EA74F712D9 +:10695B00068A740912067EE0FEA3E0FFEAF8EBF963 +:10696B0080188C828D83E088828983F0A3A882A90A +:10697B00838C828D83A3AC82AD838E088F0974FFC9 +:10698B0025081E74FF3509FFE5087002E50970D272 +:10699B007F020206EA74F712068A740912067EE079 +:1069AB00F8A3E0F9EAFEEBFF8A088B09C3EA9CEB3C +:1069BB009D405EEC28F582ED39F583C3E5829508A1 +:1069CB00E5839509404BEA28FAEB39FBAC82AD83A2 +:1069DB00126A2E7002E5096041EC24FF1CED34FFB6 +:1069EB00FDEA24FF1AEB34FFFB8C828D83E08A8255 +:1069FB008B83F080DB8C828D83E08A828B83F08C9F +:106A0B00828D83A3AC82AD838A828B83A3AA82AB54 +:106A1B0083126A2E7002E50970DBEEFAEFFB7F0240 +:106A2B000206EA8808890974FF25081874FF3509DE +:106A3B00F9E5082274F812068A740812067EE0F84B +:106A4B00A3E0F98A828B838003ECF0A3E8FEE9FFD5 +:106A5B0074FF2E1874FF3FF9EE7001EF70EB7F019E +:036A6B000206EA36 +:04000005000000E90E +:00000001FF diff --git a/chronos-ti/Recovery/RF Access Point/Recovery_eZ430-Chronos_AP_868MHz_1_2.hex b/chronos-ti/Recovery/RF Access Point/Recovery_eZ430-Chronos_AP_868MHz_1_2.hex new file mode 100755 index 0000000..205853d --- /dev/null +++ b/chronos-ti/Recovery/RF Access Point/Recovery_eZ430-Chronos_AP_868MHz_1_2.hex @@ -0,0 +1,1714 @@ +:020000040000FA +:060000000200E90211D923 +:03000B0002127965 +:030013000212884E +:03001B0002129737 +:030023000212A620 +:03002B000212B509 +:0300330002500375 +:03003B000212C4EA +:030043000212D3D3 +:03004B000211F9A6 +:030053000212E2B4 +:030063000212275F +:03006B000250A898 +:030073000212F185 +:03007B000213006D +:030083000211A3C4 +:10008B0002130F00000080FB1200F8B900030200FE +:10009B00E3E479217812B800028004F709D8FCE474 +:1000AB0090F3FF78AC79068002F0A3D8FCD9FA90D4 +:1000BB00F9AAAA82AB839000FB78AA79028015E497 +:1000CB0093A3AC82AD838A828B83F0A3AA82AB838A +:1000DB008C828D83D8E9D9E7120A2512008E75D050 +:1000EB000075814F7510FF7511F302009379012292 +:1000FB0087D6120000C201000000000001000000C2 +:10010B00F1490200FFFFFFFF0032506E0E278CFFFC +:10011B0000000001000000000000000000000000D3 +:10012B0000000000000000000000000000000000C4 +:10013B0000000000000000000000000000000000B4 +:10014B00B242873F183B0543FC34B4407856341019 +:10015B00020101010008070605040302010055AA6C +:10016B0055AA55AA55AA556CDC0200A402470347B1 +:10017B0003470347034F03200700CABA5EBA1109AE +:10018B000300CA000500CA000000010001000000C6 +:10019B000000FFFFFFFF0001804020100884422178 +:1001AB009048A45229140A85C261B058ACD66B355D +:1001BB009ACD6633994CA653A9542A95CAE5F27980 +:1001CB003C9ECF67B3D96CB65B2D160B058241A055 +:1001DB005028944AA5D269341A8D462391C8E472EB +:1001EB00391C8EC7E3F1F8FCFEFF7F3F1F0F07831F +:1001FB00C1E070389CCEE7F3F97CBEDF6F379B4DC7 +:10020B0026138944221188C4623198CCE673B95CF9 +:10021B00AED7EB75BADD6EB7DB6D361B0D06038102 +:10022B00C06030188CC663B1D8ECF67B3D1E8F478F +:10023B00A3D1E8F47ABD5EAF57AB55AAD5EAF5FA70 +:10024B00FD7EBF5F2F178B45A251A8D46AB5DAED9F +:10025B00763B1D0E87C3E1F078BCDEEF77BB5D2EDE +:10026B0097CB65B2592C964B25924924120904025F +:10027B000180402010088442219048A45229140A7E +:10028B0085C261B058ACD66B359ACD6633994CA606 +:10029B0053A9542A95CAE5013C1201100102000032 +:1002AB00205104A6160900010203010902430002B2 +:1002BB00010080190904000001020201000524005D +:1002CB00100104240202052406000105240100018B +:1002DB000705820340004009040100020A000000E8 +:1002EB0007058402400001070504024000010403D6 +:1002FB00090424035400650078006100730020009A +:10030B0049006E0073007400720075006D0065008B +:10031B006E00740073001E03430043003100310074 +:10032B0031003100200055005300420020004300F3 +:10033B00440043000803300030003100BF020000CE +:10034B00E2020000E066701008A3E066700A08A3E2 +:10035B00E066700408A3E06622C3E09608A3E0966B +:10036B0008A3E09608A3E09622BB0102E722C08215 +:10037B00C08389828A83BB0003E08002E493D0832D +:10038B00D08222BB000EC082C0838A838982F0D0C8 +:10039B0083D08222BB0101F722080808EAC0E0EBF8 +:1003AB00C0E086F0E7A4FA180986F0E7A42AFA1849 +:1003BB000986F0E7A42AFA180986F0E7A42AFA19A5 +:1003CB0086F0E7A4FBE5F02AFA190886F0E7A42BE0 +:1003DB00FBE5F03AFA190886F0E7A42BFBE5F03AB7 +:1003EB00FA18180986F0E7A4C5F02BFBE43AFA19C2 +:1003FB0008E7C5F0C6A426F6E5F03BFBE43AFA188D +:10040B0086F0E7A4F6E5F00826F6E43B08F6E43AB6 +:10041B0008F6D0E0FBD0E0FA22E4CFC0E0E4CEC097 +:10042B00E0E4CDC0E0E4CCC0E075F020C3E633F6E9 +:10043B0008E633F608E633F608E633F6181818EC38 +:10044B0033FCED33FDEE33FEEF33FFC3EC9709EDD9 +:10045B009709EE9709EF97191919400FFFEC97FCC5 +:10046B0009ED97FD09EE97FE191906D5F0BEECF7CD +:10047B0009EDF709EEF709EFF7191919D0E0FCD0E0 +:10048B00E0FDD0E0FED0E0FF226016080808C6C3EE +:10049B0013C618C613C618C613C618C613C6D5E09E +:1004AB00EA227009080808226016181818C6C33308 +:1004BB00C608C633C608C633C608C633C6D5E0EA77 +:1004CB0022E627F60809E637F60809E637F60809A3 +:1004DB00E637F622E026F608A3E036F608A3E03668 +:1004EB00F608A3E036F622E056F608A3E056F60827 +:1004FB00A3E056F608A3E056F622E647F60809E60F +:10050B0047F60809E647F60809E647F622E046F003 +:10051B0008A3E046F008A3E046F008A3E046F0226B +:10052B00E0F608A3E0F608A3E0F608A3E0F622E65F +:10053B00F008A3E6F008A3E6F008A3E6F022CAC091 +:10054B00E0E6F0A308DAFAD0E0FA22CAC0E0E0A3B2 +:10055B00C582CCC582C583CDC583F0A3C582CCC56E +:10056B0082C583CDC583DAE6D0E0CA22C3E498F80E +:10057B00E499F91205B88026C3E49AFAE49BFBE9E7 +:10058B0020E7E91205B8E498F8E499F922C3E49856 +:10059B00F8E499F91205B8E498F8E499F9C3E49AE8 +:1005AB00FAE49BFB22EB20E7CFE920E7E0B9001050 +:1005BB00BB0008E88AF084F8AAF022E4FBC8FA2210 +:1005CB00EB70227B10C833C8C933C9335007C39AA9 +:1005DB00C3DBF280069A50012ADBEAC833F4C8C9A0 +:1005EB0033F4C9FA2275F008E4C833C8C933C933E8 +:1005FB00C99AC99B5004C92AC93BD5F0ECFBC83337 +:10060B00F4C8E4C9FA22600C08C6C313C618C61393 +:10061B00C6D5E0F422700422600D18C6C333C60899 +:10062B00C633C6D5E0F41822251010AF08F51040DC +:10063B000215118008F51040021511D2AF22C0D05F +:10064B00251010AF08F510500205118008F5105059 +:10065B00020511D2AFD0D0222510F58210AF08F5CC +:10066B0010400215118008F51040021511D2AF850C +:10067B001183222510F582E43511F58322E47325CD +:10068B0010C582C0E0E51134FFC583C0E0E510C39F +:10069B00958224F9F8E4C5A8858311858210C5A835 +:1006AB00E8CEF0A3E520F0A37808E608F0A3DEFA85 +:1006BB00EFF0A3E58124FBF8E608F0A3E608F0A32E +:1006CB000808E608F0A3E608F0A315811581D0E031 +:1006DB00FED0E0F815811581E8C0E0EEC0E0228580 +:1006EB001183851082E0A3FEE0A3F5207808E0A338 +:1006FB00F608DFFAE0A3FFE0A3C0E0E0A3C0E0E070 +:10070B00A3C0E0E0A3C0E0E4C5A8858210858311F7 +:10071B00C5A8D083D08222C0D02510C582C0E0E509 +:10072B001134FFC583C0E0E510C3958224F310AFED +:10073B00088583118582108008858311858210D2EC +:10074B00AFC8F0A3E9F0A3EAF0A3EBF0A37908E7B5 +:10075B0009F0A3D8FAECF0A3EDF0A3EEF0A3EFF0C1 +:10076B00A3D0E0F0A3D0E0F0A3D0E0F0A3E520F01D +:10077B00A3E5F0F0A322851183851082E0C0E0A3EE +:10078B00E0F9A3E0FAA3E0FBA37808E0F608A3DF07 +:10079B00FAE0FCA3E0FDA3E0FEA3E0FFA3E0C0E0D2 +:1007AB00A3E0C0E0A3E0F5D0A3E0F520A3E0A3F520 +:1007BB00F0E4C5A8858311858210C5A8D082D083AB +:1007CB00D0E0F8D0E0327403800474028000C0E003 +:1007DB00F404120663D0E0120549227403800474FA +:1007EB00028000CCC0E0EDC0E0E510C39CCCAD11A5 +:1007FB0050011D10AF068C108D1180068C108D11C1 +:10080B00D2AF120556D0E0FDD0E0FC22D083D082CF +:10081B00C5F0E493A3C5F0C395F0F5F0E493A3C33F +:10082B0095F04005E5F0048001E475F002A4258203 +:10083B00F582E5F03583F583E493A3C0E0E493C040 +:10084B00E022D083D082CCC0E0E493A360061208F0 +:10085B00771470FAE493A360061208961470FAD01A +:10086B00E0FCE493A3C0E0E493C0E022C0E0E49397 +:10087B00A3D39C5010E493A3C39C400AD0E0D0E0D8 +:10088B00D0E002086AA3A3A3D0E022C0E0E493A3C4 +:10089B006C7009D0E0D0E0D0E002086AA3A3D0E0EE +:1008AB002253CBEFC2D843CB0475F00CEAA4F5CDA1 +:1008BB0074FC55CB4402F5CB43CB10A2D850FC5360 +:1008CB00CBEFC2D822C082C08353A8C0E5A853B8CF +:1008DB00F0E5B8539AC2E59A7422C0E0740755C686 +:1008EB00F8D0E0B800028004C313D8FCF5AB7475E4 +:1008FB0090FC00F074AE90FC01F0740290FC02F0DE +:10090B00E490FC03F090FC04F0747490FC05F0741C +:10091B00FF90FC06F074F590FC07F074AF90FC08A8 +:10092B00F0E490FC09F090FC0AF0747490FC0BF06E +:10093B0074FF90FC0CF074F590FC0DF074AF90FC10 +:10094B000EF0E490FC0FF090FC10F074E590FC11AD +:10095B00F074AE90FC12F0745490FC13F074409051 +:10096B00FC14F0747090FC15F074FA90FC16F07493 +:10097B002290FC17F0740190F3FFF0D083D0822209 +:10098B00C082C0838A828B83E493F9D083D0822286 +:10099B00C082C0838A828B83E493F9A3E4932400FF +:1009AB00FAE439FBD083D0822274F712068AECFE6C +:1009BB00EDFF740912067EE0FCA3E0FD74326C704F +:1009CB000374576D600479008045C2AFE5AEA2E7B2 +:1009DB0040FA8A088B0974097808120611E508F5A4 +:1009EB00ADEAFCEBC313EC13F5ACEF90FC06F0EEA9 +:1009FB0090FC0CF012FC00D2AFE9601112099B8A3B +:100A0B00088B09EE65087003EF650970B979017FF2 +:100A1B00020206EAD2AF22C2AF22750C00750D009E +:100A2B007E0043FE01D29043FE10C29443FD3FE58E +:100A3B00FD43FEE0E5FE43FF19E5FF53BEF8E5BEBF +:100A4B0000746055BE60FA780079008008E82401D4 +:100A5B0008E93400F9C3E89420E9944E40EF53C6FB +:100A6B00BF53C6C0E5C643C638E5C6746055BE6005 +:100A7B00FA780079008008E8240108E93400F9C30A +:100A8B00E89420E9944E40EF90F9AA780812052BD0 +:100A9B00AA08AB09AC0AAD0B12647374FF90F4187F +:100AAB00F07AF07B7F12098BE9700C7AF27B7F1264 +:100ABB00098BE990F412F090F412E0C3941F4008F4 +:100ACB00E0C394E25002E4F043B933E5B943A92300 +:100ADB00E5A990F9AE780812052BAA08AB09AC0A68 +:100AEB00AD0B12593B800F125993E50C2401F50CF9 +:100AFB00E50D3400F50DC3E50C9420E50D944E4047 +:100B0B00E6C29075EC4475ED0475EBDED2BCD2AF4A +:100B1B00800E12115A740590F400F0E490F404F076 +:100B2B0090F404E0600C90F401E0700690F403E0A4 +:100B3B0060E090F402E0602990F60EE06008EE7041 +:100B4B000553EBEF7E0190F608E060D412664FEE92 +:100B5B006009E490F60EF0FE43EB10E490F608808B +:100B6B00BE90F405E0603490F403E0702ED290E474 +:100B7B0090F405F012111D740390F400F0740190C1 +:100B8B00F401F012131E740190F400F0E490F401E0 +:100B9B00F074FF90F418F0C290808590F406E0603A +:100BAB003D90F401E07037D290E490F406F0125BC4 +:100BBB0019740A90F400F0740190F403F01260D0F1 +:100BCB0090F67AE0A2E25004740B8002740C90F45D +:100BDB0000F0E490F403F074FF90F67C80B890F48E +:100BEB000DE07003020B2B90F40FE06003020B2B54 +:100BFB0090F40EE01208170102190C0C0C110C16D4 +:100C0B000C12434B800812486F80031248957401F5 +:100C1B0090F40F020B2A74F112068A90F653E064DB +:100C2B00FF600302111890F654E012084D001900F2 +:100C3B00A20C01A80C02BD0C03E10C04460D058DA2 +:100C4B000D06DA0C07B10D08D10D09900E0A970DA0 +:100C5B0020870C310D0E32480E33580E40990E4141 +:100C6B00D20E46C60E47F00E48D80E49E90E705804 +:100C7B0010718F1072C01073A8100C11741290F6B3 +:100C8B0059F0743490F658F0745690F657F0747817 +:100C9B0090F656F002110C90F400E080F3121187DD +:100CAB00E490F402F090F401F090F403F090F4006F +:100CBB0080E190F401E0600790F417E0D2E5F0904A +:100CCB00F402E0600302110C740190F40480C4126E +:100CDB001187740480D790F659E0F50875090075F3 +:100CEB000A00750B00741878081204AD90F658E0E2 +:100CFB00F50C750D00750E00750F007410780C1245 +:100D0B0004AD7808790C1204CC90F657E0F50C750D +:100D1B000E007408780C1204AD7808790C1204CC10 +:100D2B0090F656E0F50C750D007808790C1204CC92 +:100D3B0090F98A780812053A02110C90F98A780C0E +:100D4B0012052B850C08850D09850E0A850F0B7472 +:100D5B00187808120494E50890F659F0850C08856C +:100D6B000D09850E0AF50B74107808120494E5082A +:100D7B0090F658F0850D09E50990F657F0E50C0251 +:100D8B000C9B90F656E090FB52020C9E90F656E0B0 +:100D9B0090F9A5F090F658E0F990F657E090F9A687 +:100DAB00F0A3E9020C9E90F402E06003121187900D +:100DBB00F401E0600302110C740290F400F0740172 +:100DCB0090F405020C9E90F417E0A2E4502F90F4DF +:100DDB001BE090F659F090F41AE090F658F090F46E +:100DEB0019E090F657F090F418E090F656F074FF77 +:100DFB0090F418F090F417E0C2E4020C9E74FF021A +:100E0B000C9B90F401E0700302110C7A00801F8A96 +:100E1B0082A882E82456F582E434F6F583E0C0E03C +:100E2B00E82418F582E434F4F583D0E0F00AEAC341 +:100E3B00941340DB90F417E0D2E6020C9E90F4077B +:100E4B00E090F656F0740490F655020C9E90F40761 +:100E5B00E0602E7A00801F8A82A882E82418F5822F +:100E6B00E434F4F583E0C0E0E82456F582E434F68C +:100E7B00F583D0E0F00AEAC3941340DBE490F40767 +:100E8B00F0741680C290F417E0D2E5020C9E90F439 +:100E9B0002E0600312118790F401E0600790F417F1 +:100EAB00E0D2E5F090F403E0600302110C740990BA +:100EBB00F400F0740190F406020C9E90F67AE0D2E6 +:100ECB00E5F0C29002110C90F977020CA590F40397 +:100EDB00E0600690F67B020CA57480020C9B74F705 +:100EEB0090F65680A6740290F67BF090F773E06450 +:100EFB00016003020FD6E490F40AF090F655E0245B +:100F0B00FB90F409F090F656E090F40BF090F65746 +:100F1B00E0F50890F40BE07035E50890F77AF09067 +:100F2B00F658E090F77BF0F9E50890F983F0A3E928 +:100F3B00F090F983E090FA41F090F984E090FA4256 +:100F4B00F0740490F773F0E490F408020C9EE5083B +:100F5B0090F40CF090F40BE06401700474018002C7 +:100F6B00740290F779F090F40CE0240590F774F08C +:100F7B007A00801F8A82A882E82458F582E434F62E +:100F8B00F583E0C0E0E8247AF582E434F7F583D00A +:100F9B00E0F00AEAC0E090F409E0FBD0E0C39B402C +:100FAB00D3740290F773F090F409E090F408F0908A +:100FBB00F409E090F40AF0E0C0E090F40CE0FAD011 +:100FCB00E0C39A500302110C020F4CE06402600361 +:100FDB0002110C90F655E024FD90F409F07A008094 +:100FEB002B8A82A882E82456F582E434F6F583E056 +:100FFB00C0E090F408E0FCE82CF8E43400F9E824B5 +:10100B007AF582E934F7F583D0E0F00AEAC0E09094 +:10101B00F409E0FBD0E0C39B40C7E0FA90F408E092 +:10102B002AF090F409E0FA90F40AE02AF090F40820 +:10103B00E0C394F7509290F40AE0C0E090F40CE017 +:10104B00FAD0E0C39A500302110C020FD390F6575B +:10105B00E0F990F656E0F874AB68700374AB697006 +:10106B001C740190F40DF0E490F40EF0740190F404 +:10107B000FF0E490F402F090F401020C9EE490F473 +:10108B000D020C9E90F40DE0607790F410E4F0A349 +:10109B00F090F40FF090F40EE004020C9E90F40D1F +:1010AB00E0605E90F410E090F656F090F411E09052 +:1010BB00F657020C9E90F40DE0604690F656E0F564 +:1010CB000890F657E0FA90F658E0F9EAFEE9FF12BD +:1010DB0008D0EEFAEFFB12098BE964FF7023750A57 +:1010EB0032750B57780A1207D57900AB0874FF24B9 +:1010FB0000FCE43BFDEEFAEFFB1209B4740212069E +:10110B0049740190F677F0740690F654F07F08025C +:10111B0006EAC082C08375C6B074D390DF00F0744A +:10112B009190DF01F0740490DF03F0E490DF05F0A1 +:10113B0090DF06F0740790DF12F0E490DF2FF09051 +:10114B00DF30F090DF31F0759100D083D08222C078 +:10115B0082C08375C6B8439190E59175E25575E5EC +:10116B004475E402D2B912686390F412E090DF0880 +:10117B00F0740190F402F0D083D08222C082C0833D +:10118B0012645EC2B975E40075E255124899E49099 +:10119B00F402F0D083D08222C0E074F212072290C6 +:1011AB00F402E060051263BD801F90F401E060055E +:1011BB00121793801490F40DE0600512483D8009DE +:1011CB0090F403E06003125C2C7F01020781C0E006 +:1011DB0074F212072290F402E0600512636B80092F +:1011EB0090F40DE060031247307F01020781C0E0ED +:1011FB0074F2120722C2C153E40FE5E490F607E044 +:10120B00601590F608E0700F1248C3E97003740183 +:10121B00F090F60FE004F07F01020781C0E074F25A +:10122B0012072290F403E0603990F873E0F8A3E022 +:10123B00F9E87001E9602B90F871E02401F0A3E06C +:10124B003400F090F871E0687003A3E069701390BC +:10125B00F871E4F0A3F090F873F0A3F0740190F838 +:10126B0075F0C2DB1259937F010207810022C0E0A7 +:10127B0074F21207221212777F01020781C0E07409 +:10128B00F21207221212777F01020781C0E074F27B +:10129B001207221212777F01020781C0E074F2124B +:1012AB0007221212777F01020781C0E074F2120746 +:1012BB00221212777F01020781C0E074F21207221B +:1012CB001212777F01020781C0E074F2120722121B +:1012DB0012777F01020781C0E074F212072212120B +:1012EB00777F01020781C0E074F212072212127796 +:1012FB007F01020781C0E074F21207221212777F7E +:10130B0001020781C0E074F21207221212777F01EB +:10131B0002078174F112068A74FA12063390F9B23D +:10132B00780812052B740190F417F07AFD7B1412D8 +:10133B0027B97402C0E0740112067ED0E0F0AC82D3 +:10134B00AD837A0A7903122AA0C290805390F414C9 +:10135B00E0704D740212067E780812053A74021280 +:10136B00067EC082C08390F9B6780812052BD08315 +:10137B00D08278081204DF740212067EC082C0830A +:10138B0090F9BA780C12052BD083D082780C12030B +:10139B0064400D639001E59090F9B2780812052B2B +:1013AB0090F416E0603190F414E0702B7A137BF418 +:1013BB001227E6E970F6740290F417F0D29090F4CD +:1013CB0014E004F0A2AFE492E0FAC2AF90F416E09E +:1013DB0014F0EAA2E092AF90F415E070030214C887 +:1013EB00851082851183AC82AD837A387BF490F4BF +:1013FB0013E0F9122A36E960030214C885108285BE +:10140B001183E064047029639001E590750C0475F9 +:10141B000D00780C1207D57C387DF47A187BF4120A +:10142B006958740212064990F417E0D2E40214C70B +:10143B00E064026008E0641360030214C863900167 +:10144B00E59090F438E01208170102C8145E14936B +:10145B0014931490F417E0A2E65008E0C2E6F0747F +:10146B0013800E740190F418F0745590F419F07405 +:10147B0002851082851183F0E0FC7A187BF490F4DE +:10148B0013E0F912285C803590F407E0702F7A0096 +:10149B00801F8A82A882E82438F582E434F4F5832D +:1014AB00E0C0E0E82418F582E434F4F583D0E0F0F2 +:1014BB000AEAC3941340DB740190F407F090F4171D +:1014CB00E0A2E54003021358539AFE75910075E9AB +:1014DB0000E490F413F090F414F090F416F090F400 +:1014EB0015F090F5A1F0C29074061206497F080220 +:1014FB0006EAC082C083E9600590F415800390F47E +:10150B0016E004F07900D083D0822274F712068A99 +:10151B0075082175090078081207D57C007D007AC3 +:10152B00597BF4126A3F740212064990DF36E0547D +:10153B00EF64016004C2AF80FE90DF37E0C3940319 +:10154B005004C2AF80FE53BEFBE5BEA2E650FA5379 +:10155B00C6BF43BE0474F4F5D575D480743C90DFDC +:10156B0013F0741490DF14F0741E90DF02F0740506 +:10157B0090DF04F0745090DF2EF0740990DF25F0AB +:10158B0090DF07F090F412E090DF08F0742490DF06 +:10159B0009F0743A90DF0AF074EE90DF0BF0746B85 +:1015AB0090DF0CF074A390DF0DF0741390DF0EF04E +:1015BB00742390DF0FF0741190DF10F0744390DF01 +:1015CB0011F0741D90DF15F0741C90DF16F074C7CA +:1015DB0090DF17F0E490DF18F074B090DF19F0741F +:1015EB00B690DF1AF0741090DF1BF074EA90DF1CDA +:1015FB00F0742A90DF1DF0E490DF1EF0741F90DF73 +:10160B001FF0748190DF23F0743590DF24F07402A7 +:10161B0090F458F07900121B8D7E007F0075E1026B +:10162B0075081475090590DF3CE0545070237A401F +:10163B007B001219A5E50824C0F508E50934FFF570 +:10164B0009C3E5089401E5099400A2D265D0335093 +:10165B00D57A008013EEC333FEEF33FF90DF3AE011 +:10166B00A2E0E492E04EFE0AEAC3941040E77480D5 +:10167B004EF5BCEFF5BC12196090F47C7436F0A3F8 +:10168B00E4F090F47E74E2F0A37404F0439A01D278 +:10169B00AF7F020206EA74F712068AEAFEEBFF89B5 +:1016AB000975080090F458E064017004C2AF80FE25 +:1016BB00121960EF90F480F0EE90F481F074DF90EB +:1016CB00F482F074D990F483F0742090F484F07465 +:1016DB002190F485F0741390F486F0744190F487A4 +:1016EB00F0E509701143D60175E103E5E9A2E45079 +:1016FB00FA53E9EF8068740165096004C2AF80FE9C +:10170B007509048008121960121ACA150943D6010B +:10171B0075E10290DF3BE0640D70F87E147F05905D +:10172B00DF3CE05450701D7A407B001219A5EE246B +:10173B00C0FEEF34FFFFC3EE9401EF9400A2D2651D +:10174B00D03350DB75E10390DF3BE0640D6008E5BF +:10175B00E9A2E450FA809AE50970AA7508011219FA +:10176B006090F458E0640370031218D7A9087F0245 +:10177B000206EAC082C08390F459EAFCEBFD7421A7 +:10178B00120556D083D0822274F712068A90F45831 +:10179B00E064036004C2AF80FEE5E9A2E45035E5E6 +:1017AB00E9A2E6502F53E9EF53E9BF539BFCE59BAE +:1017BB0012196075081F75090078081207D57C008F +:1017CB007D007A597BF4126A3F7402120649121893 +:1017DB00D702186A53E9EF539BFCE59B750802751A +:1017EB00090078081207D590F459E0042459FCE459 +:1017FB0034F4FD7A787BF41269A07402120649E086 +:10180B00FA90F479E0A2E7503B8A0874012508F8B6 +:10181B00E43400F9E89420E99400C365D0335024F4 +:10182B00EAC3940B401E7A5A7BF4121BF5E9701431 +:10183B0090F478E0F9121B38E9F090F479E0C2E704 +:10184B00F0122D5E75081F78081207D57C007D00FD +:10185B007A597BF4126A3F740212064943D6017F10 +:10186B00020206EA74F812068A90F458E0640160EA +:10187B0013A2AFE492E0FEC2AF1219857401F0EE31 +:10188B00A2E092AF7F010206EAC082C083E5C6A246 +:10189B00E65004C2AF80FE90F458E06401702274ED +:1018AB00EA90DF1CF0742A90DF1DF0E490DF1EF04D +:1018BB00740290F458F075E10490DF3BE064017022 +:1018CB00F8D083D0822243B404A9BC2274F7120649 +:1018DB008A74DF90F480F074D990F481F074F490F2 +:1018EB00F482F0745990F483F0748090F484F07463 +:1018FB002190F485F0741390F486F0741190F487B2 +:10190B00F075D68175081F75090078081207D57C0C +:10191B00007D007A597BF4126A3F74021206494328 +:10192B00D601539BFCE59B53E9EF75E10243911004 +:10193B007F020206EAC082C08390F458E064017013 +:10194B0004C2AF80FEE0640360067403F01218D784 +:10195B00D083D08222C082C0835391EF75E1049073 +:10196B00DF3BE0640170F875D68153D1FE539BFCCD +:10197B00E59B53E9EFD083D08222C082C08390F4E1 +:10198B0058E064017004C2AF80FEE064037006127D +:10199B0019607402F0D083D0822274F712068A8AFF +:1019AB00088B0974047808120611AE08AF09EA70A7 +:1019BB0001EB6028A2AFE492E0F508C2AF7A107B8E +:1019CB00001208ACE508A2E092AFEEF8EFF974FF55 +:1019DB00281E74FF39FFE87001E970D87F020206F8 +:1019EB00EA74F712068A8A088B09740478081206BF +:1019FB0011AE08AF09EA7001EB602EA2AFE492E0E2 +:101A0B00F508C2AF7A107B001208ACE508A2E09291 +:101A1B00AF90F47AE07012EEF8EFF974FF281E74B1 +:101A2B00FF39FFE87001E970D27F020206EA74F811 +:101A3B0012068AEAFEEB800E7AF47B011219A5EEF0 +:101A4B0024FF1EEF34FFFFEE7001EF70EB7F0102FE +:101A5B0006EA74F812068A90F47CE0FEA3E0FFA27B +:101A6B00AFE492E0FAC2AF740190F47BF0EAA2E02B +:101A7B0092AF8008EE24FF1EEF34FFFFEE7001EFF4 +:101A8B00600D7AF47B011219EC90F47AE060E5A218 +:101A9B00AFE492E0FAC2AFE490F47AF090F47BF00A +:101AAB00EAA2E092AF7F010206EAC082C08390F403 +:101ABB007BE06006740190F47AF0D083D0822274BC +:101ACB00F812068A1218D1E9540F04FF7E00800C1D +:101ADB0090F47EE0FAA3E0FB1219A50EEEC39F4033 +:101AEB00EF7F010206EA74F812068A90F458E0645C +:101AFB00036004C2AF80FE7E147F0590DF3CE05490 +:101B0B0050701D7A407B001219A5EE24C0FEEF34F5 +:101B1B00FFFFC3EE9401EF9400A2D265D03350DBEC +:101B2B0090DF3AE0F9121B387F010206EAC008C0C9 +:101B3B0009E9C39480E94019F879FF7A027B001216 +:101B4B0005B08808890974B72508F874FF35098032 +:101B5B000BC313F874B728F874FF3400F9C3E89477 +:101B6B0080E994FFA2D265D03350027880E8F9D097 +:101B7B0009D00822C082C08390F458E0F9D083D0FA +:101B8B00822274F712068A8908E9C394044004C2BE +:101B9B00AF80FE121960E50824C2F582E434F9F532 +:101BAB0083E090DF06F090F458E0640370031218A2 +:101BBB00D77F020206EA74F712068A8908E9C394F2 +:101BCB00034004C2AF80FE121960E50824C6F582FB +:101BDB00E434F9F583E090DF2EF090F458E06403E1 +:101BEB0070031218D77F020206EA74F812068A9065 +:101BFB00F488E07004790080487E007D007C0080D2 +:101C0B002E8C82A882EA28F582EB3400F583E0FF64 +:101C1B00E824C9F582E434F9F583E06F70010EE82E +:101C2B0024BEF582E434F9F583E06F70010D0CEC02 +:101C3B00C3940440CC74046D60BB74046E60B679BD +:101C4B00017F010206EA74F712068AEAFEEBFF75C2 +:101C5B00082C75090078081207D57C007D007ACE18 +:101C6B007BF9126A3F7402120649740290F9CEF0A6 +:101C7B00743D90F9CFF0742090F9D0F0740190F985 +:101C8B00D1F01234FFEEFAEFFB122C0112244112A9 +:101C9B0034FB124232EEFAEFFB1237D512408712A9 +:101CAB003B5F12430490F9EEE070347402F074035E +:101CBB0090F9EFF0743F90F9F7F090F9F8F074FFAA +:101CCB0090F9F9F075080478081207D5123599EADE +:101CDB00FCEBFD7AF17BF912695874021206497913 +:101CEB00007F020206EAC082C0837B0080010BEBFF +:101CFB00C394025014EB75F00CA424E2F582E5F0CA +:101D0B0034F9F583E0640260E574026B70067A00C7 +:101D1B007B00801AEB75F00CA424E2F582E5F0341D +:101D2B00F9F583AA82AB83121D3EAA82AB83D083C3 +:101D3B00D08222C082C08374FF120633E48A828B66 +:101D4B0083A3A3A3A3A3A3A3A3A3A3F074028A8235 +:101D5B008B83F090F9D1E0C0E0EA240BF582EB34F1 +:101D6B0000F583D0E0F090F9D1E004F0E0F960F6F3 +:101D7B0074FF6960F1851082851183AA82AB83128F +:101D8B002284E970E17401120649D083D08222C00B +:101D9B0082C083E48A828B83F0D083D08222C0827C +:101DAB00C08374FF120633851082851183AA82AB20 +:101DBB0083122284E96014E075F00CA424E2F5820E +:101DCB00E5F034F9F583E0640260067582007583F3 +:101DDB0000AA82AB837401120649D083D08222748D +:101DEB00F312068A8A088B09890A7EE27FF97A0048 +:101DFB00800A7A01EE240CFEEF3400FFEA70478E66 +:101E0B00828F83E0640270EA750C04750D00780C08 +:101E1B001207D5AC08AD09EE2403FAEF3400FB1220 +:101E2B0068FF7402120649EA7001EB70C58E828F4F +:101E3B0083A3A3A3A3A3A3A3A3A3A3E0650A70B245 +:101E4B00EEFAEFFB80047A007B007F060206EA7A4B +:101E5B00D27BF92274F312068A8A0A8B0B7508005F +:101E6B007509007EE27FF97A00800E8E088F097A61 +:101E7B0001EE240CFEEF3400FFEA703D8E828F835F +:101E8B00E064026005E0640170E1750C04750D00FF +:101E9B00780C1207D5E50A2405FCE50B3400FDEEA2 +:101EAB002403FAEF3400FB1268FF7402120649EAAE +:101EBB007001EB70BA7900803AE5087002E50960B1 +:101ECB00F47401850882850983F0750C04750D0087 +:101EDB00780C1207D5E50A2405FCE50B3400FDE56B +:101EEB00082403FAE5093400FB1269587402120640 +:101EFB004979017F060206EA74F512068A8A088B75 +:101F0B00097EE27FF97A00800A7A01EE240CFEEF5B +:101F1B003400FFEA70418E828F83E0640170EA75B2 +:101F2B000A04750B00780A1207D5E5082405FCE5B1 +:101F3B00093400FDEE2403FAEF3400FB1268FF7442 +:101F4B0002120649EA7001EB70BFEEFAEFFB121DAD +:101F5B003EEEFAEFFB80047A007B007F040206EA78 +:101F6B00C082C083E98A828B836001A3A3A3A3A34E +:101F7B00A3A3A3A3A3E0FCEC60078A828B83E0708E +:101F8B000479028008ECC3942040F67900D083D00A +:101F9B00822274F112068A8A0C8B0D8C0E8D0F7EA9 +:101FAB00E27FF98A828B83A3A3A3A3A3A3A3A3A3F7 +:101FBB00E0543FF509750800800A0508EE240CFE75 +:101FCB00EF3400FFE508C3940240030220998E8290 +:101FDB008F83E0640270E3A3A3A3A3A3A3A3A3A390 +:101FEB00E0650970D5743F6509602B750A04750BA4 +:101FFB0000780A1207D5E50C2405FCE50D3400FD2D +:10200B00EE2403FAEF3400FB1268FF740212064948 +:10201B00EA7001EB70A4750801EE240BF582EF3426 +:10202B0000F583E0850E82850F83F0743F650960B0 +:10203B0056E50C240AF582E50D3400F583E0A2E7A2 +:10204B0050198E828F83A3A3A3A3A3A3A3A3A3A39C +:10205B00E0F9AA0CAB0D123115802CE0A2E350274E +:10206B00EE2402F8EF3400F988828983E0FAE50C5C +:10207B00240BF582E50D3400F583E06A7006E488E5 +:10208B00828983F0750800121AB5A90880027900BD +:10209B007F080206EA74F112068A74FF120633896E +:1020AB00088A0E8B0F7EE27FF9750A01750B00789B +:1020BB000A1207D57C007D00740212067EAA82AB41 +:1020CB0083126A3F74021206497A00805D750C0414 +:1020DB00750D00780C1207D5E50E2403FCE50F34C3 +:1020EB0000FDEE2403FAEF3400FB1268FF740212BA +:1020FB000649EA7001EB70287401C0E0850A8285FD +:10210B000B83E0F8851082851183E58228F8E5833F +:10211B003400F974E028F58274FF39F583D0E0F0D0 +:10212B007A01EE240CFEEF3400FFEA7069E50E6EC7 +:10213B007003E50F6F60E98E828F83E0640270E0BD +:10214B00EE2409F50AEF3400F50B850A82F583E0DE +:10215B00C3943E50CB7401650860030220D890F9FC +:10216B00CFE0C0E0850A82850B83E0FAD0E0C39A0A +:10217B0050AE7401C0E0E0F8C3E498F8E49400F9C1 +:10218B00851082851183E58228F8E58339F9743D42 +:10219B0028F582E4808479007A0080027A01EA7063 +:1021AB0015851082851183E070F274026508700446 +:1021BB0079208002793D74026508701790F9CFE0A1 +:1021CB00C399400B90F9D0E0C399501FE9801B795C +:1021DB00008018E9C0E090F9D0E0FAD0E0C39A4053 +:1021EB00EE90F9CFE0697003E014F0E9850E82857B +:1021FB000F83A3A3A3A3A3A3A3A3A3F0740112060A +:10220B00497F080206EA74F512068AEAFEEBFF75AF +:10221B0008028C0AEE250AFAEF3400FB740C2AF53F +:10222B0082E43BF583E0A2E750488D08EE2508FADF +:10223B00EF3400FB740C2AF582E43BF583E0697004 +:10224B002E75080475090078081207D5123545EA72 +:10225B00FCEBFD8E828F83A3AA82AB831268FF7483 +:10226B0002120649EA7001EB7005750800800375D0 +:10227B000801A9087F040206EA74F812068A7CE2B8 +:10228B007DF97E0080090EEC240CFCED3400FDEE94 +:10229B00C3940250218C828D83E0640270E8EC249D +:1022AB000BF582ED3400F583E06970DAEE8A828BF0 +:1022BB0083F07901800279007F010206EA74F31240 +:1022CB00068A8A0C8B0D89097EE27FF975080080DE +:1022DB000A0508EE240CFEEF3400FFE508C3940258 +:1022EB0050478E828F83E0640270E6750A04750B8B +:1022FB0000780A1207D5EE2403FCEF3400FDAA0C7C +:10230B00AB0D1268FF7402120649EA7001EB70C143 +:10231B008E828F83A3A3A3A3A3A3A3A3A3A3E065ED +:10232B000970AEEEFAEFFB80047A007B007F0602A9 +:10233B0006EAE9FB7900EA6B601FEBC39A500EEAE1 +:10234B00C394FD4006EBC39403400E0922EBC394E8 +:10235B00FD4006EAC3940340F22274F512068AECA0 +:10236B00FEEDFF890A890875090078081207D5EA7E +:10237B00FCEBFDEEFAEFFB1269A07402120649E5C5 +:10238B000A1208170202BF239923BF23AD238E82A3 +:10239B008F83E0F8A3E0F98E828F83E8F0A3E9F056 +:1023AB0080128E828F83780812052B8E828F837812 +:1023BB000812053A7F040206EA74F512068A74FACB +:1023CB00120633EAFEEBFFECFAEDFBE912081702FB +:1023DB0002E423EA23E4230624EEFCEFFD80388E8F +:1023EB00828F83E0FCA3E0FD851082851183ECF0E6 +:1023FB00A3EDF085108285118380188E828F8378F0 +:10240B000812052B740212067E780812053A740224 +:10241B0012067EAC82AD8389087509007808120715 +:10242B00D51269A0740212064974061206497F047C +:10243B000206EA79022274F712068A7508D2750928 +:10244B000078081207D57C007D007A897BF4126A2C +:10245B003F740212064975084678081207D57C00AE +:10246B007D007A5B7BF5126A3F74021206497F028C +:10247B000206EA74F512068A7C007D007E007F005E +:10248B00780074016970097A897BF47509068007F5 +:10249B007A5B7BF575090274012509F50A880880BA +:1024AB000EEAFEEBFF0508EA2423FAEB3400FBE50A +:1024BB0008C3950950298A828B83E0601B740169DC +:1024CB0070E308E0640460DDA3E0C3950A50D6EA2C +:1024DB00FCEBFDE0F50A80CD74026970C48031EE2F +:1024EB007001EF701EEC7001ED70067A007B0080BE +:1024FB001FECFEEDFF8E828F83A3E0FA122520E501 +:10250B000880087401288E828F83A3F0EEFAEFFB0C +:10251B007F040206EAC082C083740169703A78892D +:10252B0079F4A2AFE492E0FDC2AF7B00801F8882FA +:10253B008983E0600FA3EAC0E0E0FCD0E0C39C50CD +:10254B0003E014F00BE82423F8E93400F9EBC3940F +:10255B000640DBEDA2E092AFD083D0822274F11261 +:10256B00068A74F61206338A0C8B0D8C09740412CE +:10257B00067EE4F0A3F0851082851183F0A3F0743E +:10258B000212067EE4F0A3F0740169702E7E897F3F +:10259B00F4750E078A828B83E064017052A3E0F915 +:1025AB00121DA9851082851183EAF0A3EBF085102B +:1025BB0082851183E07002A3E070077A007B000232 +:1025CB0027A0851082851183E0F8A3E0F58388822C +:1025DB00A3A3A3A3A3A3A3A3A3E0F50885108285BC +:1025EB001183E02403F8A3E03400F974088049E078 +:1025FB007006A3E0F5088048E0640270BEA3A882D1 +:10260B00A983E0240EFAA3E03400FB8A828B83E0DB +:10261B00F50888828983E02405FAA3E03400FB7473 +:10262B000812067EEAF0A3EBF088828983E0240F80 +:10263B00F8A3E03400F9740212067EE8F0A3E9F087 +:10264B007401650970057509018003750903750F20 +:10265B0000800FEAA2E092AF050FEE2423FEEF34C9 +:10266B0000FFE50FC394064003022796A2AFE49246 +:10267B00E0FAC2AF8E828F83E0650970D67404F0E6 +:10268B00EAA2E092AFEE240BF582EF3400F583E083 +:10269B00543F6508600302278E850C82850D83E00D +:1026AB0064017019743F6508700E85108285118363 +:1026BB00E02403F8A3E0800FEE24078008E0640217 +:1026CB007012EE2403F8EF3400F9740612067EE85C +:1026DB00F0A3E9F0750A04750B00780A1207D5749C +:1026EB000A12067EE0FCA3E0FD740812067EE0FAF7 +:1026FB00A3E0FB1268FF7402120649850C82850D5C +:10270B0083E06040740212067EE07002A3E0700367 +:10271B00EA6031740212067EE07002A3E060647816 +:10272B000A1207D5EE2407FCEF3400FD74041206E1 +:10273B007EE0FAA3E0FB1268FF7402120649EA700E +:10274B0001EB703F8E828F83A3AA82AB83E0C3958C +:10275B000E5030740412067EE07002A3E060107419 +:10276B000412067EE0F8A3E0F5838882E509F08A7F +:10277B00828B83E0F50E740412067EEEF0A3EFF06D +:10278B000226638E828F83E50980F4740412067E21 +:10279B00E0FAA3E0FB740A1206497F080206EA740A +:1027AB00016970057A897BF4227A5B7BF52274F8D8 +:1027BB0012068AEAFEEBFF90F5A1E07013121516D4 +:1027CB00EEFAEFFB121C51E9700C1218941219401F +:1027DB007401F0123A4F7F010206EA74F712068A6F +:1027EB008A828B83121B7FE9F509790012401574DD +:1027FB00036509600C7401650970031218941219B2 +:10280B00407E007F00800F7A0A7B00121A39EE247B +:10281B00010EEF3400FFC3EE94F4EF940150091254 +:10282B003FBCE9FA8A0860DF74036509600E740126 +:10283B006509700512186F8003121985E508700978 +:10284B00790112401579018003F079007F020206AD +:10285B00EA74F712068A75080075090078081207E2 +:10286B00D512287974021206497F020206EA74F126 +:10287B0012068A74FC120633740212067EEAF0A367 +:10288B00EBF089088C09741312067EE0FEA3E0FFBF +:10289B00121DA98A0C8B0D750B02121B7FE985107B +:1028AB0082851183F0750A00E50C7002E50D600F4F +:1028BB007901AA0CAB0D121F6BE9FA8A0B600302AC +:1028CB002A2A740212067EE07002A3E060F1E50989 +:1028DB00C3941450EAEE7001EF703D850C82850DA8 +:1028EB0083A3E0FDAC09740212067EE0FAA3E0FBC1 +:1028FB00850C82850D83A3A3A3A3A3A3A3A3A3A347 +:10290B00E0F9122C328A088B09AE08AF09EE700180 +:10291B00EF70627903022A2CEEA2E0505374FF652C +:10292B0008604DE50C2402F50AE50D3400F50B7833 +:10293B000A1207D5850C82850D83A3E0FDAC0974C3 +:10294B000412067EE0FAA3E0FB850C82850D83A3BF +:10295B00A3A3A3A3A3A3A3A3A3E0F9122D1D740206 +:10296B001206498A088B09AE08AF09750A01809DCA +:10297B007902022A2CEE2403F50EEF3400F50F75C5 +:10298B00080475090078081207D5E50C2403FCE54B +:10299B000D3400FDAA0EAB0F1269587402120649D2 +:1029AB00740112067EAC82AD83AA0EAB0F123A52A3 +:1029BB00EA7001EB600B74038E828F83F0790080D9 +:1029CB00607901EEFAEFFB1230B9E9F50B7050E5C7 +:1029DB000A604C851082851183E06403600BE06410 +:1029EB00017003121894121940121A5DE06403600F +:1029FB000DE06401700512186F8003121985A2AFE8 +:102A0B00E492E0FAC2AFE50C2402F582E50D340046 +:102A1B00F583E06005E4F0750B0CEAA2E092AFA938 +:102A2B000B74041206497F080206EA74F312068A35 +:102A3B0074FD120633890AEAFEEBFF8C088D09122E +:102A4B001DA97902EA7001EB60411919121F6BE99C +:102A5B0070397401851082851183F012067EE50AA8 +:102A6B00F0750A00750B00780A1207D5780A120761 +:102A7B00D578081207D5EEFCEFFD740612067EAA78 +:102A8B0082AB83122D927406120649740312064907 +:102A9B007F060206EA74F112068A89088A09ECFE9F +:102AAB00EDFF90F5A1E0700B122BE4E970057902B4 +:102ABB00022BDFE50812081702080C2B6F2B8D2B4E +:102ACB00982B5A2B4F2B9F2BC82B402BD92A750891 +:102ADB00008E828F83E0702FE5097014A3780C129F +:102AEB00052BAA0CAB0DAC0EAD0F123BB8022BDDB8 +:102AFB0074016509700BA3AA82AB83123BDC022B1A +:102B0B00DD750802022BDDE0640170F5E509701438 +:102B1B00A3780C12052BAA0CAB0DAC0EAD0F123813 +:102B2B0030022BDD7401650970D7A3AA82AB831227 +:102B3B003854022BDDEEFAEFFBA90912243EE9F51E +:102B4B0008022BDDEEFAEFFBA9091237A780EF7411 +:102B5B000165096004E50970A8EEFAEFFBA90912FB +:102B6B00376380DA740365097009EEFAEFFB1235EF +:102B7B009E80CB740265097088EEFAEFFB12362A41 +:102B8B0080BCEEFAEFFBA90912369B80B1A90912A2 +:102B9B00375280AA740165096003022B0C75080477 +:102BAB0075090078081207D512355EEAFCEBFDEECD +:102BBB00FAEFFB1269587402120649801274016510 +:102BCB00096003022B0C123563E98E828F83F0753B +:102BDB000800A9087F080206EAC082C083E9120830 +:102BEB004D000205F62B0AF62BFA2B7901800279A0 +:102BFB0000D083D08222C082C083E490F5A5F0740C +:102C0B002090F5A6F090F5A7EAF0A3EBF01235456E +:102C1B0090F5A3EAF0A3EBF01218D1E990F5A2F02E +:102C2B0060F6D083D0822274F112068A89088A0E4C +:102C3B008B0F8C0A8D09790212247E8A0C8B0DA8BE +:102C4B000CA90DE8FEE9FFE87001E970077A007B3B +:102C5B0000022D18740B250A8E828F83A3A3F0EE2E +:102C6B00240BF8EF3400F988828983E0C2E6F0E0A8 +:102C7B0054C04508F090F5A2E0C0E0EE240DF582BB +:102C8B00EF3400F583D0E0F090F5A2E004F0E060C3 +:102C9B00F7EE240CFAEF3400FB90F5A5C082C0834D +:102CAB008A828B83E054BFD083D082FCE04C8A8233 +:102CBB008B83F0E054F84509F0E0C2E7F0E0C2E3A3 +:102CCB00F088828983E0C2E7F0750B00780A12075F +:102CDB00D5AC0EAD0FEE240E0A0AEF3400FB1269D1 +:102CEB005874021206497508047509007808120712 +:102CFB00D590F5A3E0FCA3E0FDEE2407FAEF34003A +:102D0B00FB1269587402120649EEFAEFFB7F0802B8 +:102D1B0006EA74F712068A740912067EE0FEA3E037 +:102D2B00FF122C32EA7001EB70067A007B00801EDA +:102D3B00EA240DF582EB3400F583E08E828F83F06D +:102D4B00EA240CF582EB3400F583E0D2E7F07F0246 +:102D5B000206EA74F712068A790112247E8A088B1E +:102D6B0009A808A909E8FEE9FFE87001E96013EE7C +:102D7B0024020A0AEF3400FB12177EEEFAEFFB1265 +:102D8B002EE77F020206EA74F112068A74FE12061F +:102D9B0033851082851183ECF0A3EDF08A0C8B0D3B +:102DAB00741112067EE0F50AA3E0F50B74151206FA +:102DBB007EE0F50EA3E0F50FE4850A82850B83F028 +:102DCB007C0179011225688A088B09AE08AF09EEE0 +:102DDB007001EF7003022EDB750800750900850C7E +:102DEB0082850D83E064017015A3E0F9121DA98A99 +:102DFB00088B09EA7001EB70057902022EDD8E82D9 +:102E0B008F83A3A3E024F5850A82850B83F0E0F57D +:102E1B000A750B00780A1207D5EE240EFCEF34006E +:102E2B00FD740212067EE0FAA3E0FB1269587402ED +:102E3B00120649E5087002E5096033EE2421F5829C +:102E4B00EF3400F583E0850882850983A3A3A3A350 +:102E5B00A3A3A3F0EE2422F582EF3400F583E085E3 +:102E6B000882850983A3A3A3A3A3A3A3A3F074132D +:102E7B0012067EE07002A3E0602575080475090058 +:102E8B0078081207D5EE2407FCEF3400FD741512F9 +:102E9B00067EE0FAA3E0FB1269587402120649E5BC +:102EAB000E7002E50F6014EE240CF582EF3400F582 +:102EBB0083E05407850E82850F83F08E828F83A368 +:102ECB00E0FA7901122520E48E828F83F0F98002DB +:102EDB00790474021206497F080206EA74F312069B +:102EEB008A74FE120633EAFEEBFFEE240BF582EF3B +:102EFB003400F583E0543FF509750A04750B00782F +:102F0B000A1207D590F5A3E0FCA3E0FDEE2407FA27 +:102F1B00EF3400FB1268FF7402120649EA7001EBF2 +:102F2B007010E48E828F83F074021206497F0602C2 +:102F3B0006EAEE240BF582EF3400F583E0A2E640BF +:102F4B00E1E509603EC394075039EE2402FAEF34F1 +:102F5B0000FBE509C33324F8F582E434F9F583E08B +:102F6B00F8A3E0F5838882120688E9FA74016A7087 +:102F7B0004740180AE74026A70A8EEFAEFFB123192 +:102F8B00EC80A5743F6509600EE509C3942040925F +:102F9B00E509C3943F508BEE2403F50AEF3400F59B +:102FAB000B750C04750D00780C1207D5AC0AAD0B24 +:102FBB0090F5A3E0FAA3E0FB1268FF740212064936 +:102FCB00EA7001EB70057508018003750800E508D0 +:102FDB007020743F65097073780C1207D512359900 +:102FEB00AD0BAC0A1268FF7402120649EA7001EBD2 +:102FFB007059851082851183AC82AD83EE2402FA61 +:10300B00EF3400FB121F9DE97003022F2DE50870B2 +:10301B0007EEFAEFFB1231EC74018E828F83F09086 +:10302B00F5A7E07002A3E07003022F3385108285B1 +:10303B001183E0F990F5A7E0F8A3E0F583888212FD +:10304B000688E96003022F2D022F33740112067ECE +:10305B00AC82AD83AA0AAB0B123A52EA7001EB6059 +:10306B0036EE2402FAEF3400FB1233DFE960030281 +:10307B002F2DEE240BF582EF3400F583E0A2E75001 +:10308B0003022F2DEE240CF582EF3400F583E0C202 +:10309B00E7F07403022F2EEE240CF582EF3400F5CB +:1030AB0083E0543064206003022F85022F2D74F8C7 +:1030BB0012068AEAFEEBFFE9FAEE240CF8EF340075 +:1030CB00F990F5A6C082C08388828983E054CFD063 +:1030DB0083D082FBE04B88828983F0EAF9EE2402ED +:1030EB00FAEF3400FB1216A1E97004790080027923 +:1030FB0009E48E828F83F07F010206EAC082C083CF +:10310B0090F5A5E0F9D083D0822274F712068A7469 +:10311B00DF120633E9FEEA240BF582EB3400F5836C +:10312B00E0FF90F5A5C082C08390F5A6C082C08356 +:10313B00740A12067EE054CFD083D082FCE04C544C +:10314B00BFD083D082FCE04CC0E0740A12067ED064 +:10315B00E0F075080475090078081207D5EA240514 +:10316B00FCEB3400FD740312067EAA82AB8312695A +:10317B0058740212064978081207D590F5A3E0FCA3 +:10318B00A3E0FD740712067EAA82AB831269587402 +:10319B0002120649740912067EE054C04EF0740BFD +:1031AB00851082851183F0EFC0E0740B12067ED080 +:1031BB00E0F0740A12067EE05478F0E0440BF074F1 +:1031CB000912067EE0543FF0790085108285118349 +:1031DB00AA82AB831216A174211206497F02020642 +:1031EB00EA74F812068AEAFEEBFFEE240CF582EF86 +:1031FB003400F583E05407FA74FF2AFBEA6017E00A +:10320B0054F84BF07A017B00121A397901EEFAEF80 +:10321B00FB1230B98006E48E828F83F07F010206A9 +:10322B00EA74F312068A74FD1206338A0C8B0D892D +:10323B0008EA2508F8EB3400F9740C28F582E43918 +:10324B00F583E0F5097402851082851183F0740112 +:10325B0012067EEAF0A3EBF07C02851082851183C7 +:10326B00AA82AB8379011225688A0A8B0BA80AA95B +:10327B000BE8FEE9FFE87001E96006EEFAEFFB8070 +:10328B006C79021227AA8A0A8B0BAE0AAF0B750850 +:10329B0000804F8E828F83E06403703C750A047547 +:1032AB000B00780A1207D5E50C2405FCE50D34005C +:1032BB00FDEE2403FAEF3400FB1268FF74021206D2 +:1032CB0049EA7001EB7011EE240BF582EF3400F537 +:1032DB0083E0543F650960A30508EE2423FEEF3419 +:1032EB0000FFE508C3940240AA7A007B0074031226 +:1032FB0006497F060206EA74F512068A74DF120687 +:10330B0033EAFEEBFFEE240EF582EF3400F583E09B +:10331B00F50890F5A5C082C083740A12067EE054AE +:10332B008FD083D082FAE04A4420C0E0740A1206A0 +:10333B007ED0E0F0750A04750B00780A1207D5EE03 +:10334B002405FCEF3400FD740312067EAA82AB83C6 +:10335B001269587402120649780A1207D5EE240F27 +:10336B00FCEF3400FD740712067EAA82AB83126950 +:10337B00587402120649740912067EE054C04508BF +:10338B00FAF0740B851082851183F090F5A2E0C0E2 +:10339B00E0740B12067ED0E0F090F5A2E004F0741E +:1033AB000A12067EE05471F0E0D2E0F074BF5A448A +:1033BB0080C0E0740912067ED0E0F079008510829F +:1033CB00851183AA82AB831216A174211206497F41 +:1033DB00040206EA74F112068A8A0C8B0D8A828B20 +:1033EB0083E024F8F50979011227AA8A0A8B0BAE20 +:1033FB000AAF0B750800800A0508EE2423FEEF3494 +:10340B0000FFE508C3940640030234F48E828F83D9 +:10341B00E0640370E385098285820E8E82A3A3E0AC +:10342B00F874F828F874FF3400F9E50E687001E9B8 +:10343B0070C6750A04750B00780A1207D5850C82C5 +:10344B00850D83A3AC82AD83EE2403FAEF3400FB2E +:10345B001268FF7402120649EA7001EB709A780A3F +:10346B001207D5E50C2405FCE50D3400FDEE240711 +:10347B00FAEF3400FB1268FF7402120649EA70017E +:10348B00EB6003023403750A01780A1207D5E50CC9 +:10349B002409FCE50D3400FDEE240BFAEF3400FBA0 +:1034AB001268FF7402120649EA7001EB60030234E2 +:1034BB000374FE250EF50A74FF3400F50B780A121F +:1034CB0007D5E50C240BFCE50D3400FDEE240DFABD +:1034DB00EF3400FB1268FF7402120649EA7001EB2D +:1034EB0060030234037901800279007F080206EA47 +:1034FB002279002274F712068A7508047509007880 +:10350B00081207D57C007D007AA97BF5126A3F74FF +:10351B000212064990F5B1E0701B78081207D57CB2 +:10352B00067DFA7AAD7BF51269587402120649745E +:10353B000190F5B1F07F020206EAC082C08390F5DC +:10354B00B1E060067AAD7BF580047A067BFAD08316 +:10355B00D082227A0B7BFA2279022274F712068A26 +:10356B00790090F5B1E0702175080489097808128B +:10357B0007D5EAFCEBFD7AAD7BF5126958740212A4 +:10358B000649740190F5B1F0F97F020206EA7ABEA2 +:10359B007BF92274F512068AEAFEEBFFEE2405F89E +:1035AB00EF3400F988828983E012084D010506C2C9 +:1035BB00350103C235C6357D0180027D038E828FB6 +:1035CB0083A3A3A3A3E0FC8E828F83A3A3E0FAA320 +:1035DB00E0FB88828983E0F9122C328A088B09A9D7 +:1035EB0009EA7001E96031750A04750B00780A125B +:1035FB0007D58E828F83E0FCA3E0FDEA24030A0A41 +:10360B000AE93400FB12695874021206497901AABF +:10361B0008AB091230B9800279037F040206EA7401 +:10362B00F712068A74FD120633E485108285118326 +:10363B00F08A828B83A3A3A3A3A3E0C0E07401123F +:10364B00067ED0E0F0EA2406F508EB3400F50978A5 +:10365B00081207D58A828B831207EAEA2404F5083D +:10366B00EB3400F50978081207D58A828B83A3A364 +:10367B00E0FCA3E0FD740612067EAA82AB83122D3A +:10368B0092740612064974031206497F020206EA77 +:10369B0074F512068AEAFEEBFF7508007404697074 +:1036AB000912198512186F02374B740569700912CC +:1036BB00189412194002374B74066970398E828F39 +:1036CB0083E0F9121DA9EA7001EB70047902807294 +:1036DB00750A02750B00780A1207D5EA2407FCEB72 +:1036EB003400FD8E828F83A3AA82AB831269587438 +:1036FB0002120649804A740769700B121AF1E98E9F +:10370B00828F83F0803A74086960A7740969700529 +:10371B00121985802B740A6970238E828F83E012B5 +:10372B0008170002D7363F373B3737377902800609 +:10373B00790180027900121BC1790080057508029E +:10374B00A9087F040206EA740B69700479018002F0 +:10375B007902123AC679002274F712068AEAFEEB56 +:10376B00FF750802740169702075080475090078EB +:10377B00081207D5123545EAFCEBFDEEFAEFFB120A +:10378B00695874021206498009E97009123566E915 +:10379B006003750800A9087F020206EA74F7120697 +:1037AB008AE9FC8A828B83E0F9740E6C60047902DF +:1037BB00801374FF6960F7121DA9EA7001EB60EECC +:1037CB00121D9A79007F020206EA74F512068A909E +:1037DB00F5B2C082C08390F9B2780812052BD08362 +:1037EB00D082780812034F701090FA0F78081205E8 +:1037FB002B90F5B2780812053A90F5B6EAF0A3EBE8 +:10380B00F01218D1E990F5B8F0123875123BB87474 +:10381B000190F5BBF0121E5A90F5B9EAF0A3EBF04C +:10382B007F040206EA74F512068A8A088B098C0A51 +:10383B008D0B90F9B2780812034F600890F5B278AF +:10384B000812053A7F040206EA74F512068AEA703A +:10385B0001EB601190F5B2780812052B8A828B83ED +:10386B00780812053A7F040206EA7AEF7BBE7CAD3C +:10387B007DDE2274F312068A74F4120633EAFEEB31 +:10388B00FF8E828F83E0F874F528F874FF3400F90B +:10389B00C3E89408E99400A2D265D0334018EE2413 +:1038AB0013F582EF3400F583E0F508123563E96513 +:1038BB00086003023A457904740112067EAC82ADAE +:1038CB0083EE240EFAEF3400FB122365C082C08313 +:1038DB0090F5B2780812052BD083D08278081203AA +:1038EB004F6003023A45740112067EAA82AB831223 +:1038FB003BDC7904740712067EAC82AD8374011233 +:10390B00067EAA82AB831223C4E4C0E0740B1206BA +:10391B007ED0E0F07481C0E0740512067ED0E0F03A +:10392B00EE240DF582EF3400F583E0C0E07406124F +:10393B00067ED0E0F07D017C07740512067EAA821C +:10394B00AB837903122C328A088B09A808A9098842 +:10395B000A890BE87001E97003023A45EE2405F57C +:10396B0008EF3400F509750C04750D00780C12077F +:10397B00D5AC08AD09EA24030A0A0AE93400FB12A4 +:10398B0069587402120649EE2412F582EF3400F5E1 +:10399B0083E06024EEFAEFFB121E5FE9601A90F5EC +:1039AB00B6E07002A3E06010790090F5B6E0F8A3E2 +:1039BB00E0F58388821206888E828F83A3A3A3A34C +:1039CB00A3A3A3A3A3A3E0A2E6506685108285114F +:1039DB0083AC82AD83AA08AB09123A52EA7001EBB1 +:1039EB00704A90F5B9E0FEA3E0FF8E828F83E0C3AF +:1039FB0094035046780C1207D5AC08AD098E828F14 +:103A0B0083E075F005A4F8A9F090F5B9E028FAA3C6 +:103A1B00E0398A82F583A3AA82AB831269587402B8 +:103A2B001206498E828F83E004F08005E0F9124282 +:103A3B00187900AA0AAB0B1230B9740C1206497F25 +:103A4B00060206EA79002274F112068A8A0E8B0F9F +:103A5B008C088D0990F5B9E02401FEA3E03400FF3A +:103A6B00750A00800A050AEE2405FEEF3400FF906C +:103A7B00F5B9E0F8A3E0F5838882E0FAE50AC39A8A +:103A8B005030750C04750D00780C1207D5AC0EADCB +:103A9B000FEEFAEFFB1268FF7402120649EA70018F +:103AAB00EB70C2850882850983E50AF0EEFAEFFB1D +:103ABB0080047A007B007F080206EAC082C0837410 +:103ACB000169700474018001E490F5BBF0D083D0E0 +:103ADB008222C082C083EA240CF8EB3400F98A827C +:103AEB008B83E0FC74F52CFC74FF3400FD74076CC5 +:103AFB007001ED7007740188828983F08882898355 +:103B0B00E06401700312387ED083D0822274F812E5 +:103B1B00068AEAFEEBFF7508007D017C0090F5B884 +:103B2B00E0F9122211E9FB7008121AB57508018031 +:103B3B001C74016B7005750802801274026B700D9A +:103B4B0090F5BBE06007EEFAEFFB123ADDA9087FB8 +:103B5B00010206EA74F512068A90F5BCC082C08396 +:103B6B0090F9B2780812052BD083D0827808120313 +:103B7B004F701090FA13780812052B90F5BC78084B +:103B8B0012053A1218D1E990F5C3F060F6750801E9 +:103B9B0075090078081207D57C007D007AC17BF58A +:103BAB00126A3F74021206497F040206EA74F51288 +:103BBB00068A8A088B098C0A8D0B90F9B278081249 +:103BCB00034F600890F5BC780812053A7F04020693 +:103BDB00EA74F512068AEA7001EB601190F5BC7875 +:103BEB000812052B8A828B83780812053A7F040210 +:103BFB0006EA74F312068A74FD120633EAFEEBFF33 +:103C0B00750A08EE2405F508EF3400F509EE240ECD +:103C1B00F582EF3400F583E0F9AA08AB091222C84C +:103C2B00EA7001EB6006121D9A750A00748285100A +:103C3B0082851183F0EE240DF582EF3400F583E0DD +:103C4B00C0E0740112067ED0E0F0740212067EE52D +:103C5B000AF07D037C03851082851183AA82AB83D6 +:103C6B007902122C328A0A8B0BA80AA90BE8FEE9FF +:103C7B00FFE87001E9602A750A04750B00780A12D7 +:103C8B0007D5AC08AD09EE24030A0A0AEF3400FB92 +:103C9B0012695874021206497900EEFAEFFB1230E2 +:103CAB00B974031206497F060206EA74F112068AFA +:103CBB0074F81206338A088B098A828B83E0F874B6 +:103CCB00F528F874FF3400F9C3E89409E99400A2CD +:103CDB00D265D033401FEA2414F582EB3400F58310 +:103CEB00E0FE123563E96E600C7902740812064926 +:103CFB007F080206EA7904E912067EAC82AD83E501 +:103D0B0008240EFAE5093400FB122365C082C08338 +:103D1B0090F5BC780C12052BD083D082780C120353 +:103D2B004F70C6E5082412F582E5093400F583E0EF +:103D3B00F50AE5082405F50EE5093400F50FA90A87 +:103D4B00AA0EFB121DEA8A0C8B0DA80CA90DE8FE1E +:103D5B00E9FFE87001E97003023E1174818510825E +:103D6B00851183F0E508240DF582E5093400F58310 +:103D7B00E0C0E0740112067ED0E0F08E828F83A348 +:103D8B00A3A3A3A3A3A3A3A3E0C0E0740212067E84 +:103D9B00D0E0F0123107E9C0E0740312067ED0E0E8 +:103DAB00F0850882850983A3A3A3A3A3A3A3A3A33D +:103DBB00A3E05407FA7403C39AFD7C048510828533 +:103DCB001183AA82AB837902122C328A088B09A940 +:103DDB0009EA7001E9602A750A04750B00780A126A +:103DEB0007D5AC0EAD0FEA24030A0A0AE93400FB2F +:103DFB0012695874021206497900AA08AB091230ED +:103E0B00B97901023CF690F5C0E07003023CF4AACC +:103E1B0008AB09121F038A0C8B0DAE0CAF0DEE70A5 +:103E2B0001EF700B121CF18A0C8B0DAE0CAF0DEE6B +:103E3B007001EF60CC750C04750D00780C1207D572 +:103E4B00AC0EAD0FEE2403FAEF3400FB126958747D +:103E5B0002120649EEFAEFFB79021220A0E9700973 +:103E6B00EEFAEFFB121D9A809890F5C2E0640160A8 +:103E7B00EFE0F50C7401250CF0EE240BF582EF341A +:103E8B0000F583E0C0E0E50C24C1F582E434F5F5E0 +:103E9B0083D0E0F08E828F83A3A3A3A3A3A3A3A3BA +:103EAB00A3A3E50AF074028E828F83F0A3A882A9E4 +:103EBB0083E5082413F582E5093400F583E06440BB +:103ECB00700474018002740388828983F08E828F60 +:103EDB0083A3A3A3A3A3A3A3A3A3E0C0E074021291 +:103EEB00067ED0E0F0123107E9C0E0740312067EC3 +:103EFB00D0E0F07481851082851183F0E508240DE4 +:103F0B00F582E5093400F583E0C0E0740112067E0A +:103F1B00D0E0F0850882850983A3A3A3A3A3A3A361 +:103F2B00A3A3A3E05407FA7403C39AFD7C04851082 +:103F3B0082851183AA82AB837902122C328A088B79 +:103F4B0009A909EA7001E96030750A04750B00785C +:103F5B000A1207D5AC0EAD0FEA24030A0A0AE9349C +:103F6B0000FB12695874021206497900AA08AB09C2 +:103F7B001230B9E97003023E0C023E6B74F8120664 +:103F8B008AEAFEEBFF7D017C0090F5C3E0F912227B +:103F9B0011E9FB7007121AB57901801074016B706F +:103FAB000479028007EEFAEFFB12402C7F01020628 +:103FBB00EA74F712068A7900A2AFE492E0FAC2AF74 +:103FCB0090F5C2E0603AE014F0EAA2E092AF091279 +:103FDB00401590F5C1E0F97C00ECC0E090F5C2E033 +:103FEB00FAD0E0C39A501E8C08E50824C1FAE434D9 +:103FFB00F5FB8A828B83A3E08A828B83F00C80D9BA +:10400B00EAA2E092AF7F020206EAC082C083E970A7 +:10401B00047A0180027A00EA90F5C0F0D083D08256 +:10402B002274F812068A7E00EA240CF8EB3400F9AD +:10403B008A828B83E0FC74F52CFC74FF3400FD74D6 +:10404B00086C7001ED7007740188828983F0888297 +:10405B008983E01208170101804069407D40123CC2 +:10406B00B6E9FA90F5C0E0700C74016A60070E0EA9 +:10407B008003123BFDEEF97F010206EA74F712068C +:10408B008A1218D1E990F5C7F07508037509007805 +:10409B00081207D57C007D007AC47BF5126A3F7449 +:1040AB00021206497F020206EA74F712068AEAFE3A +:1040BB00EBFF7D017C0090F5C7E0F9122211E9FBC3 +:1040CB007007121AB57901803B74016B7004790289 +:1040DB00803275080475090078081207D51235452A +:1040EB00EAFCEBFD8E828F83A3AA82AB831268FF5F +:1040FB007402120649EA7001EB70D3EEFAEFFB1271 +:10410B00411479007F020206EAC082C083EA240CC4 +:10411B00F582EB3400F583E06401700312412FD07C +:10412B0083D0822274F612068A74FF120633EAFEDB +:10413B00EBFFEE240DF582EF3400F583E0F50A85F5 +:10414B001082851183AC82AD83EE2405FAEF340027 +:10415B00FB123A52EAF8EBF9EA7001EB70030242F8 +:10416B000EE82404F508E93400F509E024C4F582CF +:10417B00E434F5F583E07021850882850983E50A2F +:10418B00F07401C0E0851082851183E024C4F582B0 +:10419B00E434F5F583D0E08012AA0A8508828509FC +:1041AB0083E0F912233DE9605AE50AF07902EEFA51 +:1041BB00EFFB12322C8A088B09A808A909E87001B9 +:1041CB00E9603988828983A3E0FA7901122520E519 +:1041DB0008240CF582E5093400F583E054F844011A +:1041EB00F0E508240BF582E5093400F583E0D2E70E +:1041FB00F07900AA08AB091230B98007EEFAEFFB91 +:10420B0012330274011206497F030206EA74F71295 +:10421B00068AE4C0E0E924C4F582E434F5F583D0E2 +:10422B00E0F07F020206EAC082C0831218D1E99047 +:10423B00F5C8F0D083D0822274F512068AEAFEEB21 +:10424B00FF7D038E828F83E024F5FCEE240CFAEFC6 +:10425B003400FB7901122C328A088B09A909EA7008 +:10426B0001E9603E750A04750B00780A1207D5EE5A +:10427B002405FCEF3400FDEA24030A0A0AE93400A2 +:10428B00FB1269587402120649E508240EF582E503 +:10429B00093400F583E0D2E7F07900AA08AB0912E4 +:1042AB0030B97F040206EA74F812068AEAFEEBFFC5 +:1042BB007D017C0090F5C8E0F9122211E9FA700734 +:1042CB00121AB57901801274016A7004790280099F +:1042DB00EEFAEFFB1242E979007F010206EAC08297 +:1042EB00C083EA240CF582EB3400F583E0640170A3 +:1042FB0003124243D083D0822222790022C082C093 +:10430B0083124638E490F5D4F0FB8029EB75F00569 +:10431B00A424D5F8E5F034F5F9E488828983F0A379 +:10432B00F0A3F088828983A3A3A3F088828983A357 +:10433B00A3A3A3F00BEBC3940A40D1D083D082226A +:10434B0074F112068A74FB12063374018510828590 +:10435B001183F01243081248997A007BC0124971FD +:10436B0075E54475E402539BFCE59B53E9EF4391E0 +:10437B0010D2A8439A01D2B990F410E4F0A3F080C4 +:10438B000B90DF3BE06401700375E10290F5D4E024 +:10439B00C3940A500690F608E060E675E10490F6C7 +:1043AB0008E0700990F5D4E0C39405500B90F4101D +:1043BB00E4F0A374800245857A0080010AEAC39475 +:1043CB000A5031EA75F005A424D5F8E5F034F5F977 +:1043DB0088828983E060E5A3E0FAA3E0FB74031213 +:1043EB00067EEAF0A3EBF088828983A3A3A3E0F512 +:1043FB000C750D007A0980011AEA602E75F005A480 +:10440B0024D5F8E5F034F5F988828983E060E9A3D7 +:10441B00E0FAA3E0FB740112067EEAF0A3EBF0884E +:10442B00828983A3A3A3E0FE7F00750800750900B2 +:10443B007C007D007A008015E508250AF508E50962 +:10444B003400F509EC24010CED3400FD0AEAC394A9 +:10445B000A5033EA75F005A424D5F582E5F034F55E +:10446B00F583E060E7E5822404F582E5833400F50B +:10447B0083E0F50AE0A2E750BFA80AE50828F50893 +:10448B00E50934FF80BCA808A909ECFAEDFB12057D +:10449B00B0880EC3E894E7E994FFA2D265D033400D +:1044AB000EC3E8941AE99400A2D265D033400B9066 +:1044BB00F410E8F0A37420024585EEC3950CF8EFD9 +:1044CB00950DF9E875F0CCA4C8AAF075F00CA42AE8 +:1044DB00FA75F0CCE9A42AF9740112067EC082C0E9 +:1044EB0083740312067EE0FAA3E0FBD083D082E054 +:1044FB00C39AFEA3E09BFFE8C39EFAE99FFBC3EAC6 +:10450B009404EB94005036740F5AF990F410E4F0C5 +:10451B00A3E9F0C3E5099400A2D265D0335046C39A +:10452B00E49508F8E49509F9ECFAEDFB1205B8E807 +:10453B00F404F890F410E048F0A3E08045EEC39843 +:10454B00F8EF99F9C3E89404E994005025740F58D7 +:10455B00F990F410E4F0A3E9F0C3E5099400A2D2BA +:10456B0065D03340BAA808A909ECFAEDFB1205B8DF +:10457B0080C190F410E4F0A37440F0E485108285C0 +:10458B001183F0851082851183E06401600302467C +:10459B001EE490F5D4F0FA8029EA75F005A424D531 +:1045AB00F8E5F034F5F9E488828983F0A3F0A3F001 +:1045BB0088828983A3A3A3F088828983A3A3A3A35F +:1045CB00F00AEAC3940A40D1E50E90DF08F01248D6 +:1045DB00997A007B40124971800B90DF3BE06401BC +:1045EB00700375E10290F5D4E0700690F608E06078 +:1045FB00E975E10490F5D4E0601090F5D9E0FAC3C9 +:10460B0094FE500FEAC39403400990F410E4F0A316 +:10461B007410F0C2A8539AFEC2B975E40075E25546 +:10462B0012489974051206497F080206EAC082C037 +:10463B008374CA90DF00F074BA90DF01F0740A90B3 +:10464B00DF02F0E490DF03F090DF04F090DF05F081 +:10465B0090DF06F0741290DF07F0E490DF08F0743F +:10466B002490DF09F0742D90DF0AF0745590DF0B66 +:10467B00F0743D90DF0CF0745590DF0DF0741590D5 +:10468B00DF0EF0741290DF0FF0741190DF10F074E6 +:10469B006090DF11F0740790DF12F0740290DF135B +:1046AB00F0741890DF14F0741D90DF15F0741C90EB +:1046BB00DF16F074C790DF17F0741090DF18F074EA +:1046CB00B290DF19F074B690DF1AF0741090DF1B04 +:1046DB00F074EA90DF1CF0742A90DF1DF0E490DF99 +:1046EB001EF0741F90DF1FF0E490DF2FF090DF308F +:1046FB00F090DF31F0743190DF24F090DF1CE04458 +:10470B0020F0745A90DF2EF075E10475E10190DF13 +:10471B003BE0640170F890DF1CE054CFF075E104CE +:10472B00D083D0822274F112068AE5D990F5C9F0B4 +:10473B00740190F5D3F07890F9801DA2895019E59A +:10474B00D9C0E0E024C9F582E434F5F583D0E0F07C +:10475B0090F5D3E004F0C289E0C3940A5012E8FA52 +:10476B00E9FB74FF2A1874FF3BF9EA7001EB70CB7D +:10477B00E0640A600302483875E104AAE28A828584 +:10478B008208E5E3F8E4C8F50990F60FE0FA75F056 +:10479B00BDA4CAACF075F02CA42CFB880A880B7452 +:1047AB000F78081204AD90FA21780C12052B7808BB +:1047BB00790C120424E5082AF508E5093BF5097C78 +:1047CB00017B0180218B82A882E824C9F582E43425 +:1047DB00F5F583E0FAE82417F582E434FAF583E083 +:1047EB006A60027C000BEBC3940A40D9EC603E90EC +:1047FB00F5D4E075F005A424D5F8E5F034F5F9749B +:10480B000188828983F0A3E508F0A3E509F090F510 +:10481B00C9E088828983A3A3A3F090DF38E0888264 +:10482B008983A3A3A3A3F090F5D4E004F07F08023F +:10483B0006EAC082C083E5E9FA539BFCE59BEAA23A +:10484B00E7500575E1048014A2E6501075E1049061 +:10485B00DF3BE0640170F8E490F5D3F075E900D02C +:10486B0083D08222C082C083C2A8539AFE74FF9069 +:10487B00DF06F074C090DF2EF0740190DF02F0754C +:10488B00D95575E103D083D0822275E10422C08211 +:10489B00C083E490F607F090F608F090F609F0A3C9 +:1048AB00F090F60BF090F60CF0A3F090F60EF09063 +:1048BB00F60FF0D083D0822274F712068A7C009018 +:1048CB00F60BE0603E53E5BF75DBFF75DAFFE5DB0A +:1048DB00F9E5DAF874FF68700374FF69601375DB30 +:1048EB00FF75DAFFE5DBF9E5DAF8EC0CC3940B4066 +:1048FB00E3E014F053E40FE5E443E54079017F0274 +:10490B000206EA90F60CC3E09406A3E09400405232 +:10491B0053E5BF90F60CE024FFA3E034FFF5DB90EA +:10492B00F60CE014F5DAE5DBF9E5DAF8E024FFFA4A +:10493B00A3E034FFFBEA687002EB696017EBF5DB71 +:10494B0090F60CE014F5DAE5DBF9E5DAF8EC0CC3DC +:10495B00940B40D890F60CE4F0A3F0740190F60E93 +:10496B0080917900809874F112068A53E5BFE49028 +:10497B00F607F090F60B800AEA2443FAEB34D3FBEC +:10498B00E004F0C3EA94BDEB942C50EC8A088B093D +:10499B00750A00750B0090FA21780C12052B78081C +:1049AB00790C1203A4740F780812049490F60CE59A +:1049BB0008F0A3E509F01248C353E40FE5E443E51F +:1049CB0040740190F607F07F080206EAC082C083AC +:1049DB0090F609E0F8A3E0F9C3E89AE99B5009EADD +:1049EB00C398F8EB99F9800CE86A7002E96B70EFE9 +:1049FB0078FF79FF90F609EAF0A3EBF0E8FAE9FB10 +:104A0B00124971D083D08222C082C083740190F688 +:104A1B0007F0D083D08222C082C083E490F607F0E7 +:104A2B00D083D08222C082C083E490F608F0D0837A +:104A3B00D08222C082C08390F62CE0FA74226A7076 +:104A4B001A90F619E0703390F62DE0F8A3E0F99088 +:104A5B00F650E8F0A3E9F07402801B74206A70141E +:104A6B0090F619E0701490F6267449F0A374F6F0E2 +:104A7B00A3E480E2740490F619F0D083D08222C0B4 +:104A8B0082C08390F62CE06421702090F619E070C0 +:104A9B002090F6267449F0A374F6F0A3E4F090F698 +:104AAB00297407F0A3E4F074018002740490F619E2 +:104ABB00F0D083D08222C082C083740490F619F0A8 +:104ACB00D083D08222C082C083740490F619F0D0B8 +:104ADB0083D08222C082C083740490F619F0D083F5 +:104AEB00D08222C082C083740490F619F0D083D098 +:104AFB0082222222C082C08390FA25E0F8A3E0F93B +:104B0B0090F610E8F0A3E9F0D083D0822274F8126B +:104B1B00068AE9FCEAFD7A007B00802190F610E022 +:104B2B00F8A3E0F5838882E493F890F610E028F878 +:104B3B00A3E03400F990F610E8F0A3E9F090F6103A +:104B4B00E0F8A3E0F990FA27E0687003A3E069604E +:104B5B004890F610E02401F8A3E03400F98882892C +:104B6B0083E4936C702B90F610E0FAA3E0FB90F6C5 +:104B7B0010E0F8A3E0F5838882E493F890F610E058 +:104B8B0028F8A3E03400F990F610E8F0A3E9F080E0 +:104B9B0008E4936D7086ED60837F010206EA124A8A +:104BAB00FF7A007901124B182274F712068AE9FE7C +:104BBB00EAFF124AFF800E8A828B83A3A3A3A3A3CF +:104BCB00E4936E60147A007902124B18EA7001EBD1 +:104BDB006007EE70E2EF1F70EC7F020206EA74F7DB +:104BEB0012068AEAFEEBFF7A00124BB47A027904C2 +:104BFB00124B18EA7001EB60178A828B83A3A3E434 +:104C0B00936E70E88A828B83A3A3A3E4936F70DC0B +:104C1B007F020206EA74F712068AE9FE124AFF7A4D +:104C2B00007903124B18EE1E70F57F020206EAC0E4 +:104C3B0082C0837A007901124BB48A828B83A3A33F +:104C4B00A3A3A3A3A3E493A2E6500474018001E4FD +:104C5B0090F625F0E490F624F043BE80D2BDD083CD +:104C6B00D08222C082C083740290F612F0E490F6D8 +:104C7B0013F090F619F07903124EF9752100752295 +:104C8B0000D083D0822274F512068A90DE0EE0FEED +:104C9B00E4F090DE11E0FFA2E4501F7480F0740783 +:104CAB0090F619F0E5217002E522600985218285D5 +:104CBB002283120688E490F619F0EFA2E25009E481 +:104CCB0090DE11F090F619F090F619E0FA74026A82 +:104CDB006003024D6790DE16E0F50A90F626120788 +:104CEB00E6A90A7A207BDE124F3F74031206498530 +:104CFB000A0890F629C3E09508F0A3E09400F09021 +:104D0B00F626E0F9A3E0FAA3E0FBE9250AF9EA3479 +:104D1B0000FA90F626E9F0A3EAF0A3EBF090F6295F +:104D2B00E07002A3E060047A4080027A48EA90DEE9 +:104D3B0011F090F629E07002A3E07016E5217002E5 +:104D4B00E5226009852182852283120688E490F68C +:104D5B0019F0EE90DE0EF07F040206EA74066A701C +:104D6B000985218285228312068890F619E060035B +:104D7B00024E6AEFA2E04003024E6A75082B7509DA +:104D8B00F6750A0078081207D179087A207BDE12B3 +:104D9B004F3F740312064975210075220090F62BC4 +:104DAB00E054E012084D000600C74D20434E402D45 +:104DBB004E80024EA04E4EC0384EFA4D90F62CE06F +:104DCB0012084D000501EB4D03E64D05E14D09F0D1 +:104DDB004D0BF54DFA4D1252CC80711252C0806CB6 +:104DEB001252B480671256CF80621257F7805D74EF +:104DFB000490F619F0805590F62CE012084D000443 +:104E0B0000194E061E4E08234E0A284EFA4D12501C +:104E1B00CA80391253258034125686802F12579927 +:104E2B00802A7521C175224A124AC1801F7521D073 +:104E3B0075224A124AD0801475213E75224A124AB5 +:104E4B003E800975218A75224A124A8A90F619E02A +:104E5B00640470047A6080027A40EA90DE11F0906C +:104E6B00F619E0FA74016A70717F0290F629E0F886 +:104E7B00A3E0F9C3E89420E994005007E8F50A7F12 +:104E8B000A8003750A2090F6261207E6A90A7A20F3 +:104E9B007BDE124F797403120649850A0890F626B9 +:104EAB00E0F9A3E0FAA3E0FBE92508F9EA3400FAFC +:104EBB0090F626E9F0A3EAF0A3EBF090F629C3E015 +:104ECB009508F0A3E09400F0EF90DE11F0E50AC333 +:104EDB0094204003024D5D024D4774056A60030246 +:104EEB004D5D852182852283120688024D5D74F704 +:104EFB0012068A7A008014E9C0E08A08E508241AB1 +:104F0B00F582E434F6F583D0E0F00AEAC394054069 +:104F1B00E67A008014E9C0E08A08E508241FF582D0 +:104F2B00E434F6F583D0E0F00AEAC3940540E67F5B +:104F3B00020206EA74F612068AEAFCEBFDE9FE743D +:104F4B000A12067EE0F508A3E0F509A3E0A908AA7A +:104F5B0009FBEE60148C828D83E012038EE9240131 +:104F6B0009EA3400FA1EEE70EC7F030206EA74F6CF +:104F7B0012068AEAFCEBFDE9FE740A12067EE0F5E6 +:104F8B0008A3E0F509A3E0A908AA09FBEE60141237 +:104F9B0003748C828D83F0E9240109EA3400FA1E34 +:104FAB00EE70EC7F030206EA74F712068A75230093 +:104FBB007524007525008A268B27EA90DE0BF08A74 +:104FCB00088B0974047808120611E50890DE07F0C7 +:104FDB008A088B0974097808120611E508543E906B +:104FEB00DE09F0438C10758900C2C5758B00C2E8D1 +:104FFB00439A027F020206EAC0E074F1120722E52F +:10500B00BEA2E650FA90DE06E0FAA2E25036A826DF +:10501B00E890DE0BF08526088527097404780812C2 +:10502B000611E50890DE07F0852608852709740927 +:10503B007808120611E508543E90DE09F090DE0167 +:10504B00E0D2E0F07823EA46F608E6F690DE02E0DE +:10505B00F508750900740478081206207823E50812 +:10506B0046F608E50946F690DE04E0F508750900FA +:10507B00740978081206207823E6F608E50946F647 +:10508B00EAA2E0500375250174065A6003752500EA +:10509B00124AFE758B00C2E87F02020781C0E074E2 +:1050AB00F2120722E5BEA2E650FAE589A2E7500507 +:1050BB00C2BD125921758900C2C57F0102078174D7 +:1050CB00F712068A90F62DE07002A3E0701E90F6A0 +:1050DB002FE0F8A3E0F974FF59FBE47001EB700CBF +:1050EB0090F631E064027002A3E060057404025193 +:1050FB00BC90F62BE0120817800210510D513D5158 +:10510B004D51E86008740490F61902519B90F625F6 +:10511B00E0600478018002780090F633E8F0A3E4B5 +:10512B00F090F624E0606A90F633E04402F0A3E0DE +:10513B00805E90F612E0640470CB90F633E4F0A33B +:10514B00804EE8547FF50890F612E0640470B6E5E3 +:10515B0008C3940650AFE5082412F582E434F6F543 +:10516B0083E854806010A3A3A3A3A3A3A3E06403C9 +:10517B00701578018013E582240CF582E5833400E9 +:10518B00F583E0640360EB780090F633E8F0A3E47A +:10519B00F090F619E06404601C90F6267433F0A3CB +:1051AB0074F6F0A3E4F090F6297402F0A3E4F07423 +:1051BB000190F619F07F020206EA74F712068A9044 +:1051CB00F631E07002A3E0701290F612E064046016 +:1051DB001290F62FE07002A3E06008740490F619A9 +:1051EB000252AC90F62BE0541F1208170002E65146 +:1051FB0001520952235290F62DE0640160057900AB +:10520B000252AFE990F624F060047905800279062A +:10521B007A00124AFD0252AD90F62FE0547FFA90BD +:10522B00F62DE070D9EAC3940650B0EA90DE0EF08A +:10523B0090F62FE054806032E960047B1080027B93 +:10524B0040EB90DE11F0E960047B0380027B00EB06 +:10525B00C0E0EA2419F582E434F6F583D0E0F0E9F6 +:10526B0060047908803479078030E960047B208002 +:10527B00027B80EB90DE14F0E960047B0380027B01 +:10528B0000EBC0E0EA241EF582E434F6F583D0E0AF +:10529B00F0E96004790A80027909124AFDE490DE94 +:1052AB000EF079017F020206EA79001251C5E9700E +:1052BB0003124ADF2279011251C5E97003124AEE3B +:1052CB0022C082C08390F62FE07002A3E070209082 +:1052DB00F631E07002A3E0701690F62DE0F8A3E033 +:1052EB00F9748058FA74FF59FBEA7001EB6007748C +:1052FB000490F619801EE890DE00F090F62DE090F9 +:10530B00F6126009E06402700C74038007E064031A +:10531B0070037402F0D083D0822274F512068A9047 +:10532B00F62DE0FAA3E01208170102D9533E53659C +:10533B0053B053124BA990F626EAF0A3EBF0A374EB +:10534B0080F090F626E0F9A3E0FAA3E0FB120374D9 +:10535B0090F629F0A3E4F00254AB7900124BB49011 +:10536B00F626EAF0A3EBF0A37480F090F626E0F9B2 +:10537B00A3E0FAA3E0FBE924020909EA3400FA12DC +:10538B000374FC90F626E0F9A3E0FAA3E0FBE92412 +:10539B0003090909EA3400FA120374F9EC90F629AF +:1053AB00F0A3E980B1EAF9124C2090F626EAF0A3BB +:1053BB00EBF0A37480F090F626E0F9A3E0FAA3E0FB +:1053CB00FB12037490F629F0A3E4F00254AB90F6B1 +:1053DB0026E4F0A3F0A3F0FC02547C7509007403DF +:1053EB007808120620AE08AF09EA2EF8EB3FF990C9 +:1053FB00F62DE0F508A3E0F50988828983E493AAEA +:10540B00096A706CA3E4936508706590F62FE0F55C +:10541B0008A3E0F50988828983A3A3E493AA096A08 +:10542B00704E88828983A3A3A3E493650870418897 +:10543B00828983A3A3A3A3E493F508740193F509CD +:10544B0090F626E508F0A3E509F0A37480F090FA36 +:10545B0029E02EFAA3E03F8A82F583A3A3A3A3A39B +:10546B00A3E493F8740193F990F629E8F0A3E9F01B +:10547B000C90FA29E0FAA3E0FB8C0890FA2BE0F8E9 +:10548B00A3E0F9E8C39AF50AE99BF50B7403780AD4 +:10549B00120611C3E508950AE4950B50030253E677 +:1054AB0090F626E0FCA3E0FDA3E0FEEC4D4E70066B +:1054BB00740490F619F090F619E06404602590F6E8 +:1054CB0031E0FAA3E0FB90F629E0F8A3E0F9C3EA98 +:1054DB0098EB99500890F629EAF0A3EBF074019041 +:1054EB00F619F07F040206EA74F112068A74FE12B2 +:1054FB000633851082851183EAF0A3EBF0851082C9 +:10550B00851183E0F8A3E0F5838882A3A3A3A3E42A +:10551B0093602B90FA2DE0FEA3E08007EE2404FEAF +:10552B00EF3400FF8E828F83E493F8740193F98537 +:10553B001082851183E0687003A3E06970DE750843 +:10554B0000805A749090DE14F07410F08882898376 +:10555B00E493540364017003750940750A01750BDC +:10556B0000E50C780A1206208E828F83A3A3A393E7 +:10557B00550A6006E509D2E0F509E50990DE15F05C +:10558B00EA90DE13F0E4C0E0E50C241EF582E4346F +:10559B00F6F583D0E0F0E490DE0EF005088510827E +:1055AB00851183E0F8A3E0F5838882A3A3A3A3E48A +:1055BB0093FAE508C39A400302567C7A00790512E8 +:1055CB004B188A0A8B0BAC0AAD0BEC7001ED60CB60 +:1055DB00EC2402F50EED3400F50F850E82F583E415 +:1055EB0093540FF50C90DE0EF07509008C828D83B1 +:1055FB00A3A3A3A3E4932407F50AA3E4933400F530 +:10560B000B7403780A120611AA0AEC2403F8ED3482 +:10561B0000F9850E82850F83E493A2E740030255C0 +:10562B004E744890DE11F07408F088828983E493FD +:10563B00540364017003750940750A01750B00E58D +:10564B000C780A1206208E828F83A3A393550A60CF +:10565B0006E509D2E0F509E50990DE12F0EA90DEE5 +:10566B0010F0E4C0E0E50C2419F582E434F60255A1 +:10567B009C74021206497F080206EAC082C083901E +:10568B00F62DE07002A3E0701690F62FE07002A3E7 +:10569B00E0700C90F631E064017002A3E0600474DA +:1056AB0004801890F6267413F0A374F6F0A3E4F0BC +:1056BB0090F6297401F0A3E4F0740190F619F0D080 +:1056CB0083D0822274F312068A90F612E064026091 +:1056DB001F90F62FE07002A3E0701590F631E0708A +:1056EB0002A3E0700B90F62EE0F9E47001E960097B +:1056FB00740490F619F00257947A007901124AFD5E +:10570B0090F62DE0606E7A00F9124BB48A088B0983 +:10571B00EA7001EB6056740490F612F090F62DE0EF +:10572B0090F613F0750A00850882850983A3A3A35D +:10573B00A3E493FAE50AC39A5048850A0CE50C24B6 +:10574B0014FEE434F6FFE48E828F83F07A00790442 +:10575B00124B188A828B83A3A3A3E493FC8E828FB4 +:10576B0083E06C70E71254F3050A80BB740490F667 +:10577B0019F0800E90F613F0740390F612F0F912F4 +:10578B004EF97A007902124AFD7F060206EA74F698 +:10579B0012068A90F612E06404701E90F62BE064F9 +:1057AB0081701690F62DE07002A3E0700C90F6312C +:1057BB00E064017002A3E060047404802690F62F6D +:1057CB00E02414F508A3E034F6F50990F626E50875 +:1057DB00F0A3E509F0A3E4F090F6297401F0A3E43B +:1057EB00F0740190F619F07F030206EA74F71206C3 +:1057FB008A90F612E06404701290F62BE06401704C +:10580B000A90F631E07002A3E06008740490F61978 +:10581B00F0805890F62DE0FB90F62FE0FA90F613FF +:10582B00E0F9124BE98A088B09A808A909E8FEE9F7 +:10583B00FFE87001E960D490F62FE0FA7903124A81 +:10584B00FD90F62DE0C0E090F62FE02414F8A3E0D5 +:10585B0034F6F988828983D0E0F0EEFAEFFB12542C +:10586B00F390F62FE0FA7904124AFD7F020206EA62 +:10587B00C082C08390F645E07002A3E0600E90F604 +:10588B0045E0F8A3E0F5838882120688745390F6FE +:10589B0035F074BE90F636F074FC90F637F0744326 +:1058AB0090F638F074BE90F639F0740190F63AF039 +:1058BB00747590F63BF0748790F63CF0740190F69B +:1058CB003DF074E590F63EF0742590F63FF0747061 +:1058DB0090F640F074F390F641F0742290F642F09B +:1058EB00758900C2C5D2BD90F6437435F0A374F62A +:1058FB00F0758235F58312068890F647E07002A3A7 +:10590B00E0600E90F647E0F8A3E0F583888212067C +:10591B0088D083D08222C082C083E490F63AF09084 +:10592B00F63BF090F63CF090F63DF0D083D082221F +:10593B0074F512068A8A088B098C0A8D0BE490F693 +:10594B0075F090F676F090F677F090F649780812AD +:10595B00053AE490F64DF090F64EF0740890F64F41 +:10596B00F090F650E4F0A3F0740190F652F0124C64 +:10597B003A7AFF7BFF124FB353F4FDD29143FE02F1 +:10598B00120A1F7F040206EAC082C0831259AB9031 +:10599B00F652E06006125A5A1259F6D083D0822280 +:1059AB00A823E85404600E782374FB56F60874FFA2 +:1059BB0056F6124C6EA823E85410600E782374EF41 +:1059CB0056F60874FF56F6124C91A823E8A2E05045 +:1059DB0019782374FE56F60874FF56F612587B7826 +:1059EB002374FD56F60874FF56F62274F612068AD7 +:1059FB00120A2290DE0EE090F678F0740490DE0E20 +:105A0B00F090DE11E0A2E0403690F677E060307562 +:105A1B0008537509F6750A0078081207D190F655E8 +:105A2B00E0F97A287BDE124F797403120649E49071 +:105A3B00F677F0740490DE0EF0740190DE11F090A6 +:105A4B00F678E090DE0EF0120A1F7F030206EA746E +:105A5B00F612068A7E00120A2290DE0EE090F6788D +:105A6B00F0740490DE0EF090DE14E0A2E04003022E +:105A7B005B0990DE16E0FF90DE17E0742090FA31A0 +:105A8B00F090F675E0F8EF28F8E43400F9E894218B +:105A9B00E994004002E4F0E02453F508E434F6F511 +:105AAB00098E0A78081207D1EFF97A287BDE124F9C +:105ABB003F740312064990F675E02FF0740490DEE4 +:105ACB000EF0E490DE14F090F675E0C394024005FE +:105ADB0090F655E0FE8E0874FF2508F874FF34002D +:105AEB00F990F675E0FAC3E89AE99400A2D265D072 +:105AFB0033500BEEC394034005120C21E4F090F6E7 +:105B0B0078E090DE0EF0120A1F7F030206EAC082D5 +:105B1B00C08375910075E90075C6B874D390DF002A +:105B2B00F0749190DF01F0741290DF07F0E490DFD6 +:105B3B0008F0742490DF09F0743A90DF0AF074EEE9 +:105B4B0090DF0BF0E490DF06F0748C90DF2EF07496 +:105B5B001D90DF0CF0745590DF0DF0741390DF0E79 +:105B6B00F0742390DF0FF0741190DF10F0746390DA +:105B7B00DF11F074B690DF1AF0741090DF1BF07425 +:105B8B001890DF14F0743C90DF13F0740790DF1261 +:105B9B00F075A48775A36B75A2F8741D90DF15F0D3 +:105BAB00741C90DF16F074C790DF17F0E490DF18C9 +:105BBB00F074B090DF19F074EA90DF1CF0742A9047 +:105BCB00DF1DF0E490DF1EF0741F90DF1FF074599F +:105BDB0090DF20F0748890DF23F0743190DF24F095 +:105BEB00740990DF25F0747F90DF21F0748890DFCB +:105BFB0022F0742990DF2FF0741E90DF30F0741BAD +:105C0B0090DF31F0740690DF03F0744590DF04F001 +:105C1B0074CA90DF05F074FE90DF02F0D083D0825F +:105C2B002274F712068AE5E9FA90F979E0640260CA +:105C3B000575E900804574505A6450702E53E9EF96 +:105C4B0053E9BF539BFCE59B125D3D7508FF75093E +:105C5B000078081207D57C007D007A787BF8126AF1 +:105C6B003F7402120649125CC7801053E910E5E934 +:105C7B00539BFCE59B740190F876F07F020206EAD9 +:105C8B00C082C083E9701190F871E4F0A3F090F832 +:105C9B0073F0A3F090F875F0D083D08222C082C04D +:105CAB0083E9701390F871E4F0A3F090F875F0901D +:105CBB00F873EAF0A3EBF0D083D0822274F71206CC +:105CCB008A74F890F97DF0747890F97EF074DF9017 +:105CDB00F97BF074D990F97CF090F97FE054E044B3 +:105CEB0001F0E490F980F0748190F97FF0741290D8 +:105CFB00F982F0741390F981F075D6817508FF75F0 +:105D0B00090078081207D57C007D007A787BF812A1 +:105D1B006A3F740212064943D601539BFCE59B5321 +:105D2B00E9EF740290F979F075E102439110FF02EB +:105D3B0006EAC082C0835391EF740190F979F07534 +:105D4B00E10490DF3BE0640170F875D68153D1FE1E +:105D5B00539BFCE59B53E9EFD083D0822274F8125E +:105D6B00068AEAFEEBFF125D3D74DF90F97DF0745D +:105D7B00D990F97EF0EF90F97BF0EE90F97CF090F2 +:105D8B00F97FE054E04401F0E490F980F074219045 +:105D9B00F97FF0744290F982F0741390F981F0431B +:105DAB00D601740490F979F075E103E5E9A2E450AA +:105DBB00FA53E9EF125D3D79017F010206EA74F8AF +:105DCB0012068A790090F876E064016003025E5E49 +:105DDB00E4F090F879E0707B90F878E0247AF58223 +:105DEB00E434F8F583E0A2E750697E017D00802161 +:105DFB008D82AA82EA247CF582E434F8F583E0FCF8 +:105E0B00EA2435F582E434FAF583E06C60027E0017 +:105E1B000DEDC3940440D9EE603990F87AE090F917 +:105E2B007AF0E090FA3BF0740190FA3DF0FA7B00C7 +:105E3B00125CA890F875E060FA7900125C8BD29036 +:105E4B0079047A3A7BFA125D68C2907901740290F8 +:105E5B00F67AF07F010206EAC082C08390F97AE0FD +:105E6B0090FA3FF090F877E090FA43F07AB87B0124 +:105E7B007900125CA890F773E06404600690F875E3 +:105E8B00E060F290F773E06404600990F67AE0D278 +:105E9B00E5025F247900125C8BD29079067A3E7B07 +:105EAB00FA125D68C290125CC77AB87B0179001256 +:105EBB005CA890F875E0700890F876E0640170F2D9 +:105ECB007900125C8B125D3D90F876E06401704AAC +:105EDB0090F878E0247AF582E434F8F583E0548086 +:105EEB00FBE490F876F090F879E064CA702C90F8A7 +:105EFB007AE0FA90F97AE06A702090F87BE064011E +:105F0B007018EB6015E490F877F0740190F987F056 +:105F1B0090F773F0740890F67BF0D083D08222C098 +:105F2B0082C08390F986E090F777F090F985E09046 +:105F3B00F778F090F97AE090F775F07AB87B017901 +:105F4B0000125CA890F773E06404600690F875E0AB +:105F5B0060F290F773E06404600990F67AE0D2E5A2 +:105F6B000260477900125C8BD29090F774E004F9D1 +:105F7B007A747BF7125D68C290125CC77AB87B01AA +:105F8B007900125CA890F875E0700890F876E064E0 +:105F9B000170F2125D3D7900125C8B90F876E06433 +:105FAB0001600302604890F878E0247AF582E434CB +:105FBB00F8F583E05480FBE490F876F090F879E004 +:105FCB0064CA707990F87AE0FA90F97AE06A706DA9 +:105FDB0090F87BE06401706590F87CE0FA90F986AC +:105FEB00E0547F6A705790F87DE0C0E090F985E04F +:105FFB00F8D0E0687047EB6044E490F877F090F9E4 +:10600B0085E02401F0A3E03400F090F985E0F8A3DB +:10601B00E0F9E875F064A4F8AAF075F064E9A42A35 +:10602B00F990F983E0FAA3E0FB1205B8E890F97751 +:10603B00F0740890F67BF0740190F773F0D083D076 +:10604B008222C082C08390F877E004F0E0C394060C +:10605B00400D90F67AE0D2E5F0E0D2E2F0802990A4 +:10606B00F987E07005125E63801E90F985C082C0CF +:10607B008390F983E0F8A3E0F9D083D082C3E09852 +:10608B00A3E0995003125F2AD083D08222C082C032 +:10609B0083E490F877F090F977F0740190F67AF04A +:1060AB0090F67BF090F985E4F0A3F090F983F0A3E0 +:1060BB00F0740190F773F0E490F987F090F876F0B4 +:1060CB00D083D08222C082C08374F9F5D575D47B7E +:1060DB0012609874FC90F774F074CA90F776F074B1 +:1060EB000190F67AF0C2A8439A01C290E490F67937 +:1060FB00F090F977F0125D3D806090F985C082C019 +:10610B008390F983E0F8A3E0F9D083D082C3E098C1 +:10611B00A3E099400690F987E0701712604D7A0161 +:10612B007B007900125CA890F875E060FA79001298 +:10613B005C8B90F978E0701B90F985C082C08390DE +:10614B00F983E0F8A3E0F9D083D082C3E098A3E011 +:10615B0099400790F67AE0D2E5F090F679E0702A54 +:10616B00125CC7125DC9E964017017740290F67A6C +:10617B00F090F679E004F0740490F67BF0125D3D3C +:10618B00800890F67AE0A2E550D990F67AE0A2E585 +:10619B004003026105C2A8539AFE5391EF75E900C3 +:1061AB00125D3DE490F679F07A2C7B01F9125CA834 +:1061BB0090F875E060FA7900125C8BD083D0822264 +:1061CB00C082C08374B290DF01F0743790DF00F0AF +:1061DB00740A90DF02F0740090DF03F0740090DF1C +:1061EB0004F0740090DF05F0740090DF06F0741279 +:1061FB0090DF07F0740090DF08F0742490DF09F053 +:10620B00742D90DF0AF0745590DF0BF0743D90DF26 +:10621B000CF0745590DF0DF0741590DF0EF07412C6 +:10622B0090DF0FF0741190DF10F0746090DF11F0BD +:10623B00740790DF12F0740090DF13F0741890DF86 +:10624B0014F0741D90DF15F0741C90DF16F074C7FA +:10625B0090DF17F0741090DF18F074B290DF19F024 +:10626B0074B690DF1AF0741090DF1BF074EA90DFB5 +:10627B001CF0742A90DF1DF0740090DF1EF0741F69 +:10628B0090DF1FF0740090DF2FF0740090DF30F080 +:10629B00740090DF31F0743190DF24F075E10475F8 +:1062AB00E10190DF3BE0640170F8D083D08222C023 +:1062BB0082C08390DF1CE0442090DF1CF074C690FA +:1062CB00DF2EF075E10475E10190DF3BE0640170B6 +:1062DB00F890DF1CE054CFF075E104D083D082221C +:1062EB0074F712068AE990DF06F07A00EAC3940A83 +:1062FB00501E8A08750900E508249BF582E50934D0 +:10630B00F9F583E0C0E074282AF8D0E0F60A80DCC7 +:10631B00753200D29074FE559AFA8A9AC2A8C28935 +:10632B00539BFCE59B75E900D2A87401459AFC8C44 +:10633B009A740090FA44F075E1037F020206EAC0FA +:10634B0082C083C290C2A874FE559AFA8A9A7401CD +:10635B0090FA44F075E104D083D0822212634A2272 +:10636B007A007B0075320074282532F8E6F5D905E2 +:10637B0032E532C3940A502BEAF8EBF9740128FA90 +:10638B00740039FBC3E89488E994135016A2895022 +:10639B00E074282532F8E6F5D90532C2897A007BFC +:1063AB000080CEC3EA9488EB94134005C28975E94B +:1063BB00002274F812068AE5E9FEEEA2E750027E8F +:1063CB0000EEA2E45009740190FA44F01263677571 +:1063DB00E9007F010206EA74F512068A1261CB12FC +:1063EB0062BA90F9B2780812052B90F98E780812E0 +:1063FB00053A740090F992F07F040206EA74F712E2 +:10640B00068A740090F99AF0740090F999F0740070 +:10641B0090F998F0E5E3F8E4C8F990F995E8F0A362 +:10642B00E9F085E20875090090F995E04508F0A3BD +:10643B00E04509F090F995E024A4F0A3E03400F0D6 +:10644B0090F995E0FAA3E0FB1249D7124A137F02A9 +:10645B000206EAC082C083124A2212634A74009079 +:10646B00F99AF0D083D0822274F512068A8A088BAF +:10647B00098C0A8D0B90F98A780812053A7F040271 +:10648B0006EA74F512068AC0A8C2AF8A088B098C7B +:10649B000A8D0B90F98E780812053AE990F992F073 +:1064AB00D0A87F040206EA74F512068A90F999E0E7 +:1064BB001208170102C8647465CC65246690F993C1 +:1064CB00E02400F0A3E03470F012687490F99AE0C5 +:1064DB00D2E1F090FB51E0C39401A2D265D03350CE +:1064EB002890FA45780812052B90F98E780812053A +:1064FB001890FB51E06488700990F99AE0D2E0F0B3 +:10650B00800790F99AE0C2E0F012666E740790F97A +:10651B0097F075080075090878081207D590F98A65 +:10652B00780812052BAA08AB09AC0AAD0B90F998A9 +:10653B00E0F912676A74021206498A088B09A808E7 +:10654B00A90990F993E0C398F8A3E099F990F98819 +:10655B00E8F0A3E9F090F988E0FAA3E0FB1249D741 +:10656B00740190F999F002664A740090F997F075EE +:10657B00080075090278081207D590F98A78081275 +:10658B00052BAA08AB09AC0AAD0B90F998E0FE7489 +:10659B0080C39EF912676A74021206498A088B0936 +:1065AB00A808A90990F988E028F8A3E039F9740044 +:1065BB0028FA740239FB1249D7740290F999F080CA +:1065CB007E740190F997F075088075091C78081294 +:1065DB0007D590F98A780812052BAA08AB09AC0AE3 +:1065EB00AD0B90F998E0FE7440C39EF912676A7484 +:1065FB00021206498A088B09A808A90990F993E0A9 +:10660B0028F8A3E039F9740028FA740639FB12490B +:10661B00D7740390F999F0802612687390F99AE079 +:10662B00C2E1F090F998E02401F090F993E024B8DE +:10663B00FAA3E03466FB1249D7740090F999F07F06 +:10664B00040206EAC082C08390F99AE0A2E15008E6 +:10665B0090F997E0F91262EB1264B2124A30D083D0 +:10666B00D0822274F112068A90F99BC082C083906B +:10667B00FA49780812052BD083D08278081204F2DD +:10668B0090F98AC082C08390FA4D780C12052BD0FA +:10669B0083D082780C1204F27808790C12050590DD +:1066AB00F99B780812053A90F99BC082C08390FA47 +:1066BB004D780C12052BD083D082780C1204F290FB +:1066CB00F998E0F508E4F509F50AF50B7418780864 +:1066DB001204AD780C790812050590F99B780C1211 +:1066EB00053A90F99F780812052B90F98E780C12C9 +:1066FB00052B90F99F780C12053A90F992E090F9DE +:10670B00A3F07A9B7BF9126722E9FA74216A90F95C +:10671B00A4F07F080206EA74F812068A79007D005D +:10672B00EDC3940950348A828B83E0FE7C00ECC36A +:10673B009408501AE96EC394804008E9C3336497F8 +:10674B00F98004E9C333F9EEC333FE0C80E08A828F +:10675B008B83A3AA82AB830D80C67F010206EA74EA +:10676B00F112068A74FE120633E9FF8A0C8B0D8C2C +:10677B000E8D0F7CFF7D7F851082851183E50CF0DC +:10678B00AE0D850C08850D09850E0A850F0B74104F +:10679B007808120494740112067EE508F08F0875D0 +:1067AB000900E5082451F582E50934FAF583E0F890 +:1067BB00851082851183E0F508E50868F8E4C8F9CF +:1067CB008F0A750B008E08750900E508650AF50838 +:1067DB00E509650BF509E5082451F582E50934FA5D +:1067EB00F583E0F508750900E50828F8E50939F99E +:1067FB00851082851183E0F50AE4C50AF50B8E0836 +:10680B00750900740112067EE0F582758300E5823E +:10681B004508F508E5834509F509E508250AF50856 +:10682B00E509350BF509E50868F8E50969F9E8FAB2 +:10683B00E9FB741112067EC3E09AA3E09B500FECA8 +:10684B005AFAED5BFBEDC313FDEC13FC80E4740211 +:10685B001206497F080206EA43FE01C29012686CD9 +:10686B00221263E2126408222274F112068A74FC6B +:10687B0012063390F9A8E02400F0A3E03470F090F6 +:10688B00F9A8C3E09400A3E09480400C90F9A8E031 +:10689B002400F0A3E03480F090FB52E0FE90F9A5C9 +:1068AB00E0F50CE4F50DF50EF50F7410780C1204F1 +:1068BB00AD90F9A6E0F508A3E0F509E4F50AF50BB0 +:1068CB00780C79081204CC851082851183780C1210 +:1068DB00053AEEF9851082851183780812052BAAEB +:1068EB0008AB09AC0AAD0B12648D74041206497F18 +:1068FB00080206EA74F812068A740812067EE0F89B +:10690B00A3E08015A3AA82AB838C828D83A3AC8278 +:10691B00AD83E824FF18E934FFF9E87001E960243E +:10692B008A828B83E0FE8C828D83E06E8A828B83DE +:10693B0060D2E0F88C828D83E0FAE8C39AFAE49493 +:10694B0000FB80047A007B007F010206EA74F712D9 +:10695B00068A740912067EE0FEA3E0FFEAF8EBF963 +:10696B0080188C828D83E088828983F0A3A882A90A +:10697B00838C828D83A3AC82AD838E088F0974FFC9 +:10698B0025081E74FF3509FFE5087002E50970D272 +:10699B007F020206EA74F712068A740912067EE079 +:1069AB00F8A3E0F9EAFEEBFF8A088B09C3EA9CEB3C +:1069BB009D405EEC28F582ED39F583C3E5829508A1 +:1069CB00E5839509404BEA28FAEB39FBAC82AD83A2 +:1069DB00126A2E7002E5096041EC24FF1CED34FFB6 +:1069EB00FDEA24FF1AEB34FFFB8C828D83E08A8255 +:1069FB008B83F080DB8C828D83E08A828B83F08C9F +:106A0B00828D83A3AC82AD838A828B83A3AA82AB54 +:106A1B0083126A2E7002E50970DBEEFAEFFB7F0240 +:106A2B000206EA8808890974FF25081874FF3509DE +:106A3B00F9E5082274F812068A740812067EE0F84B +:106A4B00A3E0F98A828B838003ECF0A3E8FEE9FFD5 +:106A5B0074FF2E1874FF3FF9EE7001EF70EB7F019E +:036A6B000206EA36 +:04000005000000E90E +:00000001FF diff --git a/chronos-ti/Recovery/RF Access Point/Recovery_eZ430-Chronos_AP_915MHz_1_2.hex b/chronos-ti/Recovery/RF Access Point/Recovery_eZ430-Chronos_AP_915MHz_1_2.hex new file mode 100755 index 0000000..5ec2614 --- /dev/null +++ b/chronos-ti/Recovery/RF Access Point/Recovery_eZ430-Chronos_AP_915MHz_1_2.hex @@ -0,0 +1,1718 @@ +:020000040000FA +:060000000200E90211D923 +:03000B0002127965 +:030013000212884E +:03001B0002129737 +:030023000212A620 +:03002B000212B509 +:0300330002500375 +:03003B000212C4EA +:030043000212D3D3 +:03004B000211F9A6 +:030053000212E2B4 +:030063000212275F +:03006B000250A898 +:030073000212F185 +:03007B000213006D +:030083000211A3C4 +:10008B0002130F00000080FB1200F8B900030200FE +:10009B00E3E479217812B800028004F709D8FCE474 +:1000AB0090F3FF78AC79068002F0A3D8FCD9FA90D4 +:1000BB00F9AAAA82AB839000FB78AA79028015E497 +:1000CB0093A3AC82AD838A828B83F0A3AA82AB838A +:1000DB008C828D83D8E9D9E7120A2512008E75D050 +:1000EB000075814F7510FF7511F302009379012292 +:1000FB0087D6120000C201000000000001000000C2 +:10010B00F1490200FFFFFFFF1432506E0E278BFFE9 +:10011B0000000001000000000000000000000000D3 +:10012B0000000000000000000000000000000000C4 +:10013B0000000000000000000000000000000000B4 +:10014B00B242873F183B0543FC34B4407856341019 +:10015B00020101010008070605040302010055AA6C +:10016B0055AA55AA55AA556CDC0200A402470347B1 +:10017B0003470347034F03200700CABA5EBA1109AE +:10018B000300CA000500CA000000010001000000C6 +:10019B000000FFFFFFFF0001804020100884422178 +:1001AB009048A45229140A85C261B058ACD66B355D +:1001BB009ACD6633994CA653A9542A95CAE5F27980 +:1001CB003C9ECF67B3D96CB65B2D160B058241A055 +:1001DB005028944AA5D269341A8D462391C8E472EB +:1001EB00391C8EC7E3F1F8FCFEFF7F3F1F0F07831F +:1001FB00C1E070389CCEE7F3F97CBEDF6F379B4DC7 +:10020B0026138944221188C4623198CCE673B95CF9 +:10021B00AED7EB75BADD6EB7DB6D361B0D06038102 +:10022B00C06030188CC663B1D8ECF67B3D1E8F478F +:10023B00A3D1E8F47ABD5EAF57AB55AAD5EAF5FA70 +:10024B00FD7EBF5F2F178B45A251A8D46AB5DAED9F +:10025B00763B1D0E87C3E1F078BCDEEF77BB5D2EDE +:10026B0097CB65B2592C964B25924924120904025F +:10027B000180402010088442219048A45229140A7E +:10028B0085C261B058ACD66B359ACD6633994CA606 +:10029B0053A9542A95CAE5013C1201100102000032 +:1002AB00205104A6160900010203010902430002B2 +:1002BB00010080190904000001020201000524005D +:1002CB00100104240202052406000105240100018B +:1002DB000705820340004009040100020A000000E8 +:1002EB0007058402400001070504024000010403D6 +:1002FB00090424035400650078006100730020009A +:10030B0049006E0073007400720075006D0065008B +:10031B006E00740073001E03430043003100310074 +:10032B0031003100200055005300420020004300F3 +:10033B00440043000803300030003100BF020000CE +:10034B00E2020000E066701008A3E066700A08A3E2 +:10035B00E066700408A3E06622C3E09608A3E0966B +:10036B0008A3E09608A3E09622BB0102E722C08215 +:10037B00C08389828A83BB0003E08002E493D0832D +:10038B00D08222BB000EC082C0838A838982F0D0C8 +:10039B0083D08222BB0101F722080808EAC0E0EBF8 +:1003AB00C0E086F0E7A4FA180986F0E7A42AFA1849 +:1003BB000986F0E7A42AFA180986F0E7A42AFA19A5 +:1003CB0086F0E7A4FBE5F02AFA190886F0E7A42BE0 +:1003DB00FBE5F03AFA190886F0E7A42BFBE5F03AB7 +:1003EB00FA18180986F0E7A4C5F02BFBE43AFA19C2 +:1003FB0008E7C5F0C6A426F6E5F03BFBE43AFA188D +:10040B0086F0E7A4F6E5F00826F6E43B08F6E43AB6 +:10041B0008F6D0E0FBD0E0FA22E4CFC0E0E4CEC097 +:10042B00E0E4CDC0E0E4CCC0E075F020C3E633F6E9 +:10043B0008E633F608E633F608E633F6181818EC38 +:10044B0033FCED33FDEE33FEEF33FFC3EC9709EDD9 +:10045B009709EE9709EF97191919400FFFEC97FCC5 +:10046B0009ED97FD09EE97FE191906D5F0BEECF7CD +:10047B0009EDF709EEF709EFF7191919D0E0FCD0E0 +:10048B00E0FDD0E0FED0E0FF226016080808C6C3EE +:10049B0013C618C613C618C613C618C613C6D5E09E +:1004AB00EA227009080808226016181818C6C33308 +:1004BB00C608C633C608C633C608C633C6D5E0EA77 +:1004CB0022E627F60809E637F60809E637F60809A3 +:1004DB00E637F622E026F608A3E036F608A3E03668 +:1004EB00F608A3E036F622E056F608A3E056F60827 +:1004FB00A3E056F608A3E056F622E647F60809E60F +:10050B0047F60809E647F60809E647F622E046F003 +:10051B0008A3E046F008A3E046F008A3E046F0226B +:10052B00E0F608A3E0F608A3E0F608A3E0F622E65F +:10053B00F008A3E6F008A3E6F008A3E6F022CAC091 +:10054B00E0E6F0A308DAFAD0E0FA22CAC0E0E0A3B2 +:10055B00C582CCC582C583CDC583F0A3C582CCC56E +:10056B0082C583CDC583DAE6D0E0CA22C3E498F80E +:10057B00E499F91205B88026C3E49AFAE49BFBE9E7 +:10058B0020E7E91205B8E498F8E499F922C3E49856 +:10059B00F8E499F91205B8E498F8E499F9C3E49AE8 +:1005AB00FAE49BFB22EB20E7CFE920E7E0B9001050 +:1005BB00BB0008E88AF084F8AAF022E4FBC8FA2210 +:1005CB00EB70227B10C833C8C933C9335007C39AA9 +:1005DB00C3DBF280069A50012ADBEAC833F4C8C9A0 +:1005EB0033F4C9FA2275F008E4C833C8C933C933E8 +:1005FB00C99AC99B5004C92AC93BD5F0ECFBC83337 +:10060B00F4C8E4C9FA22600C08C6C313C618C61393 +:10061B00C6D5E0F422700422600D18C6C333C60899 +:10062B00C633C6D5E0F41822251010AF08F51040DC +:10063B000215118008F51040021511D2AF22C0D05F +:10064B00251010AF08F510500205118008F5105059 +:10065B00020511D2AFD0D0222510F58210AF08F5CC +:10066B0010400215118008F51040021511D2AF850C +:10067B001183222510F582E43511F58322E47325CD +:10068B0010C582C0E0E51134FFC583C0E0E510C39F +:10069B00958224F9F8E4C5A8858311858210C5A835 +:1006AB00E8CEF0A3E520F0A37808E608F0A3DEFA85 +:1006BB00EFF0A3E58124FBF8E608F0A3E608F0A32E +:1006CB000808E608F0A3E608F0A315811581D0E031 +:1006DB00FED0E0F815811581E8C0E0EEC0E0228580 +:1006EB001183851082E0A3FEE0A3F5207808E0A338 +:1006FB00F608DFFAE0A3FFE0A3C0E0E0A3C0E0E070 +:10070B00A3C0E0E0A3C0E0E4C5A8858210858311F7 +:10071B00C5A8D083D08222C0D02510C582C0E0E509 +:10072B001134FFC583C0E0E510C3958224F310AFED +:10073B00088583118582108008858311858210D2EC +:10074B00AFC8F0A3E9F0A3EAF0A3EBF0A37908E7B5 +:10075B0009F0A3D8FAECF0A3EDF0A3EEF0A3EFF0C1 +:10076B00A3D0E0F0A3D0E0F0A3D0E0F0A3E520F01D +:10077B00A3E5F0F0A322851183851082E0C0E0A3EE +:10078B00E0F9A3E0FAA3E0FBA37808E0F608A3DF07 +:10079B00FAE0FCA3E0FDA3E0FEA3E0FFA3E0C0E0D2 +:1007AB00A3E0C0E0A3E0F5D0A3E0F520A3E0A3F520 +:1007BB00F0E4C5A8858311858210C5A8D082D083AB +:1007CB00D0E0F8D0E0327403800474028000C0E003 +:1007DB00F404120663D0E0120549227403800474FA +:1007EB00028000CCC0E0EDC0E0E510C39CCCAD11A5 +:1007FB0050011D10AF068C108D1180068C108D11C1 +:10080B00D2AF120556D0E0FDD0E0FC22D083D082CF +:10081B00C5F0E493A3C5F0C395F0F5F0E493A3C33F +:10082B0095F04005E5F0048001E475F002A4258203 +:10083B00F582E5F03583F583E493A3C0E0E493C040 +:10084B00E022D083D082CCC0E0E493A360061208F0 +:10085B00771470FAE493A360061208961470FAD01A +:10086B00E0FCE493A3C0E0E493C0E022C0E0E49397 +:10087B00A3D39C5010E493A3C39C400AD0E0D0E0D8 +:10088B00D0E002086AA3A3A3D0E022C0E0E493A3C4 +:10089B006C7009D0E0D0E0D0E002086AA3A3D0E0EE +:1008AB002253CBEFC2D843CB0475F00CEAA4F5CDA1 +:1008BB0074FC55CB4402F5CB43CB10A2D850FC5360 +:1008CB00CBEFC2D822C082C08353A8C0E5A853B8CF +:1008DB00F0E5B8539AC2E59A7422C0E0740755C686 +:1008EB00F8D0E0B800028004C313D8FCF5AB7475E4 +:1008FB0090FC00F074AE90FC01F0740290FC02F0DE +:10090B00E490FC03F090FC04F0747490FC05F0741C +:10091B00FF90FC06F074F590FC07F074AF90FC08A8 +:10092B00F0E490FC09F090FC0AF0747490FC0BF06E +:10093B0074FF90FC0CF074F590FC0DF074AF90FC10 +:10094B000EF0E490FC0FF090FC10F074E590FC11AD +:10095B00F074AE90FC12F0745490FC13F074409051 +:10096B00FC14F0747090FC15F074FA90FC16F07493 +:10097B002290FC17F0740190F3FFF0D083D0822209 +:10098B00C082C0838A828B83E493F9D083D0822286 +:10099B00C082C0838A828B83E493F9A3E4932400FF +:1009AB00FAE439FBD083D0822274F712068AECFE6C +:1009BB00EDFF740912067EE0FCA3E0FD74326C704F +:1009CB000374576D600479008045C2AFE5AEA2E7B2 +:1009DB0040FA8A088B0974097808120611E508F5A4 +:1009EB00ADEAFCEBC313EC13F5ACEF90FC06F0EEA9 +:1009FB0090FC0CF012FC00D2AFE9601112099B8A3B +:100A0B00088B09EE65087003EF650970B979017FF2 +:100A1B00020206EAD2AF22C2AF22750C00750D009E +:100A2B007E0043FE01D29043FE10C29443FD3FE58E +:100A3B00FD43FEE0E5FE43FF19E5FF53BEF8E5BEBF +:100A4B0000746055BE60FA780079008008E82401D4 +:100A5B0008E93400F9C3E89420E9944E40EF53C6FB +:100A6B00BF53C6C0E5C643C638E5C6746055BE6005 +:100A7B00FA780079008008E8240108E93400F9C30A +:100A8B00E89420E9944E40EF90F9AA780812052BD0 +:100A9B00AA08AB09AC0AAD0B12647474FF90F4187E +:100AAB00F07AF07B7F12098BE9700C7AF27B7F1264 +:100ABB00098BE990F412F090F412E0C3941F4008F4 +:100ACB00E0C394E25002E4F043B933E5B943A92300 +:100ADB00E5A990F9AE780812052BAA08AB09AC0A68 +:100AEB00AD0B12593B800F125993E50C2401F50CF9 +:100AFB00E50D3400F50DC3E50C9420E50D944E4047 +:100B0B00E6C29075EC4475ED0475EBDED2BCD2AF4A +:100B1B00800E12115A740590F400F0E490F404F076 +:100B2B0090F404E0600C90F401E0700690F403E0A4 +:100B3B0060E090F402E0602990F60EE06008EE7041 +:100B4B000553EBEF7E0190F608E060D412666DEE74 +:100B5B006009E490F60EF0FE43EB10E490F608808B +:100B6B00BE90F405E0603490F403E0702ED290E474 +:100B7B0090F405F012111D740390F400F0740190C1 +:100B8B00F401F012131E740190F400F0E490F401E0 +:100B9B00F074FF90F418F0C290808590F406E0603A +:100BAB003D90F401E07037D290E490F406F0125BC4 +:100BBB0019740A90F400F0740190F403F01260D1F0 +:100BCB0090F67AE0A2E25004740B8002740C90F45D +:100BDB0000F0E490F403F074FF90F67C80B890F48E +:100BEB000DE07003020B2B90F40FE06003020B2B54 +:100BFB0090F40EE01208170102190C0C0C110C16D4 +:100C0B000C12434B800812486F80031248957401F5 +:100C1B0090F40F020B2A74F112068A90F653E064DB +:100C2B00FF600302111890F654E012084D001900F2 +:100C3B00A20C01A80C02BD0C03E10C04460D058DA2 +:100C4B000D06DA0C07B10D08D10D09900E0A970DA0 +:100C5B0020870C310D0E32480E33580E40990E4141 +:100C6B00D20E46C60E47F00E48D80E49E90E705804 +:100C7B0010718F1072C01073A8100C11741290F6B3 +:100C8B0059F0743490F658F0745690F657F0747817 +:100C9B0090F656F002110C90F400E080F3121187DD +:100CAB00E490F402F090F401F090F403F090F4006F +:100CBB0080E190F401E0600790F417E0D2E5F0904A +:100CCB00F402E0600302110C740190F40480C4126E +:100CDB001187740480D790F659E0F50875090075F3 +:100CEB000A00750B00741878081204AD90F658E0E2 +:100CFB00F50C750D00750E00750F007410780C1245 +:100D0B0004AD7808790C1204CC90F657E0F50C750D +:100D1B000E007408780C1204AD7808790C1204CC10 +:100D2B0090F656E0F50C750D007808790C1204CC92 +:100D3B0090F98A780812053A02110C90F98A780C0E +:100D4B0012052B850C08850D09850E0A850F0B7472 +:100D5B00187808120494E50890F659F0850C08856C +:100D6B000D09850E0AF50B74107808120494E5082A +:100D7B0090F658F0850D09E50990F657F0E50C0251 +:100D8B000C9B90F656E090FB52020C9E90F656E0B0 +:100D9B0090F9A5F090F658E0F990F657E090F9A687 +:100DAB00F0A3E9020C9E90F402E06003121187900D +:100DBB00F401E0600302110C740290F400F0740172 +:100DCB0090F405020C9E90F417E0A2E4502F90F4DF +:100DDB001BE090F659F090F41AE090F658F090F46E +:100DEB0019E090F657F090F418E090F656F074FF77 +:100DFB0090F418F090F417E0C2E4020C9E74FF021A +:100E0B000C9B90F401E0700302110C7A00801F8A96 +:100E1B0082A882E82456F582E434F6F583E0C0E03C +:100E2B00E82418F582E434F4F583D0E0F00AEAC341 +:100E3B00941340DB90F417E0D2E6020C9E90F4077B +:100E4B00E090F656F0740490F655020C9E90F40761 +:100E5B00E0602E7A00801F8A82A882E82418F5822F +:100E6B00E434F4F583E0C0E0E82456F582E434F68C +:100E7B00F583D0E0F00AEAC3941340DBE490F40767 +:100E8B00F0741680C290F417E0D2E5020C9E90F439 +:100E9B0002E0600312118790F401E0600790F417F1 +:100EAB00E0D2E5F090F403E0600302110C740990BA +:100EBB00F400F0740190F406020C9E90F67AE0D2E6 +:100ECB00E5F0C29002110C90F977020CA590F40397 +:100EDB00E0600690F67B020CA57480020C9B74F705 +:100EEB0090F65680A6740290F67BF090F773E06450 +:100EFB00016003020FD6E490F40AF090F655E0245B +:100F0B00FB90F409F090F656E090F40BF090F65746 +:100F1B00E0F50890F40BE07035E50890F77AF09067 +:100F2B00F658E090F77BF0F9E50890F983F0A3E928 +:100F3B00F090F983E090FA41F090F984E090FA4256 +:100F4B00F0740490F773F0E490F408020C9EE5083B +:100F5B0090F40CF090F40BE06401700474018002C7 +:100F6B00740290F779F090F40CE0240590F774F08C +:100F7B007A00801F8A82A882E82458F582E434F62E +:100F8B00F583E0C0E0E8247AF582E434F7F583D00A +:100F9B00E0F00AEAC0E090F409E0FBD0E0C39B402C +:100FAB00D3740290F773F090F409E090F408F0908A +:100FBB00F409E090F40AF0E0C0E090F40CE0FAD011 +:100FCB00E0C39A500302110C020F4CE06402600361 +:100FDB0002110C90F655E024FD90F409F07A008094 +:100FEB002B8A82A882E82456F582E434F6F583E056 +:100FFB00C0E090F408E0FCE82CF8E43400F9E824B5 +:10100B007AF582E934F7F583D0E0F00AEAC0E09094 +:10101B00F409E0FBD0E0C39B40C7E0FA90F408E092 +:10102B002AF090F409E0FA90F40AE02AF090F40820 +:10103B00E0C394F7509290F40AE0C0E090F40CE017 +:10104B00FAD0E0C39A500302110C020FD390F6575B +:10105B00E0F990F656E0F874AB68700374AB697006 +:10106B001C740190F40DF0E490F40EF0740190F404 +:10107B000FF0E490F402F090F401020C9EE490F473 +:10108B000D020C9E90F40DE0607790F410E4F0A349 +:10109B00F090F40FF090F40EE004020C9E90F40D1F +:1010AB00E0605E90F410E090F656F090F411E09052 +:1010BB00F657020C9E90F40DE0604690F656E0F564 +:1010CB000890F657E0FA90F658E0F9EAFEE9FF12BD +:1010DB0008D0EEFAEFFB12098BE964FF7023750A57 +:1010EB0032750B57780A1207D57900AB0874FF24B9 +:1010FB0000FCE43BFDEEFAEFFB1209B4740212069E +:10110B0049740190F677F0740690F654F07F08025C +:10111B0006EAC082C08375C6B074D390DF00F0744A +:10112B009190DF01F0740490DF03F0E490DF05F0A1 +:10113B0090DF06F0740790DF12F0E490DF2FF09051 +:10114B00DF30F090DF31F0759100D083D08222C078 +:10115B0082C08375C6B8439190E59175E25575E5EC +:10116B004475E402D2B91268AB90F412E090DF0838 +:10117B00F0740190F402F0D083D08222C082C0833D +:10118B0012645FC2B975E40075E255124899E49098 +:10119B00F402F0D083D08222C0E074F212072290C6 +:1011AB00F402E060051263BE801F90F401E060055D +:1011BB00121793801490F40DE0600512483D8009DE +:1011CB0090F403E06003125C2D7F01020781C0E005 +:1011DB0074F212072290F402E0600512636C80092E +:1011EB0090F40DE060031247307F01020781C0E0ED +:1011FB0074F2120722C2C153E40FE5E490F607E044 +:10120B00601590F608E0700F1248C3E97003740183 +:10121B00F090F60FE004F07F01020781C0E074F25A +:10122B0012072290F403E0603990F873E0F8A3E022 +:10123B00F9E87001E9602B90F871E02401F0A3E06C +:10124B003400F090F871E0687003A3E069701390BC +:10125B00F871E4F0A3F090F873F0A3F0740190F838 +:10126B0075F0C2DB1259937F010207810022C0E0A7 +:10127B0074F21207221212777F01020781C0E07409 +:10128B00F21207221212777F01020781C0E074F27B +:10129B001207221212777F01020781C0E074F2124B +:1012AB0007221212777F01020781C0E074F2120746 +:1012BB00221212777F01020781C0E074F21207221B +:1012CB001212777F01020781C0E074F2120722121B +:1012DB0012777F01020781C0E074F212072212120B +:1012EB00777F01020781C0E074F212072212127796 +:1012FB007F01020781C0E074F21207221212777F7E +:10130B0001020781C0E074F21207221212777F01EB +:10131B0002078174F112068A74FA12063390F9B23D +:10132B00780812052B740190F417F07AFD7B1412D8 +:10133B0027B97402C0E0740112067ED0E0F0AC82D3 +:10134B00AD837A0A7903122AA0C290805390F414C9 +:10135B00E0704D740212067E780812053A74021280 +:10136B00067EC082C08390F9B6780812052BD08315 +:10137B00D08278081204DF740212067EC082C0830A +:10138B0090F9BA780C12052BD083D082780C12030B +:10139B0064400D639001E59090F9B2780812052B2B +:1013AB0090F416E0603190F414E0702B7A137BF418 +:1013BB001227E6E970F6740290F417F0D29090F4CD +:1013CB0014E004F0A2AFE492E0FAC2AF90F416E09E +:1013DB0014F0EAA2E092AF90F415E070030214C887 +:1013EB00851082851183AC82AD837A387BF490F4BF +:1013FB0013E0F9122A36E960030214C885108285BE +:10140B001183E064047029639001E590750C0475F9 +:10141B000D00780C1207D57C387DF47A187BF4120A +:10142B0069A0740212064990F417E0D2E40214C7C3 +:10143B00E064026008E0641360030214C863900167 +:10144B00E59090F438E01208170102C8145E14936B +:10145B0014931490F417E0A2E65008E0C2E6F0747F +:10146B0013800E740190F418F0745590F419F07405 +:10147B0002851082851183F0E0FC7A187BF490F4DE +:10148B0013E0F912285C803590F407E0702F7A0096 +:10149B00801F8A82A882E82438F582E434F4F5832D +:1014AB00E0C0E0E82418F582E434F4F583D0E0F0F2 +:1014BB000AEAC3941340DB740190F407F090F4171D +:1014CB00E0A2E54003021358539AFE75910075E9AB +:1014DB0000E490F413F090F414F090F416F090F400 +:1014EB0015F090F5A1F0C29074061206497F080220 +:1014FB0006EAC082C083E9600590F415800390F47E +:10150B0016E004F07900D083D0822274F712068A99 +:10151B0075082175090078081207D57C007D007AC3 +:10152B00597BF4126A87740212064990DF36E05435 +:10153B00EF64016004C2AF80FE90DF37E0C3940319 +:10154B005004C2AF80FE53BEFBE5BEA2E650FA5379 +:10155B00C6BF43BE0474F4F5D575D480743C90DFDC +:10156B0013F0741490DF14F0741E90DF02F0740506 +:10157B0090DF04F0745090DF2EF0740990DF25F0AB +:10158B0090DF07F090F412E090DF08F0742590DF05 +:10159B0009F0749590DF0AF0745590DF0BF0746BC3 +:1015AB0090DF0CF074A390DF0DF0741390DF0EF04E +:1015BB00742390DF0FF0741190DF10F0744390DF01 +:1015CB0011F0741D90DF15F0741C90DF16F074C7CA +:1015DB0090DF17F0E490DF18F074B090DF19F0741F +:1015EB00B690DF1AF0741090DF1BF074EA90DF1CDA +:1015FB00F0742A90DF1DF0E490DF1EF0741F90DF73 +:10160B001FF0748190DF23F0743590DF24F07402A7 +:10161B0090F458F07900121B8D7E007F0075E1026B +:10162B0075081475090590DF3CE0545070237A401F +:10163B007B001219A5E50824C0F508E50934FFF570 +:10164B0009C3E5089401E5099400A2D265D0335093 +:10165B00D57A008013EEC333FEEF33FF90DF3AE011 +:10166B00A2E0E492E04EFE0AEAC3941040E77480D5 +:10167B004EF5BCEFF5BC12196090F47C7436F0A3F8 +:10168B00E4F090F47E74E2F0A37404F0439A01D278 +:10169B00AF7F020206EA74F712068AEAFEEBFF89B5 +:1016AB000975080090F458E064017004C2AF80FE25 +:1016BB00121960EF90F480F0EE90F481F074DF90EB +:1016CB00F482F074D990F483F0742090F484F07465 +:1016DB002190F485F0741390F486F0744190F487A4 +:1016EB00F0E509701143D60175E103E5E9A2E45079 +:1016FB00FA53E9EF8068740165096004C2AF80FE9C +:10170B007509048008121960121ACA150943D6010B +:10171B0075E10290DF3BE0640D70F87E147F05905D +:10172B00DF3CE05450701D7A407B001219A5EE246B +:10173B00C0FEEF34FFFFC3EE9401EF9400A2D2651D +:10174B00D03350DB75E10390DF3BE0640D6008E5BF +:10175B00E9A2E450FA809AE50970AA7508011219FA +:10176B006090F458E0640370031218D7A9087F0245 +:10177B000206EAC082C08390F459EAFCEBFD7421A7 +:10178B00120556D083D0822274F712068A90F45831 +:10179B00E064036004C2AF80FEE5E9A2E45035E5E6 +:1017AB00E9A2E6502F53E9EF53E9BF539BFCE59BAE +:1017BB0012196075081F75090078081207D57C008F +:1017CB007D007A597BF4126A87740212064912184B +:1017DB00D702186A53E9EF539BFCE59B750802751A +:1017EB00090078081207D590F459E0042459FCE459 +:1017FB0034F4FD7A787BF41269E87402120649E03E +:10180B00FA90F479E0A2E7503B8A0874012508F8B6 +:10181B00E43400F9E89420E99400C365D0335024F4 +:10182B00EAC3940B401E7A5A7BF4121BF5E9701431 +:10183B0090F478E0F9121B38E9F090F479E0C2E704 +:10184B00F0122D5E75081F78081207D57C007D00FD +:10185B007A597BF4126A87740212064943D6017FC8 +:10186B00020206EA74F812068A90F458E0640160EA +:10187B0013A2AFE492E0FEC2AF1219857401F0EE31 +:10188B00A2E092AF7F010206EAC082C083E5C6A246 +:10189B00E65004C2AF80FE90F458E06401702274ED +:1018AB00EA90DF1CF0742A90DF1DF0E490DF1EF04D +:1018BB00740290F458F075E10490DF3BE064017022 +:1018CB00F8D083D0822243B404A9BC2274F7120649 +:1018DB008A74DF90F480F074D990F481F074F490F2 +:1018EB00F482F0745990F483F0748090F484F07463 +:1018FB002190F485F0741390F486F0741190F487B2 +:10190B00F075D68175081F75090078081207D57C0C +:10191B00007D007A597BF4126A87740212064943E0 +:10192B00D601539BFCE59B53E9EF75E10243911004 +:10193B007F020206EAC082C08390F458E064017013 +:10194B0004C2AF80FEE0640360067403F01218D784 +:10195B00D083D08222C082C0835391EF75E1049073 +:10196B00DF3BE0640170F875D68153D1FE539BFCCD +:10197B00E59B53E9EFD083D08222C082C08390F4E1 +:10198B0058E064017004C2AF80FEE064037006127D +:10199B0019607402F0D083D0822274F712068A8AFF +:1019AB00088B0974047808120611AE08AF09EA70A7 +:1019BB0001EB6028A2AFE492E0F508C2AF7A107B8E +:1019CB00001208ACE508A2E092AFEEF8EFF974FF55 +:1019DB00281E74FF39FFE87001E970D87F020206F8 +:1019EB00EA74F712068A8A088B09740478081206BF +:1019FB0011AE08AF09EA7001EB602EA2AFE492E0E2 +:101A0B00F508C2AF7A107B001208ACE508A2E09291 +:101A1B00AF90F47AE07012EEF8EFF974FF281E74B1 +:101A2B00FF39FFE87001E970D27F020206EA74F811 +:101A3B0012068AEAFEEB800E7AF47B011219A5EEF0 +:101A4B0024FF1EEF34FFFFEE7001EF70EB7F0102FE +:101A5B0006EA74F812068A90F47CE0FEA3E0FFA27B +:101A6B00AFE492E0FAC2AF740190F47BF0EAA2E02B +:101A7B0092AF8008EE24FF1EEF34FFFFEE7001EFF4 +:101A8B00600D7AF47B011219EC90F47AE060E5A218 +:101A9B00AFE492E0FAC2AFE490F47AF090F47BF00A +:101AAB00EAA2E092AF7F010206EAC082C08390F403 +:101ABB007BE06006740190F47AF0D083D0822274BC +:101ACB00F812068A1218D1E9540F04FF7E00800C1D +:101ADB0090F47EE0FAA3E0FB1219A50EEEC39F4033 +:101AEB00EF7F010206EA74F812068A90F458E0645C +:101AFB00036004C2AF80FE7E147F0590DF3CE05490 +:101B0B0050701D7A407B001219A5EE24C0FEEF34F5 +:101B1B00FFFFC3EE9401EF9400A2D265D03350DBEC +:101B2B0090DF3AE0F9121B387F010206EAC008C0C9 +:101B3B0009E9C39480E94019F879FF7A027B001216 +:101B4B0005B08808890974B72508F874FF35098032 +:101B5B000BC313F874B728F874FF3400F9C3E89477 +:101B6B0080E994FFA2D265D03350027880E8F9D097 +:101B7B0009D00822C082C08390F458E0F9D083D0FA +:101B8B00822274F712068A8908E9C394044004C2BE +:101B9B00AF80FE121960E50824C2F582E434F9F532 +:101BAB0083E090DF06F090F458E0640370031218A2 +:101BBB00D77F020206EA74F712068A8908E9C394F2 +:101BCB00034004C2AF80FE121960E50824C6F582FB +:101BDB00E434F9F583E090DF2EF090F458E06403E1 +:101BEB0070031218D77F020206EA74F812068A9065 +:101BFB00F488E07004790080487E007D007C0080D2 +:101C0B002E8C82A882EA28F582EB3400F583E0FF64 +:101C1B00E824C9F582E434F9F583E06F70010EE82E +:101C2B0024BEF582E434F9F583E06F70010D0CEC02 +:101C3B00C3940440CC74046D60BB74046E60B679BD +:101C4B00017F010206EA74F712068AEAFEEBFF75C2 +:101C5B00082C75090078081207D57C007D007ACE18 +:101C6B007BF9126A877402120649740290F9CEF05E +:101C7B00743D90F9CFF0742090F9D0F0740190F985 +:101C8B00D1F01234FFEEFAEFFB122C0112244112A9 +:101C9B0034FB124232EEFAEFFB1237D512408712A9 +:101CAB003B5F12430490F9EEE070347402F074035E +:101CBB0090F9EFF0743F90F9F7F090F9F8F074FFAA +:101CCB0090F9F9F075080478081207D5123599EADE +:101CDB00FCEBFD7AF17BF91269A0740212064979CB +:101CEB00007F020206EAC082C0837B0080010BEBFF +:101CFB00C394025014EB75F00CA424E2F582E5F0CA +:101D0B0034F9F583E0640260E574026B70067A00C7 +:101D1B007B00801AEB75F00CA424E2F582E5F0341D +:101D2B00F9F583AA82AB83121D3EAA82AB83D083C3 +:101D3B00D08222C082C08374FF120633E48A828B66 +:101D4B0083A3A3A3A3A3A3A3A3A3A3F074028A8235 +:101D5B008B83F090F9D1E0C0E0EA240BF582EB34F1 +:101D6B0000F583D0E0F090F9D1E004F0E0F960F6F3 +:101D7B0074FF6960F1851082851183AA82AB83128F +:101D8B002284E970E17401120649D083D08222C00B +:101D9B0082C083E48A828B83F0D083D08222C0827C +:101DAB00C08374FF120633851082851183AA82AB20 +:101DBB0083122284E96014E075F00CA424E2F5820E +:101DCB00E5F034F9F583E0640260067582007583F3 +:101DDB0000AA82AB837401120649D083D08222748D +:101DEB00F312068A8A088B09890A7EE27FF97A0048 +:101DFB00800A7A01EE240CFEEF3400FFEA70478E66 +:101E0B00828F83E0640270EA750C04750D00780C08 +:101E1B001207D5AC08AD09EE2403FAEF3400FB1220 +:101E2B0069477402120649EA7001EB70C58E828F06 +:101E3B0083A3A3A3A3A3A3A3A3A3A3E0650A70B245 +:101E4B00EEFAEFFB80047A007B007F060206EA7A4B +:101E5B00D27BF92274F312068A8A0A8B0B7508005F +:101E6B007509007EE27FF97A00800E8E088F097A61 +:101E7B0001EE240CFEEF3400FFEA703D8E828F835F +:101E8B00E064026005E0640170E1750C04750D00FF +:101E9B00780C1207D5E50A2405FCE50B3400FDEEA2 +:101EAB002403FAEF3400FB1269477402120649EA65 +:101EBB007001EB70BA7900803AE5087002E50960B1 +:101ECB00F47401850882850983F0750C04750D0087 +:101EDB00780C1207D5E50A2405FCE50B3400FDE56B +:101EEB00082403FAE5093400FB1269A074021206F8 +:101EFB004979017F060206EA74F512068A8A088B75 +:101F0B00097EE27FF97A00800A7A01EE240CFEEF5B +:101F1B003400FFEA70418E828F83E0640170EA75B2 +:101F2B000A04750B00780A1207D5E5082405FCE5B1 +:101F3B00093400FDEE2403FAEF3400FB12694774F9 +:101F4B0002120649EA7001EB70BFEEFAEFFB121DAD +:101F5B003EEEFAEFFB80047A007B007F040206EA78 +:101F6B00C082C083E98A828B836001A3A3A3A3A34E +:101F7B00A3A3A3A3A3E0FCEC60078A828B83E0708E +:101F8B000479028008ECC3942040F67900D083D00A +:101F9B00822274F112068A8A0C8B0D8C0E8D0F7EA9 +:101FAB00E27FF98A828B83A3A3A3A3A3A3A3A3A3F7 +:101FBB00E0543FF509750800800A0508EE240CFE75 +:101FCB00EF3400FFE508C3940240030220998E8290 +:101FDB008F83E0640270E3A3A3A3A3A3A3A3A3A390 +:101FEB00E0650970D5743F6509602B750A04750BA4 +:101FFB0000780A1207D5E50C2405FCE50D3400FD2D +:10200B00EE2403FAEF3400FB1269477402120649FF +:10201B00EA7001EB70A4750801EE240BF582EF3426 +:10202B0000F583E0850E82850F83F0743F650960B0 +:10203B0056E50C240AF582E50D3400F583E0A2E7A2 +:10204B0050198E828F83A3A3A3A3A3A3A3A3A3A39C +:10205B00E0F9AA0CAB0D123115802CE0A2E350274E +:10206B00EE2402F8EF3400F988828983E0FAE50C5C +:10207B00240BF582E50D3400F583E06A7006E488E5 +:10208B00828983F0750800121AB5A90880027900BD +:10209B007F080206EA74F112068A74FF120633896E +:1020AB00088A0E8B0F7EE27FF9750A01750B00789B +:1020BB000A1207D57C007D00740212067EAA82AB41 +:1020CB0083126A8774021206497A00805D750C04CC +:1020DB00750D00780C1207D5E50E2403FCE50F34C3 +:1020EB0000FDEE2403FAEF3400FB12694774021271 +:1020FB000649EA7001EB70287401C0E0850A8285FD +:10210B000B83E0F8851082851183E58228F8E5833F +:10211B003400F974E028F58274FF39F583D0E0F0D0 +:10212B007A01EE240CFEEF3400FFEA7069E50E6EC7 +:10213B007003E50F6F60E98E828F83E0640270E0BD +:10214B00EE2409F50AEF3400F50B850A82F583E0DE +:10215B00C3943E50CB7401650860030220D890F9FC +:10216B00CFE0C0E0850A82850B83E0FAD0E0C39A0A +:10217B0050AE7401C0E0E0F8C3E498F8E49400F9C1 +:10218B00851082851183E58228F8E58339F9743D42 +:10219B0028F582E4808479007A0080027A01EA7063 +:1021AB0015851082851183E070F274026508700446 +:1021BB0079208002793D74026508701790F9CFE0A1 +:1021CB00C399400B90F9D0E0C399501FE9801B795C +:1021DB00008018E9C0E090F9D0E0FAD0E0C39A4053 +:1021EB00EE90F9CFE0697003E014F0E9850E82857B +:1021FB000F83A3A3A3A3A3A3A3A3A3F0740112060A +:10220B00497F080206EA74F512068AEAFEEBFF75AF +:10221B0008028C0AEE250AFAEF3400FB740C2AF53F +:10222B0082E43BF583E0A2E750488D08EE2508FADF +:10223B00EF3400FB740C2AF582E43BF583E0697004 +:10224B002E75080475090078081207D5123545EA72 +:10225B00FCEBFD8E828F83A3AA82AB83126947743A +:10226B0002120649EA7001EB7005750800800375D0 +:10227B000801A9087F040206EA74F812068A7CE2B8 +:10228B007DF97E0080090EEC240CFCED3400FDEE94 +:10229B00C3940250218C828D83E0640270E8EC249D +:1022AB000BF582ED3400F583E06970DAEE8A828BF0 +:1022BB0083F07901800279007F010206EA74F31240 +:1022CB00068A8A0C8B0D89097EE27FF975080080DE +:1022DB000A0508EE240CFEEF3400FFE508C3940258 +:1022EB0050478E828F83E0640270E6750A04750B8B +:1022FB0000780A1207D5EE2403FCEF3400FDAA0C7C +:10230B00AB0D1269477402120649EA7001EB70C1FA +:10231B008E828F83A3A3A3A3A3A3A3A3A3A3E065ED +:10232B000970AEEEFAEFFB80047A007B007F0602A9 +:10233B0006EAE9FB7900EA6B601FEBC39A500EEAE1 +:10234B00C394FD4006EBC39403400E0922EBC394E8 +:10235B00FD4006EAC3940340F22274F512068AECA0 +:10236B00FEEDFF890A890875090078081207D5EA7E +:10237B00FCEBFDEEFAEFFB1269E87402120649E57D +:10238B000A1208170202BF239923BF23AD238E82A3 +:10239B008F83E0F8A3E0F98E828F83E8F0A3E9F056 +:1023AB0080128E828F83780812052B8E828F837812 +:1023BB000812053A7F040206EA74F512068A74FACB +:1023CB00120633EAFEEBFFECFAEDFBE912081702FB +:1023DB0002E423EA23E4230624EEFCEFFD80388E8F +:1023EB00828F83E0FCA3E0FD851082851183ECF0E6 +:1023FB00A3EDF085108285118380188E828F8378F0 +:10240B000812052B740212067E780812053A740224 +:10241B0012067EAC82AD8389087509007808120715 +:10242B00D51269E8740212064974061206497F0434 +:10243B000206EA79022274F712068A7508D2750928 +:10244B000078081207D57C007D007A897BF4126A2C +:10245B0087740212064975084678081207D57C0066 +:10246B007D007A5B7BF5126A8774021206497F0244 +:10247B000206EA74F512068A7C007D007E007F005E +:10248B00780074016970097A897BF47509068007F5 +:10249B007A5B7BF575090274012509F50A880880BA +:1024AB000EEAFEEBFF0508EA2423FAEB3400FBE50A +:1024BB0008C3950950298A828B83E0601B740169DC +:1024CB0070E308E0640460DDA3E0C3950A50D6EA2C +:1024DB00FCEBFDE0F50A80CD74026970C48031EE2F +:1024EB007001EF701EEC7001ED70067A007B0080BE +:1024FB001FECFEEDFF8E828F83A3E0FA122520E501 +:10250B000880087401288E828F83A3F0EEFAEFFB0C +:10251B007F040206EAC082C083740169703A78892D +:10252B0079F4A2AFE492E0FDC2AF7B00801F8882FA +:10253B008983E0600FA3EAC0E0E0FCD0E0C39C50CD +:10254B0003E014F00BE82423F8E93400F9EBC3940F +:10255B000640DBEDA2E092AFD083D0822274F11261 +:10256B00068A74F61206338A0C8B0D8C09740412CE +:10257B00067EE4F0A3F0851082851183F0A3F0743E +:10258B000212067EE4F0A3F0740169702E7E897F3F +:10259B00F4750E078A828B83E064017052A3E0F915 +:1025AB00121DA9851082851183EAF0A3EBF085102B +:1025BB0082851183E07002A3E070077A007B000232 +:1025CB0027A0851082851183E0F8A3E0F58388822C +:1025DB00A3A3A3A3A3A3A3A3A3E0F50885108285BC +:1025EB001183E02403F8A3E03400F974088049E078 +:1025FB007006A3E0F5088048E0640270BEA3A882D1 +:10260B00A983E0240EFAA3E03400FB8A828B83E0DB +:10261B00F50888828983E02405FAA3E03400FB7473 +:10262B000812067EEAF0A3EBF088828983E0240F80 +:10263B00F8A3E03400F9740212067EE8F0A3E9F087 +:10264B007401650970057509018003750903750F20 +:10265B0000800FEAA2E092AF050FEE2423FEEF34C9 +:10266B0000FFE50FC394064003022796A2AFE49246 +:10267B00E0FAC2AF8E828F83E0650970D67404F0E6 +:10268B00EAA2E092AFEE240BF582EF3400F583E083 +:10269B00543F6508600302278E850C82850D83E00D +:1026AB0064017019743F6508700E85108285118363 +:1026BB00E02403F8A3E0800FEE24078008E0640217 +:1026CB007012EE2403F8EF3400F9740612067EE85C +:1026DB00F0A3E9F0750A04750B00780A1207D5749C +:1026EB000A12067EE0FCA3E0FD740812067EE0FAF7 +:1026FB00A3E0FB1269477402120649850C82850D13 +:10270B0083E06040740212067EE07002A3E0700367 +:10271B00EA6031740212067EE07002A3E060647816 +:10272B000A1207D5EE2407FCEF3400FD74041206E1 +:10273B007EE0FAA3E0FB1269477402120649EA70C5 +:10274B0001EB703F8E828F83A3AA82AB83E0C3958C +:10275B000E5030740412067EE07002A3E060107419 +:10276B000412067EE0F8A3E0F5838882E509F08A7F +:10277B00828B83E0F50E740412067EEEF0A3EFF06D +:10278B000226638E828F83E50980F4740412067E21 +:10279B00E0FAA3E0FB740A1206497F080206EA740A +:1027AB00016970057A897BF4227A5B7BF52274F8D8 +:1027BB0012068AEAFEEBFF90F5A1E07013121516D4 +:1027CB00EEFAEFFB121C51E9700C1218941219401F +:1027DB007401F0123A4F7F010206EA74F712068A6F +:1027EB008A828B83121B7FE9F509790012401574DD +:1027FB00036509600C7401650970031218941219B2 +:10280B00407E007F00800F7A0A7B00121A39EE247B +:10281B00010EEF3400FFC3EE94F4EF940150091254 +:10282B003FBCE9FA8A0860DF74036509600E740126 +:10283B006509700512186F8003121985E508700978 +:10284B00790112401579018003F079007F020206AD +:10285B00EA74F712068A75080075090078081207E2 +:10286B00D512287974021206497F020206EA74F126 +:10287B0012068A74FC120633740212067EEAF0A367 +:10288B00EBF089088C09741312067EE0FEA3E0FFBF +:10289B00121DA98A0C8B0D750B02121B7FE985107B +:1028AB0082851183F0750A00E50C7002E50D600F4F +:1028BB007901AA0CAB0D121F6BE9FA8A0B600302AC +:1028CB002A2A740212067EE07002A3E060F1E50989 +:1028DB00C3941450EAEE7001EF703D850C82850DA8 +:1028EB0083A3E0FDAC09740212067EE0FAA3E0FBC1 +:1028FB00850C82850D83A3A3A3A3A3A3A3A3A3A347 +:10290B00E0F9122C328A088B09AE08AF09EE700180 +:10291B00EF70627903022A2CEEA2E0505374FF652C +:10292B0008604DE50C2402F50AE50D3400F50B7833 +:10293B000A1207D5850C82850D83A3E0FDAC0974C3 +:10294B000412067EE0FAA3E0FB850C82850D83A3BF +:10295B00A3A3A3A3A3A3A3A3A3E0F9122D1D740206 +:10296B001206498A088B09AE08AF09750A01809DCA +:10297B007902022A2CEE2403F50EEF3400F50F75C5 +:10298B00080475090078081207D5E50C2403FCE54B +:10299B000D3400FDAA0EAB0F1269A074021206498A +:1029AB00740112067EAC82AD83AA0EAB0F123A52A3 +:1029BB00EA7001EB600B74038E828F83F0790080D9 +:1029CB00607901EEFAEFFB1230B9E9F50B7050E5C7 +:1029DB000A604C851082851183E06403600BE06410 +:1029EB00017003121894121940121A5DE06403600F +:1029FB000DE06401700512186F8003121985A2AFE8 +:102A0B00E492E0FAC2AFE50C2402F582E50D340046 +:102A1B00F583E06005E4F0750B0CEAA2E092AFA938 +:102A2B000B74041206497F080206EA74F312068A35 +:102A3B0074FD120633890AEAFEEBFF8C088D09122E +:102A4B001DA97902EA7001EB60411919121F6BE99C +:102A5B0070397401851082851183F012067EE50AA8 +:102A6B00F0750A00750B00780A1207D5780A120761 +:102A7B00D578081207D5EEFCEFFD740612067EAA78 +:102A8B0082AB83122D927406120649740312064907 +:102A9B007F060206EA74F112068A89088A09ECFE9F +:102AAB00EDFF90F5A1E0700B122BE4E970057902B4 +:102ABB00022BDFE50812081702080C2B6F2B8D2B4E +:102ACB00982B5A2B4F2B9F2BC82B402BD92A750891 +:102ADB00008E828F83E0702FE5097014A3780C129F +:102AEB00052BAA0CAB0DAC0EAD0F123BB8022BDDB8 +:102AFB0074016509700BA3AA82AB83123BDC022B1A +:102B0B00DD750802022BDDE0640170F5E509701438 +:102B1B00A3780C12052BAA0CAB0DAC0EAD0F123813 +:102B2B0030022BDD7401650970D7A3AA82AB831227 +:102B3B003854022BDDEEFAEFFBA90912243EE9F51E +:102B4B0008022BDDEEFAEFFBA9091237A780EF7411 +:102B5B000165096004E50970A8EEFAEFFBA90912FB +:102B6B00376380DA740365097009EEFAEFFB1235EF +:102B7B009E80CB740265097088EEFAEFFB12362A41 +:102B8B0080BCEEFAEFFBA90912369B80B1A90912A2 +:102B9B00375280AA740165096003022B0C75080477 +:102BAB0075090078081207D512355EEAFCEBFDEECD +:102BBB00FAEFFB1269A074021206498012740165C8 +:102BCB00096003022B0C123563E98E828F83F0753B +:102BDB000800A9087F080206EAC082C083E9120830 +:102BEB004D000205F62B0AF62BFA2B7901800279A0 +:102BFB0000D083D08222C082C083E490F5A5F0740C +:102C0B002090F5A6F090F5A7EAF0A3EBF01235456E +:102C1B0090F5A3EAF0A3EBF01218D1E990F5A2F02E +:102C2B0060F6D083D0822274F112068A89088A0E4C +:102C3B008B0F8C0A8D09790212247E8A0C8B0DA8BE +:102C4B000CA90DE8FEE9FFE87001E970077A007B3B +:102C5B0000022D18740B250A8E828F83A3A3F0EE2E +:102C6B00240BF8EF3400F988828983E0C2E6F0E0A8 +:102C7B0054C04508F090F5A2E0C0E0EE240DF582BB +:102C8B00EF3400F583D0E0F090F5A2E004F0E060C3 +:102C9B00F7EE240CFAEF3400FB90F5A5C082C0834D +:102CAB008A828B83E054BFD083D082FCE04C8A8233 +:102CBB008B83F0E054F84509F0E0C2E7F0E0C2E3A3 +:102CCB00F088828983E0C2E7F0750B00780A12075F +:102CDB00D5AC0EAD0FEE240E0A0AEF3400FB1269D1 +:102CEB00A0740212064975080475090078081207CA +:102CFB00D590F5A3E0FCA3E0FDEE2407FAEF34003A +:102D0B00FB1269A07402120649EEFAEFFB7F080270 +:102D1B0006EA74F712068A740912067EE0FEA3E037 +:102D2B00FF122C32EA7001EB70067A007B00801EDA +:102D3B00EA240DF582EB3400F583E08E828F83F06D +:102D4B00EA240CF582EB3400F583E0D2E7F07F0246 +:102D5B000206EA74F712068A790112247E8A088B1E +:102D6B0009A808A909E8FEE9FFE87001E96013EE7C +:102D7B0024020A0AEF3400FB12177EEEFAEFFB1265 +:102D8B002EE77F020206EA74F112068A74FE12061F +:102D9B0033851082851183ECF0A3EDF08A0C8B0D3B +:102DAB00741112067EE0F50AA3E0F50B74151206FA +:102DBB007EE0F50EA3E0F50FE4850A82850B83F028 +:102DCB007C0179011225688A088B09AE08AF09EEE0 +:102DDB007001EF7003022EDB750800750900850C7E +:102DEB0082850D83E064017015A3E0F9121DA98A99 +:102DFB00088B09EA7001EB70057902022EDD8E82D9 +:102E0B008F83A3A3E024F5850A82850B83F0E0F57D +:102E1B000A750B00780A1207D5EE240EFCEF34006E +:102E2B00FD740212067EE0FAA3E0FB1269A07402A5 +:102E3B00120649E5087002E5096033EE2421F5829C +:102E4B00EF3400F583E0850882850983A3A3A3A350 +:102E5B00A3A3A3F0EE2422F582EF3400F583E085E3 +:102E6B000882850983A3A3A3A3A3A3A3A3F074132D +:102E7B0012067EE07002A3E0602575080475090058 +:102E8B0078081207D5EE2407FCEF3400FD741512F9 +:102E9B00067EE0FAA3E0FB1269A07402120649E574 +:102EAB000E7002E50F6014EE240CF582EF3400F582 +:102EBB0083E05407850E82850F83F08E828F83A368 +:102ECB00E0FA7901122520E48E828F83F0F98002DB +:102EDB00790474021206497F080206EA74F312069B +:102EEB008A74FE120633EAFEEBFFEE240BF582EF3B +:102EFB003400F583E0543FF509750A04750B00782F +:102F0B000A1207D590F5A3E0FCA3E0FDEE2407FA27 +:102F1B00EF3400FB1269477402120649EA7001EBA9 +:102F2B007010E48E828F83F074021206497F0602C2 +:102F3B0006EAEE240BF582EF3400F583E0A2E640BF +:102F4B00E1E509603EC394075039EE2402FAEF34F1 +:102F5B0000FBE509C33324F8F582E434F9F583E08B +:102F6B00F8A3E0F5838882120688E9FA74016A7087 +:102F7B0004740180AE74026A70A8EEFAEFFB123192 +:102F8B00EC80A5743F6509600EE509C3942040925F +:102F9B00E509C3943F508BEE2403F50AEF3400F59B +:102FAB000B750C04750D00780C1207D5AC0AAD0B24 +:102FBB0090F5A3E0FAA3E0FB1269477402120649ED +:102FCB00EA7001EB70057508018003750800E508D0 +:102FDB007020743F65097073780C1207D512359900 +:102FEB00AD0BAC0A1269477402120649EA7001EB89 +:102FFB007059851082851183AC82AD83EE2402FA61 +:10300B00EF3400FB121F9DE97003022F2DE50870B2 +:10301B0007EEFAEFFB1231EC74018E828F83F09086 +:10302B00F5A7E07002A3E07003022F3385108285B1 +:10303B001183E0F990F5A7E0F8A3E0F583888212FD +:10304B000688E96003022F2D022F33740112067ECE +:10305B00AC82AD83AA0AAB0B123A52EA7001EB6059 +:10306B0036EE2402FAEF3400FB1233DFE960030281 +:10307B002F2DEE240BF582EF3400F583E0A2E75001 +:10308B0003022F2DEE240CF582EF3400F583E0C202 +:10309B00E7F07403022F2EEE240CF582EF3400F5CB +:1030AB0083E0543064206003022F85022F2D74F8C7 +:1030BB0012068AEAFEEBFFE9FAEE240CF8EF340075 +:1030CB00F990F5A6C082C08388828983E054CFD063 +:1030DB0083D082FBE04B88828983F0EAF9EE2402ED +:1030EB00FAEF3400FB1216A1E97004790080027923 +:1030FB0009E48E828F83F07F010206EAC082C083CF +:10310B0090F5A5E0F9D083D0822274F712068A7469 +:10311B00DF120633E9FEEA240BF582EB3400F5836C +:10312B00E0FF90F5A5C082C08390F5A6C082C08356 +:10313B00740A12067EE054CFD083D082FCE04C544C +:10314B00BFD083D082FCE04CC0E0740A12067ED064 +:10315B00E0F075080475090078081207D5EA240514 +:10316B00FCEB3400FD740312067EAA82AB8312695A +:10317B00A0740212064978081207D590F5A3E0FC5B +:10318B00A3E0FD740712067EAA82AB831269A074BA +:10319B0002120649740912067EE054C04EF0740BFD +:1031AB00851082851183F0EFC0E0740B12067ED080 +:1031BB00E0F0740A12067EE05478F0E0440BF074F1 +:1031CB000912067EE0543FF0790085108285118349 +:1031DB00AA82AB831216A174211206497F02020642 +:1031EB00EA74F812068AEAFEEBFFEE240CF582EF86 +:1031FB003400F583E05407FA74FF2AFBEA6017E00A +:10320B0054F84BF07A017B00121A397901EEFAEF80 +:10321B00FB1230B98006E48E828F83F07F010206A9 +:10322B00EA74F312068A74FD1206338A0C8B0D892D +:10323B0008EA2508F8EB3400F9740C28F582E43918 +:10324B00F583E0F5097402851082851183F0740112 +:10325B0012067EEAF0A3EBF07C02851082851183C7 +:10326B00AA82AB8379011225688A0A8B0BA80AA95B +:10327B000BE8FEE9FFE87001E96006EEFAEFFB8070 +:10328B006C79021227AA8A0A8B0BAE0AAF0B750850 +:10329B0000804F8E828F83E06403703C750A047547 +:1032AB000B00780A1207D5E50C2405FCE50D34005C +:1032BB00FDEE2403FAEF3400FB1269477402120689 +:1032CB0049EA7001EB7011EE240BF582EF3400F537 +:1032DB0083E0543F650960A30508EE2423FEEF3419 +:1032EB0000FFE508C3940240AA7A007B0074031226 +:1032FB0006497F060206EA74F512068A74DF120687 +:10330B0033EAFEEBFFEE240EF582EF3400F583E09B +:10331B00F50890F5A5C082C083740A12067EE054AE +:10332B008FD083D082FAE04A4420C0E0740A1206A0 +:10333B007ED0E0F0750A04750B00780A1207D5EE03 +:10334B002405FCEF3400FD740312067EAA82AB83C6 +:10335B001269A07402120649780A1207D5EE240FDF +:10336B00FCEF3400FD740712067EAA82AB83126950 +:10337B00A07402120649740912067EE054C0450877 +:10338B00FAF0740B851082851183F090F5A2E0C0E2 +:10339B00E0740B12067ED0E0F090F5A2E004F0741E +:1033AB000A12067EE05471F0E0D2E0F074BF5A448A +:1033BB0080C0E0740912067ED0E0F079008510829F +:1033CB00851183AA82AB831216A174211206497F41 +:1033DB00040206EA74F112068A8A0C8B0D8A828B20 +:1033EB0083E024F8F50979011227AA8A0A8B0BAE20 +:1033FB000AAF0B750800800A0508EE2423FEEF3494 +:10340B0000FFE508C3940640030234F48E828F83D9 +:10341B00E0640370E385098285820E8E82A3A3E0AC +:10342B00F874F828F874FF3400F9E50E687001E9B8 +:10343B0070C6750A04750B00780A1207D5850C82C5 +:10344B00850D83A3AC82AD83EE2403FAEF3400FB2E +:10345B001269477402120649EA7001EB709A780AF6 +:10346B001207D5E50C2405FCE50D3400FDEE240711 +:10347B00FAEF3400FB1269477402120649EA700135 +:10348B00EB6003023403750A01780A1207D5E50CC9 +:10349B002409FCE50D3400FDEE240BFAEF3400FBA0 +:1034AB001269477402120649EA7001EB6003023499 +:1034BB000374FE250EF50A74FF3400F50B780A121F +:1034CB0007D5E50C240BFCE50D3400FDEE240DFABD +:1034DB00EF3400FB1269477402120649EA7001EBE4 +:1034EB0060030234037901800279007F080206EA47 +:1034FB002279002274F712068A7508047509007880 +:10350B00081207D57C007D007AA97BF5126A8774B7 +:10351B000212064990F5B1E0701B78081207D57CB2 +:10352B00067DFA7AAD7BF51269A074021206497416 +:10353B000190F5B1F07F020206EAC082C08390F5DC +:10354B00B1E060067AAD7BF580047A067BFAD08316 +:10355B00D082227A0B7BFA2279022274F712068A26 +:10356B00790090F5B1E0702175080489097808128B +:10357B0007D5EAFCEBFD7AAD7BF51269A07402125C +:10358B000649740190F5B1F0F97F020206EA7ABEA2 +:10359B007BF92274F512068AEAFEEBFFEE2405F89E +:1035AB00EF3400F988828983E012084D010506C2C9 +:1035BB00350103C235C6357D0180027D038E828FB6 +:1035CB0083A3A3A3A3E0FC8E828F83A3A3E0FAA320 +:1035DB00E0FB88828983E0F9122C328A088B09A9D7 +:1035EB0009EA7001E96031750A04750B00780A125B +:1035FB0007D58E828F83E0FCA3E0FDEA24030A0A41 +:10360B000AE93400FB1269A074021206497901AA77 +:10361B0008AB091230B9800279037F040206EA7401 +:10362B00F712068A74FD120633E485108285118326 +:10363B00F08A828B83A3A3A3A3A3E0C0E07401123F +:10364B00067ED0E0F0EA2406F508EB3400F50978A5 +:10365B00081207D58A828B831207EAEA2404F5083D +:10366B00EB3400F50978081207D58A828B83A3A364 +:10367B00E0FCA3E0FD740612067EAA82AB83122D3A +:10368B0092740612064974031206497F020206EA77 +:10369B0074F512068AEAFEEBFF7508007404697074 +:1036AB000912198512186F02374B740569700912CC +:1036BB00189412194002374B74066970398E828F39 +:1036CB0083E0F9121DA9EA7001EB70047902807294 +:1036DB00750A02750B00780A1207D5EA2407FCEB72 +:1036EB003400FD8E828F83A3AA82AB831269A074F0 +:1036FB0002120649804A740769700B121AF1E98E9F +:10370B00828F83F0803A74086960A7740969700529 +:10371B00121985802B740A6970238E828F83E012B5 +:10372B0008170002D7363F373B3737377902800609 +:10373B00790180027900121BC1790080057508029E +:10374B00A9087F040206EA740B69700479018002F0 +:10375B007902123AC679002274F712068AEAFEEB56 +:10376B00FF750802740169702075080475090078EB +:10377B00081207D5123545EAFCEBFDEEFAEFFB120A +:10378B0069A074021206498009E97009123566E9CD +:10379B006003750800A9087F020206EA74F7120697 +:1037AB008AE9FC8A828B83E0F9740E6C60047902DF +:1037BB00801374FF6960F7121DA9EA7001EB60EECC +:1037CB00121D9A79007F020206EA74F512068A909E +:1037DB00F5B2C082C08390F9B2780812052BD08362 +:1037EB00D082780812034F701090FA0F78081205E8 +:1037FB002B90F5B2780812053A90F5B6EAF0A3EBE8 +:10380B00F01218D1E990F5B8F0123875123BB87474 +:10381B000190F5BBF0121E5A90F5B9EAF0A3EBF04C +:10382B007F040206EA74F512068A8A088B098C0A51 +:10383B008D0B90F9B2780812034F600890F5B278AF +:10384B000812053A7F040206EA74F512068AEA703A +:10385B0001EB601190F5B2780812052B8A828B83ED +:10386B00780812053A7F040206EA7AEF7BBE7CAD3C +:10387B007DDE2274F312068A74F4120633EAFEEB31 +:10388B00FF8E828F83E0F874F528F874FF3400F90B +:10389B00C3E89408E99400A2D265D0334018EE2413 +:1038AB0013F582EF3400F583E0F508123563E96513 +:1038BB00086003023A457904740112067EAC82ADAE +:1038CB0083EE240EFAEF3400FB122365C082C08313 +:1038DB0090F5B2780812052BD083D08278081203AA +:1038EB004F6003023A45740112067EAA82AB831223 +:1038FB003BDC7904740712067EAC82AD8374011233 +:10390B00067EAA82AB831223C4E4C0E0740B1206BA +:10391B007ED0E0F07481C0E0740512067ED0E0F03A +:10392B00EE240DF582EF3400F583E0C0E07406124F +:10393B00067ED0E0F07D017C07740512067EAA821C +:10394B00AB837903122C328A088B09A808A9098842 +:10395B000A890BE87001E97003023A45EE2405F57C +:10396B0008EF3400F509750C04750D00780C12077F +:10397B00D5AC08AD09EA24030A0A0AE93400FB12A4 +:10398B0069A07402120649EE2412F582EF3400F599 +:10399B0083E06024EEFAEFFB121E5FE9601A90F5EC +:1039AB00B6E07002A3E06010790090F5B6E0F8A3E2 +:1039BB00E0F58388821206888E828F83A3A3A3A34C +:1039CB00A3A3A3A3A3A3E0A2E6506685108285114F +:1039DB0083AC82AD83AA08AB09123A52EA7001EBB1 +:1039EB00704A90F5B9E0FEA3E0FF8E828F83E0C3AF +:1039FB0094035046780C1207D5AC08AD098E828F14 +:103A0B0083E075F005A4F8A9F090F5B9E028FAA3C6 +:103A1B00E0398A82F583A3AA82AB831269A0740270 +:103A2B001206498E828F83E004F08005E0F9124282 +:103A3B00187900AA0AAB0B1230B9740C1206497F25 +:103A4B00060206EA79002274F112068A8A0E8B0F9F +:103A5B008C088D0990F5B9E02401FEA3E03400FF3A +:103A6B00750A00800A050AEE2405FEEF3400FF906C +:103A7B00F5B9E0F8A3E0F5838882E0FAE50AC39A8A +:103A8B005030750C04750D00780C1207D5AC0EADCB +:103A9B000FEEFAEFFB1269477402120649EA700146 +:103AAB00EB70C2850882850983E50AF0EEFAEFFB1D +:103ABB0080047A007B007F080206EAC082C0837410 +:103ACB000169700474018001E490F5BBF0D083D0E0 +:103ADB008222C082C083EA240CF8EB3400F98A827C +:103AEB008B83E0FC74F52CFC74FF3400FD74076CC5 +:103AFB007001ED7007740188828983F08882898355 +:103B0B00E06401700312387ED083D0822274F812E5 +:103B1B00068AEAFEEBFF7508007D017C0090F5B884 +:103B2B00E0F9122211E9FB7008121AB57508018031 +:103B3B001C74016B7005750802801274026B700D9A +:103B4B0090F5BBE06007EEFAEFFB123ADDA9087FB8 +:103B5B00010206EA74F512068A90F5BCC082C08396 +:103B6B0090F9B2780812052BD083D0827808120313 +:103B7B004F701090FA13780812052B90F5BC78084B +:103B8B0012053A1218D1E990F5C3F060F6750801E9 +:103B9B0075090078081207D57C007D007AC17BF58A +:103BAB00126A8774021206497F040206EA74F51240 +:103BBB00068A8A088B098C0A8D0B90F9B278081249 +:103BCB00034F600890F5BC780812053A7F04020693 +:103BDB00EA74F512068AEA7001EB601190F5BC7875 +:103BEB000812052B8A828B83780812053A7F040210 +:103BFB0006EA74F312068A74FD120633EAFEEBFF33 +:103C0B00750A08EE2405F508EF3400F509EE240ECD +:103C1B00F582EF3400F583E0F9AA08AB091222C84C +:103C2B00EA7001EB6006121D9A750A00748285100A +:103C3B0082851183F0EE240DF582EF3400F583E0DD +:103C4B00C0E0740112067ED0E0F0740212067EE52D +:103C5B000AF07D037C03851082851183AA82AB83D6 +:103C6B007902122C328A0A8B0BA80AA90BE8FEE9FF +:103C7B00FFE87001E9602A750A04750B00780A12D7 +:103C8B0007D5AC08AD09EE24030A0A0AEF3400FB92 +:103C9B001269A074021206497900EEFAEFFB12309A +:103CAB00B974031206497F060206EA74F112068AFA +:103CBB0074F81206338A088B098A828B83E0F874B6 +:103CCB00F528F874FF3400F9C3E89409E99400A2CD +:103CDB00D265D033401FEA2414F582EB3400F58310 +:103CEB00E0FE123563E96E600C7902740812064926 +:103CFB007F080206EA7904E912067EAC82AD83E501 +:103D0B0008240EFAE5093400FB122365C082C08338 +:103D1B0090F5BC780C12052BD083D082780C120353 +:103D2B004F70C6E5082412F582E5093400F583E0EF +:103D3B00F50AE5082405F50EE5093400F50FA90A87 +:103D4B00AA0EFB121DEA8A0C8B0DA80CA90DE8FE1E +:103D5B00E9FFE87001E97003023E1174818510825E +:103D6B00851183F0E508240DF582E5093400F58310 +:103D7B00E0C0E0740112067ED0E0F08E828F83A348 +:103D8B00A3A3A3A3A3A3A3A3E0C0E0740212067E84 +:103D9B00D0E0F0123107E9C0E0740312067ED0E0E8 +:103DAB00F0850882850983A3A3A3A3A3A3A3A3A33D +:103DBB00A3E05407FA7403C39AFD7C048510828533 +:103DCB001183AA82AB837902122C328A088B09A940 +:103DDB0009EA7001E9602A750A04750B00780A126A +:103DEB0007D5AC0EAD0FEA24030A0A0AE93400FB2F +:103DFB001269A074021206497900AA08AB091230A5 +:103E0B00B97901023CF690F5C0E07003023CF4AACC +:103E1B0008AB09121F038A0C8B0DAE0CAF0DEE70A5 +:103E2B0001EF700B121CF18A0C8B0DAE0CAF0DEE6B +:103E3B007001EF60CC750C04750D00780C1207D572 +:103E4B00AC0EAD0FEE2403FAEF3400FB1269A07435 +:103E5B0002120649EEFAEFFB79021220A0E9700973 +:103E6B00EEFAEFFB121D9A809890F5C2E0640160A8 +:103E7B00EFE0F50C7401250CF0EE240BF582EF341A +:103E8B0000F583E0C0E0E50C24C1F582E434F5F5E0 +:103E9B0083D0E0F08E828F83A3A3A3A3A3A3A3A3BA +:103EAB00A3A3E50AF074028E828F83F0A3A882A9E4 +:103EBB0083E5082413F582E5093400F583E06440BB +:103ECB00700474018002740388828983F08E828F60 +:103EDB0083A3A3A3A3A3A3A3A3A3E0C0E074021291 +:103EEB00067ED0E0F0123107E9C0E0740312067EC3 +:103EFB00D0E0F07481851082851183F0E508240DE4 +:103F0B00F582E5093400F583E0C0E0740112067E0A +:103F1B00D0E0F0850882850983A3A3A3A3A3A3A361 +:103F2B00A3A3A3E05407FA7403C39AFD7C04851082 +:103F3B0082851183AA82AB837902122C328A088B79 +:103F4B0009A909EA7001E96030750A04750B00785C +:103F5B000A1207D5AC0EAD0FEA24030A0A0AE9349C +:103F6B0000FB1269A074021206497900AA08AB097A +:103F7B001230B9E97003023E0C023E6B74F8120664 +:103F8B008AEAFEEBFF7D017C0090F5C3E0F912227B +:103F9B0011E9FB7007121AB57901801074016B706F +:103FAB000479028007EEFAEFFB12402C7F01020628 +:103FBB00EA74F712068A7900A2AFE492E0FAC2AF74 +:103FCB0090F5C2E0603AE014F0EAA2E092AF091279 +:103FDB00401590F5C1E0F97C00ECC0E090F5C2E033 +:103FEB00FAD0E0C39A501E8C08E50824C1FAE434D9 +:103FFB00F5FB8A828B83A3E08A828B83F00C80D9BA +:10400B00EAA2E092AF7F020206EAC082C083E970A7 +:10401B00047A0180027A00EA90F5C0F0D083D08256 +:10402B002274F812068A7E00EA240CF8EB3400F9AD +:10403B008A828B83E0FC74F52CFC74FF3400FD74D6 +:10404B00086C7001ED7007740188828983F0888297 +:10405B008983E01208170101804069407D40123CC2 +:10406B00B6E9FA90F5C0E0700C74016A60070E0EA9 +:10407B008003123BFDEEF97F010206EA74F712068C +:10408B008A1218D1E990F5C7F07508037509007805 +:10409B00081207D57C007D007AC47BF5126A877401 +:1040AB00021206497F020206EA74F712068AEAFE3A +:1040BB00EBFF7D017C0090F5C7E0F9122211E9FBC3 +:1040CB007007121AB57901803B74016B7004790289 +:1040DB00803275080475090078081207D51235452A +:1040EB00EAFCEBFD8E828F83A3AA82AB8312694716 +:1040FB007402120649EA7001EB70D3EEFAEFFB1271 +:10410B00411479007F020206EAC082C083EA240CC4 +:10411B00F582EB3400F583E06401700312412FD07C +:10412B0083D0822274F612068A74FF120633EAFEDB +:10413B00EBFFEE240DF582EF3400F583E0F50A85F5 +:10414B001082851183AC82AD83EE2405FAEF340027 +:10415B00FB123A52EAF8EBF9EA7001EB70030242F8 +:10416B000EE82404F508E93400F509E024C4F582CF +:10417B00E434F5F583E07021850882850983E50A2F +:10418B00F07401C0E0851082851183E024C4F582B0 +:10419B00E434F5F583D0E08012AA0A8508828509FC +:1041AB0083E0F912233DE9605AE50AF07902EEFA51 +:1041BB00EFFB12322C8A088B09A808A909E87001B9 +:1041CB00E9603988828983A3E0FA7901122520E519 +:1041DB0008240CF582E5093400F583E054F844011A +:1041EB00F0E508240BF582E5093400F583E0D2E70E +:1041FB00F07900AA08AB091230B98007EEFAEFFB91 +:10420B0012330274011206497F030206EA74F71295 +:10421B00068AE4C0E0E924C4F582E434F5F583D0E2 +:10422B00E0F07F020206EAC082C0831218D1E99047 +:10423B00F5C8F0D083D0822274F512068AEAFEEB21 +:10424B00FF7D038E828F83E024F5FCEE240CFAEFC6 +:10425B003400FB7901122C328A088B09A909EA7008 +:10426B0001E9603E750A04750B00780A1207D5EE5A +:10427B002405FCEF3400FDEA24030A0A0AE93400A2 +:10428B00FB1269A07402120649E508240EF582E5BB +:10429B00093400F583E0D2E7F07900AA08AB0912E4 +:1042AB0030B97F040206EA74F812068AEAFEEBFFC5 +:1042BB007D017C0090F5C8E0F9122211E9FA700734 +:1042CB00121AB57901801274016A7004790280099F +:1042DB00EEFAEFFB1242E979007F010206EAC08297 +:1042EB00C083EA240CF582EB3400F583E0640170A3 +:1042FB0003124243D083D0822222790022C082C093 +:10430B0083124638E490F5D4F0FB8029EB75F00569 +:10431B00A424D5F8E5F034F5F9E488828983F0A379 +:10432B00F0A3F088828983A3A3A3F088828983A357 +:10433B00A3A3A3F00BEBC3940A40D1D083D082226A +:10434B0074F112068A74FB12063374018510828590 +:10435B001183F01243081248997A007BC0124971FD +:10436B0075E54475E402539BFCE59B53E9EF4391E0 +:10437B0010D2A8439A01D2B990F410E4F0A3F080C4 +:10438B000B90DF3BE06401700375E10290F5D4E024 +:10439B00C3940A500690F608E060E675E10490F6C7 +:1043AB0008E0700990F5D4E0C39405500B90F4101D +:1043BB00E4F0A374800245857A0080010AEAC39475 +:1043CB000A5031EA75F005A424D5F8E5F034F5F977 +:1043DB0088828983E060E5A3E0FAA3E0FB74031213 +:1043EB00067EEAF0A3EBF088828983A3A3A3E0F512 +:1043FB000C750D007A0980011AEA602E75F005A480 +:10440B0024D5F8E5F034F5F988828983E060E9A3D7 +:10441B00E0FAA3E0FB740112067EEAF0A3EBF0884E +:10442B00828983A3A3A3E0FE7F00750800750900B2 +:10443B007C007D007A008015E508250AF508E50962 +:10444B003400F509EC24010CED3400FD0AEAC394A9 +:10445B000A5033EA75F005A424D5F582E5F034F55E +:10446B00F583E060E7E5822404F582E5833400F50B +:10447B0083E0F50AE0A2E750BFA80AE50828F50893 +:10448B00E50934FF80BCA808A909ECFAEDFB12057D +:10449B00B0880EC3E894E7E994FFA2D265D033400D +:1044AB000EC3E8941AE99400A2D265D033400B9066 +:1044BB00F410E8F0A37420024585EEC3950CF8EFD9 +:1044CB00950DF9E875F0CCA4C8AAF075F00CA42AE8 +:1044DB00FA75F0CCE9A42AF9740112067EC082C0E9 +:1044EB0083740312067EE0FAA3E0FBD083D082E054 +:1044FB00C39AFEA3E09BFFE8C39EFAE99FFBC3EAC6 +:10450B009404EB94005036740F5AF990F410E4F0C5 +:10451B00A3E9F0C3E5099400A2D265D0335046C39A +:10452B00E49508F8E49509F9ECFAEDFB1205B8E807 +:10453B00F404F890F410E048F0A3E08045EEC39843 +:10454B00F8EF99F9C3E89404E994005025740F58D7 +:10455B00F990F410E4F0A3E9F0C3E5099400A2D2BA +:10456B0065D03340BAA808A909ECFAEDFB1205B8DF +:10457B0080C190F410E4F0A37440F0E485108285C0 +:10458B001183F0851082851183E06401600302467C +:10459B001EE490F5D4F0FA8029EA75F005A424D531 +:1045AB00F8E5F034F5F9E488828983F0A3F0A3F001 +:1045BB0088828983A3A3A3F088828983A3A3A3A35F +:1045CB00F00AEAC3940A40D1E50E90DF08F01248D6 +:1045DB00997A007B40124971800B90DF3BE06401BC +:1045EB00700375E10290F5D4E0700690F608E06078 +:1045FB00E975E10490F5D4E0601090F5D9E0FAC3C9 +:10460B0094FE500FEAC39403400990F410E4F0A316 +:10461B007410F0C2A8539AFEC2B975E40075E25546 +:10462B0012489974051206497F080206EAC082C037 +:10463B008374CA90DF00F074BA90DF01F0740A90B3 +:10464B00DF02F0E490DF03F090DF04F090DF05F081 +:10465B0090DF06F0741290DF07F0E490DF08F0743F +:10466B002690DF09F0741990DF0AF0741190DF0BBC +:10467B00F0743D90DF0CF0745590DF0DF0741590D5 +:10468B00DF0EF0741290DF0FF0741190DF10F074E6 +:10469B006090DF11F0740790DF12F0740290DF135B +:1046AB00F0741890DF14F0741D90DF15F0741C90EB +:1046BB00DF16F074C790DF17F0741090DF18F074EA +:1046CB00B290DF19F074B690DF1AF0741090DF1B04 +:1046DB00F074EA90DF1CF0742A90DF1DF0E490DF99 +:1046EB001EF0741F90DF1FF0E490DF2FF090DF308F +:1046FB00F090DF31F0743190DF24F090DF1CE04458 +:10470B0020F0745A90DF2EF075E10475E10190DF13 +:10471B003BE0640170F890DF1CE054CFF075E104CE +:10472B00D083D0822274F112068AE5D990F5C9F0B4 +:10473B00740190F5D3F07890F9801DA2895019E59A +:10474B00D9C0E0E024C9F582E434F5F583D0E0F07C +:10475B0090F5D3E004F0C289E0C3940A5012E8FA52 +:10476B00E9FB74FF2A1874FF3BF9EA7001EB70CB7D +:10477B00E0640A600302483875E104AAE28A828584 +:10478B008208E5E3F8E4C8F50990F60FE0FA75F056 +:10479B00BDA4CAACF075F02CA42CFB880A880B7452 +:1047AB000F78081204AD90FA21780C12052B7808BB +:1047BB00790C120424E5082AF508E5093BF5097C78 +:1047CB00017B0180218B82A882E824C9F582E43425 +:1047DB00F5F583E0FAE82417F582E434FAF583E083 +:1047EB006A60027C000BEBC3940A40D9EC603E90EC +:1047FB00F5D4E075F005A424D5F8E5F034F5F9749B +:10480B000188828983F0A3E508F0A3E509F090F510 +:10481B00C9E088828983A3A3A3F090DF38E0888264 +:10482B008983A3A3A3A3F090F5D4E004F07F08023F +:10483B0006EAC082C083E5E9FA539BFCE59BEAA23A +:10484B00E7500575E1048014A2E6501075E1049061 +:10485B00DF3BE0640170F8E490F5D3F075E900D02C +:10486B0083D08222C082C083C2A8539AFE74FF9069 +:10487B00DF06F074C090DF2EF0740190DF02F0754C +:10488B00D95575E103D083D0822275E10422C08211 +:10489B00C083E490F607F090F608F090F609F0A3C9 +:1048AB00F090F60BF090F60CF0A3F090F60EF09063 +:1048BB00F60FF0D083D0822274F712068A7C009018 +:1048CB00F60BE0603E53E5BF75DBFF75DAFFE5DB0A +:1048DB00F9E5DAF874FF68700374FF69601375DB30 +:1048EB00FF75DAFFE5DBF9E5DAF8EC0CC3940B4066 +:1048FB00E3E014F053E40FE5E443E54079017F0274 +:10490B000206EA90F60CC3E09406A3E09400405232 +:10491B0053E5BF90F60CE024FFA3E034FFF5DB90EA +:10492B00F60CE014F5DAE5DBF9E5DAF8E024FFFA4A +:10493B00A3E034FFFBEA687002EB696017EBF5DB71 +:10494B0090F60CE014F5DAE5DBF9E5DAF8EC0CC3DC +:10495B00940B40D890F60CE4F0A3F0740190F60E93 +:10496B0080917900809874F112068A53E5BFE49028 +:10497B00F607F090F60B800AEA2443FAEB34D3FBEC +:10498B00E004F0C3EA94BDEB942C50EC8A088B093D +:10499B00750A00750B0090FA21780C12052B78081C +:1049AB00790C1203A4740F780812049490F60CE59A +:1049BB0008F0A3E509F01248C353E40FE5E443E51F +:1049CB0040740190F607F07F080206EAC082C083AC +:1049DB0090F609E0F8A3E0F9C3E89AE99B5009EADD +:1049EB00C398F8EB99F9800CE86A7002E96B70EFE9 +:1049FB0078FF79FF90F609EAF0A3EBF0E8FAE9FB10 +:104A0B00124971D083D08222C082C083740190F688 +:104A1B0007F0D083D08222C082C083E490F607F0E7 +:104A2B00D083D08222C082C083E490F608F0D0837A +:104A3B00D08222C082C08390F62CE0FA74226A7076 +:104A4B001A90F619E0703390F62DE0F8A3E0F99088 +:104A5B00F650E8F0A3E9F07402801B74206A70141E +:104A6B0090F619E0701490F6267449F0A374F6F0E2 +:104A7B00A3E480E2740490F619F0D083D08222C0B4 +:104A8B0082C08390F62CE06421702090F619E070C0 +:104A9B002090F6267449F0A374F6F0A3E4F090F698 +:104AAB00297407F0A3E4F074018002740490F619E2 +:104ABB00F0D083D08222C082C083740490F619F0A8 +:104ACB00D083D08222C082C083740490F619F0D0B8 +:104ADB0083D08222C082C083740490F619F0D083F5 +:104AEB00D08222C082C083740490F619F0D083D098 +:104AFB0082222222C082C08390FA25E0F8A3E0F93B +:104B0B0090F610E8F0A3E9F0D083D0822274F8126B +:104B1B00068AE9FCEAFD7A007B00802190F610E022 +:104B2B00F8A3E0F5838882E493F890F610E028F878 +:104B3B00A3E03400F990F610E8F0A3E9F090F6103A +:104B4B00E0F8A3E0F990FA27E0687003A3E069604E +:104B5B004890F610E02401F8A3E03400F98882892C +:104B6B0083E4936C702B90F610E0FAA3E0FB90F6C5 +:104B7B0010E0F8A3E0F5838882E493F890F610E058 +:104B8B0028F8A3E03400F990F610E8F0A3E9F080E0 +:104B9B0008E4936D7086ED60837F010206EA124A8A +:104BAB00FF7A007901124B182274F712068AE9FE7C +:104BBB00EAFF124AFF800E8A828B83A3A3A3A3A3CF +:104BCB00E4936E60147A007902124B18EA7001EBD1 +:104BDB006007EE70E2EF1F70EC7F020206EA74F7DB +:104BEB0012068AEAFEEBFF7A00124BB47A027904C2 +:104BFB00124B18EA7001EB60178A828B83A3A3E434 +:104C0B00936E70E88A828B83A3A3A3E4936F70DC0B +:104C1B007F020206EA74F712068AE9FE124AFF7A4D +:104C2B00007903124B18EE1E70F57F020206EAC0E4 +:104C3B0082C0837A007901124BB48A828B83A3A33F +:104C4B00A3A3A3A3A3E493A2E6500474018001E4FD +:104C5B0090F625F0E490F624F043BE80D2BDD083CD +:104C6B00D08222C082C083740290F612F0E490F6D8 +:104C7B0013F090F619F07903124EF9752100752295 +:104C8B0000D083D0822274F512068A90DE0EE0FEED +:104C9B00E4F090DE11E0FFA2E4501F7480F0740783 +:104CAB0090F619F0E5217002E522600985218285D5 +:104CBB002283120688E490F619F0EFA2E25009E481 +:104CCB0090DE11F090F619F090F619E0FA74026A82 +:104CDB006003024D6790DE16E0F50A90F626120788 +:104CEB00E6A90A7A207BDE124F3F74031206498530 +:104CFB000A0890F629C3E09508F0A3E09400F09021 +:104D0B00F626E0F9A3E0FAA3E0FBE9250AF9EA3479 +:104D1B0000FA90F626E9F0A3EAF0A3EBF090F6295F +:104D2B00E07002A3E060047A4080027A48EA90DEE9 +:104D3B0011F090F629E07002A3E07016E5217002E5 +:104D4B00E5226009852182852283120688E490F68C +:104D5B0019F0EE90DE0EF07F040206EA74066A701C +:104D6B000985218285228312068890F619E060035B +:104D7B00024E6AEFA2E04003024E6A75082B7509DA +:104D8B00F6750A0078081207D179087A207BDE12B3 +:104D9B004F3F740312064975210075220090F62BC4 +:104DAB00E054E012084D000600C74D20434E402D45 +:104DBB004E80024EA04E4EC0384EFA4D90F62CE06F +:104DCB0012084D000501EB4D03E64D05E14D09F0D1 +:104DDB004D0BF54DFA4D1252CC80711252C0806CB6 +:104DEB001252B480671256CF80621257F7805D74EF +:104DFB000490F619F0805590F62CE012084D000443 +:104E0B0000194E061E4E08234E0A284EFA4D12501C +:104E1B00CA80391253258034125686802F12579927 +:104E2B00802A7521C175224A124AC1801F7521D073 +:104E3B0075224A124AD0801475213E75224A124AB5 +:104E4B003E800975218A75224A124A8A90F619E02A +:104E5B00640470047A6080027A40EA90DE11F0906C +:104E6B00F619E0FA74016A70717F0290F629E0F886 +:104E7B00A3E0F9C3E89420E994005007E8F50A7F12 +:104E8B000A8003750A2090F6261207E6A90A7A20F3 +:104E9B007BDE124F797403120649850A0890F626B9 +:104EAB00E0F9A3E0FAA3E0FBE92508F9EA3400FAFC +:104EBB0090F626E9F0A3EAF0A3EBF090F629C3E015 +:104ECB009508F0A3E09400F0EF90DE11F0E50AC333 +:104EDB0094204003024D5D024D4774056A60030246 +:104EEB004D5D852182852283120688024D5D74F704 +:104EFB0012068A7A008014E9C0E08A08E508241AB1 +:104F0B00F582E434F6F583D0E0F00AEAC394054069 +:104F1B00E67A008014E9C0E08A08E508241FF582D0 +:104F2B00E434F6F583D0E0F00AEAC3940540E67F5B +:104F3B00020206EA74F612068AEAFCEBFDE9FE743D +:104F4B000A12067EE0F508A3E0F509A3E0A908AA7A +:104F5B0009FBEE60148C828D83E012038EE9240131 +:104F6B0009EA3400FA1EEE70EC7F030206EA74F6CF +:104F7B0012068AEAFCEBFDE9FE740A12067EE0F5E6 +:104F8B0008A3E0F509A3E0A908AA09FBEE60141237 +:104F9B0003748C828D83F0E9240109EA3400FA1E34 +:104FAB00EE70EC7F030206EA74F712068A75230093 +:104FBB007524007525008A268B27EA90DE0BF08A74 +:104FCB00088B0974047808120611E50890DE07F0C7 +:104FDB008A088B0974097808120611E508543E906B +:104FEB00DE09F0438C10758900C2C5758B00C2E8D1 +:104FFB00439A027F020206EAC0E074F1120722E52F +:10500B00BEA2E650FA90DE06E0FAA2E25036A826DF +:10501B00E890DE0BF08526088527097404780812C2 +:10502B000611E50890DE07F0852608852709740927 +:10503B007808120611E508543E90DE09F090DE0167 +:10504B00E0D2E0F07823EA46F608E6F690DE02E0DE +:10505B00F508750900740478081206207823E50812 +:10506B0046F608E50946F690DE04E0F508750900FA +:10507B00740978081206207823E6F608E50946F647 +:10508B00EAA2E0500375250174065A6003752500EA +:10509B00124AFE758B00C2E87F02020781C0E074E2 +:1050AB00F2120722E5BEA2E650FAE589A2E7500507 +:1050BB00C2BD125921758900C2C57F0102078174D7 +:1050CB00F712068A90F62DE07002A3E0701E90F6A0 +:1050DB002FE0F8A3E0F974FF59FBE47001EB700CBF +:1050EB0090F631E064027002A3E060057404025193 +:1050FB00BC90F62BE0120817800210510D513D5158 +:10510B004D51E86008740490F61902519B90F625F6 +:10511B00E0600478018002780090F633E8F0A3E4B5 +:10512B00F090F624E0606A90F633E04402F0A3E0DE +:10513B00805E90F612E0640470CB90F633E4F0A33B +:10514B00804EE8547FF50890F612E0640470B6E5E3 +:10515B0008C3940650AFE5082412F582E434F6F543 +:10516B0083E854806010A3A3A3A3A3A3A3E06403C9 +:10517B00701578018013E582240CF582E5833400E9 +:10518B00F583E0640360EB780090F633E8F0A3E47A +:10519B00F090F619E06404601C90F6267433F0A3CB +:1051AB0074F6F0A3E4F090F6297402F0A3E4F07423 +:1051BB000190F619F07F020206EA74F712068A9044 +:1051CB00F631E07002A3E0701290F612E064046016 +:1051DB001290F62FE07002A3E06008740490F619A9 +:1051EB000252AC90F62BE0541F1208170002E65146 +:1051FB0001520952235290F62DE0640160057900AB +:10520B000252AFE990F624F060047905800279062A +:10521B007A00124AFD0252AD90F62FE0547FFA90BD +:10522B00F62DE070D9EAC3940650B0EA90DE0EF08A +:10523B0090F62FE054806032E960047B1080027B93 +:10524B0040EB90DE11F0E960047B0380027B00EB06 +:10525B00C0E0EA2419F582E434F6F583D0E0F0E9F6 +:10526B0060047908803479078030E960047B208002 +:10527B00027B80EB90DE14F0E960047B0380027B01 +:10528B0000EBC0E0EA241EF582E434F6F583D0E0AF +:10529B00F0E96004790A80027909124AFDE490DE94 +:1052AB000EF079017F020206EA79001251C5E9700E +:1052BB0003124ADF2279011251C5E97003124AEE3B +:1052CB0022C082C08390F62FE07002A3E070209082 +:1052DB00F631E07002A3E0701690F62DE0F8A3E033 +:1052EB00F9748058FA74FF59FBEA7001EB6007748C +:1052FB000490F619801EE890DE00F090F62DE090F9 +:10530B00F6126009E06402700C74038007E064031A +:10531B0070037402F0D083D0822274F512068A9047 +:10532B00F62DE0FAA3E01208170102D9533E53659C +:10533B0053B053124BA990F626EAF0A3EBF0A374EB +:10534B0080F090F626E0F9A3E0FAA3E0FB120374D9 +:10535B0090F629F0A3E4F00254AB7900124BB49011 +:10536B00F626EAF0A3EBF0A37480F090F626E0F9B2 +:10537B00A3E0FAA3E0FBE924020909EA3400FA12DC +:10538B000374FC90F626E0F9A3E0FAA3E0FBE92412 +:10539B0003090909EA3400FA120374F9EC90F629AF +:1053AB00F0A3E980B1EAF9124C2090F626EAF0A3BB +:1053BB00EBF0A37480F090F626E0F9A3E0FAA3E0FB +:1053CB00FB12037490F629F0A3E4F00254AB90F6B1 +:1053DB0026E4F0A3F0A3F0FC02547C7509007403DF +:1053EB007808120620AE08AF09EA2EF8EB3FF990C9 +:1053FB00F62DE0F508A3E0F50988828983E493AAEA +:10540B00096A706CA3E4936508706590F62FE0F55C +:10541B0008A3E0F50988828983A3A3E493AA096A08 +:10542B00704E88828983A3A3A3E493650870418897 +:10543B00828983A3A3A3A3E493F508740193F509CD +:10544B0090F626E508F0A3E509F0A37480F090FA36 +:10545B0029E02EFAA3E03F8A82F583A3A3A3A3A39B +:10546B00A3E493F8740193F990F629E8F0A3E9F01B +:10547B000C90FA29E0FAA3E0FB8C0890FA2BE0F8E9 +:10548B00A3E0F9E8C39AF50AE99BF50B7403780AD4 +:10549B00120611C3E508950AE4950B50030253E677 +:1054AB0090F626E0FCA3E0FDA3E0FEEC4D4E70066B +:1054BB00740490F619F090F619E06404602590F6E8 +:1054CB0031E0FAA3E0FB90F629E0F8A3E0F9C3EA98 +:1054DB0098EB99500890F629EAF0A3EBF074019041 +:1054EB00F619F07F040206EA74F112068A74FE12B2 +:1054FB000633851082851183EAF0A3EBF0851082C9 +:10550B00851183E0F8A3E0F5838882A3A3A3A3E42A +:10551B0093602B90FA2DE0FEA3E08007EE2404FEAF +:10552B00EF3400FF8E828F83E493F8740193F98537 +:10553B001082851183E0687003A3E06970DE750843 +:10554B0000805A749090DE14F07410F08882898376 +:10555B00E493540364017003750940750A01750BDC +:10556B0000E50C780A1206208E828F83A3A3A393E7 +:10557B00550A6006E509D2E0F509E50990DE15F05C +:10558B00EA90DE13F0E4C0E0E50C241EF582E4346F +:10559B00F6F583D0E0F0E490DE0EF005088510827E +:1055AB00851183E0F8A3E0F5838882A3A3A3A3E48A +:1055BB0093FAE508C39A400302567C7A00790512E8 +:1055CB004B188A0A8B0BAC0AAD0BEC7001ED60CB60 +:1055DB00EC2402F50EED3400F50F850E82F583E415 +:1055EB0093540FF50C90DE0EF07509008C828D83B1 +:1055FB00A3A3A3A3E4932407F50AA3E4933400F530 +:10560B000B7403780A120611AA0AEC2403F8ED3482 +:10561B0000F9850E82850F83E493A2E740030255C0 +:10562B004E744890DE11F07408F088828983E493FD +:10563B00540364017003750940750A01750B00E58D +:10564B000C780A1206208E828F83A3A393550A60CF +:10565B0006E509D2E0F509E50990DE12F0EA90DEE5 +:10566B0010F0E4C0E0E50C2419F582E434F60255A1 +:10567B009C74021206497F080206EAC082C083901E +:10568B00F62DE07002A3E0701690F62FE07002A3E7 +:10569B00E0700C90F631E064017002A3E0600474DA +:1056AB0004801890F6267413F0A374F6F0A3E4F0BC +:1056BB0090F6297401F0A3E4F0740190F619F0D080 +:1056CB0083D0822274F312068A90F612E064026091 +:1056DB001F90F62FE07002A3E0701590F631E0708A +:1056EB0002A3E0700B90F62EE0F9E47001E960097B +:1056FB00740490F619F00257947A007901124AFD5E +:10570B0090F62DE0606E7A00F9124BB48A088B0983 +:10571B00EA7001EB6056740490F612F090F62DE0EF +:10572B0090F613F0750A00850882850983A3A3A35D +:10573B00A3E493FAE50AC39A5048850A0CE50C24B6 +:10574B0014FEE434F6FFE48E828F83F07A00790442 +:10575B00124B188A828B83A3A3A3E493FC8E828FB4 +:10576B0083E06C70E71254F3050A80BB740490F667 +:10577B0019F0800E90F613F0740390F612F0F912F4 +:10578B004EF97A007902124AFD7F060206EA74F698 +:10579B0012068A90F612E06404701E90F62BE064F9 +:1057AB0081701690F62DE07002A3E0700C90F6312C +:1057BB00E064017002A3E060047404802690F62F6D +:1057CB00E02414F508A3E034F6F50990F626E50875 +:1057DB00F0A3E509F0A3E4F090F6297401F0A3E43B +:1057EB00F0740190F619F07F030206EA74F71206C3 +:1057FB008A90F612E06404701290F62BE06401704C +:10580B000A90F631E07002A3E06008740490F61978 +:10581B00F0805890F62DE0FB90F62FE0FA90F613FF +:10582B00E0F9124BE98A088B09A808A909E8FEE9F7 +:10583B00FFE87001E960D490F62FE0FA7903124A81 +:10584B00FD90F62DE0C0E090F62FE02414F8A3E0D5 +:10585B0034F6F988828983D0E0F0EEFAEFFB12542C +:10586B00F390F62FE0FA7904124AFD7F020206EA62 +:10587B00C082C08390F645E07002A3E0600E90F604 +:10588B0045E0F8A3E0F5838882120688745390F6FE +:10589B0035F074BE90F636F074FC90F637F0744326 +:1058AB0090F638F074BE90F639F0740190F63AF039 +:1058BB00747590F63BF0748790F63CF0740190F69B +:1058CB003DF074E590F63EF0742590F63FF0747061 +:1058DB0090F640F074F390F641F0742290F642F09B +:1058EB00758900C2C5D2BD90F6437435F0A374F62A +:1058FB00F0758235F58312068890F647E07002A3A7 +:10590B00E0600E90F647E0F8A3E0F583888212067C +:10591B0088D083D08222C082C083E490F63AF09084 +:10592B00F63BF090F63CF090F63DF0D083D082221F +:10593B0074F512068A8A088B098C0A8D0BE490F693 +:10594B0075F090F676F090F677F090F649780812AD +:10595B00053AE490F64DF090F64EF0740890F64F41 +:10596B00F090F650E4F0A3F0740190F652F0124C64 +:10597B003A7AFF7BFF124FB353F4FDD29143FE02F1 +:10598B00120A1F7F040206EAC082C0831259AB9031 +:10599B00F652E06006125A5A1259F6D083D0822280 +:1059AB00A823E85404600E782374FB56F60874FFA2 +:1059BB0056F6124C6EA823E85410600E782374EF41 +:1059CB0056F60874FF56F6124C91A823E8A2E05045 +:1059DB0019782374FE56F60874FF56F612587B7826 +:1059EB002374FD56F60874FF56F62274F612068AD7 +:1059FB00120A2290DE0EE090F678F0740490DE0E20 +:105A0B00F090DE11E0A2E0403690F677E060307562 +:105A1B0008537509F6750A0078081207D190F655E8 +:105A2B00E0F97A287BDE124F797403120649E49071 +:105A3B00F677F0740490DE0EF0740190DE11F090A6 +:105A4B00F678E090DE0EF0120A1F7F030206EA746E +:105A5B00F612068A7E00120A2290DE0EE090F6788D +:105A6B00F0740490DE0EF090DE14E0A2E04003022E +:105A7B005B0990DE16E0FF90DE17E0742090FA31A0 +:105A8B00F090F675E0F8EF28F8E43400F9E894218B +:105A9B00E994004002E4F0E02453F508E434F6F511 +:105AAB00098E0A78081207D1EFF97A287BDE124F9C +:105ABB003F740312064990F675E02FF0740490DEE4 +:105ACB000EF0E490DE14F090F675E0C394024005FE +:105ADB0090F655E0FE8E0874FF2508F874FF34002D +:105AEB00F990F675E0FAC3E89AE99400A2D265D072 +:105AFB0033500BEEC394034005120C21E4F090F6E7 +:105B0B0078E090DE0EF0120A1F7F030206EAC082D5 +:105B1B00C08375910075E90075C6B874D390DF002A +:105B2B00F0749190DF01F0741290DF07F0E490DFD6 +:105B3B0008F0742590DF09F0749590DF0AF0745526 +:105B4B0090DF0BF0741490DF06F0748B90DF2EF067 +:105B5B00741D90DF0CF0745590DF0DF0741390DF13 +:105B6B000EF0742390DF0FF0741190DF10F074635C +:105B7B0090DF11F074B690DF1AF0741090DF1BF009 +:105B8B00741890DF14F0743C90DF13F0740790DFFF +:105B9B0012F075A48775A36B75A2F8741D90DF15B1 +:105BAB00F0741C90DF16F074C790DF17F0E490DFF1 +:105BBB0018F074B090DF19F074EA90DF1CF0742ABF +:105BCB0090DF1DF0E490DF1EF0741F90DF1FF07468 +:105BDB005990DF20F0748890DF23F0743190DF242C +:105BEB00F0740990DF25F0747F90DF21F0748890BA +:105BFB00DF22F0742990DF2FF0741E90DF30F074E9 +:105C0B001B90DF31F0740690DF03F0744590DF04D6 +:105C1B00F074CA90DF05F074FE90DF02F0D083D0F1 +:105C2B00822274F712068AE5E9FA90F979E06402A8 +:105C3B00600575E900804574505A6450702E53E925 +:105C4B00EF53E9BF539BFCE59B125D3E7508FF7557 +:105C5B00090078081207D57C007D007A787BF81252 +:105C6B006A877402120649125CC8801053E910E56A +:105C7B00E9539BFCE59B740190F876F07F020206DA +:105C8B00EAC082C083E9701190F871E4F0A3F09040 +:105C9B00F873F0A3F090F875F0D083D08222C08215 +:105CAB00C083E9701390F871E4F0A3F090F875F0ED +:105CBB0090F873EAF0A3EBF0D083D0822274F71242 +:105CCB00068A74F890F97DF0747890F97EF074DFA1 +:105CDB0090F97BF074D990F97CF090F97FE054E067 +:105CEB004401F0E490F980F0748190F97FF0741224 +:105CFB0090F982F0741390F981F075D6817508FFD5 +:105D0B0075090078081207D57C007D007A787BF83E +:105D1B00126A87740212064943D601539BFCE59B1A +:105D2B0053E9EF740290F979F075E102439110FF9A +:105D3B000206EAC082C0835391EF740190F979F0A7 +:105D4B0075E10490DF3BE0640170F875D68153D1A7 +:105D5B00FE539BFCE59B53E9EFD083D0822274F872 +:105D6B0012068AEAFEEBFF125D3E74DF90F97DF0BE +:105D7B0074D990F97EF0EF90F97BF0EE90F97CF00E +:105D8B0090F97FE054E04401F0E490F980F0742145 +:105D9B0090F97FF0744290F982F0741390F981F0CE +:105DAB0043D601740490F979F075E103E5E9A2E4B7 +:105DBB0050FA53E9EF125D3E79017F010206EA7456 +:105DCB00F812068A790090F876E064016003025EAF +:105DDB005FE4F090F879E0707B90F878E0247AF546 +:105DEB0082E434F8F583E0A2E750697E017D008000 +:105DFB00218D82AA82EA247CF582E434F8F583E0D3 +:105E0B00FCEA2435F582E434FAF583E06C60027E1B +:105E1B00000DEDC3940440D9EE603990F87AE09010 +:105E2B00F97AF0E090FA3BF0740190FA3DF0FA7BCE +:105E3B0000125CA990F875E060FA7900125C8CD2C4 +:105E4B009079047A3A7BFA125D69C29079017402F7 +:105E5B0090F67AF07F010206EAC082C08390F97A4D +:105E6B00E090FA3FF090F877E090FA43F07AB87B45 +:105E7B00017900125CA990F773E06404600690F856 +:105E8B0075E060F290F773E06404600990F67AE0D5 +:105E9B00D2E5025F257900125C8CD29079067A3EAE +:105EAB007BFA125D69C290125CC87AB87B017900EB +:105EBB00125CA990F875E0700890F876E0640170B8 +:105ECB00F27900125C8C125D3E90F876E064017002 +:105EDB004A90F878E0247AF582E434F8F583E054BC +:105EEB0080FBE490F876F090F879E064CA702C901F +:105EFB00F87AE0FA90F97AE06A702090F87BE06427 +:105F0B00017018EB6015E490F877F0740190F98745 +:105F1B00F090F773F0740890F67BF0D083D0822268 +:105F2B00C082C08390F986E090F777F090F985E016 +:105F3B0090F778F090F97AE090F775F07AB87B01EA +:105F4B007900125CA990F773E06404600690F87511 +:105F5B00E060F290F773E06404600990F67AE0D2A7 +:105F6B00E50260487900125C8CD29090F774E004E3 +:105F7B00F97A747BF7125D69C290125CC87AB87BB0 +:105F8B00017900125CA990F875E0700890F876E042 +:105F9B00640170F2125D3E7900125C8C90F876E031 +:105FAB006401600302604990F878E0247AF582E49A +:105FBB0034F8F583E05480FBE490F876F090F879B0 +:105FCB00E064CA707990F87AE0FA90F97AE06A7036 +:105FDB006D90F87BE06401706590F87CE0FA90F9C5 +:105FEB0086E0547F6A705790F87DE0C0E090F985A9 +:105FFB00E0F8D0E0687047EB6044E490F877F090FD +:10600B00F985E02401F0A3E03400F090F985E0F885 +:10601B00A3E0F9E875F064A4F8AAF075F064E9A4BC +:10602B002AF990F983E0FAA3E0FB1205B8E890F99E +:10603B0077F0740890F67BF0740190F773F0D083CF +:10604B00D08222C082C08390F877E004F0E0C39442 +:10605B0006400D90F67AE0D2E5F0E0D2E2F080292E +:10606B0090F987E07005125E64801E90F985C082FE +:10607B00C08390F983E0F8A3E0F9D083D082C3E02A +:10608B0098A3E0995003125F2BD083D08222C08259 +:10609B00C083E490F877F090F977F0740190F67A7A +:1060AB00F090F67BF090F985E4F0A3F090F983F093 +:1060BB00A3F0740190F773F0E490F987F090F87601 +:1060CB00F0D083D08222C082C08374F9F5D575D409 +:1060DB007B12609974FC90F774F074CA90F776F0A9 +:1060EB00740190F67AF0C2A8439A01C290E490F63C +:1060FB0079F090F977F0125D3E806090F985C0825F +:10610B00C08390F983E0F8A3E0F9D083D082C3E099 +:10611B0098A3E099400690F987E0701712604E7AC9 +:10612B00017B007900125CA990F875E060FA7900A8 +:10613B00125C8C90F978E0701B90F985C082C0835B +:10614B0090F983E0F8A3E0F9D083D082C3E098A361 +:10615B00E099400790F67AE0D2E5F090F679E0709E +:10616B002A125CC8125DCAE964017017740290F6BA +:10617B007AF090F679E004F0740490F67BF0125DFF +:10618B003E800890F67AE0A2E550D990F67AE0A22C +:10619B00E54003026106C2A8539AFE5391EF75E9DD +:1061AB0000125D3EE490F679F07A2C7B01F9125CDB +:1061BB00A990F875E060FA7900125C8CD083D082DC +:1061CB0022C082C08374B290DF01F0743790DF007D +:1061DB00F0740A90DF02F0740090DF03F07400900B +:1061EB00DF04F0740090DF05F0740090DF06F074AC +:1061FB001290DF07F0740090DF08F0742690DF092F +:10620B00F0741990DF0AF0741190DF0BF0743D906D +:10621B00DF0CF0745590DF0DF0741590DF0EF074F9 +:10622B001290DF0FF0741190DF10F0746090DF119B +:10623B00F0740790DF12F0740090DF13F074189075 +:10624B00DF14F0741D90DF15F0741C90DF16F074E2 +:10625B00C790DF17F0741090DF18F074B290DF194D +:10626B00F074B690DF1AF0741090DF1BF074EA90A4 +:10627B00DF1CF0742A90DF1DF0740090DF1EF074A9 +:10628B001F90DF1FF0740090DF2FF0740090DF3051 +:10629B00F0740090DF31F0743190DF24F075E1047D +:1062AB0075E10190DF3BE0640170F8D083D082226E +:1062BB00C082C08390DF1CE0442090DF1CF074C6CA +:1062CB0090DF2EF075E10475E10190DF3BE0640196 +:1062DB0070F890DF1CE054CFF075E104D083D082CE +:1062EB002274F712068AE990DF06F07A00EAC3946B +:1062FB000A501E8A08750900E508249BF582E509FA +:10630B0034F9F583E0C0E074282AF8D0E0F60A806F +:10631B00DC753200D29074FE559AFA8A9AC2A8C2E2 +:10632B0089539BFCE59B75E900D2A87401459AFC47 +:10633B008C9A740090FA44F075E1037F020206EA2E +:10634B00C082C083C290C2A874FE559AFA8A9A740E +:10635B000190FA44F075E104D083D0822212634B92 +:10636B00227A007B0075320074282532F8E6F5D9C5 +:10637B000532E532C3940A502BEAF8EBF974012885 +:10638B00FA740039FBC3E89488E994135016A28978 +:10639B0050E074282532F8E6F5D90532C2897A0027 +:1063AB007B0080CEC3EA9488EB94134005C28975B9 +:1063BB00E9002274F812068AE5E9FEEEA2E7500224 +:1063CB007E00EEA2E45009740190FA44F012636867 +:1063DB0075E9007F010206EA74F512068A1261CC98 +:1063EB001262BB90F9B2780812052B90F98E7808DF +:1063FB0012053A740090F992F07F040206EA74F7E2 +:10640B0012068A740090F99AF0740090F999F0745E +:10641B000090F998F0E5E3F8E4C8F990F995E8F005 +:10642B00A3E9F085E20875090090F995E04508F0BD +:10643B00A3E04509F090F995E024A4F0A3E0340023 +:10644B00F090F995E0FAA3E0FB1249D7124A137FBB +:10645B00020206EAC082C083124A2212634B740006 +:10646B0090F99AF0D083D0822274F512068A8A08AA +:10647B008B098C0A8D0B90F98A780812053A7F04E8 +:10648B000206EA74F512068AC0A8C2AF8A088B0905 +:10649B008C0A8D0B90F98E780812053AE990F992D7 +:1064AB00F0D0A87F040206EA74F512068A90F999D7 +:1064BB00E01208170102C9647565CE65426690F952 +:1064CB0093E02400F0A3E03470F01268BC90F99ACA +:1064DB00E0D2E1F090FB51E0C39401A2D265D0333E +:1064EB00502890FA45780812052B90F98E780812EF +:1064FB00051890FB51E06488700990F99AE0D2E09E +:10650B00F0800790F99AE0C2E0F012668C7400906C +:10651B00F997F075080075090878081207D590F9F6 +:10652B008A780812052BAA08AB09AC0AAD0B90F9B7 +:10653B0098E0F912678874021206498A088B09A839 +:10654B0008A90990F993E0C398F8A3E099F990F999 +:10655B0088E8F0A3E9F090F988E0FAA3E0FB124990 +:10656B00D7740190F999F0026668742290F997F04C +:10657B0075080075090278081207D590F98A780812 +:10658B0012052BAA08AB09AC0AAD0B90F998E0FEEB +:10659B007480C39EF912678874021206498A088BAD +:1065AB0009A808A90990F988E028F8A3E039F9743B +:1065BB000028FA740239FB1249D7740290F999F04A +:1065CB00026668740190F997F090F98A78081205C1 +:1065DB002BAA08AB0990F998E0F9126881E9FA90B7 +:1065EB00F997E02AF075088075091C78081207D511 +:1065FB0090F98A780812052BAA08AB09AC0AAD0BE7 +:10660B0090F998E0FE7440C39EF9126788740212E9 +:10661B0006498A088B09A808A90990F993E028F87C +:10662B00A3E039F9740028FA740639FB1249D774C0 +:10663B000390F999F080261268BB90F99AE0C2E1B9 +:10664B00F090F998E02401F090F993E024B8FAA3C4 +:10665B00E03466FB1249D7740090F999F07F04027D +:10666B0006EAC082C08390F99AE0A2E1500890F943 +:10667B0097E0F91262EC1264B3124A30D083D082E5 +:10668B002274F112068A90F99BC082C08390FA495A +:10669B00780812052BD083D08278081204F290F977 +:1066AB008AC082C08390FA4D780C12052BD083D010 +:1066BB0082780C1204F27808790C12050590F99B7C +:1066CB00780812053A90F99BC082C08390FA4D78F6 +:1066DB000C12052BD083D082780C1204F290F9980F +:1066EB00E0F508E4F509F50AF50B741878081204BF +:1066FB00AD780C790812050590F99B780C12053AC8 +:10670B0090F99F780812052B90F98E780C12052BB7 +:10671B0090F99F780C12053A90F992E090F9A3F05A +:10672B007A9B7BF9126740E9FA74216A90F9A4F01D +:10673B007F080206EA74F812068A79007D00EDC321 +:10674B00940950348A828B83E0FE7C00ECC394085E +:10675B00501AE96EC394804008E9C3336497F980FB +:10676B0004E9C333F9EEC333FE0C80E08A828B83DA +:10677B00A3AA82AB830D80C67F010206EA74F112D5 +:10678B00068A74FE120633E9FF8A0C8B0D8C0E8D74 +:10679B000F7CFF7D7F851082851183E50CF0AE0D9C +:1067AB00850C08850D09850E0A850F0B741078086A +:1067BB00120494740112067EE508F08F0875090027 +:1067CB00E5082451F582E50934FAF583E0F88510E4 +:1067DB0082851183E0F508E50868F8E4C8F98F0AAB +:1067EB00750B008E08750900E508650AF508E509C3 +:1067FB00650BF509E5082451F582E50934FAF583B3 +:10680B00E0F508750900E50828F8E50939F9851060 +:10681B0082851183E0F50AE4C50AF50B8E0875092C +:10682B0000740112067EE0F582758300E58245084F +:10683B00F508E5834509F509E508250AF508E50995 +:10684B00350BF509E50868F8E50969F9E8FAE9FB9C +:10685B00741112067EC3E09AA3E09B500FEC5AFA18 +:10686B00ED5BFBEDC313FDEC13FC80E4740212062D +:10687B00497F080206EA74F712068A89087509002F +:10688B00EA79006508F8E96509F9E82451F582E928 +:10689B0034FAF583E0F8EB68541FF97F020206EA3D +:1068AB0043FE01C2901268B4221263E31264092200 +:1068BB002274F112068A74FC12063390F9A8E024B4 +:1068CB0000F0A3E03470F090F9A8C3E09400A3E0CB +:1068DB009480400C90F9A8E02400F0A3E03480F001 +:1068EB0090FB52E0FE90F9A5E0F50CE4F50DF50EEA +:1068FB00F50F7410780C1204AD90F9A6E0F508A30F +:10690B00E0F509E4F50AF50B780C79081204CC854F +:10691B001082851183780C12053AEEF98510828569 +:10692B001183780812052BAA08AB09AC0AAD0B1220 +:10693B00648E74041206497F080206EA74F8120684 +:10694B008A740812067EE0F8A3E08015A3AA82AB36 +:10695B00838C828D83A3AC82AD83E824FF18E9344A +:10696B00FFF9E87001E960248A828B83E0FE8C8258 +:10697B008D83E06E8A828B8360D2E0F88C828D836C +:10698B00E0FAE8C39AFAE49400FB80047A007B00F7 +:10699B007F010206EA74F712068A740912067EE07A +:1069AB00FEA3E0FFEAF8EBF980188C828D83E08878 +:1069BB00828983F0A3A882A9838C828D83A3AC8266 +:1069CB00AD838E088F0974FF25081E74FF3509FFF0 +:1069DB00E5087002E50970D27F020206EA74F7122D +:1069EB00068A740912067EE0F8A3E0F9EAFEEBFFD3 +:1069FB008A088B09C3EA9CEB9D405EEC28F582ED7F +:106A0B0039F583C3E5829508E5839509404BEA2860 +:106A1B00FAEB39FBAC82AD83126A767002E5096042 +:106A2B0041EC24FF1CED34FFFDEA24FF1AEB34FF8D +:106A3B00FB8C828D83E08A828B83F080DB8C828D52 +:106A4B0083E08A828B83F08C828D83A3AC82AD83AF +:106A5B008A828B83A3AA82AB83126A767002E509C2 +:106A6B0070DBEEFAEFFB7F020206EA8808890974F5 +:106A7B00FF25081874FF3509F9E5082274F812068A +:106A8B008A740812067EE0F8A3E0F98A828B838071 +:106A9B0003ECF0A3E8FEE9FF74FF2E1874FF3FF937 +:0B6AAB00EE7001EF70EB7F010206EAC5 +:04000005000000E90E +:00000001FF diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.ccsproject b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.ccsproject new file mode 100755 index 0000000..fb1bc89 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.ccsproject @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.cdtbuild b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.cdtbuild new file mode 100755 index 0000000..fcd4a32 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.cdtbuild @@ -0,0 +1,896 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.cdtproject b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.cdtproject new file mode 100755 index 0000000..fa82503 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.cdtproject @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.project b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.project new file mode 100755 index 0000000..28ab14c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.project @@ -0,0 +1,20 @@ + + + ez430_chronos_datalogger + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + com.ti.ccstudio.managedbuild.core.ccsNature + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.settings/org.eclipse.cdt.managedbuilder.core.prefs b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.settings/org.eclipse.cdt.managedbuilder.core.prefs new file mode 100755 index 0000000..ad18ca8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/.settings/org.eclipse.cdt.managedbuilder.core.prefs @@ -0,0 +1,35 @@ +#Wed Nov 03 14:36:44 CET 2010 +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1031097535/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1031097535/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1079752688/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1079752688/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1516359669/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1516359669/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.16580540/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.16580540/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.193329876/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.193329876/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1934951040/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1934951040/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1976430675/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1976430675/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.2073861884/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.2073861884/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.347057253/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.347057253/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.434572269/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.434572269/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.513051802/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.513051802/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.743520591/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.743520591/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.916524374/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.916524374/internalBuilder/ignoreErr=true +eclipse.preferences.version=1 +environment/project=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.1079752688=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.1934951040=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.1976430675=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.2073861884=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.434572269=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.513051802=\r\n\r\n diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/CC430F6137.ccxml b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/CC430F6137.ccxml new file mode 100755 index 0000000..f2be62d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/CC430F6137.ccxml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_433MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_433MHz.lib new file mode 100755 index 0000000..5c81259 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_433MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_868MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_868MHz.lib new file mode 100755 index 0000000..d14e7de Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_868MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_915MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_915MHz.lib new file mode 100755 index 0000000..3057022 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_915MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_API.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_API.h new file mode 100755 index 0000000..049c99f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/BlueRobin_RX_API.h @@ -0,0 +1,157 @@ +// ************************************************************************************************* +// +// Copyright 2009 BM innovations GmbH (www.bm-innovations.com), all rights reserved. +// +// This trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC" may be used for non-profit non-commercial purposes only. If you want to use +// BlueRobin(TM) in a commercial project, please contact the copyright holder for a +// separate license agreement. +// +// By using this trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC", you implicitly agree that you will not modify, adapt, disassemble, decompile, +// reverse engineer, translate or otherwise attempt to discover the source code of the +// "BlueRobin(TM) receiver library for the Texas Instruments CC430 SoC". +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// +// Public header for eZ430-Chronos specific BlueRobin(TM) receiver library. +// +// The following BlueRobin(TM) profiles are supported by this build +// - heart rate (HR) transmitter +// +// The following number of channels is supported: 1 +// +// ************************************************************************************************* +// +// BlueRobin(TM) packet size +// ------------------------- +// +// * average packet rate 1 packet/875 msec = ~1.14 packets/second +// * payload per packet 5 bytes +// +// BlueRobin(TM) frequency overview +// (Please note: Settings apply for the transmitter side, i.e. the USB dongle) +// ---------------------------------------------------------------------- +// +// Bluerobin_RX_433MHz.lib (433MHz ISM band) +// +// * frequency 433.30 MHz - 434.00 MHz +// * deviation 95 kHz +// * channels 3 +// * data rate 250 kBaud +// +// Bluerobin_RX_868MHz.lib (868MHz ISM band) +// +// * frequency 868.25 MHz - 868.95 MHz +// * deviation 95 kHz +// * channels 3 +// * data rate 250 kBaud +// +// +// Bluerobin_RX_915MHz.lib (915MHz ISM band) +// +// * frequency 914.35 MHz - 917.75 MHz +// * deviation 95 kHz +// * channels 34 +// * data rate 250 kBaud +// +// ************************************************************************************************* + +#ifndef BRRX_API_H_ +#define BRRX_API_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Defines section + +// List of all possible channel states +typedef enum +{ + TX_OFF = 0, // Powerdown mode + TX_ACTIVE, // Active mode + TX_SEARCH // Search mode +} brtx_state_t; + +// Transmitter to channel assignment +#define HR_CHANNEL (0) + +// ************************************************************************************************* +// API section + +// ---------------------------------------------------------- +// Functions for initializing and controlling the library + +// Initialize several global variables. +void BRRX_Init_v(void); + +// Set delay after which a channel will be switched off if no new data can be received. +// Param1: Powerdown delay in packet intervals (875 ms) +void BRRX_SetPowerdownDelay_v(u8 Delay_u8); + +// Set timeout when searching for a transmitter +// Param1: Search timeout in seconds +void BRRX_SetSearchTimeout_v(u8 Timeout_u8); + +// Set reduction of valid signal level in learn mode. +// Param1: Reduction of signal level +void BRRX_SetSignalLevelReduction_v(u8 Reduction_u8); + +// Set ID for a channel. To search for an unknown transmitter the ID has to be set to 0. +// Can be only executed on channels currently in powerdown mode. +// Param1: Channel index +// Param2: New ID +void BRRX_SetID_v(u8 Index_u8, u32 ID_u32); + +// Get current ID of channel. +// Return: Current ID of channel +// Param1: Channel index +u32 BRRX_GetID_u32(u8 Index_u8); + +// Start reception on one or all channels. +// Param1: Channel index (use 0xFF to start all channels) +void BRRX_Start_v(u8 Index_u8); + +// Stop reception on one or all channels. +// Param1: Channel index (0xFF for all channels) +void BRRX_Stop_v(u8 Index_u8); + +// Get current state of a channel +// Param1: Channel index +brtx_state_t BRRX_GetState_t(u8 Index_u8); + +// ---------------------------------------------------------- +// eZ430-Chronos specific functions + +// Get current heart rate. +// Return: Heart rate in bpm +u8 BRRX_GetHeartRate_u8(void); + +// Get current distance. +// Return: Distance in 10m steps. +u16 BRRX_GetDistance_u16(void); + +// Get current speed. +// Return: Speed in 0.1km/h steps. Trial version is limited to 25.5km/h. +u8 BRRX_GetSpeed_u8(void); + +// ---------------------------------------------------------- +// Radio-related functions + +// RX packet end service function +// Must be called by CC1101_VECTOR ISR +void BlueRobin_RadioISR_v(void); + +#endif /*BRRX_API_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/bm.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/bm.h new file mode 100755 index 0000000..781b1e1 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/bluerobin/bm.h @@ -0,0 +1,480 @@ +// ************************************************************************************************* +// +// Copyright 2009 BM innovations GmbH (www.bm-innovations.com), all rights reserved. +// +// This trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC" may be used for non-profit non-commercial purposes only. If you want to use +// BlueRobin(TM) in a commercial project, please contact the copyright holder for a +// separate license agreement. +// +// By using this trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC", you implicitly agree that you will not modify, adapt, disassemble, decompile, +// reverse engineer, translate or otherwise attempt to discover the source code of the +// "BlueRobin(TM) receiver library for the Texas Instruments CC430 SoC". +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Standard definitions, have to be included in every source and header file. +// ************************************************************************************************* + +#ifndef __BM_H +#define __BM_H + +#if (defined __IAR_SYSTEMS_ASM) || (defined __IAR_SYSTEMS_ASM__) +# define _ASSEMBLER_USED_ +#endif + +#ifndef _ASSEMBLER_USED_ +# include +#endif + +#ifndef FALSE +// the classic false +# define FALSE (0 == 1) +#endif + +#ifndef TRUE +// the classic true +# define TRUE (1 == 1) +#endif + +#ifndef USE_RAW_ATTR +// per default this feature is disabled +# define USE_RAW_ATTR FALSE +#endif + +// ************************************************************************************************* +// First Section: Basic Data Types +// ************************************************************************************************* + +// Fundamental #definitions +// CPU target idents are used for target dependent compilations + +// Texas Instruments MSP430 +#define _TI_MSP430_ (16) + +// Find the currently running compiler +// and make the related #define's + +// _IAR_TID_ target ID from IAR compilers +// _CPU_TID_ remap to enum of processor target numbers +// _CPU_8BIT_INT_ type for 8 bit int +// _CPU_16BIT_INT_ type for 16 bit int +// _CPU_32BIT_INT_ type for 32 bit int +// _CPU_32BIT_FLOAT_ type for 32 bit float +// _CPU_64BIT_FLOAT_ type for 64 bit float +// INTERRUPT declares an interrupt service routine without an entry in the vector +// table +// ISR(vector) declares an interrupt service routine which is added in vector table at +// offset vector +// MONITOR declares a function atomic +// INTERRUPTS_ENABLE remap to the intrinsic for enable interrupts +// INTERRUPTS_DISABLE remap to the intrinsic for disable interrupts +// NO_OPERATION remap to the intrinsic for no operation +// _CPU_DIRECTION_OUT_1_ if TRUE the direction register indicates with an 1: direction is output +// _CPU_EDGE_HIGH_LOW_1_ if TRUE the edge select register indicates with an 1: trigger on high +// low +// NO_INIT declare a variable as not initialized +// INLINE_FUNC declare a function as inline for release builds + +#if ((defined __IAR_SYSTEMS_ICC) || (defined __IAR_SYSTEMS_ASM)) && (__IAR_SYSTEMS_ICC__ < 2) +// Found IAR Compiler with classic IAR frontend +# ifndef _IAR_TID_ +# define _IAR_TID_ ((__TID__ >> 8) & 0x7f) +# endif + +# define INTERRUPT interrupt +# define ISR(vector) interrupt[(vector)] +# define MONITOR monitor + +# if ((_IAR_TID_) == 43) +// Found Texas Instruments MSP430 CPU +# define _CPU_TID_ _TI_MSP430_ +# define _CPU_DIRECTION_OUT_1_ TRUE +# define _CPU_EDGE_HIGH_LOW_1_ TRUE +# define INTERRUPTS_ENABLE() _EINT() +// WA for HW bug, add a NOP +# define INTERRUPTS_DISABLE() { _DINT(); _NOP(); } +# define NO_OPERATION() _NOP() + +# else +# error "Unknown IAR Compiler, the file bm.h has to be expanded !" +# endif + +#elif defined __IAR_SYSTEMS_ICC__ +// Found IAR Compiler with EDG frontend +# define _IAR_TID_ ((__TID__ >> 8) & 0x7f) + +# if USE_RAW_ATTR == TRUE +// Use the raw attribute in ISR's +# define _RAW __raw +# else +// Empty define RAW as it is not used +# define _RAW +# endif +# define INTERRUPT _RAW __interrupt +# define MONITOR __monitor +# define NO_INIT __no_init +# define INTERRUPTS_ENABLE() __enable_interrupt() +# define INTERRUPTS_DISABLE() __disable_interrupt() +# define NO_OPERATION() __no_operation() + +# ifndef DEBUG +// Force inlining of function in release builds +# define INLINE_FUNC PRAGMA(inline = forced) +# else +// Do not force inlining of function in debug builds +# define INLINE_FUNC +# endif + +# if (!defined CODECHECK) && (!defined __DA_C__) +// Define to a new way of using #pragmas in preprocessor +# define PRAGMA(x) _Pragma(# x) +# define ISR(x) PRAGMA(vector = (x)) INTERRUPT +# endif + +# if ((_IAR_TID_) == 43) +// Found Texas Instruments MSP430 CPU (V2) +# define _CPU_TID_ _TI_MSP430_ +# define _CPU_DIRECTION_OUT_1_ TRUE +# define _CPU_EDGE_HIGH_LOW_1_ TRUE +# define _CPU_64BIT_INT_ long long +# if __VER__ < 220 +// WA for HW bug, add a nop after DINT, Compiler has a bugfix since version 2.20 +# undef INTERRUPTS_DISABLE +# define INTERRUPTS_DISABLE() { __disable_interrupt(); __no_operation(); } +# endif + +# else +# error "Unknown new IAR Compiler, the file bm.h has to be expanded !" +# endif + +#elif defined __CCE__ +// Found CCE Compiler +# define INTERRUPT __interrupt +# define MONITOR // __monitor +# define NO_INIT __no_init +# define INTERRUPTS_ENABLE() __enable_interrupt() +# define INTERRUPTS_DISABLE() __disable_interrupt() +# define NO_OPERATION() __no_operation() + +# ifndef DEBUG +// Force inlining of function in release builds +# define INLINE_FUNC PRAGMA(inline = forced) +# else +// Do not force inlining of function in debug builds +# define INLINE_FUNC +# endif + +// Found Texas Instruments MSP430 CPU (V2) +# define _CPU_TID_ _TI_MSP430_ +# define _CPU_DIRECTION_OUT_1_ TRUE +# define _CPU_EDGE_HIGH_LOW_1_ TRUE +//#define _CPU_64BIT_INT_ long long + +// #endif + +#else +# error "Unknown Compiler, the file bm.h has to be expanded !" +#endif + +#ifndef _ASSEMBLER_USED_ +// Get the limits to autodetect the size of integral types +# include +// Get floats to autodetect the size of float types +# include + +// *********************************************************************************************** +// +// Common basic data types +// +// *********************************************************************************************** +# if UCHAR_MAX == 0xFFu +# define _CPU_8BIT_INT_ char +# else +# error "unable to get size of u8 automatically" +# endif + +# if USHRT_MAX == 0xFFFFu +# define _CPU_16BIT_INT_ short +# elif UINT_MAX == 0xFFFFu +# define _CPU_16BIT_INT_ int +# else +# error "unable to get size of u16 automatically" +# endif + +# if USHRT_MAX == 0xFFFFFFFFu +# define _CPU_32BIT_INT_ short +# elif UINT_MAX == 0xFFFFFFFFu +# define _CPU_32BIT_INT_ int +# elif ULONG_MAX == 0xFFFFFFFFu +# define _CPU_32BIT_INT_ long +# else +# error "unable to get size of u32 automatically" +# endif + +# ifdef __IAR_SYSTEMS_ICC__ +# if __IAR_SYSTEMS_ICC__ > 1 +# define _CPU_32BIT_FLOAT_ float +# if __DOUBLE_SIZE__ == 8 +# define _CPU_64BIT_FLOAT_ double +# endif +# endif +# endif + +# ifndef _CPU_32BIT_FLOAT_ +# if FLT_MANT_DIG == 24 +# define _CPU_32BIT_FLOAT_ float +# elif DBL_MANT_DIG == 24 +# define _CPU_32BIT_FLOAT_ double +# else +# error "unable to get size of f32 automatically" +# endif + +# if DBL_MANT_DIG == 53 +# define _CPU_64BIT_FLOAT_ double +# endif +# endif + +// *********************************************************************************************** +// +// Following lines #typedef the basic data types in a compiler independent way. +// +// *********************************************************************************************** + +# ifdef _CPU_8BIT_INT_ +// unsigned 8 bit +typedef unsigned _CPU_8BIT_INT_ u8; +// unsigned 8 bit max value +# define U8_MAX (0xFFU) +// signed 8 bit max value +typedef signed _CPU_8BIT_INT_ s8; +// signed 8 bit min value +# define S8_MIN (-127 - 1) +// signed 8 bit max value +# define S8_MAX (127) +# endif + +# ifdef _CPU_16BIT_INT_ +// unsigned 16 bit +typedef unsigned _CPU_16BIT_INT_ u16; +// unsigned 16 bit max value +# define U16_MAX (0xFFFFU) +// signed 16 bit +typedef signed _CPU_16BIT_INT_ s16; +// signed 16 bit min value +# define S16_MIN (-32767 - 1) +// signed 16 bit max value +# define S16_MAX (32767) +# endif + +# ifdef _CPU_32BIT_INT_ +// unsigned 32 bit +typedef unsigned _CPU_32BIT_INT_ u32; +// unsigned 32 bit max value +# define U32_MAX (0xFFFFFFFFUL) +// signed 32 bit +typedef signed _CPU_32BIT_INT_ s32; +// signed 32 bit min value +# define S32_MIN (-2147483647L - 1L) +// signed 32 bit max value +# define S32_MAX (2147483647L) +# endif + +# ifdef _CPU_64BIT_INT_ +// unsigned 64 bit +typedef unsigned _CPU_64BIT_INT_ u64; +// signed 64 bit +typedef signed _CPU_64BIT_INT_ s64; +# endif + +# ifdef _CPU_32BIT_FLOAT_ +// float 32 bit +typedef _CPU_32BIT_FLOAT_ f32; +// number of digits in mantissa of f32 +# define F32_MANT_DIG (24) +// epsilon for f32 +# define F32_EPSILON (1.192092896e-07) +// number of digits of precision of f32 +# define F32_DIG (6) +// exponent min of f32 +# define F32_MIN_EXP (-125) +// min positive value of f32 +# define F32_MIN (1.175494351e-38) +// decimal exponent min of f32 +# define F32_MIN_10_EXP (-37) +// exponent max of f32 +# define F32_MAX_EXP (128) +// max value of f32 +# define F32_MAX (3.402823466e+38) +// decimal exponent max of f32 +# define F32_MAX_10_EXP (38) +# endif + +# ifdef _CPU_64BIT_FLOAT_ +// float 64 bit +typedef _CPU_64BIT_FLOAT_ f64; +// number of digits in mantissa of f64 +# define F64_MANT_DIG (53) +// epsilon for f64 +# define F64_EPSILON (2.2204460492503131e-016) +// number of digits of precision of f64 +# define F64_DIG (15) +// exponent min of f64 +# define F64_MIN_EXP (-1021) +// min positive value of f64 +# define F64_MIN (2.2250738585072014e-308) +// decimal exponent min of f64 +# define F64_MIN_10_EXP (-307) +// exponent max of f64 +# define F64_MAX_EXP (1024) +// max value of f64 +# define F64_MAX (1.7976931348623158e+308) +// decimal exponent max of f64 +# define F64_MAX_10_EXP (308) +# endif + +typedef unsigned char BYTE; +typedef unsigned int WORD; +typedef unsigned long DWORD; + +#endif // _ASSMEBLER_USED_ + +// A macro that calculates the number of bits of a given type +#ifndef BITSIZEOF +# define BITSIZEOF(type) (sizeof(type) * CHAR_BIT) +#endif + +/* A macro that generates a bit mask according to a given bit number. + * Example: + * - BIT(0) expands to 1 (== 0x01) + * - BIT(3) expands to 8 (== 0x08) + */ +#define BIT(x) (1uL << (x)) + +/* A macro that generates a bit mask according to a given bit number with a cast to type. + * The difference to BIT(X) is the additional type argument T that is used to cast the type of the + * constant 1 and the type of the result as well. + * Example: + * - BIT_T(u8,0) expands to (u8)1 (== 0x01) + * - BIT_T(u32,3) expands to (u32)8 (== 0x08L) + */ +#define BIT_T(t, x) ((t)((t)1 << (x))) + +/* A macro to calculate the position of the highest bit. + * The result is same as LOG2 in case only one bit is set. Use with constant values only because + * of code size. + */ +#define BIT_HIGHEST(Input_u32) ( \ + ((Input_u32) & BIT(31)) ? 31 : ( \ + ((Input_u32) & BIT(30)) ? 30 : ( \ + ((Input_u32) & BIT(29)) ? 29 : ( \ + ((Input_u32) & BIT(28)) ? 28 : ( \ + ((Input_u32) & BIT(27)) ? 27 : ( \ + ((Input_u32) & BIT(26)) ? 26 : ( \ + ((Input_u32) & BIT(25)) ? 25 : ( \ + ((Input_u32) & BIT(24)) ? 24 : ( \ + ((Input_u32) & BIT(23)) ? 23 : ( \ + ((Input_u32) & BIT(22)) ? 22 : ( \ + ((Input_u32) & BIT(21)) ? 21 : ( \ + ((Input_u32) & BIT(20)) ? 20 : ( \ + ((Input_u32) & BIT(19)) ? 19 : ( \ + ((Input_u32) & BIT(18)) ? 18 : ( \ + ((Input_u32) & BIT(17)) ? 17 : ( \ + ((Input_u32) & BIT(16)) ? 16 : ( \ + ((Input_u32) & \ + BIT(15)) ? 15 : ( \ + ((Input_u32) & \ + BIT(14)) ? 14 : ( \ + ((Input_u32) & \ + BIT(13)) ? 13 : ( \ + ((Input_u32) & \ + BIT(12)) ? 12 \ + : ( \ + ((Input_u32) \ + & BIT(11)) \ + ? 11 : ( \ + (( \ + Input_u32) \ + & BIT( \ + 10)) ? 10 : ( \ + (( \ + Input_u32) \ + & \ + BIT(9)) ? 9 : ( \ + (( \ + Input_u32) \ + & \ + BIT(8)) ? 8 : ( \ + (( \ + Input_u32) \ + & \ + BIT(7)) ? 7 : ( \ + (( \ + Input_u32) \ + & \ + BIT(6)) ? 6 : ( \ + (( \ + Input_u32) \ + & \ + BIT(5)) ? 5 : ( \ + (( \ + Input_u32) \ + & \ + BIT(4)) ? 4 : ( \ + (( \ + Input_u32) \ + & \ + BIT(3)) ? 3 : ( \ + (( \ + Input_u32) \ + & \ + BIT(2)) ? 2 : ( \ + (( \ + Input_u32) \ + & \ + BIT(1)) ? 1 : ( \ + (( \ + Input_u32) \ + & \ + BIT(0)) ? 0 : -1uL)))))))))))))))))))))))))))))))) + +#ifndef MONITOR +# define MONITOR +#endif + +#ifndef NO_INIT +# define NO_INIT +#endif + +#ifndef INTERRUPT +# define INTERRUPT +#endif + +#ifndef ISR +# define ISR(ignore) +#endif + +#ifndef INLINE_FUNC +# define INLINE_FUNC +#endif + +#ifndef INTERRUPTS_ENABLE +# define INTERRUPTS_ENABLE() +#endif + +#ifndef INTERRUPTS_DISABLE +# define INTERRUPTS_DISABLE() +#endif + +#endif // __BM_H diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/change_record.txt b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/change_record.txt new file mode 100755 index 0000000..d1dccb2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/change_record.txt @@ -0,0 +1,35 @@ +V1.6 (21.11.2010) +Fixed following bugs +- rfsimpliciti.c/simpliciti_sync_decode_ap_cmd_callback(), +- timer.c/TIMER0_A0_ISR() LCD shows "done" after successfully received data +- main.c/wakeup_event(), +- rfbsl.c/sx_rfbsl() rfBSL requires two button presses in order to update watch +- timer.c/Timer0_A3_Start() Fixed register read (Asynchronous) +- timer.c/Timer0_A4_Delay() Fixed register read (Asynchronous) + Avoid unwanted flag changes caused by interrupt methods +- port.c/PORT2_ISR() and timer.c/TIMER0_A0_ISR() Changes the menu if the pressed time from STAR or NUM button are between "short(50ms)" and "long(3s)" + The backlight stays 3 seconds on +- display.c Removed file display1.c. The content is now in display.c +- display.h Fixed LCD_UNIT_L1_PER_S_MASK bit + +Other changes: +- DCO settling time Set to 375000 cycles + +__________________________________________________________________________________________________________________________________________________ +V1.5 (16.03.2010) +Fixed following bugs +- main.c/init_application() Changed XT1 drive level to highest to avoid ACLK noise when turning on backlight. +- main.c/wakeup_event(), timer.c/TIMER0_A0_ISR() Modified key lock procedure. +- vti_ps.c/ps_get_temp() Negative °C are now converted correctly to Kelvin + +Other changes +- main.c/read_calibration_values() Added range check for rf_frequoffset variable + Added bytes for altitude offset correction and s/w version +- altitude.h, altitude.c Added initial altitude offset correction +- SimpliciTI Added SimpliciTI sources to project. Upgraded to Version 1.1.1. +- RFBSL Added wireless update support +- Button names Changed button names from M1/M2/S1/S2/BL to STAR/NUM/UP/DOWN/BACKLIGHT + +__________________________________________________________________________________________________________________________________________________ +V1.4 (22.11.2009) +First version released to manufacturing. \ No newline at end of file diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/adc12.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/adc12.c new file mode 100755 index 0000000..07f13cc --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/adc12.c @@ -0,0 +1,164 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// ADC12 functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include + +// driver +#include "adc12.h" +#include "timer.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +u16 adc12_result; +u8 adc12_data_ready; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn adc12_single_conversion +// @brief Init ADC12. Do single conversion. Turn off ADC12. +// @param u16 ref Select reference +// u16 sht Sample-and-hold time +// u16 channel Channel of the conversion +// @return u16 adc12_result Return ADC result +// ************************************************************************************************* +u16 adc12_single_conversion(u16 ref, u16 sht, u16 channel) +{ + // Initialize the shared reference module + REFCTL0 |= REFMSTR + ref + REFON; // Enable internal reference (1.5V or 2.5V) + + // Initialize ADC12_A + ADC12CTL0 = sht + ADC12ON; // Set sample time + ADC12CTL1 = ADC12SHP; // Enable sample timer + ADC12MCTL0 = ADC12SREF_1 + channel; // ADC input channel + ADC12IE = 0x001; // ADC_IFG upon conv result-ADCMEMO + + // Wait 2 ticks (66us) to allow internal reference to settle + Timer0_A4_Delay(2); + + // Start ADC12 + ADC12CTL0 |= ADC12ENC; + + // Clear data ready flag + adc12_data_ready = 0; + + // Sampling and conversion start + ADC12CTL0 |= ADC12SC; + + // Delay to get next ADC value + Timer0_A4_Delay(5); + while (!adc12_data_ready) ; + + // Shut down ADC12 + ADC12CTL0 &= ~(ADC12ENC | ADC12SC | sht); + ADC12CTL0 &= ~ADC12ON; + + // Shut down reference voltage + REFCTL0 &= ~(REFMSTR + ref + REFON); + + ADC12IE = 0; + + // Return ADC result + return (adc12_result); +} + +// ************************************************************************************************* +// @fn ADC12ISR +// @brief Store ADC12 conversion result. Set flag to indicate data ready. +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=ADC12_VECTOR +__interrupt void ADC12ISR(void) +{ + switch (__even_in_range(ADC12IV, 34)) + { + case 0: + break; // Vector 0: No interrupt + case 2: + break; // Vector 2: ADC overflow + case 4: + break; // Vector 4: ADC timing overflow + case 6: // Vector 6: ADC12IFG0 + adc12_result = ADC12MEM0; // Move results, IFG is cleared + adc12_data_ready = 1; + _BIC_SR_IRQ(LPM3_bits); // Exit active CPU + break; + case 8: + break; // Vector 8: ADC12IFG1 + case 10: + break; // Vector 10: ADC12IFG2 + case 12: + break; // Vector 12: ADC12IFG3 + case 14: + break; // Vector 14: ADC12IFG4 + case 16: + break; // Vector 16: ADC12IFG5 + case 18: + break; // Vector 18: ADC12IFG6 + case 20: + break; // Vector 20: ADC12IFG7 + case 22: + break; // Vector 22: ADC12IFG8 + case 24: + break; // Vector 24: ADC12IFG9 + case 26: + break; // Vector 26: ADC12IFG10 + case 28: + break; // Vector 28: ADC12IFG11 + case 30: + break; // Vector 30: ADC12IFG12 + case 32: + break; // Vector 32: ADC12IFG13 + case 34: + break; // Vector 34: ADC12IFG14 + default: + break; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/adc12.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/adc12.h new file mode 100755 index 0000000..90fc327 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/adc12.h @@ -0,0 +1,57 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ADC12_H_ +#define ADC12_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern u16 adc12_single_conversion(u16 ref, u16 sht, u16 channel); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +extern u16 adc12_result; +extern u8 adc12_data_ready; + +// ************************************************************************************************* +// Extern section + +#endif /*ADC12_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/buzzer.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/buzzer.c new file mode 100755 index 0000000..ec5df8b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/buzzer.c @@ -0,0 +1,220 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Buzzer functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "buzzer.h" +#include "timer.h" +#include "display.h" + +// logic + +// ************************************************************************************************* +// Prototypes section +void toggle_buzzer(void); +void countdown_buzzer(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct buzzer sBuzzer; + +// ************************************************************************************************* +// Extern section +//extern u16 timer0_A3_ticks_g; + +// ************************************************************************************************* +// @fn reset_buzzer +// @brief Init buzzer variables +// @param none +// @return none +// ************************************************************************************************* +void reset_buzzer(void) +{ + sBuzzer.time = 0; + sBuzzer.state = BUZZER_OFF; +} + +// ************************************************************************************************* +// @fn start_buzzer +// @brief Start buzzer output for a number of cylces +// @param u8 cycles Keep buzzer output for number of cycles +// u16 on_time Output buzzer for "on_time" ACLK ticks +// u16 off_time Do not output buzzer for "off_time" ACLK ticks +// @return none +// ************************************************************************************************* +void start_buzzer(u8 cycles, u16 on_time, u16 off_time) +{ + // Store new buzzer duration while buzzer is off + if (sBuzzer.time == 0) + { + sBuzzer.time = cycles; + sBuzzer.on_time = on_time; + sBuzzer.off_time = off_time; + + // Need to init every time, because SimpliciTI claims same timer + + // Reset TA1R, set up mode, TA1 runs from 32768Hz ACLK + TA1CTL = TACLR | MC_1 | TASSEL__ACLK; + + // Set PWM frequency + TA1CCR0 = BUZZER_TIMER_STEPS; + + // Enable IRQ, set output mode "toggle" + TA1CCTL0 = OUTMOD_4; + + // Allow buzzer PWM output on P2.7 + P2SEL |= BIT7; + + // Activate Timer0_A3 periodic interrupts + fptr_Timer0_A3_function = toggle_buzzer; + Timer0_A3_Start(sBuzzer.on_time); + + // Preload timer advance variable + sTimer.timer0_A3_ticks = sBuzzer.off_time; + + // Start with buzzer output on + sBuzzer.state = BUZZER_ON_OUTPUT_ENABLED; + } +} + +// ************************************************************************************************* +// @fn toggle_buzzer +// @brief Keeps track of buzzer on/off duty cycle +// @param none +// @return none +// ************************************************************************************************* +void toggle_buzzer(void) +{ + // Turn off buzzer + if (sBuzzer.state == BUZZER_ON_OUTPUT_ENABLED) + { + // Stop PWM timer + TA1CTL &= ~(BIT4 | BIT5); + + // Reset and disable buzzer PWM output + P2OUT &= ~BIT7; + P2SEL &= ~BIT7; + + // Update buzzer state + sBuzzer.state = BUZZER_ON_OUTPUT_DISABLED; + + // Reload Timer0_A4 IRQ to restart output + sTimer.timer0_A3_ticks = sBuzzer.on_time; + } + else // Turn on buzzer + { + // Decrement buzzer total cycles + countdown_buzzer(); + + // Reload Timer0_A4 to stop output if sBuzzer.time > 0 + if (sBuzzer.state != BUZZER_OFF) + { + // Reset timer TA1 + TA1R = 0; + TA1CTL |= MC_1; + + // Enable buzzer PWM output + P2SEL |= BIT7; + + // Update buzzer state + sBuzzer.state = BUZZER_ON_OUTPUT_ENABLED; + + // Reload Timer0_A4 IRQ to turn off output + sTimer.timer0_A3_ticks = sBuzzer.off_time; + } + } +} + +// ************************************************************************************************* +// @fn stop_buzzer +// @brief Stop buzzer output +// @param none +// @return none +// ************************************************************************************************* +void stop_buzzer(void) +{ + // Stop PWM timer + TA1CTL &= ~(BIT4 | BIT5); + + // Disable buzzer PWM output + P2OUT &= ~BIT7; + P2SEL &= ~BIT7; + + // Clear PWM timer interrupt + TA1CCTL0 &= ~CCIE; + + // Disable periodic start/stop interrupts + Timer0_A3_Stop(); + + // Clear variables + reset_buzzer(); +} + +// ************************************************************************************************* +// @fn is_buzzer +// @brief Check if buzzer is operating +// @param none +// @return u8 1 = Buzzer is operating, 0 = Buzzer is off +// ************************************************************************************************* +u8 is_buzzer(void) +{ + return (sBuzzer.state != BUZZER_OFF); +} + +// ************************************************************************************************* +// @fn countdown_buzzer +// @brief Decrement active buzzer time. Turn off buzzer if cycle end reached. +// @param none +// @return none +// ************************************************************************************************* +void countdown_buzzer(void) +{ + // Stop buzzer when reaching 0 cycles + if (--sBuzzer.time == 0) + { + stop_buzzer(); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/buzzer.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/buzzer.h new file mode 100755 index 0000000..59fbba9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/buzzer.h @@ -0,0 +1,87 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BUZZER_H_ +#define BUZZER_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_buzzer(void); +extern void start_buzzer(u8 cycles, u16 on_time, u16 off_time); +extern void stop_buzzer(void); +extern void toggle_buzzer(void); +extern u8 is_buzzer(void); +extern void countdown_buzzer(void); + +// ************************************************************************************************* +// Defines section + +// Buzzer states +#define BUZZER_OFF (0u) +#define BUZZER_ON_OUTPUT_DISABLED (1u) +#define BUZZER_ON_OUTPUT_ENABLED (2u) + +// Buzzer output signal frequency = 32,768kHz/(BUZZER_TIMER_STEPS+1)/2 = 2.7kHz +#define BUZZER_TIMER_STEPS (5u) + +// Buzzer on time +#define BUZZER_ON_TICKS (CONV_MS_TO_TICKS(20)) + +// Buzzer off time +#define BUZZER_OFF_TICKS (CONV_MS_TO_TICKS(200)) + +// ************************************************************************************************* +// Global Variable section +struct buzzer +{ + // Keep output for "time" seconds + u8 time; + + // On/off duty + u16 on_time; + u16 off_time; + + // Current buzzer output state + u8 state; +}; +extern struct buzzer sBuzzer; + +// ************************************************************************************************* +// Extern section + +#endif /*BUZZER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/display.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/display.c new file mode 100755 index 0000000..c249f04 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/display.c @@ -0,0 +1,759 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Display functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include +#include + +// driver +#include "display.h" + +// logic +#include "clock.h" +#include "user.h" +#include "date.h" +#include "temperature.h" + +// ************************************************************************************************* +// Prototypes section +void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state); +void clear_line(u8 line); +void display_symbol(u8 symbol, u8 mode); +void display_char(u8 segment, u8 chr, u8 mode); +void display_chars(u8 segments, u8 * str, u8 mode); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// Table with memory bit assignment for digits "0" to "9" and characters "A" to "Z" +const u8 lcd_font[] = { + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F, // Displays "0" + SEG_B + SEG_C, // Displays "1" + SEG_A + SEG_B + SEG_D + SEG_E + SEG_G, // Displays "2" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_G, // Displays "3" + SEG_B + SEG_C + SEG_F + SEG_G, // Displays "4" + SEG_A + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "5" + SEG_A + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "6" + SEG_A + SEG_B + SEG_C, // Displays "7" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "8" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "9" + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + SEG_D + SEG_E + SEG_G, // Displays "c" + 0, // Displays " " + SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G, // Displays "A" + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "b" + SEG_A + SEG_D + SEG_E + SEG_F, // Displays "C" + SEG_B + SEG_C + SEG_D + SEG_E + SEG_G, // Displays "d" + SEG_A + +SEG_D + SEG_E + SEG_F + SEG_G, // Displays "E" + SEG_A + SEG_E + SEG_F + SEG_G, // Displays "F" + // SEG_A+ SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "G" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "g" + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G, // Displays "H" + SEG_E + SEG_F, // Displays "I" + SEG_A + SEG_B + SEG_C + SEG_D, // Displays "J" + // SEG_B+SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "k" + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "k" + SEG_D + SEG_E + SEG_F, // Displays "L" + SEG_A + SEG_B + SEG_C + SEG_E + SEG_F, // Displays "M" + SEG_C + SEG_E + SEG_G, // Displays "n" + SEG_C + SEG_D + SEG_E + SEG_G, // Displays "o" + SEG_A + SEG_B + SEG_E + SEG_F + SEG_G, // Displays "P" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F, // Displays "Q" + SEG_E + SEG_G, // Displays "r" + SEG_A + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "S" + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "t" + SEG_C + SEG_D + SEG_E, // Displays "u" + SEG_C + SEG_D + SEG_E, // Displays "u" + SEG_G, // Displays "-" + SEG_B + SEG_C + +SEG_E + SEG_F + SEG_G, // Displays "X" + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "Y" + SEG_A + SEG_B + SEG_D + SEG_E + SEG_G, // Displays "Z" +}; + +// Table with memory address for each display element +const u8 *segments_lcdmem[] = { + LCD_SYMB_AM_MEM, + LCD_SYMB_PM_MEM, + LCD_SYMB_ARROW_UP_MEM, + LCD_SYMB_ARROW_DOWN_MEM, + LCD_SYMB_PERCENT_MEM, + LCD_SYMB_TOTAL_MEM, + LCD_SYMB_AVERAGE_MEM, + LCD_SYMB_MAX_MEM, + LCD_SYMB_BATTERY_MEM, + LCD_UNIT_L1_FT_MEM, + LCD_UNIT_L1_K_MEM, + LCD_UNIT_L1_M_MEM, + LCD_UNIT_L1_I_MEM, + LCD_UNIT_L1_PER_S_MEM, + LCD_UNIT_L1_PER_H_MEM, + LCD_UNIT_L1_DEGREE_MEM, + LCD_UNIT_L2_KCAL_MEM, + LCD_UNIT_L2_KM_MEM, + LCD_UNIT_L2_MI_MEM, + LCD_ICON_HEART_MEM, + LCD_ICON_STOPWATCH_MEM, + LCD_ICON_RECORD_MEM, + LCD_ICON_ALARM_MEM, + LCD_ICON_BEEPER1_MEM, + LCD_ICON_BEEPER2_MEM, + LCD_ICON_BEEPER3_MEM, + LCD_SEG_L1_3_MEM, + LCD_SEG_L1_2_MEM, + LCD_SEG_L1_1_MEM, + LCD_SEG_L1_0_MEM, + LCD_SEG_L1_COL_MEM, + LCD_SEG_L1_DP1_MEM, + LCD_SEG_L1_DP0_MEM, + LCD_SEG_L2_5_MEM, + LCD_SEG_L2_4_MEM, + LCD_SEG_L2_3_MEM, + LCD_SEG_L2_2_MEM, + LCD_SEG_L2_1_MEM, + LCD_SEG_L2_0_MEM, + LCD_SEG_L2_COL1_MEM, + LCD_SEG_L2_COL0_MEM, + LCD_SEG_L2_DP_MEM, +}; + +// Table with bit mask for each display element +const u8 segments_bitmask[] = { + LCD_SYMB_AM_MASK, + LCD_SYMB_PM_MASK, + LCD_SYMB_ARROW_UP_MASK, + LCD_SYMB_ARROW_DOWN_MASK, + LCD_SYMB_PERCENT_MASK, + LCD_SYMB_TOTAL_MASK, + LCD_SYMB_AVERAGE_MASK, + LCD_SYMB_MAX_MASK, + LCD_SYMB_BATTERY_MASK, + LCD_UNIT_L1_FT_MASK, + LCD_UNIT_L1_K_MASK, + LCD_UNIT_L1_M_MASK, + LCD_UNIT_L1_I_MASK, + LCD_UNIT_L1_PER_S_MASK, + LCD_UNIT_L1_PER_H_MASK, + LCD_UNIT_L1_DEGREE_MASK, + LCD_UNIT_L2_KCAL_MASK, + LCD_UNIT_L2_KM_MASK, + LCD_UNIT_L2_MI_MASK, + LCD_ICON_HEART_MASK, + LCD_ICON_STOPWATCH_MASK, + LCD_ICON_RECORD_MASK, + LCD_ICON_ALARM_MASK, + LCD_ICON_BEEPER1_MASK, + LCD_ICON_BEEPER2_MASK, + LCD_ICON_BEEPER3_MASK, + LCD_SEG_L1_3_MASK, + LCD_SEG_L1_2_MASK, + LCD_SEG_L1_1_MASK, + LCD_SEG_L1_0_MASK, + LCD_SEG_L1_COL_MASK, + LCD_SEG_L1_DP1_MASK, + LCD_SEG_L1_DP0_MASK, + LCD_SEG_L2_5_MASK, + LCD_SEG_L2_4_MASK, + LCD_SEG_L2_3_MASK, + LCD_SEG_L2_2_MASK, + LCD_SEG_L2_1_MASK, + LCD_SEG_L2_0_MASK, + LCD_SEG_L2_COL1_MASK, + LCD_SEG_L2_COL0_MASK, + LCD_SEG_L2_DP_MASK, +}; + +// Quick integer to array conversion table for most common integer values +const u8 int_to_array_conversion_table[][3] = { + "000", "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", + "013", "014", "015", + "016", "017", "018", "019", "020", "021", "022", "023", "024", "025", "026", "027", "028", + "029", "030", "031", + "032", "033", "034", "035", "036", "037", "038", "039", "040", "041", "042", "043", "044", + "045", "046", "047", + "048", "049", "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", "060", + "061", "062", "063", + "064", "065", "066", "067", "068", "069", "070", "071", "072", "073", "074", "075", "076", + "077", "078", "079", + "080", "081", "082", "083", "084", "085", "086", "087", "088", "089", "090", "091", "092", + "093", "094", "095", + "096", "097", "098", "099", "100", "101", "102", "103", "104", "105", "106", "107", "108", + "109", "110", "111", + "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", + "125", "126", "127", + "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", + "141", "142", "143", + "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", + "157", "158", "159", + "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", + "173", "174", "175", + "176", "177", "178", "179", "180", +}; + +// Display flags +volatile s_display_flags display; + +// Global return string for int_to_array function +u8 int_to_array_str[8]; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); +extern void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn lcd_init +// @brief Erase LCD memory. Init LCD peripheral. +// @param none +// @return none +// ************************************************************************************************* +void lcd_init(void) +{ + // Clear entire display memory + LCDBMEMCTL |= LCDCLRBM + LCDCLRM; + + // LCD_FREQ = ACLK/16/8 = 256Hz + // Frame frequency = 256Hz/4 = 64Hz, LCD mux 4, LCD on + LCDBCTL0 = (LCDDIV0 + LCDDIV1 + LCDDIV2 + LCDDIV3) | (LCDPRE0 + LCDPRE1) | LCD4MUX | LCDON; + + // LCB_BLK_FREQ = ACLK/8/4096 = 1Hz + LCDBBLKCTL = LCDBLKPRE0 | LCDBLKPRE1 | LCDBLKDIV0 | LCDBLKDIV1 | LCDBLKDIV2 | LCDBLKMOD0; + + // I/O to COM outputs + P5SEL |= (BIT5 | BIT6 | BIT7); + P5DIR |= (BIT5 | BIT6 | BIT7); + + // Activate LCD output + LCDBPCTL0 = 0xFFFF; // Select LCD segments S0-S15 + LCDBPCTL1 = 0x00FF; // Select LCD segments S16-S22 + +#ifdef USE_LCD_CHARGE_PUMP + // Charge pump voltage generated internally, internal bias (V2-V4) generation + LCDBVCTL = LCDCPEN | VLCD_2_72; +#endif +} + +// ************************************************************************************************* +// @fn clear_display_all +// @brief Erase LINE1 and LINE2 segments. Clear also function-specific content. +// @param none +// @return none +// ************************************************************************************************* +void clear_display_all(void) +{ + // Clear generic content + clear_line(LINE1); + clear_line(LINE2); + + // Clean up function-specific content + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_CLEAR); + +} + +// ************************************************************************************************* +// @fn clear_display +// @brief Erase LINE1 and LINE2 segments. Keep icons. +// @param none +// @return none +// ************************************************************************************************* +void clear_display(void) +{ + clear_line(LINE1); + clear_line(LINE2); +} + +// ************************************************************************************************* +// @fn clear_line +// @brief Erase segments of a given line. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void clear_line(u8 line) +{ + display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_5_0), NULL, SEG_OFF); + if (line == LINE1) + { + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + display_symbol(LCD_SEG_L1_DP0, SEG_OFF); + display_symbol(LCD_SEG_L1_COL, SEG_OFF); + } + else // line == LINE2 + { + display_symbol(LCD_SEG_L2_DP, SEG_OFF); + display_symbol(LCD_SEG_L2_COL1, SEG_OFF); + display_symbol(LCD_SEG_L2_COL0, SEG_OFF); + } +} + +// ************************************************************************************************* +// @fn write_segment +// @brief Write to one or multiple LCD segments +// @param lcdmem Pointer to LCD byte memory +// bits Segments to address +// bitmask Bitmask for particular display item +// mode On, off or blink segments +// @return +// ************************************************************************************************* +void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state) +{ + if (state == SEG_ON) + { + // Clear segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (u8) (*lcdmem | bits); + } + else if (state == SEG_OFF) + { + // Clear segments + *lcdmem = (u8) (*lcdmem & ~bitmask); + } + else if (state == SEG_ON_BLINK_ON) + { + // Clear visible / blink segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + + // Set visible / blink segments + *lcdmem = (u8) (*lcdmem | bits); + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) | bits); + } + else if (state == SEG_ON_BLINK_OFF) + { + // Clear visible segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (u8) (*lcdmem | bits); + + // Clear blink segments + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + } + else if (state == SEG_OFF_BLINK_OFF) + { + // Clear segments + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Clear blink segments + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + } +} + +// ************************************************************************************************* +// @fn int_to_array +// @brief Generic integer to array routine. Converts integer n to string. +// Default conversion result has leading zeros, e.g. "00123" +// Option to convert leading '0' into whitespace (blanks) +// @param u32 n integer to convert +// u8 digits number of digits +// u8 blanks fill up result string with number of +// whitespaces instead of leading zeros +// @return u8 string +// ************************************************************************************************* +u8 *int_to_array(u32 n, u8 digits, u8 blanks) +{ + u8 i; + u8 digits1 = digits; + + // Preset result string + memcpy(int_to_array_str, "0000000", 7); + + // Return empty string if number of digits is invalid (valid range for digits: 1-7) + if ((digits == 0) || (digits > 7)) + return (int_to_array_str); + + // Numbers 0 .. 180 can be copied from int_to_array_conversion_table without conversion + if (n <= 180) + { + if (digits >= 3) + { + memcpy(int_to_array_str + (digits - 3), int_to_array_conversion_table[n], 3); + } + else // digits == 1 || 2 + { + memcpy(int_to_array_str, int_to_array_conversion_table[n] + (3 - digits), digits); + } + } + else // For n > 180 need to calculate string content + { + // Calculate digits from least to most significant number + do + { + int_to_array_str[digits - 1] = n % 10 + '0'; + n /= 10; + } + while (--digits > 0); + } + + // Remove specified number of leading '0', always keep last one + i = 0; + while ((int_to_array_str[i] == '0') && (i < digits1 - 1)) + { + if (blanks > 0) + { + // Convert only specified number of leading '0' + int_to_array_str[i] = ' '; + blanks--; + } + i++; + } + + return (int_to_array_str); +} + +// ************************************************************************************************* +// @fn display_value +// @brief Generic decimal display routine. Used exclusively by set_value function. +// @param u8 segments LCD segments where value is displayed +// u32 value Integer value to be displayed +// u8 digits Number of digits to convert +// u8 blanks Number of leadings blanks in +// int_to_array result string +// @return none +// ************************************************************************************************* +void display_value(u8 segments, u32 value, u8 digits, u8 blanks) +{ + u8 *str; + + str = int_to_array(value, digits, blanks); + + // Display string in blink mode + display_chars(segments, str, SEG_ON_BLINK_ON); +} + +// ************************************************************************************************* +// @fn display_hours +// @brief Display hours in 24H / 12H time format. +// @param u8 segments Segments where to display hour data +// u32 value Hour data +// u8 digits Must be "2" +// u8 blanks Must be "0" +// @return none +// ************************************************************************************************* +void display_hours(u8 segments, u32 value, u8 digits, u8 blanks) +{ + u8 hours; + + if (sys.flag.use_metric_units) + { + // Display hours in 24H time format + display_value(segments, (u16) value, digits, blanks); + } + else + { + // convert internal 24H time format to 12H time format + hours = convert_hour_to_12H_format(value); + + // display hours in 12H time format + display_value(segments, hours, digits, blanks); + display_am_pm_symbol(value); + } +} + +// ************************************************************************************************* +// @fn display_am_pm_symbol +// @brief Display AM or PM symbol. +// @param u8 hour 24H internal time format +// @return none +// ************************************************************************************************* +void display_am_pm_symbol(u8 hour) +{ + // Display AM/PM symbol + if (is_hour_am(hour)) + { + display_symbol(LCD_SYMB_AM, SEG_ON); + } + else + { + // Clear AM segments first - required when changing from AM to PM + display_symbol(LCD_SYMB_AM, SEG_OFF); + display_symbol(LCD_SYMB_PM, SEG_ON); + } +} + +// ************************************************************************************************* +// @fn display_symbol +// @brief Switch symbol on or off on LCD. +// @param u8 symbol A valid LCD symbol (index 0..42) +// u8 state SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_symbol(u8 symbol, u8 mode) +{ + u8 *lcdmem; + u8 bits; + u8 bitmask; + + if (symbol <= LCD_SEG_L2_DP) + { + // Get LCD memory address for symbol from table + lcdmem = (u8 *) segments_lcdmem[symbol]; + + // Get bits for symbol from table + bits = segments_bitmask[symbol]; + + // Bitmask for symbols equals bits + bitmask = bits; + + // Write LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + +// ************************************************************************************************* +// @fn display_char +// @brief Write to 7-segment characters. +// @param u8 segment A valid LCD segment +// u8 chr Character to display +// u8 mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_char(u8 segment, u8 chr, u8 mode) +{ + u8 *lcdmem; // Pointer to LCD memory + u8 bitmask; // Bitmask for character + u8 bits, bits1; // Bits to write + + // Write to single 7-segment character + if ((segment >= LCD_SEG_L1_3) && (segment <= LCD_SEG_L2_DP)) + { + // Get LCD memory address for segment from table + lcdmem = (u8 *) segments_lcdmem[segment]; + + // Get bitmask for character from table + bitmask = segments_bitmask[segment]; + + // Get bits from font set + if ((chr >= 0x30) && (chr <= 0x5A)) + { + // Use font set + bits = lcd_font[chr - 0x30]; + } + else if (chr == 0x2D) + { + // '-' not in font set + bits = BIT1; + } + else + { + // Other characters map to ' ' (blank) + bits = 0; + } + + // When addressing LINE2 7-segment characters need to swap high- and low-nibble, + // because LCD COM/SEG assignment is mirrored against LINE1 + if (segment >= LCD_SEG_L2_5) + { + bits1 = ((bits << 4) & 0xF0) | ((bits >> 4) & 0x0F); + bits = bits1; + + // When addressing LCD_SEG_L2_5, need to convert ASCII '1' and 'L' to 1 bit, + // because LCD COM/SEG assignment is special for this incomplete character + if (segment == LCD_SEG_L2_5) + { + if ((chr == '1') || (chr == 'L')) + bits = BIT7; + } + } + + // Physically write to LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + +// ************************************************************************************************* +// @fn display_chars +// @brief Write to consecutive 7-segment characters. +// @param u8 segments LCD segment array +// u8 * str Pointer to a string +// u8 mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_chars(u8 segments, u8 * str, u8 mode) +{ + u8 i; + u8 length = 0; // Write length + u8 char_start; // Starting point for consecutive write + + switch (segments) + { + // LINE1 + case LCD_SEG_L1_3_0: + length = 4; + char_start = LCD_SEG_L1_3; + break; + case LCD_SEG_L1_2_0: + length = 3; + char_start = LCD_SEG_L1_2; + break; + case LCD_SEG_L1_1_0: + length = 2; + char_start = LCD_SEG_L1_1; + break; + case LCD_SEG_L1_3_1: + length = 3; + char_start = LCD_SEG_L1_3; + break; + case LCD_SEG_L1_3_2: + length = 2; + char_start = LCD_SEG_L1_3; + break; + + // LINE2 + case LCD_SEG_L2_5_0: + length = 6; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_4_0: + length = 5; + char_start = LCD_SEG_L2_4; + break; + case LCD_SEG_L2_3_0: + length = 4; + char_start = LCD_SEG_L2_3; + break; + case LCD_SEG_L2_2_0: + length = 3; + char_start = LCD_SEG_L2_2; + break; + case LCD_SEG_L2_1_0: + length = 2; + char_start = LCD_SEG_L2_1; + break; + case LCD_SEG_L2_5_4: + length = 2; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_5_2: + length = 4; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_3_2: + length = 2; + char_start = LCD_SEG_L2_3; + break; + case LCD_SEG_L2_4_2: + length = 3; + char_start = LCD_SEG_L2_4; + break; + } + + // Write to consecutive digits + for (i = 0; i < length; i++) + { + // Use single character routine to write display memory + display_char(char_start + i, *(str + i), mode); + } +} + +// ************************************************************************************************* +// @fn switch_seg +// @brief Returns index of 7-segment character. Required for display routines that can draw +// information on both lines. +// @param u8 line LINE1 or LINE2 +// u8 index1 Index of LINE1 +// u8 index2 Index of LINE2 +// @return uint8 +// ************************************************************************************************* +u8 switch_seg(u8 line, u8 index1, u8 index2) +{ + if (line == LINE1) + { + return index1; + } + else // line == LINE2 + { + return index2; + } +} + +// ************************************************************************************************* +// @fn start_blink +// @brief Start blinking. +// @param none +// @return none +// ************************************************************************************************* +void start_blink(void) +{ + LCDBBLKCTL |= LCDBLKMOD0; +} + +// ************************************************************************************************* +// @fn stop_blink +// @brief Stop blinking. +// @param none +// @return none +// ************************************************************************************************* +void stop_blink(void) +{ + LCDBBLKCTL &= ~LCDBLKMOD0; +} + +// ************************************************************************************************* +// @fn stop_blink +// @brief Clear blinking memory. +// @param none +// @return none +// ************************************************************************************************* +void clear_blink_mem(void) +{ + LCDBMEMCTL |= LCDCLRBM; +} + +// ************************************************************************************************* +// @fn set_blink_rate +// @brief Set blink rate register bits. +// @param none +// @return none +// ************************************************************************************************* +void set_blink_rate(u8 bits) +{ + LCDBBLKCTL &= ~(BIT7 | BIT6 | BIT5); + LCDBBLKCTL |= bits; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/display.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/display.h new file mode 100755 index 0000000..044c3bd --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/display.h @@ -0,0 +1,338 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef __DISPLAY_H +#define __DISPLAY_H + +// ************************************************************************************************* +// Include section + +#include + +// ************************************************************************************************* +// Extern section + +// Constants defined in library +extern const u8 lcd_font[]; +extern const u8 *segments_lcdmem[]; +extern const u8 segments_bitmask[]; +extern const u8 int_to_array_conversion_table[][3]; + +// ************************************************************************************************* +// Global Variable section + +// Set of display flags +typedef union +{ + struct + { + // Line1 + Line2 + Icons + u16 full_update : 1; // 1 = Redraw all content + u16 partial_update : 1; // 1 = Update changes + + // Line only + u16 line1_full_update : 1; // 1 = Redraw Line1 content + u16 line2_full_update : 1; // 1 = Redraw Line2 content + + // Logic module data update flags + u16 update_time : 1; // 1 = Time was updated + u16 update_stopwatch : 1; // 1 = Stopwatch was updated + u16 update_temperature : 1; // 1 = Temperature was updated + u16 update_battery_voltage : 1; // 1 = Battery voltage was updated + u16 update_date : 1; // 1 = Date was updated + u16 update_alarm : 1; // 1 = Alarm time was updated + u16 update_acceleration : 1; // 1 = Acceleration data was updated + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_display_flags; +extern volatile s_display_flags display; + +// ************************************************************************************************* +// Defines section + +// Display function modes +#define DISPLAY_LINE_UPDATE_FULL (BIT0) +#define DISPLAY_LINE_UPDATE_PARTIAL (BIT1) +#define DISPLAY_LINE_CLEAR (BIT2) + +// Definitions for line view style +#define DISPLAY_DEFAULT_VIEW (0u) +#define DISPLAY_ALTERNATIVE_VIEW (1u) + +// Definitions for line access +#define LINE1 (1u) +#define LINE2 (2u) + +// LCD display modes +#define SEG_OFF (0u) +#define SEG_ON (1u) +#define SEG_ON_BLINK_ON (2u) +#define SEG_ON_BLINK_OFF (3u) +#define SEG_OFF_BLINK_OFF (4u) + +// 7-segment character bit assignments +#define SEG_A (BIT4) +#define SEG_B (BIT5) +#define SEG_C (BIT6) +#define SEG_D (BIT7) +#define SEG_E (BIT2) +#define SEG_F (BIT0) +#define SEG_G (BIT1) + +// ------------------------------------------ +// LCD symbols for easier access +// +// xxx_SEG_xxx = Seven-segment character (sequence 5-4-3-2-1-0) +// xxx_SYMB_xxx = Display symbol, e.g. "AM" for ante meridiem +// xxx_UNIT_xxx = Display unit, e.g. "km/h" for kilometers per hour +// xxx_ICON_xxx = Display icon, e.g. heart to indicate reception of heart rate data +// xxx_L1_xxx = Item is part of Line1 information +// xxx_L2_xxx = Item is part of Line2 information + +// Symbols for Line1 +#define LCD_SYMB_AM 0 +#define LCD_SYMB_PM 1 +#define LCD_SYMB_ARROW_UP 2 +#define LCD_SYMB_ARROW_DOWN 3 +#define LCD_SYMB_PERCENT 4 + +// Symbols for Line2 +#define LCD_SYMB_TOTAL 5 +#define LCD_SYMB_AVERAGE 6 +#define LCD_SYMB_MAX 7 +#define LCD_SYMB_BATTERY 8 + +// Units for Line1 +#define LCD_UNIT_L1_FT 9 +#define LCD_UNIT_L1_K 10 +#define LCD_UNIT_L1_M 11 +#define LCD_UNIT_L1_I 12 +#define LCD_UNIT_L1_PER_S 13 +#define LCD_UNIT_L1_PER_H 14 +#define LCD_UNIT_L1_DEGREE 15 + +// Units for Line2 +#define LCD_UNIT_L2_KCAL 16 +#define LCD_UNIT_L2_KM 17 +#define LCD_UNIT_L2_MI 18 + +// Icons +#define LCD_ICON_HEART 19 +#define LCD_ICON_STOPWATCH 20 +#define LCD_ICON_RECORD 21 +#define LCD_ICON_ALARM 22 +#define LCD_ICON_BEEPER1 23 +#define LCD_ICON_BEEPER2 24 +#define LCD_ICON_BEEPER3 25 + +// Line1 7-segments +#define LCD_SEG_L1_3 26 +#define LCD_SEG_L1_2 27 +#define LCD_SEG_L1_1 28 +#define LCD_SEG_L1_0 29 +#define LCD_SEG_L1_COL 30 +#define LCD_SEG_L1_DP1 31 +#define LCD_SEG_L1_DP0 32 + +// Line2 7-segments +#define LCD_SEG_L2_5 33 +#define LCD_SEG_L2_4 34 +#define LCD_SEG_L2_3 35 +#define LCD_SEG_L2_2 36 +#define LCD_SEG_L2_1 37 +#define LCD_SEG_L2_0 38 +#define LCD_SEG_L2_COL1 39 +#define LCD_SEG_L2_COL0 40 +#define LCD_SEG_L2_DP 41 + +// Line1 7-segment arrays +#define LCD_SEG_L1_3_0 70 +#define LCD_SEG_L1_2_0 71 +#define LCD_SEG_L1_1_0 72 +#define LCD_SEG_L1_3_1 73 +#define LCD_SEG_L1_3_2 74 + +// Line2 7-segment arrays +#define LCD_SEG_L2_5_0 90 +#define LCD_SEG_L2_4_0 91 +#define LCD_SEG_L2_3_0 92 +#define LCD_SEG_L2_2_0 93 +#define LCD_SEG_L2_1_0 94 +#define LCD_SEG_L2_5_2 95 +#define LCD_SEG_L2_3_2 96 +#define LCD_SEG_L2_5_4 97 +#define LCD_SEG_L2_4_2 98 + +// LCD controller memory map +#define LCD_MEM_1 ((u8*)0x0A20) +#define LCD_MEM_2 ((u8*)0x0A21) +#define LCD_MEM_3 ((u8*)0x0A22) +#define LCD_MEM_4 ((u8*)0x0A23) +#define LCD_MEM_5 ((u8*)0x0A24) +#define LCD_MEM_6 ((u8*)0x0A25) +#define LCD_MEM_7 ((u8*)0x0A26) +#define LCD_MEM_8 ((u8*)0x0A27) +#define LCD_MEM_9 ((u8*)0x0A28) +#define LCD_MEM_10 ((u8*)0x0A29) +#define LCD_MEM_11 ((u8*)0x0A2A) +#define LCD_MEM_12 ((u8*)0x0A2B) + +// Memory assignment +#define LCD_SEG_L1_0_MEM (LCD_MEM_6) +#define LCD_SEG_L1_1_MEM (LCD_MEM_4) +#define LCD_SEG_L1_2_MEM (LCD_MEM_3) +#define LCD_SEG_L1_3_MEM (LCD_MEM_2) +#define LCD_SEG_L1_COL_MEM (LCD_MEM_1) +#define LCD_SEG_L1_DP1_MEM (LCD_MEM_1) +#define LCD_SEG_L1_DP0_MEM (LCD_MEM_5) +#define LCD_SEG_L2_0_MEM (LCD_MEM_8) +#define LCD_SEG_L2_1_MEM (LCD_MEM_9) +#define LCD_SEG_L2_2_MEM (LCD_MEM_10) +#define LCD_SEG_L2_3_MEM (LCD_MEM_11) +#define LCD_SEG_L2_4_MEM (LCD_MEM_12) +#define LCD_SEG_L2_5_MEM (LCD_MEM_12) +#define LCD_SEG_L2_COL1_MEM (LCD_MEM_1) +#define LCD_SEG_L2_COL0_MEM (LCD_MEM_5) +#define LCD_SEG_L2_DP_MEM (LCD_MEM_9) +#define LCD_SYMB_AM_MEM (LCD_MEM_1) +#define LCD_SYMB_PM_MEM (LCD_MEM_1) +#define LCD_SYMB_ARROW_UP_MEM (LCD_MEM_1) +#define LCD_SYMB_ARROW_DOWN_MEM (LCD_MEM_1) +#define LCD_SYMB_PERCENT_MEM (LCD_MEM_5) +#define LCD_SYMB_TOTAL_MEM (LCD_MEM_11) +#define LCD_SYMB_AVERAGE_MEM (LCD_MEM_10) +#define LCD_SYMB_MAX_MEM (LCD_MEM_8) +#define LCD_SYMB_BATTERY_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_FT_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_K_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_M_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_I_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_PER_S_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_PER_H_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_DEGREE_MEM (LCD_MEM_5) +#define LCD_UNIT_L2_KCAL_MEM (LCD_MEM_7) +#define LCD_UNIT_L2_KM_MEM (LCD_MEM_7) +#define LCD_UNIT_L2_MI_MEM (LCD_MEM_7) +#define LCD_ICON_HEART_MEM (LCD_MEM_2) +#define LCD_ICON_STOPWATCH_MEM (LCD_MEM_3) +#define LCD_ICON_RECORD_MEM (LCD_MEM_1) +#define LCD_ICON_ALARM_MEM (LCD_MEM_4) +#define LCD_ICON_BEEPER1_MEM (LCD_MEM_5) +#define LCD_ICON_BEEPER2_MEM (LCD_MEM_6) +#define LCD_ICON_BEEPER3_MEM (LCD_MEM_7) + +// Bit masks for write access +#define LCD_SEG_L1_0_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_1_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_2_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_3_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_COL_MASK (BIT5) +#define LCD_SEG_L1_DP1_MASK (BIT6) +#define LCD_SEG_L1_DP0_MASK (BIT2) +#define LCD_SEG_L2_0_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_1_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_2_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_3_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_4_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_5_MASK (BIT7) +#define LCD_SEG_L2_COL1_MASK (BIT4) +#define LCD_SEG_L2_COL0_MASK (BIT0) +#define LCD_SEG_L2_DP_MASK (BIT7) +#define LCD_SYMB_AM_MASK (BIT1 + BIT0) +#define LCD_SYMB_PM_MASK (BIT0) +#define LCD_SYMB_ARROW_UP_MASK (BIT2) +#define LCD_SYMB_ARROW_DOWN_MASK (BIT3) +#define LCD_SYMB_PERCENT_MASK (BIT4) +#define LCD_SYMB_TOTAL_MASK (BIT7) +#define LCD_SYMB_AVERAGE_MASK (BIT7) +#define LCD_SYMB_MAX_MASK (BIT7) +#define LCD_SYMB_BATTERY_MASK (BIT7) +#define LCD_UNIT_L1_FT_MASK (BIT5) +#define LCD_UNIT_L1_K_MASK (BIT6) +#define LCD_UNIT_L1_M_MASK (BIT1) +#define LCD_UNIT_L1_I_MASK (BIT0) +#define LCD_UNIT_L1_PER_S_MASK (BIT7) +#define LCD_UNIT_L1_PER_H_MASK (BIT2) +#define LCD_UNIT_L1_DEGREE_MASK (BIT1) +#define LCD_UNIT_L2_KCAL_MASK (BIT4) +#define LCD_UNIT_L2_KM_MASK (BIT5) +#define LCD_UNIT_L2_MI_MASK (BIT6) +#define LCD_ICON_HEART_MASK (BIT3) +#define LCD_ICON_STOPWATCH_MASK (BIT3) +#define LCD_ICON_RECORD_MASK (BIT7) +#define LCD_ICON_ALARM_MASK (BIT3) +#define LCD_ICON_BEEPER1_MASK (BIT3) +#define LCD_ICON_BEEPER2_MASK (BIT3) +#define LCD_ICON_BEEPER3_MASK (BIT3) + +// ************************************************************************************************* +// API section + +// Physical LCD memory write +extern void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state); + +// Display init / clear +extern void lcd_init(void); +extern void clear_display(void); +extern void clear_display_all(void); +extern void clear_line(u8 line); + +// Blinking function +extern void start_blink(void); +extern void stop_blink(void); +extern void clear_blink_mem(void); +extern void set_blink_rate(u8 bits); + +// Character / symbol draw functions +extern void display_char(u8 segment, u8 chr, u8 mode); +extern void display_chars(u8 segments, u8 * str, u8 mode); +extern void display_symbol(u8 symbol, u8 mode); + +// Time display function +extern void DisplayTime(u8 updateMode); +extern void display_am_pm_symbol(u8 timeAM); + +// Set_value display functions +extern void display_value(u8 segments, u32 value, u8 digits, u8 blanks); +extern void display_hours(u8 segments, u32 value, u8 digits, u8 blanks); + +// Integer to string conversion +extern u8 *int_to_array(u32 n, u8 digits, u8 blanks); + +// Segment index helper function +extern u8 switch_seg(u8 line, u8 index1, u8 index2); + +#endif /*__DISPLAY_H*/ + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/ez430_chronos_datalogger_drivers.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/ez430_chronos_datalogger_drivers.lib new file mode 100755 index 0000000..b100e40 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/ez430_chronos_datalogger_drivers.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/flash.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/flash.c new file mode 100755 index 0000000..2247f4c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/flash.c @@ -0,0 +1,95 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Data logger routines. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// logic +#include "datalog.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Implementation + +void flash_erase_page(u8 page) +{ + // Convert page index to memory address + u16 *wptr = (u16 *) (page * 512); + + // Range check + if ((page < DATALOG_PAGE_START) || (page > DATALOG_PAGE_END)) + return; + + // Wait until not busy + while ((FCTL3 & BUSY) != 0) ; + + __disable_interrupt(); + FCTL3 = FWKEY; // Clear Lock bit + FCTL1 = FWKEY + ERASE; // Set Erase bit + *wptr = 0; // Dummy write to erase Flash seg + FCTL1 = FWKEY + WRT; // Set WRT bit for write operation + FCTL1 = FWKEY; // Clear WRT bit + FCTL3 = FWKEY + LOCK; // Set LOCK bit + __enable_interrupt(); +} + +void flash_write(u16 * wptr, u16 data) +{ + // Range check + //if ((page < DATALOG_MEMORY_START) || (page > DATALOG_MEMORY_END)) return; + + // Wait until not busy + while ((FCTL3 & BUSY) != 0) ; + + __disable_interrupt(); + FCTL3 = FWKEY; // Clear Lock bit + *wptr = 0; // Dummy write to erase Flash seg + FCTL1 = FWKEY + WRT; // Set WRT bit for write operation + *wptr = data; + FCTL1 = FWKEY; // Clear WRT bit + FCTL3 = FWKEY + LOCK; // Set LOCK bit + __enable_interrupt(); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/flash.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/flash.h new file mode 100755 index 0000000..b9cafa9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/flash.h @@ -0,0 +1,44 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef FLASH_H_ +#define FLASH_H_ + +// ************************************************************************************************* +// Extern section +extern void flash_erase_page(u8 page); +extern void flash_write(u16 * wptr, u16 data); + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/pmm.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/pmm.c new file mode 100755 index 0000000..3257e7a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/pmm.c @@ -0,0 +1,78 @@ +//****************************************************************************// +// Function Library for setting the PMM +// +// This file is used in conjunction with PMM.c to set the core +// voltage level of a device. To set a core voltage level, call +// SetVCore(level). See RF project(s) for example usage. +// +// Original programm Stefan Schauer +// Rev 1.1: changed VCoreUp to fit with recommended flow (09/04/2008) +// +//****************************************************************************// +#include "cc430x613x.h" +#include "pmm.h" + +//****************************************************************************// +// Set VCore level +// SetVCore level is called from the user API +//****************************************************************************// +void SetVCore(unsigned char level) // Note: change level by one + // step only +{ + unsigned char actLevel; + + do + { + actLevel = PMMCTL0_L & PMMCOREV_3; + if (actLevel < level) + SetVCoreUp(++actLevel); // Set VCore (step by step) + if (actLevel > level) + SetVCoreDown(--actLevel); // Set VCore (step by step) + } + while (actLevel != level); +} + +//****************************************************************************// +// Set VCore up +//****************************************************************************// +void SetVCoreUp(unsigned char level) // Note: change level by one + // step only +{ + PMMCTL0_H = 0xA5; // Open PMM module registers + // for write access + + SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; // Set SVS/M high side to new + // level + + SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; // Set SVM new Level + while ((PMMIFG & SVSMLDLYIFG) == 0) ; // Wait till SVM is settled + // (Delay) + PMMCTL0_L = PMMCOREV0 * level; // Set VCore to x + PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); // Clear already set flags + if ((PMMIFG & SVMLIFG)) + while ((PMMIFG & SVMLVLRIFG) == 0) ; // Wait till level is reached + + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Set SVS/M Low side to new + // level + PMMCTL0_H = 0x00; // Lock PMM module registers + // for write access +} + +//****************************************************************************// +// Set VCore down +//****************************************************************************// +void SetVCoreDown(unsigned char level) +{ + PMMCTL0_H = 0xA5; // Open PMM module registers + // for write access + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Set SVS/M Low side to new + // level + while ((PMMIFG & SVSMLDLYIFG) == 0) ; // Wait till SVM is settled + // (Delay) + PMMCTL0_L = (level * PMMCOREV0); // Set VCore to 1.85 V for Max + // Speed. + PMMCTL0_H = 0x00; // Lock PMM module registers + // for write access +} + +//****************************************************************************// diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/pmm.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/pmm.h new file mode 100755 index 0000000..170008f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/pmm.h @@ -0,0 +1,43 @@ +//==================================================================== +// File: PMM.h +// +// This file is used in conjunction with PMM.c to set the core +// voltage level of a device. To set a core voltage level, call +// SetVCore(level). See RF project(s) for example usage. +// +// Version 1.0 first +// 07/14/07 +// +//==================================================================== + +#ifndef __PMM +#define __PMM + +//==================================================================== + +/** + * Set the VCore to a new level + * + * \param level PMM level ID + */ +void SetVCore(unsigned char level); + +//==================================================================== + +/** + * Set the VCore to a new higher level + * + * \param level PMM level ID + */ +void SetVCoreUp(unsigned char level); + +//==================================================================== + +/** + * Set the VCore to a new Lower level + * + * \param level PMM level ID + */ +void SetVCoreDown(unsigned char level); + +#endif /* __PMM */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/ports.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/ports.c new file mode 100755 index 0000000..5a83a11 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/ports.c @@ -0,0 +1,440 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Button entry functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "ports.h" +#include "buzzer.h" +#include "vti_as.h" +#include "vti_ps.h" +#include "timer.h" +#include "display.h" + +// logic +#include "clock.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "altitude.h" + +// ************************************************************************************************* +// Prototypes section +void button_repeat_on(u16 msec); +void button_repeat_off(void); +void button_repeat_function(void); + +// ************************************************************************************************* +// Defines section + +// Macro for button IRQ +#define IRQ_TRIGGERED(flags, bit) ((flags & bit) == bit) + +// ************************************************************************************************* +// Global Variable section +volatile s_button_flags button; +volatile struct struct_button sButton; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// @fn init_buttons +// @brief Init and enable button interrupts. +// @param none +// @return none +// ************************************************************************************************* +void init_buttons(void) +{ + // Set button ports to input + BUTTONS_DIR &= ~ALL_BUTTONS; + + // Enable internal pull-downs + BUTTONS_OUT &= ~ALL_BUTTONS; + BUTTONS_REN |= ALL_BUTTONS; + + // IRQ triggers on rising edge + BUTTONS_IES &= ~ALL_BUTTONS; + + // Reset IRQ flags + BUTTONS_IFG &= ~ALL_BUTTONS; + + // Enable button interrupts + BUTTONS_IE |= ALL_BUTTONS; +} + +// ************************************************************************************************* +// @fn PORT2_ISR +// @brief Interrupt service routine for +// - buttons +// - acceleration sensor CMA_INT +// - pressure sensor DRDY +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=PORT2_VECTOR +__interrupt void PORT2_ISR(void) +{ + // Clear flags + u8 int_flag, int_enable; + u8 buzzer = 0; + u8 simpliciti_button_event = 0; + static u8 simpliciti_button_repeat = 0; + + // Remember interrupt enable bits + int_enable = BUTTONS_IE; + + if ((!button.flag.star_long) && (!button.flag.num_long)) + { + // Clear button flags + button.all_flags = 0; + + // Store valid button interrupt flag + int_flag = BUTTONS_IFG & int_enable; + + // --------------------------------------------------- + // While SimpliciTI stack is active, buttons behave differently: + // - Store button events in SimpliciTI packet data + // - Exit SimpliciTI when button DOWN was pressed + if (is_rf()) + { + // Erase previous button press after a number of resends (increase number if link + // quality is low) + // This will create a series of packets containing the same button press + // Necessary because we have no acknowledge + // Filtering (edge detection) will be done by receiver software + if (simpliciti_button_repeat++ > 6) + { + simpliciti_data[0] &= ~0xF0; + simpliciti_button_repeat = 0; + } + + if ((int_flag & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_STAR; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_NUM; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_UP_PIN) == BUTTON_UP_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_UP; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN) + { + simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; + } + + // Trigger packet sending inside SimpliciTI stack + if (simpliciti_button_event) + simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; + } + else // Normal operation + { + // Debounce buttons + if ((int_flag & ALL_BUTTONS) != 0) + { + // Disable PORT2 IRQ + __disable_interrupt(); + BUTTONS_IE = 0x00; + __enable_interrupt(); + + // Debounce delay 1 + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN)); + + // Reset inactivity detection + sTime.last_activity = sTime.system_time; + } + + // --------------------------------------------------- + // STAR button IRQ + if (IRQ_TRIGGERED(int_flag, BUTTON_STAR_PIN)) + { + // Filter bouncing noise + if (BUTTON_STAR_IS_PRESSED) + { + button.flag.star = 1; + button.flag.star_not_long = 0; + // Generate button click + buzzer = 1; + } + else if ((BUTTONS_IES & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) + { + button.flag.star = 1; + button.flag.star_not_long = 0; + BUTTONS_IES &= ~BUTTON_STAR_PIN; + } + } + // --------------------------------------------------- + // NUM button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN)) + { + // Filter bouncing noise + if (BUTTON_NUM_IS_PRESSED) + { + button.flag.num = 1; + button.flag.num_not_long = 0; + // Generate button click + buzzer = 1; + } + else if ((BUTTONS_IES & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) + { + button.flag.num = 1; + button.flag.num_not_long = 0; + BUTTONS_IES &= ~BUTTON_NUM_PIN; + } + } + // --------------------------------------------------- + // UP button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_UP_PIN)) + { + // Filter bouncing noise + if (BUTTON_UP_IS_PRESSED) + { + button.flag.up = 1; + + // Generate button click + buzzer = 1; + } + } + // --------------------------------------------------- + // DOWN button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_DOWN_PIN)) + { + // Filter bouncing noise + if (BUTTON_DOWN_IS_PRESSED) + { + button.flag.down = 1; + + // Generate button click + buzzer = 1; + } + } + // --------------------------------------------------- + // B/L button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_BACKLIGHT_PIN)) + { + // Filter bouncing noise + if (BUTTON_BACKLIGHT_IS_PRESSED) + { + sButton.backlight_status = 1; + sButton.backlight_timeout = 0; + P2OUT |= BUTTON_BACKLIGHT_PIN; + P2DIR |= BUTTON_BACKLIGHT_PIN; + } + } + } + + // Trying to lock/unlock buttons? + if (button.flag.num && button.flag.down) + { + // No buzzer output + buzzer = 0; + button.all_flags = 0; + } + + // Generate button click when button was activated + if (buzzer) + { + + if (!sys.flag.up_down_repeat_enabled) + { + start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150)); + } + + // Debounce delay 2 + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + } + + // --------------------------------------------------- + // Acceleration sensor IRQ + if (IRQ_TRIGGERED(int_flag, AS_INT_PIN)) + { + // Get data from sensor + request.flag.acceleration_measurement = 1; + } + + // --------------------------------------------------- + // Pressure sensor IRQ + if (IRQ_TRIGGERED(int_flag, PS_INT_PIN)) + { + // Get data from sensor + request.flag.altitude_measurement = 1; + } + + // --------------------------------------------------- + // Safe long button event detection + if (button.flag.star || button.flag.num) + { + // Additional debounce delay to enable safe high detection - 50ms + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT)); + + // Check if this button event is short enough + if (BUTTON_STAR_IS_PRESSED) + { + // Change interrupt edge to detect button release + BUTTONS_IES |= BUTTON_STAR_PIN; + button.flag.star = 0; + // This flag is used to detect if the user released the button before the + // time for a long button press (3s) + button.flag.star_not_long = 1; + } + if (BUTTON_NUM_IS_PRESSED) + { + // Change interrupt edge to detect button release + BUTTONS_IES |= BUTTON_NUM_PIN; + button.flag.num = 0; + // This flag is used to detect if the user released the button before the + // time for a long button press (3s) + button.flag.num_not_long = 1; + } + } + } + // Reenable PORT2 IRQ + __disable_interrupt(); + BUTTONS_IFG = 0x00; + BUTTONS_IE = int_enable; + __enable_interrupt(); + + // Exit from LPM3/LPM4 on RETI + __bic_SR_register_on_exit(LPM4_bits); +} + +// ************************************************************************************************* +// @fn button_repeat_on +// @brief Start button auto repeat timer. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_on(u16 msec) +{ + // Set button repeat flag + sys.flag.up_down_repeat_enabled = 1; + + // Set Timer0_A3 function pointer to button repeat function + fptr_Timer0_A3_function = button_repeat_function; + + // Timer0_A3 IRQ triggers every 200ms + Timer0_A3_Start(CONV_MS_TO_TICKS(msec)); +} + +// ************************************************************************************************* +// @fn button_repeat_off +// @brief Stop button auto repeat timer. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_off(void) +{ + // Clear button repeat flag + sys.flag.up_down_repeat_enabled = 0; + + // Timer0_A3 IRQ repeats with 4Hz + Timer0_A3_Stop(); +} + +// ************************************************************************************************* +// @fn button_repeat_function +// @brief Check at regular intervals if button is pushed continuously +// and trigger virtual button event. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_function(void) +{ + static u8 start_delay = 10; // Wait for 2 seconds before starting auto up/down + u8 repeat = 0; + + // If buttons UP or DOWN are continuously high, repeatedly set button flag + if (BUTTON_UP_IS_PRESSED) + { + if (start_delay == 0) + { + // Generate a virtual button event + button.flag.up = 1; + repeat = 1; + } + else + { + start_delay--; + } + } + else if (BUTTON_DOWN_IS_PRESSED) + { + if (start_delay == 0) + { + // Generate a virtual button event + button.flag.down = 1; + repeat = 1; + } + else + { + start_delay--; + } + } + else + { + // Reset repeat counter + sButton.repeats = 0; + start_delay = 10; + + // Enable blinking + start_blink(); + } + + // If virtual button event is generated, stop blinking and reset timeout counter + if (repeat) + { + // Increase repeat counter + sButton.repeats++; + + // Reset inactivity detection counter + sTime.last_activity = sTime.system_time; + + // Disable blinking + stop_blink(); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/ports.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/ports.h new file mode 100755 index 0000000..96c3fc2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/ports.h @@ -0,0 +1,130 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef PORTS_H_ +#define PORTS_H_ + +// ************************************************************************************************* +// Defines section + +// Port, pins and interrupt resources for buttons +#define BUTTONS_IN (P2IN) +#define BUTTONS_OUT (P2OUT) +#define BUTTONS_DIR (P2DIR) +#define BUTTONS_REN (P2REN) +#define BUTTONS_IE (P2IE) +#define BUTTONS_IES (P2IES) +#define BUTTONS_IFG (P2IFG) +#define BUTTONS_IRQ_VECT2 (PORT2_VECTOR) + +// Button ports +#define BUTTON_STAR_PIN (BIT2) +#define BUTTON_NUM_PIN (BIT1) +#define BUTTON_UP_PIN (BIT4) +#define BUTTON_DOWN_PIN (BIT0) +#define BUTTON_BACKLIGHT_PIN (BIT3) +#define ALL_BUTTONS (BUTTON_STAR_PIN + BUTTON_NUM_PIN + BUTTON_UP_PIN + \ + BUTTON_DOWN_PIN + BUTTON_BACKLIGHT_PIN) + +// Macros for button press detection +#define BUTTON_STAR_IS_PRESSED ((BUTTONS_IN & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) +#define BUTTON_NUM_IS_PRESSED ((BUTTONS_IN & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) +#define BUTTON_UP_IS_PRESSED ((BUTTONS_IN & BUTTON_UP_PIN) == BUTTON_UP_PIN) +#define BUTTON_DOWN_IS_PRESSED ((BUTTONS_IN & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN) +#define BUTTON_BACKLIGHT_IS_PRESSED ((BUTTONS_IN & BUTTON_BACKLIGHT_PIN) == \ + BUTTON_BACKLIGHT_PIN) +#define NO_BUTTON_IS_PRESSED ((BUTTONS_IN & ALL_BUTTONS) == 0) + +// Macros for button release detection +#define BUTTON_STAR_IS_RELEASED ((BUTTONS_IN & BUTTON_STAR_PIN) == 0) +#define BUTTON_NUM_IS_RELEASED ((BUTTONS_IN & BUTTON_NUM_PIN) == 0) +#define BUTTON_UP_IS_RELEASED (BUTTONS_IN & BUTTON_UP_PIN) == 0) +#define BUTTON_DOWN_IS_RELEASED ((BUTTONS_IN & BUTTON_DOWN_PIN) == 0) +#define BUTTON_BACKLIGHT_IS_RELEASED ((BUTTONS_IN & BUTTON_BACKLIGHT_PIN) == 0) + +// Button debounce time (msec) +#define BUTTONS_DEBOUNCE_TIME_IN (5u) +#define BUTTONS_DEBOUNCE_TIME_OUT (250u) +#define BUTTONS_DEBOUNCE_TIME_LEFT (50u) + +// Detect if STAR / NUM button is held low continuously +#define LEFT_BUTTON_LONG_TIME (2u) + +// Backlight time (sec) +#define BACKLIGHT_TIME_ON (3u) + +// Leave set_value() function after some seconds of user inactivity +#define INACTIVITY_TIME (30u) + +// Set of button flags +typedef union +{ + struct + { + // Manual button events + u16 star : 1; // Short STAR button press + u16 num : 1; // Short NUM button press + u16 up : 1; // Short UP button press + u16 down : 1; // Short DOWN button press + u16 backlight : 1; // Short BACKLIGHT button press + u16 star_long : 1; // Long STAR button press + u16 num_long : 1; // Long NUM button press + u16 star_not_long : 1; // Between short and long STAR button press + u16 num_not_long : 1; // Between short and long NUM button press + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_button_flags; +extern volatile s_button_flags button; + +struct struct_button +{ + u8 star_timeout; // This variable is incremented once per second if STAR button is + // still pressed + u8 num_timeout; // This variable is incremented once per second if NUM button is + // still pressed + u8 backlight_timeout; // controls the timeout for the backlight + u8 backlight_status; // 1 case backlight is on + s16 repeats; +}; +extern volatile struct struct_button sButton; + +// ************************************************************************************************* +// Extern section +extern void button_repeat_on(u16 msec); +extern void button_repeat_off(void); +extern void button_repeat_function(void); +extern void init_buttons(void); + +#endif /*PORTS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/radio.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/radio.c new file mode 100755 index 0000000..8e5a36b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/radio.c @@ -0,0 +1,187 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// system +#include "project.h" + +// driver +#include "rf1a.h" +#include "timer.h" + +// logic +#include "rfsimpliciti.h" +#include "bluerobin.h" + +// ************************************************************************************************* +// Extern section + +// SimpliciTI CC430 radio ISR - located in SimpliciTi library +extern void MRFI_RadioIsr(void); + +// BlueRobin CC430 radio ISR - located in BlueRobin library +extern void BlueRobin_RadioISR_v(void); + +// ************************************************************************************************* +// @fn radio_reset +// @brief Reset radio core. +// @param none +// @return none +// ************************************************************************************************* +void radio_reset(void) +{ + volatile u16 i; + u8 x; + + // Reset radio core + Strobe(RF_SRES); + // Wait before checking IDLE + for (i = 0; i < 100; i++) ; + do + { + x = Strobe(RF_SIDLE); + } + while ((x & 0x70) != 0x00); + + // Clear radio error register + RF1AIFERR = 0; +} + +// ************************************************************************************************* +// @fn radio_powerdown +// @brief Put radio to SLEEP mode. +// @param none +// @return none +// ************************************************************************************************* +void radio_powerdown(void) +{ + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + // Powerdown radio + Strobe(RF_SIDLE); + Strobe(RF_SPWD); +} + +// ************************************************************************************************* +// @fn radio_sxoff +// @brief Put radio to SLEEP mode (XTAL off only). +// @param none +// @return none +// ************************************************************************************************* +void radio_sxoff(void) +{ + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + // Powerdown radio + Strobe(RF_SIDLE); + Strobe(RF_SXOFF); +} + +// ************************************************************************************************* +// @fn open_radio +// @brief Prepare radio for RF communication. +// @param none +// @return none +// ************************************************************************************************* +void open_radio(void) +{ + // Reset radio core + radio_reset(); + + // Enable radio IRQ + RF1AIFG &= ~BIT4; // Clear a pending interrupt + RF1AIE |= BIT4; // Enable the interrupt +} + +// ************************************************************************************************* +// @fn close_radio +// @brief Shutdown radio for RF communication. +// @param none +// @return none +// ************************************************************************************************* +void close_radio(void) +{ + // Disable radio IRQ + RF1AIFG = 0; + RF1AIE = 0; + + // Reset radio core + radio_reset(); + + // Put radio to sleep + radio_powerdown(); +} + +// ************************************************************************************************* +// @fn GDOx_ISR +// @brief GDO0/2 ISR to detect received packet. +// In BlueRobin mode: capture packet end time and decode received +// packet +// In SimpliciTI mode: go to SimpliciTI handler +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=CC1101_VECTOR +__interrupt void radio_ISR(void) +{ + u8 rf1aivec = RF1AIV; + + // Forward to SimpliciTI interrupt service routine + if (is_rf()) + { + MRFI_RadioIsr(); + } + else // BlueRobin packet end interrupt service routine + { + if (rf1aivec == RF1AIV_RFIFG9) + { + if ((sBlueRobin.state == BLUEROBIN_SEARCHING) || + (sBlueRobin.state == BLUEROBIN_CONNECTED)) + { + BlueRobin_RadioISR_v(); + } + } + else if (rf1aivec == RF1AIV_NONE) // RF1A interface interrupt (error etc.) + { + asm (" nop"); // break here + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/radio.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/radio.h new file mode 100755 index 0000000..f4c1bb9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/radio.h @@ -0,0 +1,48 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RADIO_H_ +#define RADIO_H_ + +extern void radio_reset(void); +extern void radio_powerdown(void); +extern void radio_sxoff(void); +extern void radio_idle(void); +extern void open_radio(void); +extern void close_radio(void); +extern void pmm_set_high_current_mode(void); +extern void pmm_set_low_current_mode(void); + +#endif /*RADIO_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/rf1a.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/rf1a.c new file mode 100755 index 0000000..9f3b5be --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/rf1a.c @@ -0,0 +1,233 @@ +// ************************************************************************************************* +// +// Actual revision: $Revision: $ +// Revision label: $Name: $ +// Revision state: $State: $ +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include + +// driver +#include "rf1a.h" + +// ************************************************************************************************* +// Global section + +// ************************************************************************************************* +// Define section +#define st(x) do { x } while (__LINE__ == -1) +#define ENTER_CRITICAL_SECTION(x) st(x = __get_interrupt_state(); __disable_interrupt(); ) +#define EXIT_CRITICAL_SECTION(x) __set_interrupt_state(x) + +// ************************************************************************************************* +// @fn Strobe +// @brief Send command to radio. +// @param unsigned char strobe Command to radio +// @return statusByte Radio core status +// ************************************************************************************************* +unsigned char Strobe(unsigned char strobe) +{ + u8 statusByte = 0; + u16 int_state, gdo_state; + + // Check for valid strobe command + if ((strobe == 0xBD) || ((strobe > RF_SRES) && (strobe < RF_SNOP))) + { + ENTER_CRITICAL_SECTION(int_state); + + // Clear the Status read flag + RF1AIFCTL1 &= ~(RFSTATIFG); + + // Wait for radio to be ready for next instruction + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + + // Write the strobe instruction + if ((strobe > RF_SRES) && (strobe < RF_SNOP)) + { + + gdo_state = ReadSingleReg(IOCFG2); // buffer IOCFG2 state + WriteSingleReg(IOCFG2, 0x29); // c-ready to GDO2 + + RF1AINSTRB = strobe; + if ((RF1AIN & 0x04) == 0x04) // chip at sleep mode + { + if ((strobe == RF_SXOFF) || (strobe == RF_SPWD) || (strobe == RF_SWOR)) + { + } + else + { + while ((RF1AIN & 0x04) == 0x04) ; // c-ready ? + __delay_cycles(9800); // Delay for ~810usec at 12MHz CPU clock + } + } + WriteSingleReg(IOCFG2, gdo_state); // restore IOCFG2 setting + } + else // chip active mode + { + RF1AINSTRB = strobe; + } + statusByte = RF1ASTATB; + while (!(RF1AIFCTL1 & RFSTATIFG)) ; + EXIT_CRITICAL_SECTION(int_state); + } + return statusByte; +} + +// ************************************************************************************************* +// @fn ResetRadioCore +// @brief Software reset radio core. +// @param none +// @return none +// ************************************************************************************************* +void ResetRadioCore(void) +{ + Strobe(RF_SRES); // Reset the Radio Core + Strobe(RF_SNOP); // Reset Radio Pointer +} + +// ************************************************************************************************* +// @fn ReadSingleReg +// @brief Read byte from register. +// @param none +// @return none +// ************************************************************************************************* +unsigned char ReadSingleReg(unsigned char addr) +{ + unsigned char x; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + RF1AINSTR1B = (addr | RF_REGRD); + x = RF1ADOUT1B; + + EXIT_CRITICAL_SECTION(int_state); + + return x; +} + +// ************************************************************************************************* +// @fn WriteSingleReg +// @brief Write byte to register. +// @param none +// @return none +// ************************************************************************************************* +void WriteSingleReg(unsigned char addr, unsigned char value) +{ + volatile unsigned int i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for the next + // instruction + + RF1AINSTRW = ((addr | RF_REGWR) << 8) + value; // Send address + Instruction + while (!(RFDINIFG & RF1AIFCTL1)) ; + + i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status + // byte + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn ReadBurstReg +// @brief Read sequence of bytes from register. +// @param none +// @return none +// ************************************************************************************************* +void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) +{ + unsigned int i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for next instruction + RF1AINSTR1B = (addr | RF_REGRD); // Send address + Instruction + + for (i = 0; i < (count - 1); i++) + { + while (!(RFDOUTIFG & RF1AIFCTL1)) ; // Wait for the Radio Core to update the RF1ADOUTB reg + buffer[i] = RF1ADOUT1B; // Read DOUT from Radio Core + clears RFDOUTIFG + // Also initiates auo-read for next DOUT byte + } + buffer[count - 1] = RF1ADOUT0B; // Store the last DOUT from Radio Core + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn WriteBurstReg +// @brief Write sequence of bytes to register. +// @param none +// @return none +// ************************************************************************************************* +void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) +{ + // Write Burst works wordwise not bytewise - bug known already + unsigned char i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for next + // instruction + RF1AINSTRW = ((addr | RF_REGWR) << 8) + buffer[0]; // Send address + Instruction + + for (i = 1; i < count; i++) + { + RF1ADINB = buffer[i]; // Send data + while (!(RFDINIFG & RF1AIFCTL1)) ; // Wait for TX to finish + } + i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status + // byte + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn WritePATable +// @brief Write data to power table +// @param unsigned char value Value to write +// @return none +// ************************************************************************************************* +void WritePATable(unsigned char value) +{ + unsigned char readbackPATableValue = 0; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (readbackPATableValue != value) + { + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRW = 0x7E00 + value; // PA Table write (burst) + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; // reset pointer + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = 0xFE; // PA Table read (burst) + + while (!(RF1AIFCTL1 & RFDINIFG)) ; + RF1ADINB = 0x00; //dummy write + + while (!(RF1AIFCTL1 & RFDOUTIFG)) ; + readbackPATableValue = RF1ADOUT0B; + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; + } + + EXIT_CRITICAL_SECTION(int_state); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/rf1a.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/rf1a.h new file mode 100755 index 0000000..f1acd1c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/rf1a.h @@ -0,0 +1,20 @@ +// ************************************************************************************************* +// +// Actual revision: $Revision: $ +// Revision label: $Name: $ +// Revision state: $State: $ +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// ************************************************************************************************* +// Prototype section +unsigned char Strobe(unsigned char strobe); +unsigned char ReadSingleReg(unsigned char addr); +void WriteSingleReg(unsigned char addr, unsigned char value); +void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count); +void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count); +void ResetRadioCore(void); +void WritePATable(unsigned char value); +void WaitForXT2(void); diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/timer.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/timer.c new file mode 100755 index 0000000..428bb68 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/timer.c @@ -0,0 +1,485 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Timer service routines. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "timer.h" +#include "ports.h" +#include "buzzer.h" +#include "vti_ps.h" +#include "vti_as.h" + +// logic +#include "clock.h" +#include "battery.h" +#include "altitude.h" +#include "display.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "acceleration.h" +#include "bluerobin.h" +#include "temperature.h" +#include "datalog.h" + +// ************************************************************************************************* +// Prototypes section +void Timer0_Init(void); +void Timer0_Stop(void); +void Timer0_A1_Start(void); +void Timer0_A1_Stop(void); +void Timer0_A3_Start(u16 ticks); +void Timer0_A3_Stop(void); +void Timer0_A4_Delay(u16 ticks); + +void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct timer sTimer; + +// ************************************************************************************************* +// Extern section +extern void BRRX_TimerTask_v(void); +extern void to_lpm(void); + +// ************************************************************************************************* +// @fn Timer0_Init +// @brief Set Timer0 to a period of 1 or 2 sec. IRQ TACCR0 is asserted when timer overflows. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Init(void) +{ + // Set interrupt frequency to 1Hz + TA0CCR0 = 32768 - 1; + + // Enable timer interrupt + TA0CCTL0 |= CCIE; + + // Clear and start timer now + // Continuous mode: Count to 0xFFFF and restart from 0 again - 1sec timing will be generated by + // ISR + TA0CTL |= TASSEL0 + MC1 + TACLR; +} + +// ************************************************************************************************* +// @fn Timer0_Start +// @brief Start Timer0. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Start(void) +{ + // Start Timer0 in continuous mode + TA0CTL |= MC_2; +} + +// ************************************************************************************************* +// @fn Timer0_Stop +// @brief Stop and reset Timer0. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Stop(void) +{ + // Stop Timer0 + TA0CTL &= ~MC_2; + + // Set Timer0 count register to 0x0000 + TA0R = 0; +} + +// ************************************************************************************************* +// @fn Timer0_A3_Start +// @brief Trigger IRQ every "ticks" microseconds +// @param ticks (1 tick = 1/32768 sec) +// @return none +// ************************************************************************************************* +void Timer0_A3_Start(u16 ticks) +{ + u16 value = 0; + + // Store timer ticks in global variable + sTimer.timer0_A3_ticks = ticks; + + // Delay based on current counter value + // To make sure this value is correctly read + while (value != TA0R) + value = TA0R; + value += ticks; + + // Update CCR + TA0CCR3 = value; + + // Reset IRQ flag + TA0CCTL3 &= ~CCIFG; + + // Enable timer interrupt + TA0CCTL3 |= CCIE; +} + +// ************************************************************************************************* +// @fn Timer0_A3_Stop +// @brief Stop Timer0_A3. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_A3_Stop(void) +{ + // Clear timer interrupt + TA0CCTL3 &= ~CCIE; +} + +// ************************************************************************************************* +// @fn Timer0_A4_Delay +// @brief Wait for some microseconds +// @param ticks (1 tick = 1/32768 sec) +// @return none +// ************************************************************************************************* +void Timer0_A4_Delay(u16 ticks) +{ + u16 value = 0; + + // Exit immediately if Timer0 not running - otherwise we'll get stuck here + if ((TA0CTL & (BIT4 | BIT5)) == 0) + return; + + // Disable timer interrupt + TA0CCTL4 &= ~CCIE; + + // Clear delay_over flag + sys.flag.delay_over = 0; + + // Add delay to current timer value + // To make sure this value is correctly read + while (value != TA0R) + value = TA0R; + value += ticks; + + // Update CCR + TA0CCR4 = value; + + // Reset IRQ flag + TA0CCTL4 &= ~CCIFG; + + // Enable timer interrupt + TA0CCTL4 |= CCIE; + + // Wait for timer IRQ + while (1) + { + // Delay in LPM + to_lpm(); // will also set GIE again + +#ifdef USE_WATCHDOG + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; +#endif + + // Check stop condition + // disable interrupt to prevent flag's change caused by interrupt methods + __disable_interrupt(); + if (sys.flag.delay_over) + break; + } + __enable_interrupt(); +} + +// ************************************************************************************************* +// @fn TIMER0_A0_ISR +// @brief IRQ handler for TIMER0_A0 IRQ +// Timer0_A0 1/1sec clock tick (serviced by +// function TIMER0_A0_ISR) +// Timer0_A1 +// (serviced by function +// TIMER0_A1_5_ISR) +// Timer0_A2 1/100 sec Stopwatch (serviced by +// function TIMER0_A1_5_ISR) +// Timer0_A3 Configurable periodic IRQ (serviced by +// function TIMER0_A1_5_ISR) +// Timer0_A4 One-time delay (serviced by +// function TIMER0_A1_5_ISR) +// @param none +// @return none +// ************************************************************************************************* +#pragma vector = TIMER0_A0_VECTOR +__interrupt void TIMER0_A0_ISR(void) +{ + static u8 button_lock_counter = 0; + + // Disable IE + TA0CCTL0 &= ~CCIE; + // Reset IRQ flag + TA0CCTL0 &= ~CCIFG; + // Add 1 sec to TACCR0 register (IRQ will be asserted at 0x7FFF and 0xFFFF = 1 sec intervals) + TA0CCR0 += 32768; + // Enable IE + TA0CCTL0 |= CCIE; + + // Add 1 second to global time + clock_tick(); + + // Set clock update flag + display.flag.update_time = 1; + + // While BlueRobin searches freeze system state + if (is_bluerobin_searching()) + { + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); + return; + } + + if ((is_rf()) && (sRFsmpl.mode == SIMPLICITI_SYNC)) + { + if (sRFsmpl.display_sync_done == 0) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " SYNC", SEG_ON); + } + else + { + sRFsmpl.display_sync_done--; + } + } + + // ------------------------------------------------------------------- + // Service modules that require 1/min processing + if (sTime.drawFlag >= 2) + { + // Measure battery voltage + request.flag.voltage_measurement = 1; + } + + // ------------------------------------------------------------------- + // Service active modules that require 1/s processing + + // Request data logging + if (is_datalog()) + request.flag.datalog = 1; + + // Request temperature and pressure measurement + if (is_altitude_measurement()) + request.flag.altitude_measurement = 1; + + // Get BlueRobin data from API + if (is_bluerobin()) + get_bluerobin_data(); + + // If battery is low, count down display counter + if (sys.flag.low_battery) + { + if (sBatt.lobatt_display-- == 0) + { + message.flag.prepare = 1; + message.flag.type_lobatt = 1; + sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE; + } + } + + // If a message has to be displayed, set display flag + if (message.all_flags) + { + if (message.flag.prepare) + { + message.flag.prepare = 0; + message.flag.show = 1; + } + else if (message.flag.erase) // message cycle is over, so erase it + { + message.flag.erase = 0; + display.flag.full_update = 1; + } + } + + // ------------------------------------------------------------------- + // Check idle timeout, set timeout flag + if (sys.flag.idle_timeout_enabled) + { + if (sTime.system_time - sTime.last_activity > INACTIVITY_TIME) + sys.flag.idle_timeout = 1; //setFlag(sysFlag_g, SYS_TIMEOUT_IDLE); + } + + // ------------------------------------------------------------------- + // Turn the Backlight off after timeout + if (sButton.backlight_status == 1) + { + if (sButton.backlight_timeout > BACKLIGHT_TIME_ON) + { + //turn off Backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + sButton.backlight_timeout = 0; + sButton.backlight_status = 0; + } + else + { + sButton.backlight_timeout++; + } + } + + // ------------------------------------------------------------------- + // Detect continuous button high states + + // Trying to lock/unlock buttons? + if (BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED) + { + if (button_lock_counter++ > LEFT_BUTTON_LONG_TIME) + { + // Toggle lock / unlock buttons flag + sys.flag.lock_buttons = ~sys.flag.lock_buttons; + + // Show "buttons are locked/unlocked" message synchronously with next second tick + message.flag.prepare = 1; + if (sys.flag.lock_buttons) + message.flag.type_locked = 1; + else + message.flag.type_unlocked = 1; + + // Reset button lock counter + button_lock_counter = 0; + } + } + else // Trying to create a long button press? + { + // Reset button lock counter + button_lock_counter = 0; + + if (BUTTON_STAR_IS_PRESSED) + { + sButton.star_timeout++; + + // Check if button was held low for some seconds + if (sButton.star_timeout > LEFT_BUTTON_LONG_TIME) + { + button.flag.star_long = 1; + button.flag.star_not_long = 0; + sButton.star_timeout = 0; + // Return interrupt edge to normal value + BUTTONS_IES &= ~BUTTON_STAR_PIN; + } + } + else // there was a button press not long enough + { + sButton.star_timeout = 0; + } + + if (BUTTON_NUM_IS_PRESSED) + { + sButton.num_timeout++; + + // Check if button was held low for some seconds + if (sButton.num_timeout > LEFT_BUTTON_LONG_TIME) + { + button.flag.num_long = 1; + button.flag.num_not_long = 0; + sButton.num_timeout = 0; + // Return interrupt edge to normal value + BUTTONS_IES &= ~BUTTON_NUM_PIN; + } + } + else // there was a button press not long enough + { + sButton.num_timeout = 0; + } + } + + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); +} + +// ************************************************************************************************* +// @fn Timer0_A1_5_ISR +// @brief IRQ handler for timer IRQ. +// Timer0_A0 1/1sec clock tick (serviced by function +// TIMER0_A0_ISR) +// Timer0_A1 BlueRobin timer +// Timer0_A2 +// Timer0_A3 Configurable periodic IRQ (used by button_repeat and +// buzzer) +// Timer0_A4 One-time delay +// @param none +// @return none +// ************************************************************************************************* +#pragma vector = TIMER0_A1_VECTOR +__interrupt void TIMER0_A1_5_ISR(void) +{ + u16 value; + + switch (TA0IV) + { + // Timer0_A1 BlueRobin timer + case 0x02: // Timer0_A1 handler + BRRX_TimerTask_v(); + break; + + // Timer0_A3 Configurable periodic IRQ (used by button_repeat and buzzer) + case 0x06: // Disable IE + TA0CCTL3 &= ~CCIE; + // Reset IRQ flag + TA0CCTL3 &= ~CCIFG; + // Store new value in CCR + value = TA0R + sTimer.timer0_A3_ticks; //timer0_A3_ticks_g; + // Load CCR register with next capture point + TA0CCR3 = value; + // Enable timer interrupt + TA0CCTL3 |= CCIE; + // Call function handler + fptr_Timer0_A3_function(); + break; + + // Timer0_A4 One-time delay + case 0x08: // Disable IE + TA0CCTL4 &= ~CCIE; + // Reset IRQ flag + TA0CCTL4 &= ~CCIFG; + // Set delay over flag + sys.flag.delay_over = 1; + break; + } + + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/timer.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/timer.h new file mode 100755 index 0000000..a65bf92 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/timer.h @@ -0,0 +1,68 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef TIMER_H_ +#define TIMER_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void Timer0_Init(void); +extern void Timer0_Start(void); +extern void Timer0_Stop(void); +extern void Timer0_A3_Start(u16 ticks); +extern void Timer0_A3_Stop(void); +extern void Timer0_A4_Delay(u16 ticks); + +extern void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// Defines section +struct timer +{ + // Timer0_A3 periodic delay + u16 timer0_A3_ticks; +}; +extern struct timer sTimer; + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*TIMER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_as.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_as.c new file mode 100755 index 0000000..0bd4912 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_as.c @@ -0,0 +1,356 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// VTI CMA3000-D0x acceleration sensor driver functions +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// logic +#include "simpliciti.h" + +// driver +#include "vti_as.h" +#include "timer.h" +#include "display.h" + +// ************************************************************************************************* +// Prototypes section +void as_start(void); +void as_stop(void); +u8 as_read_register(u8 bAddress); +u8 as_write_register(u8 bAddress, u8 bData); + +// ************************************************************************************************* +// Defines section + +// ================================================================================================= +// CMA3000-D0x acceleration sensor configuration +// ================================================================================================= +// DCO frequency division factor determining speed of the acceleration sensor SPI interface +// Speed in Hz = 12MHz / AS_BR_DIVIDER (max. 500kHz) +#define AS_BR_DIVIDER (30u) + +// Acceleration measurement range in g +// Valid ranges are: 2 and 8 +#define AS_RANGE (2u) + +// Sample rate for acceleration values in Hz +// Valid sample rates for 2g range are: 100, 400 +// Valid sample rates for 8g range are: 40, 100, 400 +#define AS_SAMPLE_RATE (100u) + +// ************************************************************************************************* +// Global Variable section + +// Global flag for proper acceleration sensor operation +u8 as_ok; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn as_init +// @brief Setup acceleration sensor connection, do not power up yet +// @param none +// @return none +// ************************************************************************************************* +void as_init(void) +{ +#ifdef AS_DISCONNECT + // Deactivate connection to acceleration sensor + AS_PWR_OUT &= ~AS_PWR_PIN; // Power off + AS_INT_OUT &= ~AS_INT_PIN; // Pin to low to avoid floating pins + AS_SPI_OUT &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Pin to low to avoid floating pins + AS_CSN_OUT &= ~AS_CSN_PIN; // Pin to low to avoid floating pins + AS_INT_DIR |= AS_INT_PIN; // Pin to output to avoid floating pins + AS_SPI_DIR |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Pin to output to avoid floating pins + AS_CSN_DIR |= AS_CSN_PIN; // Pin to output to avoid floating pins + AS_PWR_DIR |= AS_PWR_PIN; // Power pin to output direction +#else + AS_INT_DIR &= ~AS_INT_PIN; // Input + AS_SPI_DIR &= ~AS_SDI_PIN; // Input + AS_SPI_DIR |= AS_SDO_PIN + AS_SCK_PIN; // Output + AS_SPI_SEL |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Port pins to SDO, SDI and SCK function + AS_CSN_OUT |= AS_CSN_PIN; // CSN=1 + AS_CSN_DIR |= AS_CSN_PIN; // + AS_PWR_OUT |= AS_PWR_PIN; // VDD=1 + AS_PWR_DIR |= AS_PWR_PIN; // +#endif + + // Reset global sensor flag + as_ok = 1; +} + +// ************************************************************************************************* +// @fn as_start +// @brief Power-up and initialize acceleration sensor +// @param none +// @return none +// ************************************************************************************************* +void as_start(void) +{ + volatile u16 Counter_u16; + u8 bConfig; //, bStatus; + + // Initialize SPI interface to acceleration sensor + AS_SPI_CTL0 |= UCSYNC | UCMST | UCMSB // SPI master, 8 data bits, MSB first, + | UCCKPH; // clock idle low, data output on falling + // edge + AS_SPI_CTL1 |= UCSSEL1; // SMCLK as clock source + AS_SPI_BR0 = AS_BR_DIVIDER; // Low byte of division factor for baud rate + AS_SPI_BR1 = 0x00; // High byte of division factor for baud + // rate + AS_SPI_CTL1 &= ~UCSWRST; // Start SPI hardware + + // Initialize interrupt pin for data read out from acceleration sensor + AS_INT_IES &= ~AS_INT_PIN; // Interrupt on rising edge + +#ifdef AS_DISCONNECT + // Enable interrupt + AS_INT_DIR &= ~AS_INT_PIN; // Switch INT pin to input + AS_SPI_DIR &= ~AS_SDI_PIN; // Switch SDI pin to input + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin + AS_SPI_SEL |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Port pins to SDO, SDI and SCK function + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_PWR_OUT |= AS_PWR_PIN; // Power on active high +#endif + + // Delay of >5ms required between switching on power and configuring sensor + Timer0_A4_Delay(CONV_MS_TO_TICKS(10)); + + // Initialize interrupt pin for data read out from acceleration sensor + AS_INT_IFG &= ~AS_INT_PIN; // Reset flag + AS_INT_IE |= AS_INT_PIN; // Enable interrupt + + // Configure sensor and start to sample data +#if (AS_RANGE == 2) + bConfig = 0x80; +# if (AS_SAMPLE_RATE == 100) + bConfig |= 0x02; +# elif (AS_SAMPLE_RATE == 400) + bConfig |= 0x04; +# else +# error "Sample rate not supported" +# endif +#elif (AS_RANGE == 8) + bConfig = 0x00; +# if (AS_SAMPLE_RATE == 40) + bConfig |= 0x06; +# elif (AS_SAMPLE_RATE == 100) + bConfig |= 0x02; +# elif (AS_SAMPLE_RATE == 400) + bConfig |= 0x04; +# else +# error "Sample rate not supported" +# endif +#else +# error "Measurement range not supported" +#endif + + // Reset sensor + as_write_register(0x04, 0x02); + as_write_register(0x04, 0x0A); + as_write_register(0x04, 0x04); + + // Wait 5 ms before starting sensor output + Timer0_A4_Delay(CONV_MS_TO_TICKS(5)); + + // Set 2g measurement range, start to output data with 100Hz rate + as_write_register(0x02, bConfig); +} + +// ************************************************************************************************* +// @fn as_stop +// @brief Power down acceleration sensor +// @param none +// @return none +// ************************************************************************************************* +void as_stop(void) +{ + // Disable interrupt + AS_INT_IE &= ~AS_INT_PIN; // Disable interrupt + +#ifdef AS_DISCONNECT + // Power-down sensor + AS_PWR_OUT &= ~AS_PWR_PIN; // Power off + AS_INT_OUT &= ~AS_INT_PIN; // Pin to low to avoid floating pins + AS_SPI_OUT &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Pins to low to avoid floating pins + AS_SPI_SEL &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Port pins to I/O function + AS_CSN_OUT &= ~AS_CSN_PIN; // Pin to low to avoid floating pins + AS_INT_DIR |= AS_INT_PIN; // Pin to output to avoid floating pins + AS_SPI_DIR |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Pins to output to avoid floating pins + AS_CSN_DIR |= AS_CSN_PIN; // Pin to output to avoid floating pins +#else + // Reset sensor -> sensor to powerdown + as_write_register(0x04, 0x02); + as_write_register(0x04, 0x0A); + as_write_register(0x04, 0x04); +#endif +} + +// ************************************************************************************************* +// @fn as_read_register +// @brief Read a byte from the acceleration sensor +// @param u8 bAddress Register address +// @return u8 Register content +// ************************************************************************************************* +u8 as_read_register(u8 bAddress) +{ + u8 bResult; + u16 timeout; + + // Exit function if an error was detected previously + if (!as_ok) + return (0); + + bAddress <<= 2; // Address to be shifted left by 2 and + // RW bit to be reset + + AS_SPI_REN &= ~AS_SDI_PIN; // Pulldown on SDI pin not required + AS_CSN_OUT &= ~AS_CSN_PIN; // Select acceleration sensor + + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bAddress; // Write address to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = 0; // Write dummy data to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer + + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin required again + + // Return new data from RX buffer + return bResult; +} + +// ************************************************************************************************* +// @fn as_write_register +// @brief Write a byte to the acceleration sensor +// @param u8 bAddress Register address +// u8 bData Data to write +// @return +// ************************************************************************************************* +u8 as_write_register(u8 bAddress, u8 bData) +{ + u8 bResult; + u16 timeout; + + // Exit function if an error was detected previously + if (!as_ok) + return (0); + + bAddress <<= 2; // Address to be shifted left by 1 + bAddress |= BIT1; // RW bit to be set + + AS_SPI_REN &= ~AS_SDI_PIN; // Pulldown on SDI pin not required + AS_CSN_OUT &= ~AS_CSN_PIN; // Select acceleration sensor + + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bAddress; // Write address to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bData; // Write data to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer + + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin required again + + return bResult; +} + +// ************************************************************************************************* +// @fn as_get_data +// @brief Service routine to read acceleration values. +// @param none +// @return none +// ************************************************************************************************* +void as_get_data(u8 * data) +{ + // Exit if sensor is not powered up + if ((AS_PWR_OUT & AS_PWR_PIN) != AS_PWR_PIN) + return; + + // Store X/Y/Z acceleration data in buffer + *(data + 0) = as_read_register(0x06); + *(data + 1) = as_read_register(0x07); + *(data + 2) = as_read_register(0x08); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_as.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_as.h new file mode 100755 index 0000000..178af33 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_as.h @@ -0,0 +1,106 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef VTI_AS_H_ +#define VTI_AS_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void as_init(void); +extern void as_start(void); +extern void as_stop(void); +extern u8 as_read_register(u8 bAddress); +extern u8 as_write_register(u8 bAddress, u8 bData); +extern void as_get_data(u8 * data); + +// ************************************************************************************************* +// Defines section + +// Disconnect power supply for acceleration sensor when not used +#define AS_DISCONNECT + +// Port and pin resource for SPI interface to acceleration sensor +// SDO=MOSI=P1.6, SDI=MISO=P1.5, SCK=P1.7 +#define AS_SPI_IN (P1IN) +#define AS_SPI_OUT (P1OUT) +#define AS_SPI_DIR (P1DIR) +#define AS_SPI_SEL (P1SEL) +#define AS_SPI_REN (P1REN) +#define AS_SDO_PIN (BIT6) +#define AS_SDI_PIN (BIT5) +#define AS_SCK_PIN (BIT7) + +// CSN=PJ.1 +#define AS_CSN_OUT (PJOUT) +#define AS_CSN_DIR (PJDIR) +#define AS_CSN_PIN (BIT1) + +#define AS_TX_BUFFER (UCA0TXBUF) +#define AS_RX_BUFFER (UCA0RXBUF) +#define AS_TX_IFG (UCTXIFG) +#define AS_RX_IFG (UCRXIFG) +#define AS_IRQ_REG (UCA0IFG) +#define AS_SPI_CTL0 (UCA0CTL0) +#define AS_SPI_CTL1 (UCA0CTL1) +#define AS_SPI_BR0 (UCA0BR0) +#define AS_SPI_BR1 (UCA0BR1) + +// Port and pin resource for power-up of acceleration sensor, VDD=PJ.0 +#define AS_PWR_OUT (PJOUT) +#define AS_PWR_DIR (PJDIR) +#define AS_PWR_PIN (BIT0) + +// Port, pin and interrupt resource for interrupt from acceleration sensor, CMA_INT=P2.5 +#define AS_INT_IN (P2IN) +#define AS_INT_OUT (P2OUT) +#define AS_INT_DIR (P2DIR) +#define AS_INT_IE (P2IE) +#define AS_INT_IES (P2IES) +#define AS_INT_IFG (P2IFG) +#define AS_INT_PIN (BIT5) + +// SPI timeout to detect sensor failure +#define SPI_TIMEOUT (1000u) + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*VTI_AS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_ps.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_ps.c new file mode 100755 index 0000000..fa2d493 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_ps.c @@ -0,0 +1,563 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// VTI SCP1000-D0x pressure sensor driver functions +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "vti_ps.h" +#include "timer.h" + +// ************************************************************************************************* +// Prototypes section +u16 ps_read_register(u8 address, u8 mode); +u8 ps_write_register(u8 address, u8 data); +u8 ps_twi_read(u8 ack); +void twi_delay(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// VTI pressure (hPa) to altitude (m) conversion tables +const s16 h0[17] = +{ -153, 0, 111, 540, 989, 1457, 1949, 2466, 3012, 3591, 4206, 4865, 5574, 6344, 7185, 8117, 9164 }; +const u16 p0[17] = +{ 1031, 1013, 1000, 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300 }; + +float p[17]; + +// Global flag for proper pressure sensor operation +u8 ps_ok; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn ps_init +// @brief Init pressure sensor I/O +// @param none +// @return none +// ************************************************************************************************* +void ps_init(void) +{ + volatile u8 success, status, eeprom, timeout; + + PS_INT_DIR &= ~PS_INT_PIN; // DRDY is input + PS_INT_IES &= ~PS_INT_PIN; // Interrupt on DRDY rising edge + PS_TWI_OUT |= PS_SCL_PIN + PS_SDA_PIN; // SCL and SDA are outputs by default + PS_TWI_DIR |= PS_SCL_PIN + PS_SDA_PIN; // SCL and SDA are outputs by default + + // Reset global ps_ok flag + ps_ok = 0; + + // 100msec delay to allow VDD stabilisation + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + + // Reset pressure sensor -> powerdown sensor + success = ps_write_register(0x06, 0x01); + + // 100msec delay + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + + // Check if STATUS register BIT0 is cleared + status = ps_read_register(0x07, PS_TWI_8BIT_ACCESS); + if (((status & BIT0) == 0) && (status != 0)) + { + // Check EEPROM checksum in DATARD8 register + eeprom = ps_read_register(0x7F, PS_TWI_8BIT_ACCESS); + if (eeprom == 0x01) + ps_ok = 1; + else + ps_ok = 0; + } +} + +// ************************************************************************************************* +// @fn ps_start +// @brief Init pressure sensor registers and start sampling +// @param none +// @return u8 1=Sensor started, 0=Sensor did not start +// ************************************************************************************************* +void ps_start(void) +{ + // Start sampling data in ultra low power mode + ps_write_register(0x03, 0x0B); +} + +// ************************************************************************************************* +// @fn ps_stop +// @brief Power down pressure sensor +// @param none +// @return none +// ************************************************************************************************* +void ps_stop(void) +{ + // Put sensor to standby + ps_write_register(0x03, 0x00); +} + +// ************************************************************************************************* +// @fn ps_twi_sda +// @brief Control SDA line +// @param u8 condition PS_TWI_SEND_START, PS_TWI_SEND_RESTART, PS_TWI_SEND_STOP +// PS_TWI_CHECK_ACK +// @return u8 1=ACK, 0=NACK +// ************************************************************************************************* +u8 ps_twi_sda(u8 condition) +{ + u8 sda = 0; + + if (condition == PS_TWI_SEND_START) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; // SCL 1-0 transition while SDA=0 + twi_delay(); + } + else if (condition == PS_TWI_SEND_RESTART) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SCL_LO; + PS_TWI_SDA_HI; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; + twi_delay(); + } + else if (condition == PS_TWI_SEND_STOP) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_HI; // SDA 0-1 transition while SCL=1 + twi_delay(); + } + else if (condition == PS_TWI_CHECK_ACK) + { + PS_TWI_SDA_IN; // SDA is input + PS_TWI_SCL_LO; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + sda = PS_TWI_IN & PS_SDA_PIN; + PS_TWI_SCL_LO; + } + + // Return value will only be evaluated when checking device ACK + return (sda == 0); +} + +// ************************************************************************************************* +// @fn twi_delay +// @brief Delay between TWI signal edges. +// @param none +// @return none +// ************************************************************************************************* +void twi_delay(void) +{ + asm (" nop"); +} + +// ************************************************************************************************* +// @fn ps_twi_write +// @brief Clock out bits through SDA. +// @param u8 data Byte to send +// @return none +// ************************************************************************************************* +void ps_twi_write(u8 data) +{ + u8 i, mask; + + // Set mask byte to 10000000b + mask = BIT0 << 7; + + PS_TWI_SDA_OUT; // SDA is output + + for (i = 8; i > 0; i--) + { + PS_TWI_SCL_LO; // SCL=0 + if ((data & mask) == mask) + { + PS_TWI_SDA_HI; // SDA=1 + } + else + { + PS_TWI_SDA_LO; // SDA=0 + } + mask = mask >> 1; + twi_delay(); + PS_TWI_SCL_HI; // SCL=1 + twi_delay(); + } + + PS_TWI_SCL_LO; // SCL=0 + PS_TWI_SDA_IN; // SDA is input +} + +// ************************************************************************************************* +// @fn ps_twi_read +// @brief Read bits from SDA +// @param u8 ack 1=Send ACK after read, 0=Send NACK after read +// @return u8 Bits read +// ************************************************************************************************* +u8 ps_twi_read(u8 ack) +{ + u8 i; + u8 data = 0; + + PS_TWI_SDA_IN; // SDA is input + + for (i = 0; i < 8; i++) + { + PS_TWI_SCL_LO; // SCL=0 + twi_delay(); + PS_TWI_SCL_HI; // SCL=0 + twi_delay(); + + // Shift captured bits to left + data = data << 1; + + // Capture new bit + if ((PS_TWI_IN & PS_SDA_PIN) == PS_SDA_PIN) + data |= BIT0; + } + + PS_TWI_SDA_OUT; // SDA is output + + // 1 aditional clock phase to generate master ACK + PS_TWI_SCL_LO; // SCL=0 + if (ack == 1) // Send ack -> continue read + { + PS_TWI_SDA_LO + } + else // Send nack -> stop read + { + PS_TWI_SDA_HI + } + twi_delay(); + PS_TWI_SCL_HI; // SCL=0 + twi_delay(); + PS_TWI_SCL_LO; + + return (data); +} + +// ************************************************************************************************* +// @fn as_write_register +// @brief Write a byte to the pressure sensor +// @param u8 address Register address +// u8 data Data to write +// @return u8 +// ************************************************************************************************* +u8 ps_write_register(u8 address, u8 data) +{ + volatile u8 success; + + ps_twi_sda(PS_TWI_SEND_START); // Generate start condition + + ps_twi_write((0x11 << 1) | PS_TWI_WRITE); // Send 7bit device address 0x11 + write bit '0' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(address); // Send 8bit register address + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(data); // Send 8bit data to register + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + // Slave does not send this ACK + // if (!success) return (0); + + ps_twi_sda(PS_TWI_SEND_STOP); // Generate stop condition + + return (1); +} + +// ************************************************************************************************* +// @fn ps_read_register +// @brief Read a byte from the pressure sensor +// @param u8 address Register address +// u8 mode PS_TWI_8BIT_ACCESS, PS_TWI_16BIT_ACCESS +// @return u16 Register content +// ************************************************************************************************* +u16 ps_read_register(u8 address, u8 mode) +{ + u8 success; + u16 data = 0; + + ps_twi_sda(PS_TWI_SEND_START); // Generate start condition + + ps_twi_write((0x11 << 1) | PS_TWI_WRITE); // Send 7bit device address 0x11 + write bit '0' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(address); // Send 8bit register address + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_sda(PS_TWI_SEND_RESTART); // Generate restart condition + + ps_twi_write((0x11 << 1) | PS_TWI_READ); // Send 7bit device address 0x11 + read bit '1' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + if (mode == PS_TWI_16BIT_ACCESS) + { + data = ps_twi_read(1) << 8; // Read MSB 8bit data from register + data |= ps_twi_read(0); // Read LSB 8bit data from register + } + else + { + data = ps_twi_read(0); // Read 8bit data from register + } + + ps_twi_sda(PS_TWI_SEND_STOP); // Generate stop condition + + return (data); +} + +// ************************************************************************************************* +// @fn ps_get_pa +// @brief Read out pressure. Format is Pa. Range is 30000 .. 120000 Pa. +// @param none +// @return u32 15-bit pressure sensor value (Pa) +// ************************************************************************************************* +u32 ps_get_pa(void) +{ + volatile u32 data = 0; + + // Get 3 MSB from DATARD8 register + data = ps_read_register(0x7F, PS_TWI_8BIT_ACCESS); + data = ((data & 0x07) << 8) << 8; + + // Get 16 LSB from DATARD16 register + data |= ps_read_register(0x80, PS_TWI_16BIT_ACCESS); + + // Convert decimal value to Pa + data = (data >> 2); + + return (data); +} + +// ************************************************************************************************* +// @fn ps_get_temp +// @brief Read out temperature. +// @param none +// @return u16 13-bit temperature value in xx.x K format +// ************************************************************************************************* +u16 ps_get_temp(void) +{ + volatile u16 data = 0; + u16 temp = 0; + u8 is_negative = 0; + u16 kelvin; + + // Get 13 bit from TEMPOUT register + data = ps_read_register(0x81, PS_TWI_16BIT_ACCESS); + + // Convert negative temperatures + if ((data & BIT(13)) == BIT(13)) + { + // Sign extend temperature + data |= 0xC000; + // Convert two's complement + data = ~data; + data += 1; + is_negative = 1; + } + + temp = data / 2; + + // Convert from °C to K + if (is_negative) + kelvin = 2732 - temp; + else + kelvin = temp + 2732; + + return (kelvin); +} + +// ************************************************************************************************* +// @fn init_pressure_table +// @brief Init pressure table with constants +// @param u32 p Pressure (Pa) +// @return u16 Altitude (m) +// ************************************************************************************************* +void init_pressure_table(void) +{ + u8 i; + + for (i = 0; i < 17; i++) + p[i] = p0[i]; +} + +// ************************************************************************************************* +// @fn update_pressure_table +// @brief Calculate pressure table for reference altitude. +// Implemented straight from VTI reference code. +// @param s16 href Reference height +// u32 p_meas Pressure (Pa) +// u16 t_meas Temperature (10*K) +// @return none +// ************************************************************************************************* +void update_pressure_table(s16 href, u32 p_meas, u16 t_meas) +{ + const float Invt00 = 0.003470415; + const float coefp = 0.00006; + volatile float p_fact; + volatile float p_noll; + volatile float hnoll; + volatile float h_low = 0; + volatile float t0; + u8 i; + + // Typecast arguments + volatile float fl_href = href; + volatile float fl_p_meas = (float)p_meas / 100; // Convert from Pa to hPa + volatile float fl_t_meas = (float)t_meas / 10; // Convert from 10 K to 1 K + + t0 = fl_t_meas + (0.0065 * fl_href); + + hnoll = fl_href / (t0 * Invt00); + + for (i = 0; i <= 15; i++) + { + if (h0[i] > hnoll) + break; + h_low = h0[i]; + } + + p_noll = + (float)(hnoll - + h_low) * + (1 - + (hnoll - + (float)h0[i]) * + coefp) * ((float)p0[i] - (float)p0[i - 1]) / ((float)h0[i] - h_low) + (float)p0[i - 1]; + + // Calculate multiplicator + p_fact = fl_p_meas / p_noll; + + // Apply correction factor to pressure table + for (i = 0; i <= 16; i++) + { + p[i] = p0[i] * p_fact; + } +} + +// ************************************************************************************************* +// @fn conv_pa_to_meter +// @brief Convert pressure (Pa) to altitude (m) using a conversion table +// Implemented straight from VTI reference code. +// @param u32 p_meas Pressure (Pa) +// u16 t_meas Temperature (10* K) +// @return s16 Altitude (m) +// ************************************************************************************************* +s16 conv_pa_to_meter(u32 p_meas, u16 t_meas) +{ + const float coef2 = 0.0007; + const float Invt00 = 0.003470415; + volatile float hnoll; + volatile float t0; + volatile float p_low; + volatile float fl_h; + volatile s16 h; + u8 i; + + // Typecast arguments + volatile float fl_p_meas = (float)p_meas / 100; // Convert from Pa to hPa + volatile float fl_t_meas = (float)t_meas / 10; // Convert from 10 K to 1 K + + for (i = 0; i <= 16; i++) + { + if (p[i] < fl_p_meas) + break; + p_low = p[i]; + } + + if (i == 0) + { + hnoll = (float)(fl_p_meas - p[0]) / (p[1] - p[0]) * ((float)(h0[1] - h0[0])); + } + else if (i < 15) + { + hnoll = + (float)(fl_p_meas - + p_low) * + (1 - + (fl_p_meas - + p[i]) * coef2) / (p[i] - p_low) * ((float)(h0[i] - h0[i - 1])) + h0[i - 1]; + } + else if (i == 15) + { + hnoll = + (float)(fl_p_meas - p_low) / (p[i] - p_low) * ((float)(h0[i] - h0[i - 1])) + h0[i - 1]; + } + else // i==16 + { + hnoll = (float)(fl_p_meas - p[16]) / (p[16] - p[15]) * ((float)(h0[16] - h0[15])) + h0[16]; + } + + // Compensate temperature error + t0 = fl_t_meas / (1 - hnoll * Invt00 * 0.0065); + fl_h = Invt00 * t0 * hnoll; + h = (u16) fl_h; + + return (h); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_ps.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_ps.h new file mode 100755 index 0000000..e044695 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/driver/vti_ps.h @@ -0,0 +1,99 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef VTI_PS_H_ +#define VTI_PS_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void ps_init(void); +extern void ps_start(void); +extern void ps_stop(void); +extern u32 ps_get_pa(void); +extern u16 ps_get_temp(void); +extern void init_pressure_table(void); +extern void update_pressure_table(s16 href, u32 p_meas, u16 t_meas); +extern s16 conv_pa_to_meter(u32 p_meas, u16 t_meas); + +// ************************************************************************************************* +// Defines section + +// Port and pin resource for TWI interface to pressure sensor +// SCL=PJ.3, SDA=PJ.2, DRDY=P2.6 +#define PS_TWI_IN (PJIN) +#define PS_TWI_OUT (PJOUT) +#define PS_TWI_DIR (PJDIR) +#define PS_TWI_REN (PJREN) +#define PS_SCL_PIN (BIT3) +#define PS_SDA_PIN (BIT2) + +// Port, pin and interrupt resource for interrupt from acceleration sensor, DRDY=P2.6 +#define PS_INT_IN (P2IN) +#define PS_INT_OUT (P2OUT) +#define PS_INT_DIR (P2DIR) +#define PS_INT_IE (P2IE) +#define PS_INT_IES (P2IES) +#define PS_INT_IFG (P2IFG) +#define PS_INT_PIN (BIT6) + +// TWI defines +#define PS_TWI_WRITE (0u) +#define PS_TWI_READ (1u) + +#define PS_TWI_SEND_START (0u) +#define PS_TWI_SEND_RESTART (1u) +#define PS_TWI_SEND_STOP (2u) +#define PS_TWI_CHECK_ACK (3u) + +#define PS_TWI_8BIT_ACCESS (0u) +#define PS_TWI_16BIT_ACCESS (1u) + +#define PS_TWI_SCL_HI { PS_TWI_OUT |= PS_SCL_PIN; } +#define PS_TWI_SCL_LO { PS_TWI_OUT &= ~PS_SCL_PIN; } +#define PS_TWI_SDA_HI { PS_TWI_OUT |= PS_SDA_PIN; } +#define PS_TWI_SDA_LO { PS_TWI_OUT &= ~PS_SDA_PIN; } +#define PS_TWI_SDA_IN { PS_TWI_OUT |= PS_SDA_PIN; PS_TWI_DIR &= ~PS_SDA_PIN; } +#define PS_TWI_SDA_OUT { PS_TWI_DIR |= PS_SDA_PIN; } + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*VTI_PS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/include/project.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/include/project.h new file mode 100755 index 0000000..de97736 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/include/project.h @@ -0,0 +1,134 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef PROJECT_H_ +#define PROJECT_H_ + +// ************************************************************************************************* +// Include section +#include +#include + +// ************************************************************************************************* +// Defines section + +// Comment this to not use the LCD charge pump +//#define USE_LCD_CHARGE_PUMP + +// Uncomment this define to build the application without watchdog support +#define USE_WATCHDOG + +// Use/not use filter when measuring physical values +#define FILTER_OFF (0u) +#define FILTER_ON (1u) + +// Uncomment this define to build the application with BlueRobin heartrate support +#define INCLUDE_BLUEROBIN_SUPPORT + +// ************************************************************************************************* +// Macro section + +// Conversion from usec to ACLK timer ticks +#define CONV_US_TO_TICKS(usec) (((usec) * 32768) / 1000000) + +// Conversion from msec to ACLK timer ticks +#define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000) + +// ************************************************************************************************* +// Typedef section + +typedef enum +{ + MENU_ITEM_NOT_VISIBLE = 0, // Menu item is not visible + MENU_ITEM_VISIBLE // Menu item is visible +} menu_t; + +// Set of system flags +typedef union +{ + struct + { + u16 idle_timeout : 1; // Timeout after inactivity + u16 idle_timeout_enabled : 1; // When in set mode, timeout after a given period + u16 lock_buttons : 1; // Lock buttons + u16 mask_buzzer : 1; // Do not output buzz for next button event + u16 up_down_repeat_enabled : 1; // While in set_value(), create virtual UP / DOWN button + // press + u16 low_battery : 1; // 1 = Battery is low + u16 use_metric_units : 1; // 1 = Use metric units, 0 = use English units + u16 delay_over : 1; // 1 = Timer delay over + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_system_flags; +extern volatile s_system_flags sys; + +// Set of request flags +typedef union +{ + struct + { + u16 voltage_measurement : 1; // 1 = Measure voltage + u16 altitude_measurement : 1; // 1 = Measure air pressure + u16 acceleration_measurement : 1; // 1 = Measure acceleration + u16 datalog : 1; // 1 = Add data + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_request_flags; +extern volatile s_request_flags request; + +// Set of message flags +typedef union +{ + struct + { + u16 prepare : 1; // 1 = Wait for clock tick, then set + // display.flag.show_message flag + u16 show : 1; // 1 = Display message now + u16 erase : 1; // 1 = Erase message + u16 type_locked : 1; // 1 = Show "buttons are locked" in Line2 + u16 type_unlocked : 1; // 1 = Show "buttons are unlocked" in Line2 + u16 type_lobatt : 1; // 1 = Show "lobatt" text in Line2 + u16 type_on : 1; // 1 = Show " on" text in Line1 + u16 type_off : 1; // 1 = Show " off" text in Line1 + u16 type_nomem : 1; // 1 = Show "nomem" text in Line2 + } flag; + u16 all_flags; // Shortcut to all message flags (for reset) +} s_message_flags; +extern volatile s_message_flags message; + +// ************************************************************************************************* +// Global Variable section + +#endif /*PROJECT_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/lnk_cc430f6137.cmd b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/lnk_cc430f6137.cmd new file mode 100755 index 0000000..4a74364 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/lnk_cc430f6137.cmd @@ -0,0 +1,202 @@ +/******************************************************************************/ +/* lnk_cc430f6137.cmd - LINKER COMMAND FILE FOR LINKING CC430F6137 PROGRAMS */ +/* */ +/* Ver | dd mmm yyyy | Who | Description of changes */ +/* =====|=============|======|============================================= */ +/* 0.01| 08 Mar 2004 | A.D. | First prototype */ +/* 0.02| 26 Mai 2004 | A.D. | Leading symbol underscores removed, */ +/* | | | Interrupt vector definition changed */ +/* 0.03| 22 Jun 2004 | A.D. | File reformatted */ +/* */ +/* Usage: lnk430 -o -m lnk.cmd */ +/* cl430 -z -o -m lnk.cmd */ +/* */ +/*----------------------------------------------------------------------------*/ + +/* These linker options are for command line linking only. For IDE linking, */ +/* you should set your linker options in Project Properties */ +/* -c LINK USING C CONVENTIONS */ +/* -stack 0x0100 SOFTWARE STACK SIZE */ +/* -heap 0x0100 HEAP AREA SIZE */ + +/*----------------------------------------------------------------------------*/ +/* 'Allocate' peripheral registers at given addresses */ +/*----------------------------------------------------------------------------*/ + +/****************************************************************************/ +/* SPECIFY THE SYSTEM MEMORY MAP */ +/****************************************************************************/ + +MEMORY +{ + SFR : origin = 0x0000, length = 0x0010 + PERIPHERALS_8BIT : origin = 0x0010, length = 0x00F0 + PERIPHERALS_16BIT : origin = 0x0100, length = 0x0100 + RAM : origin = 0x1C00, length = 0x0FFE + INFOA : origin = 0x1980, length = 0x0080 + INFOB : origin = 0x1900, length = 0x0080 + INFOC : origin = 0x1880, length = 0x0080 + INFOD : origin = 0x1800, length = 0x0080 + DATALOG_MEMORY : origin = 0x8000, length = 0x1E00 + FLASH : origin = 0x9E00, length = 0x6180 +/* FLASH : origin = 0x8000, length = 0x7F80 */ + INT00 : origin = 0xFF80, length = 0x0002 + INT01 : origin = 0xFF82, length = 0x0002 + INT02 : origin = 0xFF84, length = 0x0002 + INT03 : origin = 0xFF86, length = 0x0002 + INT04 : origin = 0xFF88, length = 0x0002 + INT05 : origin = 0xFF8A, length = 0x0002 + INT06 : origin = 0xFF8C, length = 0x0002 + INT07 : origin = 0xFF8E, length = 0x0002 + INT08 : origin = 0xFF90, length = 0x0002 + INT09 : origin = 0xFF92, length = 0x0002 + INT10 : origin = 0xFF94, length = 0x0002 + INT11 : origin = 0xFF96, length = 0x0002 + INT12 : origin = 0xFF98, length = 0x0002 + INT13 : origin = 0xFF9A, length = 0x0002 + INT14 : origin = 0xFF9C, length = 0x0002 + INT15 : origin = 0xFF9E, length = 0x0002 + INT16 : origin = 0xFFA0, length = 0x0002 + INT17 : origin = 0xFFA2, length = 0x0002 + INT18 : origin = 0xFFA4, length = 0x0002 + INT19 : origin = 0xFFA6, length = 0x0002 + INT20 : origin = 0xFFA8, length = 0x0002 + INT21 : origin = 0xFFAA, length = 0x0002 + INT22 : origin = 0xFFAC, length = 0x0002 + INT23 : origin = 0xFFAE, length = 0x0002 + INT24 : origin = 0xFFB0, length = 0x0002 + INT25 : origin = 0xFFB2, length = 0x0002 + INT26 : origin = 0xFFB4, length = 0x0002 + INT27 : origin = 0xFFB6, length = 0x0002 + INT28 : origin = 0xFFB8, length = 0x0002 + INT29 : origin = 0xFFBA, length = 0x0002 + INT30 : origin = 0xFFBC, length = 0x0002 + INT31 : origin = 0xFFBE, length = 0x0002 + INT32 : origin = 0xFFC0, length = 0x0002 + INT33 : origin = 0xFFC2, length = 0x0002 + INT34 : origin = 0xFFC4, length = 0x0002 + INT35 : origin = 0xFFC6, length = 0x0002 + INT36 : origin = 0xFFC8, length = 0x0002 + INT37 : origin = 0xFFCA, length = 0x0002 + INT38 : origin = 0xFFCC, length = 0x0002 + INT39 : origin = 0xFFCE, length = 0x0002 + INT40 : origin = 0xFFD0, length = 0x0002 + INT41 : origin = 0xFFD2, length = 0x0002 + INT42 : origin = 0xFFD4, length = 0x0002 + INT43 : origin = 0xFFD6, length = 0x0002 + INT44 : origin = 0xFFD8, length = 0x0002 + INT45 : origin = 0xFFDA, length = 0x0002 + INT46 : origin = 0xFFDC, length = 0x0002 + INT47 : origin = 0xFFDE, length = 0x0002 + INT48 : origin = 0xFFE0, length = 0x0002 + INT49 : origin = 0xFFE2, length = 0x0002 + INT50 : origin = 0xFFE4, length = 0x0002 + INT51 : origin = 0xFFE6, length = 0x0002 + INT52 : origin = 0xFFE8, length = 0x0002 + INT53 : origin = 0xFFEA, length = 0x0002 + INT54 : origin = 0xFFEC, length = 0x0002 + INT55 : origin = 0xFFEE, length = 0x0002 + INT56 : origin = 0xFFF0, length = 0x0002 + INT57 : origin = 0xFFF2, length = 0x0002 + INT58 : origin = 0xFFF4, length = 0x0002 + INT59 : origin = 0xFFF6, length = 0x0002 + INT60 : origin = 0xFFF8, length = 0x0002 + INT61 : origin = 0xFFFA, length = 0x0002 + INT62 : origin = 0xFFFC, length = 0x0002 + RESET : origin = 0xFFFE, length = 0x0002 +} + +/****************************************************************************/ +/* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */ +/****************************************************************************/ + +SECTIONS +{ + .bss : {} > RAM /* GLOBAL & STATIC VARS */ + .sysmem : {} > RAM /* DYNAMIC MEMORY ALLOCATION AREA */ + .stack : {} > RAM (HIGH) /* SOFTWARE SYSTEM STACK */ + + .text : {} > FLASH /* CODE */ + .cinit : {} > FLASH /* INITIALIZATION TABLES */ + .const : {} > FLASH /* CONSTANT DATA */ + .cio : {} > RAM /* C I/O BUFFER */ + + .pinit : {} > FLASH /* C++ CONSTRUCTOR TABLES */ + + .infoA : {} > INFOA /* MSP430 INFO FLASH MEMORY SEGMENTS */ + .infoB : {} > INFOB + .infoC : {} > INFOC + .infoD : {} > INFOD + + .int00 : {} > INT00 /* MSP430 INTERRUPT VECTORS */ + .int01 : {} > INT01 + .int02 : {} > INT02 + .int03 : {} > INT03 + .int04 : {} > INT04 + .int05 : {} > INT05 + .int06 : {} > INT06 + .int07 : {} > INT07 + .int08 : {} > INT08 + .int09 : {} > INT09 + .int10 : {} > INT10 + .int11 : {} > INT11 + .int12 : {} > INT12 + .int13 : {} > INT13 + .int14 : {} > INT14 + .int15 : {} > INT15 + .int16 : {} > INT16 + .int17 : {} > INT17 + .int18 : {} > INT18 + .int19 : {} > INT19 + .int20 : {} > INT20 + .int21 : {} > INT21 + .int22 : {} > INT22 + .int23 : {} > INT23 + .int24 : {} > INT24 + .int25 : {} > INT25 + .int26 : {} > INT26 + .int27 : {} > INT27 + .int28 : {} > INT28 + .int29 : {} > INT29 + .int30 : {} > INT30 + .int31 : {} > INT31 + .int32 : {} > INT32 + .int33 : {} > INT33 + .int34 : {} > INT34 + .int35 : {} > INT35 + .int36 : {} > INT36 + .int37 : {} > INT37 + .int38 : {} > INT38 + .int39 : {} > INT39 + .int40 : {} > INT40 + .int41 : {} > INT41 + .int42 : {} > INT42 + .int43 : {} > INT43 + .int44 : {} > INT44 + .int45 : {} > INT45 + .int46 : {} > INT46 + .int47 : {} > INT47 + .int48 : {} > INT48 + .int49 : {} > INT49 + .int50 : {} > INT50 + .int51 : {} > INT51 + .int52 : {} > INT52 + .int53 : {} > INT53 + .int54 : {} > INT54 + .int55 : {} > INT55 + .int56 : {} > INT56 + .int57 : {} > INT57 + .int58 : {} > INT58 + .int59 : {} > INT59 + .int60 : {} > INT60 + .int61 : {} > INT61 + .int62 : {} > INT62 + .reset : {} > RESET /* MSP430 RESET VECTOR */ +} + +/****************************************************************************/ +/* INCLUDE PERIPHERALS MEMORY MAP */ +/****************************************************************************/ + +-l cc430x613x.cmd + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/acceleration.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/acceleration.c new file mode 100755 index 0000000..c422496 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/acceleration.c @@ -0,0 +1,241 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Acceleration measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "vti_as.h" + +// logic +#include "acceleration.h" +#include "simpliciti.h" +#include "user.h" + +// ************************************************************************************************* +// Global Variable section +struct accel sAccel; + +// Conversion values from data to mgrav taken from CMA3000-D0x datasheet (rev 0.4, table 4) +const u16 mgrav_per_bit[7] = { 18, 36, 71, 143, 286, 571, 1142 }; + +// ************************************************************************************************* +// Extern section + +// Global flag for proper acceleration sensor operation +extern u8 as_ok; + +// ************************************************************************************************* +// @fn reset_acceleration +// @brief Reset acceleration variables. +// @param none +// @return none +// ************************************************************************************************* +void reset_acceleration(void) +{ +} + +// ************************************************************************************************* +// @fn acceleration_value_is_positive +// @brief Returns 1 if 2's complement number is positive +// @param u8 value 2's complement number +// @return u8 1 = number is positive, 0 = number is negavtive +// ************************************************************************************************* +u8 acceleration_value_is_positive(u8 value) +{ + return ((value & BIT7) == 0); +} + +// ************************************************************************************************* +// @fn convert_acceleration_value_to_mgrav +// @brief Converts measured value to mgrav units +// @param u8 value g data from sensor +// @return u16 Acceleration (mgrav) +// ************************************************************************************************* +u16 convert_acceleration_value_to_mgrav(u8 value) +{ + u16 result; + u8 i; + + if (!acceleration_value_is_positive(value)) + { + // Convert 2's complement negative number to positive number + value = ~value; + value += 1; + } + + result = 0; + for (i = 0; i < 7; i++) + { + result += ((value & (BIT(i))) >> i) * mgrav_per_bit[i]; + } + + return (result); +} + +// +//// +// ************************************************************************************************* +//// @fn display_acceleration +//// @brief Display routine. +//// @param u8 line LINE1 +//// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +//// @return none +//// +// ************************************************************************************************* +//void display_acceleration(u8 line, u8 update) +//{ +// u8 * str; +// u8 raw_data; +// u16 accel_data; +// +// // Show warning if acceleration sensor was not initialised properly +// if (!as_ok) +// { +// display_chars(LCD_SEG_L1_2_0, (u8*)"ERR", SEG_ON); +// } +// else +// { +// // Redraw whole screen +// if (update == DISPLAY_LINE_UPDATE_FULL) +// { +// { +// // Start acceleration sensor +// if (!is_acceleration_measurement()) +// { +// // Clear previous acceleration value +// sAccel.data = 0; +// +// // Start sensor +// as_start(); +// +// // Set timeout counter +// sAccel.timeout = ACCEL_MEASUREMENT_TIMEOUT; +// +// // Set mode +// sAccel.mode = ACCEL_MODE_ON; +// +// // Start with Y-axis values +// sAccel.view_style = DISPLAY_ACCEL_Y; +// } +// +// // Display decimal point +// display_symbol(LCD_SEG_L1_DP1, SEG_ON); +// } +// } +// else if (update == DISPLAY_LINE_UPDATE_PARTIAL) +// { +// // Convert X/Y/Z values to mg +// switch (sAccel.view_style) +// { +// case DISPLAY_ACCEL_X: raw_data = sAccel.xyz[0]; +// +// +// +// +// +// +// +// display_char(LCD_SEG_L1_3, +// 'X', SEG_ON); +// break; +// case DISPLAY_ACCEL_Y: raw_data = sAccel.xyz[1]; +// +// +// +// +// +// +// +// display_char(LCD_SEG_L1_3, +// 'Y', SEG_ON); +// break; +// default: raw_data = sAccel.xyz[2]; +// +// +// +// +// +// +// +// display_char(LCD_SEG_L1_3, +// 'Z', SEG_ON); +// break; +// } +// accel_data = convert_acceleration_value_to_mgrav(raw_data) / 10; +// +// // Filter acceleration +// accel_data = (u16)((accel_data * 0.2) + (sAccel.data * 0.8)); +// +// // Store average acceleration +// sAccel.data = accel_data; +// +// // Display acceleration in x.xx format +// str = int_to_array(accel_data, 3, 0); +// display_chars(LCD_SEG_L1_2_0, str, SEG_ON); +// +// // Display sign +// if (acceleration_value_is_positive(raw_data)) +// { +// display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); +// display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); +// } +// else +// { +// display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); +// display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); +// } +// } +// else if (update == DISPLAY_LINE_CLEAR) +// { +// // Stop acceleration sensor +// as_stop(); +// +// // Clear mode +// sAccel.mode = ACCEL_MODE_OFF; +// +// // Clean up display +// display_symbol(LCD_SEG_L1_DP1, SEG_OFF); +// display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); +// display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); +// } +// } +//} diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/acceleration.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/acceleration.h new file mode 100755 index 0000000..7b39c2a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/acceleration.h @@ -0,0 +1,78 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ACCELERATION_H_ +#define ACCELERATION_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +//#define DISPLAY_ACCEL_X (0u) +//#define DISPLAY_ACCEL_Y (1u) +//#define DISPLAY_ACCEL_Z (2u) + +//#define ACCEL_MODE_OFF (0u) +//#define ACCEL_MODE_ON (1u) + +// Stop acceleration measurement after 60 minutes to save battery +//#define ACCEL_MEASUREMENT_TIMEOUT (60*60u) + +// ************************************************************************************************* +// Global Variable section +struct accel +{ + // u8 mode; // ACC_MODE_OFF, ACC_MODE_ON + u8 xyz[3]; // Sensor raw data + u16 data; // Acceleration data in 10 * mgrav + // u8 view_style; // Display X/Y/Z values + // u16 timeout; // Timeout +}; +extern struct accel sAccel; + +// ************************************************************************************************* +// Extern section +extern void reset_acceleration(void); +extern void sx_acceleration(u8 line); +extern void display_acceleration(u8 line, u8 update); +extern u8 is_acceleration_measurement(void); +extern void do_acceleration_measurement(void); + +#endif /*ACCELERATION_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/altitude.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/altitude.c new file mode 100755 index 0000000..b1cf98d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/altitude.c @@ -0,0 +1,342 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Altitude measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "altitude.h" +#include "display.h" +#include "vti_ps.h" +#include "ports.h" +#include "timer.h" + +// logic +#include "user.h" +#include "datalog.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct alt sAlt; + +// ************************************************************************************************* +// Extern section + +// Global flag for pressure sensor initialisation status +extern u8 ps_ok; + +// ************************************************************************************************* +// @fn reset_altitude_measurement +// @brief Reset altitude measurement. +// @param none +// @return none +// ************************************************************************************************* +void reset_altitude_measurement(void) +{ + // Set default values + sAlt.on = 0; + sAlt.altitude = 0; + sAlt.temperature_C = 0; + sAlt.temperature_C_offset = 0; + + // Pressure sensor ok? + if (ps_ok) + { + // Initialise pressure table + init_pressure_table(); + + // Do single conversion + start_altitude_measurement(); + stop_altitude_measurement(); + + // Apply calibration offset and recalculate pressure table + if (sAlt.altitude_offset != 0) + { + sAlt.altitude += sAlt.altitude_offset; + update_pressure_table(sAlt.altitude, sAlt.pressure, sAlt.temperature_K); + } + } +} + +// ************************************************************************************************* +// @fn conv_m_to_ft +// @brief Convert meters to feet +// @param u16 m Meters +// @return u16 Feet +// ************************************************************************************************* +s16 convert_m_to_ft(s16 m) +{ + return (((s32) 328 * m) / 100); +} + +// ************************************************************************************************* +// @fn conv_ft_to_m +// @brief Convert feet to meters +// @param u16 ft Feet +// @return u16 Meters +// ************************************************************************************************* +s16 convert_ft_to_m(s16 ft) +{ + return (((s32) ft * 61) / 200); +} + +// ************************************************************************************************* +// @fn start_altitude_measurement +// @brief Start altitude measurement +// @param none +// @return none +// ************************************************************************************************* +void start_altitude_measurement(void) +{ + u8 timeout = 15; + + // Already on? + if (sAlt.on) + return; + + // Show warning if pressure sensor was not initialised properly + if (!ps_ok) + { + display_chars(LCD_SEG_L1_2_0, (u8 *) "ERR", SEG_ON); + return; + } + + // Enable DRDY IRQ on rising edge + PS_INT_IFG &= ~PS_INT_PIN; + PS_INT_IE |= PS_INT_PIN; + + // Start pressure sensor + ps_start(); + + // Set altitude measurement flag + sAlt.on = 1; + + // Get updated altitude + while (((PS_INT_IN & PS_INT_PIN) == 0) && (timeout > 0)) + { + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + timeout--; + } + + // Failed to start? + if (timeout == 0) + { + sAlt.on = 0; + } + + do_altitude_measurement(FILTER_OFF); +} + +// ************************************************************************************************* +// @fn stop_altitude_measurement +// @brief Stop altitude measurement +// @param none +// @return none +// ************************************************************************************************* +void stop_altitude_measurement(void) +{ + // Return if pressure sensor was not initialised properly + if (!ps_ok) + return; + + // Not on? + if (!sAlt.on) + return; + + // Logging data? + if (is_datalog()) + return; + + // Stop pressure sensor + ps_stop(); + + // Clear on flag + sAlt.on = 0; + + // Disable DRDY IRQ + PS_INT_IE &= ~PS_INT_PIN; + PS_INT_IFG &= ~PS_INT_PIN; +} + +// ************************************************************************************************* +// @fn is_altitude_measurement +// @brief Altitude measurement check +// @param none +// @return u8 1=Measurement ongoing, 0=measurement off +// ************************************************************************************************* +u8 is_altitude_measurement(void) +{ + return (sAlt.on); +} + +// ************************************************************************************************* +// @fn do_altitude_measurement +// @brief Perform single altitude measurement +// @param u8 filter Filter option +// @return none +// ************************************************************************************************* +void do_altitude_measurement(u8 filter) +{ + volatile u32 pressure; + + // If sensor is not ready, skip data read + if ((PS_INT_IN & PS_INT_PIN) == 0) + return; + + // Get temperature (format is *10 K) from sensor + sAlt.temperature_K = ps_get_temp(); + sAlt.temperature_C = sAlt.temperature_K - 2721 + sAlt.temperature_C_offset; + + // Get pressure (format is 1Pa) from sensor + pressure = ps_get_pa(); + + // Store measured pressure value + if (filter == FILTER_OFF) + { + sAlt.pressure = pressure; + } + else + { + // Filter current pressure + pressure = (u32) ((pressure * 0.2) + (sAlt.pressure * 0.8)); + + // Store average pressure + sAlt.pressure = pressure; + } + + // Convert pressure (Pa) and temperature ( K) to altitude (m) + sAlt.altitude = conv_pa_to_meter(sAlt.pressure, sAlt.temperature_K); +} + +// ************************************************************************************************* +// @fn display_altitude +// @brief Display routine. Supports display in meters and feet. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_altitude(u8 line, u8 update) +{ + u8 *str; + s16 ft; + + // Start measurement + start_altitude_measurement(); + + // redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sys.flag.use_metric_units) + { + // Display "m" symbol + display_symbol(LCD_UNIT_L1_M, SEG_ON); + } + else + { + // Display "ft" symbol + display_symbol(LCD_UNIT_L1_FT, SEG_ON); + } + + // Display altitude + display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + if (sys.flag.use_metric_units) + { + // Display altitude in xxxx m format, allow 3 leading blank digits + if (sAlt.altitude >= 0) + { + str = int_to_array(sAlt.altitude, 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + else + { + str = int_to_array(sAlt.altitude * (-1), 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + } + else + { + // Convert from meters to feet + ft = convert_m_to_ft(sAlt.altitude); + + // Limit to 9999ft (3047m) + if (ft > 9999) + ft = 9999; + + // Display altitude in xxxx ft format, allow 3 leading blank digits + if (ft >= 0) + { + str = int_to_array(ft, 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + else + { + str = int_to_array(ft * (-1), 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + } + display_chars(LCD_SEG_L1_3_0, str, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Stop measurement + stop_altitude_measurement(); + + // Clean up function-specific segments before leaving function + display_symbol(LCD_UNIT_L1_M, SEG_OFF); + display_symbol(LCD_UNIT_L1_FT, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/altitude.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/altitude.h new file mode 100755 index 0000000..f9550d8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/altitude.h @@ -0,0 +1,73 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ALTITUDE_H_ +#define ALTITUDE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_altitude_measurement(void); +extern void start_altitude_measurement(void); +extern void stop_altitude_measurement(void); +extern u8 is_altitude_measurement(void); +extern void do_altitude_measurement(u8 filter); + +// menu functions +extern void display_altitude(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct alt +{ + u8 on; // 1 = Measurement started, 0 = measurement off + u32 pressure; // Pressure (Pa) + u16 temperature_K; // Temperature in K + s16 temperature_C; // Temperature in ºC + s16 temperature_C_offset; // Temperature ºC offset + s16 altitude; // Altitude (m) + s16 altitude_offset; // Altitude offset stored during calibration +}; +extern struct alt sAlt; + +// ************************************************************************************************* +// Extern section + +#endif /*ALTITUDE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/battery.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/battery.c new file mode 100755 index 0000000..d02a821 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/battery.c @@ -0,0 +1,135 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Battery voltage measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" +#include "adc12.h" + +// logic +#include "menu.h" +#include "battery.h" + +// ************************************************************************************************* +// Prototypes section +void reset_batt_measurement(void); +void battery_measurement(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct batt sBatt; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_batt_measurement +// @brief Reset battery measurement module. +// @param none +// @return none +// ************************************************************************************************* +void reset_batt_measurement(void) +{ + // Reset lobatt display counter + sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE; + + // Start with battery voltage of 3.00V + sBatt.voltage = 300; +} + +// ************************************************************************************************* +// @fn battery_measurement +// @brief Init ADC12. Do single conversion of AVCC voltage. Turn off ADC12. +// @param none +// @return none +// ************************************************************************************************* +void battery_measurement(void) +{ + u16 voltage; + + // Convert external battery voltage (ADC12INCH_11=AVCC-AVSS/2) + voltage = adc12_single_conversion(REFVSEL_1, ADC12SHT0_10, ADC12INCH_11); + + // Convert ADC value to "x.xx V" + // Ideally we have A11=0->AVCC=0V ... A11=4095(2^12-1)->AVCC=4V + // --> (A11/4095)*4V=AVCC --> AVCC=(A11*4)/4095 + voltage = (voltage * 2 * 2) / 41; + + // Correct measured voltage with calibration value + voltage += sBatt.offset; + + // Discard values that are clearly outside the measurement range + if (voltage > BATTERY_HIGH_THRESHOLD) + { + voltage = sBatt.voltage; + } + + // Filter battery voltage + sBatt.voltage = ((voltage * 2) + (sBatt.voltage * 8)) / 10; + + // If battery voltage falls below low battery threshold, set system flag and modify LINE2 + // display function pointer + if (sBatt.voltage < BATTERY_LOW_THRESHOLD) + { + sys.flag.low_battery = 1; + + // Set sticky battery icon + display_symbol(LCD_SYMB_BATTERY, SEG_ON); + } + else + { + sys.flag.low_battery = 0; + + // Clear sticky battery icon + display_symbol(LCD_SYMB_BATTERY, SEG_OFF); + } + // Update LINE2 + display.flag.line2_full_update = 1; + + // Indicate to display function that new value is available + display.flag.update_battery_voltage = 1; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/battery.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/battery.h new file mode 100755 index 0000000..ade8b8e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/battery.h @@ -0,0 +1,79 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BATTERY_H_ +#define BATTERY_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// Internal functions +extern void reset_batt_measurement(void); +extern void battery_measurement(void); + +// ************************************************************************************************* +// Defines section + +// Battery high voltage threshold +#define BATTERY_HIGH_THRESHOLD (360u) + +// Battery end of life voltage threshold -> disable radio, show "lobatt" message +#define BATTERY_LOW_THRESHOLD (240u) + +// Show "lobatt" message every n seconds +#define BATTERY_LOW_MESSAGE_CYCLE (15u) + +// ************************************************************************************************* +// Global Variable section +struct batt +{ + // Counter for alternating "lobatt" display + u8 lobatt_display; + + // Battery voltage + u16 voltage; + + // Battery voltage offset + s16 offset; +}; +extern struct batt sBatt; + +// ************************************************************************************************* +// Extern section + +#endif /*BATTERY_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/bluerobin.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/bluerobin.c new file mode 100755 index 0000000..f4460ef --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/bluerobin.c @@ -0,0 +1,396 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// BlueRobin functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "radio.h" +#include "ports.h" +#include "timer.h" +#include "rf1a.h" + +// logic +#include "BlueRobin_RX_API.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// Set to TRUE if transmitter ID should be remembered when reconnecting +// Transmitter ID can be cleared by pressing button STAR for more than 3 seconds +#define REMEMBER_TX_ID (FALSE) + +// ************************************************************************************************* +// Global Variable section +struct bluerobin sBlueRobin; + +// ************************************************************************************************* +// Extern section + +// Stop BlueRobin timer +extern void BRRX__StopTimer_v(void); + +// Calibration value for FSCTRL0 register (corrects deviation of 26MHz crystal) +extern u8 rf_frequoffset; + +// ************************************************************************************************* +// @fn reset_bluerobin +// @brief Reset BlueRobin data. +// @param none +// @return none +// ************************************************************************************************* +void reset_bluerobin(void) +{ + // Reset state is no connection + sBlueRobin.state = BLUEROBIN_OFF; + + // Reset value of chest strap ID is 0 --> connect to next best chest strap + sBlueRobin.cs_id = 0; + + // No new data available + sBlueRobin.update = BLUEROBIN_NO_UPDATE; + sBlueRobin.heartrate = 0; +} + +// ************************************************************************************************* +// @fn mx_rfblue +// @brief BlueRobin sub menu. Button STAR resets chest strap ID to 0. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void mx_bluerobin(u8 line) +{ +#if REMEMBER_TX_ID == TRUE + u8 i; + + // Reset chest strap ID + sBlueRobin.cs_id = 0; + + display_chars(LCD_SEG_L1_2_0, (u8 *) "CLR", SEG_ON); + for (i = 0; i < 4; i++) + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); +#endif + + // Clear simulated button event + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn sx_bluerobin +// @brief BlueRobin direct function. Button UP connects/disconnects with transmitter unit. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void sx_bluerobin(u8 line) +{ + u8 stop = 0; + + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if SimpliciTI stack is active + if (is_rf()) + return; + + // UP: connect / disconnect transmitter + if (button.flag.up) + { + if (sBlueRobin.state == BLUEROBIN_OFF) + { + // If no transmitter can be found, stop BlueRobin stack + if (!start_bluerobin()) + stop = 1; + } + else if (sBlueRobin.state == BLUEROBIN_CONNECTED) + { + // Shutdown connection + stop = 1; + } + } + + // Shutdown connection + if (stop) + { + stop_bluerobin(); + } +} + +// ************************************************************************************************* +// @fn display_heartrate +// @brief Heart rate display routine. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_heartrate(u8 line, u8 update) +{ + u8 *str; + + if (update != DISPLAY_LINE_CLEAR) + { + if (is_bluerobin()) + { + str = int_to_array(sBlueRobin.heartrate, 3, 2); + display_chars(LCD_SEG_L1_2_0, str, SEG_ON); + } + else + { + display_chars(LCD_SEG_L1_2_0, (u8 *) "---", SEG_ON); + } + } + + // Redraw whole screen + if (!is_bluerobin()) + { + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_symbol(LCD_ICON_HEART, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Clear heart when not connected + display_symbol(LCD_ICON_HEART, SEG_OFF); + } + } +} + +// ************************************************************************************************* +// @fn is_bluerobin +// @brief Returns TRUE if BlueRobin transmitter is connected. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_bluerobin(void) +{ + return (sBlueRobin.state == BLUEROBIN_CONNECTED); +} + +// ************************************************************************************************* +// @fn is_bluerobin_searching +// @brief Returns TRUE if BlueRobin is searching for a transmitter. +// @param none +// @return u8 1 if it is trying to connect +// ************************************************************************************************* +u8 is_bluerobin_searching(void) +{ + return (sBlueRobin.state == BLUEROBIN_SEARCHING); +} + +// ************************************************************************************************* +// @fn get_bluerobin_data +// @brief Read BlueRobin packet data from API. +// @param none +// @return none +// ************************************************************************************************* +void get_bluerobin_data(void) +{ + brtx_state_t bChannelState; + + // Check connection status + bChannelState = BRRX_GetState_t(HR_CHANNEL); + + switch (bChannelState) + { + case TX_ACTIVE: // Read heart rate data from BlueRobin API + sBlueRobin.heartrate = BRRX_GetHeartRate_u8(); + sBlueRobin.update = BLUEROBIN_NEW_DATA; + break; + + case TX_OFF: // Shutdown connection + stop_bluerobin(); + break; + + // BR_SEARCH, BR_LEARN, BR_PAUSE: Keep old values until we receive new data + default: + break; + } +} + +// ************************************************************************************************* +// @fn start_bluerobin +// @brief Start BlueRobin stack and search for a transmitter. +// @param none +// @return 0 = no transmitter found, 1 = connected to a transmitter +// ************************************************************************************************* +u8 start_bluerobin(void) +{ + u8 timeout, i; + + // Init BlueRobin timer and radio + // Enable high current mode + open_radio(); + + // Initialize BR library + BRRX_Init_v(); + + // Set BR data transmission properties + BRRX_SetPowerdownDelay_v(10); // Power down channel after 10 consecutive lost data packets (~9 + // seconds) + BRRX_SetSearchTimeout_v(6); // Stop searching after 8 seconds + + // Sensitivity in learn mode reduced --> connect only to close transmitters + // Skip this part if chest strap id was set in a previous learn mode run +#if REMEMBER_TX_ID == TRUE + if (sBlueRobin.cs_id == 0) + BRRX_SetSignalLevelReduction_v(5); +#else + // Forget previously learned transmitter ID and connect to next close transmitter + sBlueRobin.cs_id = 0; + BRRX_SetSignalLevelReduction_v(5); +#endif + + // Apply frequency offset compensation to radio register FSCTRL0 + // If calibration memory was erased, rf_frequoffset defaults to 0x00 and has no effect + WriteSingleReg(FSCTRL0, rf_frequoffset); + + // New state is SEARCH + sBlueRobin.state = BLUEROBIN_SEARCHING; + + // Blink RF icon to show searching + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + + // Turn on radio and establish connection if channel not already started + if (BRRX_GetState_t(HR_CHANNEL) == TX_OFF) + { + // Start in learn mode (connect to closest heart rate transmitter) + BRRX_SetID_v(HR_CHANNEL, sBlueRobin.cs_id); + BRRX_Start_v(HR_CHANNEL); + + // Wait until learning phase is over, additional timeout prevents race condition if hardware + // works incorrect + timeout = 40; + while ((BRRX_GetState_t(HR_CHANNEL) == TX_SEARCH) && (timeout-- > 0)) + { + Timer0_A4_Delay(CONV_MS_TO_TICKS(200)); + } + + // Timeout? + if (timeout == 0) + { + display_chars(LCD_SEG_L1_3_0, (u8 *) "FAIL", SEG_ON); + for (i = 0; i < 4; i++) + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); + } + } + + // Check if connection attempt was successful + if (BRRX_GetState_t(HR_CHANNEL) == TX_ACTIVE) + { + // Successfully connected to transmitter + sBlueRobin.state = BLUEROBIN_CONNECTED; + + // When in learn mode, copy chest strap ID + if (sBlueRobin.cs_id == 0) + sBlueRobin.cs_id = BRRX_GetID_u32(HR_CHANNEL); + + // Show steady RF icon to indicate established connection + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF); + + // Show blinking icon + display_symbol(LCD_ICON_HEART, SEG_ON_BLINK_ON); + + return (1); + } + else // Error -> Shutdown connection + { + // Clear RF icon + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); + + return (0); + } +} + +// ************************************************************************************************* +// @fn stop_bluerobin +// @brief Stop communication and put peripherals in power-down mode. +// @param none +// @return none +// ************************************************************************************************* +void stop_bluerobin(void) +{ + // Reset connection status byte + sBlueRobin.state = BLUEROBIN_OFF; + + // Stop channel + BRRX_Stop_v(HR_CHANNEL); + + // Powerdown radio + close_radio(); + + // Force full display update to clear heart rate and speed data + sBlueRobin.heartrate = 0; + display.flag.full_update = 1; + + // Clear heart and RF symbol + display_symbol(LCD_ICON_HEART, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); +} + +// ************************************************************************************************* +// @fn bluerobin_flash_write_window +// @brief Returns 1 if next BlueRobin ISR is more than 15msec away. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_bluerobin_flash_write_window(void) +{ + if (is_bluerobin()) + return ((TA0CCR1 - TA0R) > 500); + else + return (1); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/bluerobin.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/bluerobin.h new file mode 100755 index 0000000..7127c04 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/bluerobin.h @@ -0,0 +1,90 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BLUEROBIN_H_ +#define BLUEROBIN_H_ + +// ************************************************************************************************* +// Include section +#include + +// ************************************************************************************************* +// Prototypes section +extern void reset_bluerobin(void); +extern void mx_bluerobin(u8 line); +extern void sx_bluerobin(u8 line); +extern void display_heartrate(u8 line, u8 update); +extern u8 is_bluerobin(void); +extern u8 is_bluerobin_searching(void); +extern void get_bluerobin_data(void); +extern u8 start_bluerobin(void); +extern void stop_bluerobin(void); +extern u8 is_bluerobin_flash_write_window(void); + +// ************************************************************************************************* +// Defines section + +// BlueRobin connection states +typedef enum +{ + BLUEROBIN_OFF = 0, // Not connected + BLUEROBIN_SEARCHING, // Searching for transmitter + BLUEROBIN_CONNECTED, // Connected + BLUEROBIN_ERROR // Error occurred while trying to connect or while connected +} BlueRobin_state_t; + +// BlueRobin data update states +typedef enum +{ + BLUEROBIN_NO_UPDATE = 0, // No new data available + BLUEROBIN_NEW_DATA // New data arrived +} BlueRobin_update_t; + +// ************************************************************************************************* +// Global Variable section +struct bluerobin +{ + BlueRobin_state_t state; // BLUEROBIN_OFF, BLUEROBIN_SEARCHING, BLUEROBIN_CONNECTED, + // BLUEROBIN_ERROR + BlueRobin_update_t update; // BLUEROBIN_NO_UPDATE, BLUEROBIN_NEW_DATA + u32 cs_id; // BLUEROBIN_NO_UPDATE, BLUEROBIN_NEW_DATA + u8 heartrate; // Heart rate (1 bpm) +}; +extern struct bluerobin sBlueRobin; + +// ************************************************************************************************* +// Extern section + +#endif /*BLUEROBIN_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/clock.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/clock.c new file mode 100755 index 0000000..bc44675 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/clock.c @@ -0,0 +1,292 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Time functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "ports.h" +#include "display.h" +#include "timer.h" + +// logic +#include "menu.h" +#include "clock.h" +#include "user.h" +#include "bluerobin.h" +#include "date.h" + +// ************************************************************************************************* +// Prototypes section +void reset_clock(void); +void clock_tick(void); +void mx_time(u8 line); +void sx_time(u8 line); + +void calc_24H_to_12H(u8 * hours, u8 * timeAM); +void conv_24H_to_12H(u8 * hours24, u8 * hours12, u8 * timeAMorPM); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct time sTime; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_clock +// @brief Resets clock time to 00:00:00, 24H time format. +// @param none +// @return none +// ************************************************************************************************* +void reset_clock(void) +{ + // Set global system time to 0 + sTime.system_time = 0; + + // Set main 24H time to start value + sTime.hour = 4; + sTime.minute = 30; + sTime.second = 0; + + // Display style of both lines is default (HH:MM) + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; + + // Reset timeout detection + sTime.last_activity = 0; +} + +// ************************************************************************************************* +// @fn clock_tick +// @brief Add 1 second to system time and to display time +// @param none +// @return none +// ************************************************************************************************* +void clock_tick(void) +{ + // Use sTime.drawFlag to minimize display updates + // sTime.drawFlag = 1: second + // sTime.drawFlag = 2: minute, second + // sTime.drawFlag = 3: hour, minute + sTime.drawFlag = 1; + + // Increase global system time + sTime.system_time++; + + // Add 1 second + sTime.second++; + + // Add 1 minute + if (sTime.second == 60) + { + sTime.second = 0; + sTime.minute++; + sTime.drawFlag++; + + // Add 1 hour + if (sTime.minute == 60) + { + sTime.minute = 0; + sTime.hour++; + sTime.drawFlag++; + + // Add 1 day + if (sTime.hour == 24) + { + sTime.hour = 0; + add_day(); + } + } + } +} + +// ************************************************************************************************* +// @fn convert_hour_to_12H_format +// @brief Convert internal 24H time to 12H time. +// @param u8 hour Hour in 24H format +// @return u8 Hour in 12H format +// ************************************************************************************************* +u8 convert_hour_to_12H_format(u8 hour) +{ + // 00:00 .. 11:59 --> AM 12:00 .. 11:59 + if (hour == 0) + return (hour + 12); + else if (hour <= 12) + return (hour); + // 13:00 .. 23:59 --> PM 01:00 .. 11:59 + else + return (hour - 12); +} + +// ************************************************************************************************* +// @fn is_hour_am +// @brief Checks if internal 24H time is AM or PM +// @param u8 hour Hour in 24H format +// @return u8 1 = AM, 0 = PM +// ************************************************************************************************* +u8 is_hour_am(u8 hour) +{ + // 00:00 .. 11:59 --> AM 12:00 .. 11:59 + if (hour < 12) + return (1); + // 12:00 .. 23:59 --> PM 12:00 .. 11:59 + else + return (0); +} + +// ************************************************************************************************* +// @fn sx_time +// @brief Time user routine. Toggles view style between HH:MM and SS. +// @param line LINE1 +// @return none +// ************************************************************************************************* +void sx_time(u8 line) +{ + // Toggle display view style + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + sTime.line1ViewStyle = DISPLAY_ALTERNATIVE_VIEW; + else + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn display_time +// @brief Clock display routine. Supports 24H and 12H time format. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL +// @return none +// ************************************************************************************************* +void display_time(u8 line, u8 update) +{ + u8 hour12; + + // Partial update + if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + if (sTime.drawFlag != 0) + { + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + { + switch (sTime.drawFlag) + { + case 3: + if (sys.flag.use_metric_units) + { + // Display 24H time "HH" + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(sTime.hour, 2, + 0), SEG_ON); + } + else + { + // Display 12H time "HH" + AM/PM + hour12 = convert_hour_to_12H_format(sTime.hour); + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(hour12, 2, + 0), SEG_ON); + display_am_pm_symbol(sTime.hour); + } + + case 2: + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.minute, 2, + 0), SEG_ON); + } + } + else + { + // Seconds are always updated + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.second, 2, 0), SEG_ON); + } + } + } + else if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Full update + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + { + // Display 24H/12H time + if (sys.flag.use_metric_units) + { + // Display 24H time "HH" + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(sTime.hour, 2, 0), SEG_ON); + } + else + { + // Display 12H time "HH" + AM/PM information + hour12 = convert_hour_to_12H_format(sTime.hour); + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(hour12, 2, 0), SEG_ON); + // Display AM/PM information + if (line == LINE1) + { + display_am_pm_symbol(sTime.hour); + } + } + + // Display minute + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.minute, 2, 0), SEG_ON); + display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_ON_BLINK_ON); + } + else + { + // Display seconds + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.second, 2, 0), SEG_ON); + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_OFF_BLINK_OFF); + // Change display style to default (HH:MM) + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; + // Clean up AM/PM icon + display_symbol(LCD_SYMB_AM, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/clock.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/clock.h new file mode 100755 index 0000000..a4ad480 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/clock.h @@ -0,0 +1,74 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef CLOCK_H_ +#define CLOCK_H_ + +// ************************************************************************************************* +// Defines section + +// Definitions for time format +#define TIMEFORMAT_24H (0u) +#define TIMEFORMAT_12H (1u) + +// ************************************************************************************************* +// Prototypes section +extern void reset_clock(void); +extern void sx_time(u8 line); +extern void mx_time(u8 line); +extern void clock_tick(void); +extern void display_selection_Timeformat1(u8 segments, u32 index, u8 digits, u8 blanks); +extern void display_time(u8 line, u8 update); + +// English units support +extern void calc_24H_to_12H(u8 * hours, u8 * timeAM); +extern u8 convert_hour_to_12H_format(u8 hour); +extern u8 is_hour_am(u8 hour); + +// ************************************************************************************************* +// Global Variable section +struct time +{ + u32 system_time; // Global system time. Used to calculate last activity + u32 last_activity; // Inactivity detection (exits set_value() function) + u8 drawFlag; // Flag to minimize display updates + u8 line1ViewStyle; // Viewing style + u8 hour; // Time data + u8 minute; // Time data + u8 second; // Time data +}; +extern struct time sTime; + +#endif /*CLOCK_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/datalog.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/datalog.c new file mode 100755 index 0000000..6bd327b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/datalog.c @@ -0,0 +1,465 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Data logger routines. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "flash.h" +#include "ports.h" + +// logic +#include "datalog.h" +#include "date.h" +#include "clock.h" +#include "altitude.h" +#include "temperature.h" +#include "bluerobin.h" + +// ************************************************************************************************* +// Prototypes section +void start_datalog(void); +void stop_datalog(void); +void datalog_sm(u8 * data, u8 len, u8 cmd); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct datalog sDatalog; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_datalog +// @brief Reset data logger memory and init variables. +// @param none +// @return none +// ************************************************************************************************* +void reset_datalog(void) +{ + u8 i; + + // Clear data logger memory + for (i = DATALOG_PAGE_START; i <= DATALOG_PAGE_END; i++) + { + flash_erase_page(i); + } + + sDatalog.flags.all = 0; + sDatalog.mode = DATALOG_MODE_TEMPERATURE + DATALOG_MODE_ALTITUDE; + sDatalog.interval = DATALOG_INTERVAL; + sDatalog.delay = 0; + sDatalog.wptr = (u16 *) DATALOG_MEMORY_START; + sDatalog.idx = 0; +} + +// ************************************************************************************************* +// @fn sx_alarm +// @brief Sx button turns alarm on/off. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void sx_datalog(u8 line) +{ + // Turn off the backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + + // Toggle data logger state + if (!sDatalog.flags.flag.on) + { + if (!sDatalog.flags.flag.memory_full) + { + // Turn on data logger + start_datalog(); + } + else // Memory full + { + // Show "nomem" message + message.flag.prepare = 1; + message.flag.type_nomem = 1; + } + } + else + { + // Turn off data logger + stop_datalog(); + } +} + +// ************************************************************************************************* +// @fn start_datalog +// @brief Begin to log data. +// @param none +// @return none +// ************************************************************************************************* +void start_datalog(void) +{ + // Start BlueRobin RX + if ((sDatalog.mode & DATALOG_MODE_HEARTRATE) != 0) + { + // Keep existing connection + if (!is_bluerobin()) + { + // Start BlueRobin + if (!start_bluerobin()) + { + // No connection established? -> Close stack + stop_bluerobin(); + } + } + } + + // Start pressure measurement + if ((sDatalog.mode & (DATALOG_MODE_TEMPERATURE | DATALOG_MODE_ALTITUDE)) != 0) + { + // Start altitude measurement + start_altitude_measurement(); + } + + // Set datalogger icon + display_symbol(LCD_ICON_RECORD, SEG_ON_BLINK_OFF); + + // Start data logging + datalog_sm(NULL, 0, DATALOG_CMD_START); +} + +// ************************************************************************************************* +// @fn stop_datalog +// @brief Stop data logging. +// @param none +// @return none +// ************************************************************************************************* +void stop_datalog(void) +{ + if ((sDatalog.mode & DATALOG_MODE_HEARTRATE) != 0) + { + // Stop BlueRobin connection + if (is_bluerobin()) + stop_bluerobin(); + } + + // Stop data logging and write out buffer + datalog_sm(NULL, 0, DATALOG_CMD_CLOSE); + + if ((sDatalog.mode & (DATALOG_MODE_TEMPERATURE | DATALOG_MODE_ALTITUDE)) != 0) + { + // Stop altitude measurement + stop_altitude_measurement(); + } + + // Clear datalogger icon + display_symbol(LCD_ICON_RECORD, SEG_OFF_BLINK_OFF); +} + +u8 is_datalog(void) +{ + return (sDatalog.flags.flag.on); +} + +// ************************************************************************************************* +// @fn display_datalog +// @brief Display data logger information. +// @param u8 line LINE1, LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_datalog(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_chars(LCD_SEG_L2_4_0, (u8 *) " DLOG", SEG_ON); + } +} + +// ************************************************************************************************* +// @fn do_datalog +// @brief Add data to data logging buffer. Called by second tick. +// @param none +// @return none +// ************************************************************************************************* +void do_datalog(void) +{ + u8 temp[4]; + u8 count; + + // If logging delay is over, add new data + if (--sDatalog.delay == 0) + { + // Store data when possible compressed (heartrate = 8 bits, temperature/altitude = min. 12 + // bits) + if (sDatalog.mode == DATALOG_MODE_HEARTRATE) + { + temp[0] = sBlueRobin.heartrate; + count = 1; + } + else if (sDatalog.mode == DATALOG_MODE_TEMPERATURE) + { + temp[0] = (sAlt.temperature_C >> 8) & 0xFF; + temp[1] = sAlt.temperature_C & 0xFF; + count = 2; + } + else if (sDatalog.mode == DATALOG_MODE_ALTITUDE) + { + temp[0] = (sAlt.altitude >> 8) & 0xFF; + temp[1] = sAlt.altitude & 0xFF; + count = 2; + } + else if (sDatalog.mode == + (DATALOG_MODE_HEARTRATE | DATALOG_MODE_TEMPERATURE | DATALOG_MODE_ALTITUDE)) + { + temp[0] = sBlueRobin.heartrate; + temp[1] = (sAlt.temperature_C >> 4) & 0xFF; + temp[2] = ((sAlt.temperature_C << 4) & 0xF0) | ((sAlt.altitude >> 8) & 0x0F); + temp[3] = sAlt.altitude & 0xFF; + count = 4; + } + else if (sDatalog.mode == (DATALOG_MODE_HEARTRATE | DATALOG_MODE_TEMPERATURE)) + { + temp[0] = sBlueRobin.heartrate; + temp[1] = (sAlt.temperature_C >> 8) & 0xFF; + temp[2] = sAlt.temperature_C & 0xFF; + count = 3; + } + else if (sDatalog.mode == (DATALOG_MODE_HEARTRATE | DATALOG_MODE_ALTITUDE)) + { + temp[0] = sBlueRobin.heartrate; + temp[1] = (sAlt.altitude >> 8) & 0xFF; + temp[2] = sAlt.altitude & 0xFF; + count = 3; + } + else if (sDatalog.mode == (DATALOG_MODE_TEMPERATURE | DATALOG_MODE_ALTITUDE)) + { + temp[0] = (sAlt.temperature_C >> 4) & 0xFF; + temp[1] = ((sAlt.temperature_C << 4) & 0xF0) | ((sAlt.altitude >> 8) & 0x0F); + temp[2] = sAlt.altitude & 0xFF; + count = 3; + } + + // Add data to recording buffer + datalog_sm((u8 *) &temp, count, DATALOG_CMD_ADD_DATA); + + // Reset delay counter + sDatalog.delay = sDatalog.interval; + + // Write to flash if buffer is over write threshold and no BlueRobin event is close + datalog_sm(NULL, 0, DATALOG_CMD_WRITE_DATA); + } +} + +// ************************************************************************************************* +// @fn datalog_add_to_buffer +// @brief Add byte-data to data logging buffer +// @param u8 * data Pointer to byte-data +// u8 len Byte count +// @return none +// ************************************************************************************************* +void datalog_add_to_buffer(u8 * data, u8 len) +{ + u8 i; + + for (i = 0; i < len; i++) + { + // Copy values to buffer + if (sDatalog.idx < DATALOG_BUFFER_SIZE) + { + sDatalog.buffer[sDatalog.idx++] = *(data + i); + } + } +} + +// ************************************************************************************************* +// Write buffer content to flash +// ************************************************************************************************* +void datalog_write_buffer(void) +{ + u8 i = 0; + u16 data; + u8 eom = 0; + volatile u16 temp; + + // Check if we cross end of memory threshold with this buffer write + if (sDatalog.wptr >= (u16 *) (DATALOG_MEMORY_END - 1 - sDatalog.idx)) + { + // Correct index to only write to end of memory + // Leave 2 bytes for session end marker + temp = (u16) sDatalog.wptr; + sDatalog.idx = (u8) ((u16) DATALOG_MEMORY_END - 1 - temp); + eom = 1; + } + + // Write buffer content to flash + while (i < sDatalog.idx - 1) + { + // Keep array order when writing to flash memory + data = sDatalog.buffer[i++]; + data += (u16) (sDatalog.buffer[i++] << 8); + + // Write 16-bit word to flash + flash_write(sDatalog.wptr++, data); + } + + // Stop data logging and write session end marker + if (eom) + { + // Write end marker + flash_write((u16 *) (DATALOG_MEMORY_END - 1), 0xFFFE); + // Clear buffer index + sDatalog.idx = 0; + // Clear flags + sDatalog.flags.flag.on = 0; + sDatalog.flags.flag.memory_full = 1; + // Clear datalogger icon + display_symbol(LCD_ICON_RECORD, SEG_OFF_BLINK_OFF); + } + else + { + // If index was odd number, 1 byte remains in buffer and must be written next time + if ((sDatalog.idx & 0x01) == 0x01) + { + sDatalog.buffer[0] = sDatalog.buffer[sDatalog.idx - 1]; + sDatalog.idx = 1; + } + else // All bytes haven been written + { + sDatalog.idx = 0; + } + } +} + +// ************************************************************************************************* +// @fn datalog_sm +// @brief Data logging state machine +// @param u8 line LINE1, LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void datalog_sm(u8 * data, u8 len, u8 cmd) +{ + u8 i; + u16 temp; + + switch (cmd) + { + case DATALOG_CMD_START: + if (!sDatalog.flags.flag.on && !sDatalog.flags.flag.memory_full) + { + // Clear index + sDatalog.idx = 0; + sDatalog.delay = sDatalog.interval; + + // Add session begin marker to buffer (2 byte) + temp = 0xFFFB; + datalog_add_to_buffer((u8 *) &temp, 2); + + // Add recording mode to buffer (1 byte) + datalog_add_to_buffer((u8 *) &sDatalog.mode, 1); + + // Add recording interval to buffer (1 byte) + datalog_add_to_buffer((u8 *) &sDatalog.interval, 1); + + // Add date to buffer (DD.MM.YYYY) (4 bytes) + datalog_add_to_buffer((u8 *) &sDate.day, 1); + datalog_add_to_buffer((u8 *) &sDate.month, 1); + datalog_add_to_buffer((u8 *) &sDate.year, 2); + + // Add system time to buffer (HH.MM.SS) (3 bytes) + datalog_add_to_buffer((u8 *) &sTime.hour, 3); + + // Data logging has started + sDatalog.flags.flag.on = 1; + } + break; + + case DATALOG_CMD_CLOSE: + if (sDatalog.flags.flag.on && !sDatalog.flags.flag.memory_full) + { + // If index is odd, add a dummy byte before writing session end marker + if ((sDatalog.idx & 0x01) == 0x01) + { + temp = 0x00; + datalog_add_to_buffer((u8 *) &temp, 1); + } + // Add session end marker to buffer (2 byte) + temp = 0xFFFE; + datalog_add_to_buffer((u8 *) &temp, 2); + // Write buffer to flash + datalog_write_buffer(); + } + sDatalog.flags.flag.on = 0; + break; + + case DATALOG_CMD_ADD_DATA: + if (sDatalog.flags.flag.on && !sDatalog.flags.flag.memory_full) + { + datalog_add_to_buffer(data, len); + } + break; + + case DATALOG_CMD_WRITE_DATA: + if (sDatalog.flags.flag.on && !sDatalog.flags.flag.memory_full) + { + // Over write threshold? + if (sDatalog.idx > DATALOG_BUFFER_WRITE_THRESHOLD) + { + // BlueRobin ISR call more than ~13ms away? + if (is_bluerobin_flash_write_window()) + datalog_write_buffer(); + } + } + break; + + case DATALOG_CMD_ERASE: + if (!sDatalog.flags.flag.on) + { + for (i = DATALOG_PAGE_START; i <= DATALOG_PAGE_END; i++) + { + flash_erase_page(i); + } + } + break; + + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/datalog.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/datalog.h new file mode 100755 index 0000000..da3903f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/datalog.h @@ -0,0 +1,134 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef DATALOG_H_ +#define DATALOG_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// internal functions +extern void reset_datalog(void); +extern u8 is_datalog(void); +extern void do_datalog(void); +extern void display_datalog(u8 line, u8 update); +extern void stop_datalog(void); + +// menu functions +extern void sx_datalog(u8 line); + +// ************************************************************************************************* +// Defines section + +// Data logger state +#define DATALOG_OFF (0u) +#define DATALOG_ON (1u) + +// Data memory range: 0x8000 - 0x9DFF (7.5kB) +#define DATALOG_MEMORY_START (0x8000) +#define DATALOG_MEMORY_END (0x9DFF) +#define DATALOG_BYTES_PER_PAGE (512u) +#define DATALOG_PAGE_START (DATALOG_MEMORY_START / \ + DATALOG_BYTES_PER_PAGE) +#define DATALOG_PAGE_END (DATALOG_MEMORY_END / \ + DATALOG_BYTES_PER_PAGE) + +// Store data in buffer before writing to flash memory +#define DATALOG_BUFFER_SIZE (128u) +#define DATALOG_BUFFER_WRITE_THRESHOLD (100u) + +// Datalogging interval in seconds +#define DATALOG_INTERVAL (5u) + +// Datalogger state machine commands +#define DATALOG_CMD_START (BIT0) +#define DATALOG_CMD_CLOSE (BIT1) +#define DATALOG_CMD_ERASE (BIT2) +#define DATALOG_CMD_ADD_DATA (BIT3) +#define DATALOG_CMD_WRITE_DATA (BIT4) + +// Datalog modes +#define DATALOG_MODE_HEARTRATE (BIT0) +#define DATALOG_MODE_TEMPERATURE (BIT1) +#define DATALOG_MODE_ALTITUDE (BIT2) +#define DATALOG_MODE_ACCELERATION (BIT3) + +// ************************************************************************************************* +// Global Variable section + +// Flags +typedef union +{ + struct + { + u8 on : 1; // 1 = data logging has started + u8 memory_full : 1; // 1 = memory is full + u8 one_second : 1; // 1 = 1 second has elapsed + } flag; + u8 all; // Shortcut to all flags (for reset) +} datalog_flags; + +struct datalog +{ + // Flags + datalog_flags flags; + + // Data logging mode + u8 mode; + + // Data logging interval + u8 interval; + + // Data logging delay counter + u8 delay; + + // Datalog memory write pointer + u16 *wptr; + + // Datalogger write buffer index + u8 idx; + + // Datalogger write buffer + u8 buffer[DATALOG_BUFFER_SIZE]; +}; +extern struct datalog sDatalog; + +// ************************************************************************************************* +// Extern section + +#endif /*DATALOG_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/date.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/date.c new file mode 100755 index 0000000..1e34ec5 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/date.c @@ -0,0 +1,234 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Date functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" + +// logic +#include "date.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section +void reset_date(void); +u8 get_numberOfDays(u8 month, u16 year); +void add_day(void); +void mx_date(u8 line); +void sx_date(u8 line); +void display_date(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct date sDate; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_date +// @brief Reset date to start value. +// @param none +// @return none +// ************************************************************************************************* +void reset_date(void) +{ + // Set date + sDate.year = 2009; + sDate.month = 8; + sDate.day = 1; + + // Show day and month on display + sDate.display = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn get_NumberOfDays +// @brief Return number of days for a given month +// @param month month as char +// year year as int +// @return day count for given month +// ************************************************************************************************* +u8 get_numberOfDays(u8 month, u16 year) +{ + switch (month) + { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + return (31); + + case 4: + case 6: + case 9: + case 11: + return (30); + + // 1. A year that is divisible by 4 is a leap year. (Y % 4) == 0 + // 2. Exception to rule 1: a year that is divisible by 100 is not a leap year. (Y % 100) != + // 0 + // 3. Exception to rule 2: a year that is divisible by 400 is a leap year. (Y % 400) == 0 + + case 2: + if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))) + return (29); + else + return (28); + + default: + return (0); + } +} + +// ************************************************************************************************* +// @fn add_day +// @brief Add one day to current date. Called when clock changes from 23:59 to 00:00 +// @param none +// @return none +// ************************************************************************************************* +void add_day(void) +{ + // Add 1 day + sDate.day++; + + // Check if day overflows into next month + if (sDate.day > get_numberOfDays(sDate.month, sDate.year)) + { + // Add 1 month and reset to day to 1 + sDate.day = 1; + sDate.month++; + + // Check if month overflows into next year + if (sDate.month > 12) + { + // Add 1 year and reset month and day to 1 + sDate.day = 1; + sDate.month = 1; + sDate.year++; + } + } + + // Indicate to display function that new value is available + display.flag.full_update = 1; +} + +// ************************************************************************************************* +// @fn sx_date +// @brief Date user routine. Toggles view between DD.MM and YYYY. +// @param line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void sx_date(u8 line) +{ + // Toggle display items + if (sDate.display == DISPLAY_DEFAULT_VIEW) + sDate.display = DISPLAY_ALTERNATIVE_VIEW; + else + sDate.display = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn display_date +// @brief Display date in DD.MM format (metric units) or MM.DD (English units). +// @param u8 line LINE1, LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL +// @return none +// ************************************************************************************************* +void display_date(u8 line, u8 update) +{ + u8 *str; + + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sDate.display == DISPLAY_DEFAULT_VIEW) + { + // Convert day to string + str = int_to_array(sDate.day, 2, 0); + if (sys.flag.use_metric_units) + { + display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); + } + else + { + display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); + } + + // Convert month to string + str = int_to_array(sDate.month, 2, 0); + if (sys.flag.use_metric_units) + { + display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); + } + else + { + display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); + } + + // Display "." to separate day and month + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); + } + else + { + // Convert year to string + str = int_to_array(sDate.year, 4, 0); + display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_3_0), str, SEG_ON); + + // Clear "." + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_OFF); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Show day and month on display when coming around next time + sDate.display = DISPLAY_DEFAULT_VIEW; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/date.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/date.h new file mode 100755 index 0000000..f3a65b8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/date.h @@ -0,0 +1,68 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef DATE_H_ +#define DATE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_date(void); +extern void add_day(void); +extern void mx_date(u8 line); +extern void sx_date(u8 line); +extern void display_date(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct date +{ + u8 display; // Toggles view between DISPLAY_DEFAULT_VIEW = DD.MM and + // DISPLAY_ALTERNATIVE_VIEW = YYYY + u8 day; + u8 month; + u16 year; +}; +extern struct date sDate; + +// ************************************************************************************************* +// Extern section + +#endif /*DATE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/menu.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/menu.c new file mode 100755 index 0000000..f664cdf --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/menu.c @@ -0,0 +1,172 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Menu management functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" + +// logic +#include "menu.h" +#include "user.h" +#include "clock.h" +#include "date.h" +#include "temperature.h" +#include "altitude.h" +#include "battery.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "acceleration.h" +#include "datalog.h" +#include "rfbsl.h" + +// ************************************************************************************************* +// Defines section +#define FUNCTION(function) function + +// ************************************************************************************************* +// Global Variable section +const struct menu *ptrMenu_L1 = NULL; +const struct menu *ptrMenu_L2 = NULL; + +// ************************************************************************************************* +// Global Variable section + +void display_nothing(u8 line, u8 update) +{ +} + +u8 update_time(void) +{ + return (display.flag.update_time); +} + +u8 update_date(void) +{ + return (display.flag.update_date); +} + +u8 update_temperature(void) +{ + return (display.flag.update_temperature); +} + +// ************************************************************************************************* +// User navigation ( [____] = default menu item after reset ) +// +// LINE1: [Time] -> Temperature -> Altitude -> Heart rate +// +// LINE2: [Date] -> Datalog -> SYNC -> RFBSL +// ************************************************************************************************* + +// Line1 - Time +const struct menu menu_L1_Time = { + FUNCTION(sx_time), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_time), // display function + FUNCTION(update_time), // new display data + &menu_L1_Temperature, +}; + +// Line1 - Temperature +const struct menu menu_L1_Temperature = { + FUNCTION(dummy), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_temperature), // display function + FUNCTION(update_time), // new display data + &menu_L1_Altitude, +}; + +// Line1 - Altitude +const struct menu menu_L1_Altitude = { + FUNCTION(dummy), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_altitude), // display function + FUNCTION(update_time), // new display data +#ifdef INCLUDE_BLUEROBIN_SUPPORT + &menu_L1_Heartrate, +}; + +// Line1 - Heart Rate +const struct menu menu_L1_Heartrate = { + FUNCTION(sx_bluerobin), // direct function + FUNCTION(mx_bluerobin), // sub menu function + FUNCTION(display_heartrate), // display function + FUNCTION(update_time), // new display data +#endif + &menu_L1_Time, +}; + +// Line2 - Date +const struct menu menu_L2_Date = { + FUNCTION(sx_date), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_date), // display function + FUNCTION(update_date), // new display data + &menu_L2_DataLog, +}; + +// Line2 - DataLog (data recording on/off) +const struct menu menu_L2_DataLog = { + FUNCTION(sx_datalog), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_datalog), // display function + FUNCTION(update_time), // new display data + &menu_L2_Sync, +}; + +// Line2 - SYNC (synchronization/data download via SimpliciTI) +const struct menu menu_L2_Sync = { + FUNCTION(sx_sync), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_sync), // display function + FUNCTION(update_time), // new display data + &menu_L2_RFBSL, +}; + +// Line2 - RFBSL (software update) +const struct menu menu_L2_RFBSL = { + FUNCTION(sx_rfbsl), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_rfbsl), // display function + FUNCTION(update_time), // new display data + &menu_L2_Date, +}; diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/menu.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/menu.h new file mode 100755 index 0000000..6b543e1 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/menu.h @@ -0,0 +1,84 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef MENU_H_ +#define MENU_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +struct menu +{ + // Pointer to direct function (start, stop etc) + void (*sx_function)(u8 line); + // Pointer to sub menu function (change settings, reset counter etc) + void (*mx_function)(u8 line); + // Pointer to display function + void (*display_function)(u8 line, u8 mode); + // Display update trigger + u8 (*display_update)(void); + // Pointer to next menu item + const struct menu *next; +}; + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +// Line1 navigation +extern const struct menu menu_L1_Time; +extern const struct menu menu_L1_Temperature; +extern const struct menu menu_L1_Altitude; +extern const struct menu menu_L1_Heartrate; + +// Line2 navigation +extern const struct menu menu_L2_Date; +extern const struct menu menu_L2_DataLog; +extern const struct menu menu_L2_Sync; +extern const struct menu menu_L2_RFBSL; + +// Pointers to current menu item +extern const struct menu *ptrMenu_L1; +extern const struct menu *ptrMenu_L2; + +#endif /*MENU_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfbsl.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfbsl.c new file mode 100755 index 0000000..c32c980 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfbsl.c @@ -0,0 +1,118 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Wireless Update functions. +// ************************************************************************************************* + + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" + +// logic +#include "rfbsl.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" + +// ************************************************************************************************* +// Global Variable section +u8 rfBSL_button_confirmation; + +// ************************************************************************************************* +// @fn sx_rfbsl +// @brief This functions starts the RFBSL +// @param line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void sx_rfbsl(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Exit if SimpliciTI stack is active + if (is_rf()) + return; + + rfBSL_button_confirmation++; + + if (rfBSL_button_confirmation == 2) + { + // Before entering RFBSL clear the LINE1 Symbols + display_symbol(LCD_SYMB_AM, SEG_OFF); + + clear_line(LINE1); + + // Write RAM to indicate we will be downloading the RAM Updater first + display_chars(LCD_SEG_L2_5_0, (u8 *) " RFBSL", SEG_ON); + display_chars(LCD_SEG_L1_3_0, (u8 *) " RAM", SEG_ON); + + // Call RFBSL + CALL_RFSBL(); + } +} + +// ************************************************************************************************* +// @fn display_rfbsl +// @brief RFBSL display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_rfbsl(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (rfBSL_button_confirmation == 0) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " RFBSL", SEG_ON); + } + else if (rfBSL_button_confirmation < 2) + { + // Request one more button press to confirm rfBSL call + display_chars(LCD_SEG_L2_5_0, (u8 *) " CONF", SEG_ON); + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfbsl.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfbsl.h new file mode 100755 index 0000000..364749f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfbsl.h @@ -0,0 +1,55 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RFBSL_H_ +#define RFBSL_H_ + +// ************************************************************************************************* +// Prototypes section +extern void sx_rfbsl(u8 line); +extern void display_rfbsl(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// Entry point of of the Flash Updater in BSL memory +#define CALL_RFSBL() ((void (*)()) 0x1000)() + + +// ************************************************************************************************* +// Global Variable section +extern u8 rfBSL_button_confirmation; + +#endif /*RFBSL_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfsimpliciti.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfsimpliciti.c new file mode 100755 index 0000000..6887571 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfsimpliciti.c @@ -0,0 +1,403 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// SimpliciTI functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "vti_as.h" +#include "ports.h" +#include "timer.h" +#include "radio.h" +#include "flash.h" + +// logic +#include "acceleration.h" +#include "rfsimpliciti.h" +#include "bluerobin.h" +#include "simpliciti.h" +#include "clock.h" +#include "date.h" +#include "temperature.h" +#include "vti_ps.h" +#include "altitude.h" +#include "datalog.h" + +// ************************************************************************************************* +// Prototypes section +void simpliciti_get_data_callback(void); +void start_simpliciti_sync(void); + +// ************************************************************************************************* +// Defines section + +// Each packet index requires 2 bytes, so we can have 9 packet indizes in 18 bytes usable payload +#define BM_SYNC_BURST_PACKETS_IN_DATA (9u) + +// ************************************************************************************************* +// Global Variable section +struct RFsmpl sRFsmpl; + +// flag contains status information, trigger to send data and trigger to exit SimpliciTI +unsigned char simpliciti_flag; + +// 4 data bytes to send +unsigned char simpliciti_data[SIMPLICITI_MAX_PAYLOAD_LENGTH]; + +// 4 byte device address overrides SimpliciTI end device address set in "smpl_config.dat" +unsigned char simpliciti_ed_address[4]; + +// 1 = send one or more reply packets, 0 = no need to reply +//unsigned char simpliciti_reply; +unsigned char simpliciti_reply_count; + +// 1 = send packets sequentially from burst_start to burst_end, 2 = send packets addressed by their +// index +u8 burst_mode; + +// Start and end index of packets to send out +u16 burst_start, burst_end; + +// Array containing requested packets +u16 burst_packet[BM_SYNC_BURST_PACKETS_IN_DATA]; + +// Current packet index +u8 burst_packet_index; + +// Byte-Pointer to flash memory +u8 *flash_ptr; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn reset_rf +// @brief Reset SimpliciTI data. +// @param none +// @return none +// ************************************************************************************************* +void reset_rf(void) +{ + // No connection + sRFsmpl.mode = SIMPLICITI_OFF; +} + +// ************************************************************************************************* +// @fn sx_sync +// @brief Start SimpliciTI. Button DOWN connects/disconnects to access point. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_sync(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Turn off the backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + BUTTONS_IE &= ~BUTTON_BACKLIGHT_PIN; + + // Start SimpliciTI in sync mode + start_simpliciti_sync(); + + BUTTONS_IE |= BUTTON_BACKLIGHT_PIN; +} + +// ************************************************************************************************* +// @fn display_sync +// @brief SimpliciTI display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_sync(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " SYNC", SEG_ON); + } +} + +// ************************************************************************************************* +// @fn is_rf +// @brief Returns TRUE if SimpliciTI receiver is connected. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_rf(void) +{ + return (sRFsmpl.mode != SIMPLICITI_OFF); +} + +// ************************************************************************************************* +// @fn start_simpliciti_sync +// @brief Start SimpliciTI (sync mode). +// @param none +// @return none +// ************************************************************************************************* +void start_simpliciti_sync(void) +{ + // Clear LINE1 + clear_line(LINE1); + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + + // Stop data logging and close session + stop_datalog(); + + // Turn on beeper icon to show activity + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + + // Prepare radio for RF communication + open_radio(); + + // Set SimpliciTI mode + sRFsmpl.mode = SIMPLICITI_SYNC; + + // Set SimpliciTI timeout to save battery power + sRFsmpl.timeout = SIMPLICITI_TIMEOUT; + + // Start SimpliciTI stack. Try to link to access point. + // Exit with timeout or by a DOWN button press. + if (simpliciti_link()) + { + // Enter sync routine. This will send ready-to-receive packets at regular intervals to the + // access point. + // The access point always replies a command (NOP if no other command is set) + simpliciti_main_sync(); + } + + // Set SimpliciTI state to OFF + sRFsmpl.mode = SIMPLICITI_OFF; + + // Powerdown radio + close_radio(); + + // Clear last button events + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + BUTTONS_IFG = 0x00; + button.all_flags = 0; + + // Clear icons + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); + + // Force full display update + display.flag.full_update = 1; +} + +// ************************************************************************************************* +// @fn simpliciti_sync_decode_ap_cmd_callback +// @brief For SYNC mode only: Decode command from access point and trigger actions. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_sync_decode_ap_cmd_callback(void) +{ + u8 i; + s16 t1, offset; + + // Default behaviour is to send no reply packets + simpliciti_reply_count = 0; + + switch (simpliciti_data[0]) + { + case SYNC_AP_CMD_NOP: + break; + + case SYNC_AP_CMD_GET_STATUS: // Send watch parameters + simpliciti_data[0] = SYNC_ED_TYPE_STATUS; + // Send single reply packet + simpliciti_reply_count = 1; + break; + + case SYNC_AP_CMD_SET_WATCH: // Set watch parameters + sys.flag.use_metric_units = (simpliciti_data[1] >> 7) & 0x01; + sTime.hour = simpliciti_data[1] & 0x7F; + sTime.minute = simpliciti_data[2]; + sTime.second = simpliciti_data[3]; + sDate.year = (simpliciti_data[4] << 8) + simpliciti_data[5]; + sDate.month = simpliciti_data[6]; + sDate.day = simpliciti_data[7]; + // Set temperature and temperature offset + t1 = (s16) ((simpliciti_data[10] << 8) + simpliciti_data[11]); + offset = t1 - (sAlt.temperature_C - sAlt.temperature_C_offset); + sAlt.temperature_C_offset = offset; + sAlt.temperature_C = t1; + // Set altitude + sAlt.altitude = (s16) ((simpliciti_data[12] << 8) + simpliciti_data[13]); + update_pressure_table(sAlt.altitude, sAlt.pressure, sAlt.temperature_K); + // Data logging mode + sDatalog.mode = simpliciti_data[14]; + // Data logging interval + sDatalog.interval = simpliciti_data[15]; + + display_chars(LCD_SEG_L2_5_0, (u8 *) " DONE", SEG_ON); + sRFsmpl.display_sync_done = 1; + break; + + case SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_1: + // Send sequential packets out in a burst + simpliciti_data[0] = SYNC_ED_TYPE_MEMORY; + // Get burst start and end packet + burst_start = (simpliciti_data[1] << 8) + simpliciti_data[2]; + burst_end = (simpliciti_data[3] << 8) + simpliciti_data[4]; + // Set burst mode + burst_mode = 1; + // Number of packets to send + simpliciti_reply_count = burst_end - burst_start + 1; + break; + + case SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_2: + // Send specified packets out in a burst + simpliciti_data[0] = SYNC_ED_TYPE_MEMORY; + // Store the requested packets + for (i = 0; i < BM_SYNC_BURST_PACKETS_IN_DATA; i++) + { + burst_packet[i] = (simpliciti_data[i * 2 + 1] << 8) + simpliciti_data[i * 2 + 2]; + } + // Set burst mode + burst_mode = 2; + // Number of packets to send + simpliciti_reply_count = BM_SYNC_BURST_PACKETS_IN_DATA; + break; + + case SYNC_AP_CMD_ERASE_MEMORY: // Erase data logger memory + for (i = DATALOG_PAGE_START; i <= DATALOG_PAGE_END; i++) + { + flash_erase_page(i); + } + sDatalog.wptr = (u16 *) DATALOG_MEMORY_START; + sDatalog.flags.flag.memory_full = 0; + break; + + case SYNC_AP_CMD_EXIT: // Exit sync mode + simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; + break; + } + +} + +// ************************************************************************************************* +// @fn simpliciti_sync_get_data_callback +// @brief For SYNC mode only: Access point has requested data. Copy this data into the TX +// buffer now. +// @param u16 index Index used for memory requests +// @return none +// ************************************************************************************************* +void simpliciti_sync_get_data_callback(unsigned int index) +{ + u8 i; + u16 bytes_ready; + + volatile u16 addr, mem; + + // Calculate bytes ready for sync + bytes_ready = (sDatalog.wptr - (u16 *) DATALOG_MEMORY_START) * 2; + + // simpliciti_data[0] contains data type and needs to be returned to AP + switch (simpliciti_data[0]) + { + case SYNC_ED_TYPE_STATUS: // Status packet + // Time + simpliciti_data[1] = (sys.flag.use_metric_units << 7) | (sTime.hour & 0x7F); + simpliciti_data[2] = sTime.minute; + simpliciti_data[3] = sTime.second; + // Date + simpliciti_data[4] = sDate.year >> 8; + simpliciti_data[5] = sDate.year & 0xFF; + simpliciti_data[6] = sDate.month; + simpliciti_data[7] = sDate.day; + // Unused + simpliciti_data[8] = 0; + simpliciti_data[9] = 0; + // Temperature + simpliciti_data[10] = sAlt.temperature_C >> 8; + simpliciti_data[11] = sAlt.temperature_C & 0xFF; + // Altitude + simpliciti_data[12] = sAlt.altitude >> 8; + simpliciti_data[13] = sAlt.altitude & 0xFF; + // Data logging mode + simpliciti_data[14] = sDatalog.mode; + // Data logging interval + simpliciti_data[15] = sDatalog.interval; + // Bytes ready for download + simpliciti_data[16] = bytes_ready >> 8; + simpliciti_data[17] = bytes_ready & 0xFF; + // Unused + simpliciti_data[18] = 0; + + break; + + case SYNC_ED_TYPE_MEMORY: + if (burst_mode == 1) + { + // Set burst packet address + simpliciti_data[1] = ((burst_start + index) >> 8) & 0xFF; + simpliciti_data[2] = (burst_start + index) & 0xFF; + // Assemble payload + flash_ptr = (u8 *) (DATALOG_MEMORY_START + (burst_start + index) * 16); + for (i = 3; i < BM_SYNC_DATA_LENGTH; i++) + simpliciti_data[i] = *flash_ptr++; + } + else if (burst_mode == 2) + { + // Set burst packet address + simpliciti_data[1] = (burst_packet[index] >> 8) & 0xFF; + simpliciti_data[2] = burst_packet[index] & 0xFF; + // Assemble payload + flash_ptr = (u8 *) (DATALOG_MEMORY_START + burst_packet[index] * 16); + for (i = 3; i < BM_SYNC_DATA_LENGTH; i++) + simpliciti_data[i] = *flash_ptr++; + } + break; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfsimpliciti.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfsimpliciti.h new file mode 100755 index 0000000..3cf7902 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/rfsimpliciti.h @@ -0,0 +1,98 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RFSIMPLICITI_H_ +#define RFSIMPLICITI_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_rf(void); +extern void sx_rf(u8 line); +extern void sx_ppt(u8 line); +extern void sx_sync(u8 line); +extern void display_rf(u8 line, u8 update); +extern void display_ppt(u8 line, u8 update); +extern void display_sync(u8 line, u8 update); +extern void send_smpl_data(u16 data); +extern u8 is_rf(void); + +// ************************************************************************************************* +// Defines section + +// SimpliciTI connection states +typedef enum +{ + SIMPLICITI_OFF = 0, // Not connected + SIMPLICITI_ACCELERATION, // Transmitting acceleration data and button events + SIMPLICITI_BUTTONS, // Transmitting button events + SIMPLICITI_SYNC // Syncing +} simpliciti_mode_t; + +// Stop SimpliciTI transmission after 60 minutes to save power +#define SIMPLICITI_TIMEOUT (60 * 60u) + +// Button flags for SimpliciTI data +#define SIMPLICITI_BUTTON_STAR (0x10) +#define SIMPLICITI_BUTTON_NUM (0x20) +#define SIMPLICITI_BUTTON_UP (0x30) + +// SimpliciTI mode flag +#define SIMPLICITI_MOUSE_EVENTS (0x01) +#define SIMPLICITI_KEY_EVENTS (0x02) + +// ************************************************************************************************* +// Global Variable section +struct RFsmpl +{ + // SIMPLICITI_OFF, SIMPLICITI_ACCELERATION, SIMPLICITI_BUTTONS + simpliciti_mode_t mode; + + // Timeout until SimpliciTI transmission is automatically stopped + u16 timeout; + + // Variable to display + u8 display_sync_done; +}; +extern struct RFsmpl sRFsmpl; + +extern unsigned char simpliciti_flag; + +// ************************************************************************************************* +// Extern section + +#endif /*RFSIMPLICITI_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/temperature.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/temperature.c new file mode 100755 index 0000000..5a4f897 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/temperature.c @@ -0,0 +1,170 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Temperature measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "temperature.h" +#include "display.h" + +// logic +#include "altitude.h" + +// ************************************************************************************************* +// Prototypes section +s16 convert_C_to_F(s16 value); +s16 convert_F_to_C(s16 value); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn convert_C_to_F +// @brief Convert °C to °F +// @param s16 value Temperature in °C +// @return s16 Temperature in °F +// ************************************************************************************************* +s16 convert_C_to_F(s16 value) +{ + s16 DegF; + + // Celsius in Fahrenheit = (( TCelsius × 9 ) / 5 ) + 32 + DegF = ((value * 9 * 10) / 5 / 10) + 32 * 10; + + return (DegF); +} + +// ************************************************************************************************* +// @fn convert_F_to_C +// @brief Convert °F to °C +// @param s16 value Temperature in 2.1 °F +// @return s16 Temperature in 2.1 °C +// ************************************************************************************************* +s16 convert_F_to_C(s16 value) +{ + s16 DegC; + + // TCelsius =( TFahrenheit - 32 ) × 5 / 9 + DegC = (((value - 320) * 5)) / 9; + + return (DegC); +} + +// ************************************************************************************************* +// @fn display_temperature +// @brief Common display routine for metric and English units. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_temperature(u8 line, u8 update) +{ + u8 *str; + s16 temperature; + + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Start measurement + start_altitude_measurement(); + + // Display °C / °F + display_symbol(LCD_SEG_L1_DP1, SEG_ON); + display_symbol(LCD_UNIT_L1_DEGREE, SEG_ON); + if (sys.flag.use_metric_units) + display_char(LCD_SEG_L1_0, 'C', SEG_ON); + else + display_char(LCD_SEG_L1_0, 'F', SEG_ON); + + // Display temperature + display_temperature(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + // When using English units, convert °C to °F (temp*1.8+32) + if (!sys.flag.use_metric_units) + { + temperature = convert_C_to_F(sAlt.temperature_C); + } + else + { + temperature = sAlt.temperature_C; + } + + // Indicate temperature sign through arrow up/down icon + if (temperature < 0) + { + // Convert negative to positive number + temperature = ~temperature; + temperature += 1; + + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + else // Temperature is >= 0 + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + + // Display result in xx.x format + str = int_to_array(temperature, 3, 1); + display_chars(LCD_SEG_L1_3_1, str, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Stop measurement + stop_altitude_measurement(); + + // Clean up function-specific segments before leaving function + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + display_symbol(LCD_UNIT_L1_DEGREE, SEG_OFF); + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/temperature.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/temperature.h new file mode 100755 index 0000000..81121ac --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/temperature.h @@ -0,0 +1,55 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef TEMPERATURE_H_ +#define TEMPERATURE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void display_temperature(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*TEMPERATURE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/user.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/user.c new file mode 100755 index 0000000..6410d0b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/user.c @@ -0,0 +1,282 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Several user functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "buzzer.h" +#include "ports.h" + +// logic +#include "menu.h" +#include "date.h" +#include "clock.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section +extern void idle_loop(void); + +// ************************************************************************************************* +// @fn dummy +// @brief Dummy direct function. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void dummy(u8 line) +{ +} + +// ************************************************************************************************* +// @fn set_value +// @brief Generic value setting routine +// @param s32 * value Pointer to value to +// set +// u8digits +// Number of digits +// u8 blanks +// Number of whitespaces before first valid +// digit +// s32 limitLow Lower limit +// of value +// s32 limitHigh Upper limit +// of value +// u16 mode +// u8 segments +// Segments where value should be drawn +// fptr_setValue_display_function1 Value-specific display +// routine +// @return none +// ************************************************************************************************* +void set_value(s32 * value, u8 digits, u8 blanks, s32 limitLow, s32 limitHigh, u16 mode, + u8 segments, + void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, + u8 blanks)) +{ + u8 update; + s16 stepValue = 1; + u8 doRound = 0; + u32 val; + + // Clear button flags + button.all_flags = 0; + + // Clear blink memory + clear_blink_mem(); + + // For safety only - buzzer on/off and button_repeat share same IRQ + stop_buzzer(); + + // Init step size and repeat counter + sButton.repeats = 0; + + // Initial display update + update = 1; + + // Turn on 200ms button repeat function + button_repeat_on(200); + + // Start blinking with with 2Hz + set_blink_rate(BIT6 + BIT5); + + // Value set loop + while (1) + { + // Idle timeout: exit function + if (sys.flag.idle_timeout) + break; + + // STAR (short) button: exit function + if (button.flag.star) + break; + + // NUM button: exit function and goto to next value (if available) + if (button.flag.num) + { + if ((mode & SETVALUE_NEXT_VALUE) == SETVALUE_NEXT_VALUE) + break; + } + + // UP button: increase value + if (button.flag.up) + { + // Increase value + *value = *value + stepValue; + + // Check value limits + if (*value > limitHigh) + { + // Check if value can roll over, else stick to limit + if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) + *value = limitLow; + else + *value = limitHigh; + + // Reset step size to default + stepValue = 1; + } + + // Trigger display update + update = 1; + + // Clear button flag + button.flag.up = 0; + } + + // DOWN button: decrease value + if (button.flag.down) + { + // Decrease value + *value = *value - stepValue; + + // Check value limits + if (*value < limitLow) + { + // Check if value can roll over, else stick to limit + if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) + *value = limitHigh; + else + *value = limitLow; + + // Reset step size to default + stepValue = 1; + } + + // Trigger display update + update = 1; + + // Clear button flag + button.flag.down = 0; + } + + // When fast mode is enabled, increase step size if Sx button is continuously + if ((mode & SETVALUE_FAST_MODE) == SETVALUE_FAST_MODE) + { + switch (sButton.repeats) + { + case 0: + stepValue = 1; + doRound = 0; + break; + case 10: + case -10: + stepValue = 10; + doRound = 1; + break; + case 20: + case -20: + stepValue = 100; + doRound = 1; + break; + case 30: + case -30: + stepValue = 1000; + doRound = 1; + break; + } + + // Round value to avoid odd numbers on display + if (stepValue != 1 && doRound == 1) + { + *value -= *value % stepValue; + doRound = 0; + } + } + + // Update display when there is new data + if (update) + { + // Display up or down arrow according to sign of value + if ((mode & SETVALUE_DISPLAY_ARROWS) == SETVALUE_DISPLAY_ARROWS) + { + if (*value >= 0) + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + val = *value; + } + else + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + val = *value * (-1); + } + } + else + { + val = *value; + } + + // Display function can either display value directly, modify value before displaying + // or display a string referenced by the value + fptr_setValue_display_function1(segments, val, digits, blanks); + + // Clear update flag + update = 0; + } + + // Call idle loop to serve background tasks + idle_loop(); + + } + + // Clear up and down arrows + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + + // Set blinking rate to 1Hz and stop + set_blink_rate(BIT7 + BIT6 + BIT5); + clear_blink_mem(); + + // Turn off button repeat function + button_repeat_off(); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/user.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/user.h new file mode 100755 index 0000000..f48cea4 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/logic/user.h @@ -0,0 +1,59 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef USER_H_ +#define USER_H_ + +// ************************************************************************************************* +// Defines section +#define SETVALUE_ROLLOVER_VALUE BIT0 +#define SETVALUE_DISPLAY_VALUE BIT1 +#define SETVALUE_DISPLAY_ARROWS BIT2 +#define SETVALUE_DISPLAY_SELECTION BIT3 +#define SETVALUE_FAST_MODE BIT4 +#define SETVALUE_NEXT_VALUE BIT5 + +// ************************************************************************************************* +// Prototypes section +extern u8 *select_view_style(u8 line, u8 * view1, u8 * view2); + +extern void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, u8 blanks); +extern void set_value(s32 * value, u8 digits, u8 blanks, s32 limitLow, s32 limitHigh, u16 mode, + u8 segments, + void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, + u8 blanks)); +extern void dummy(u8 line); + +#endif /*USER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/main.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/main.c new file mode 100755 index 0000000..7c96545 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/main.c @@ -0,0 +1,707 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// +//****************************************************************************** +// eZ430-Chronos +// +// Description: Software for the eZ430-Chronos Datalogger +// +// P.Francisco +// Version 1.6 +// Texas Instruments, Inc +// November 2010 +// Known working builds: +// IAR Embedded Workbench (Version: 5.10.4) +// Code Composer Studio (Version 4.2.0.10012) +//****************************************************************************** +//Change Log (More detailed information can be found in change_record.txt): +//****************************************************************************** +//Version: 1.6 +//Comments: Several bugs were fixed. +// LCD shows "done" after successfully received data +// rfBSL requires two button presses in order to update watch +// New method detects a long button press +// Removed file display1.c. The content is now in display.c +// Backlight of Chronos stays on for 3 sec after backlight button was pushed. +// +//Version: 1.5 +//Comments: Changed XT1 drive level to highest +// Modified key lock procedure. +// Negative °C are now converted correctly to Kelvin +// Enabled fast mode when changing altitude offset +// Disabled stopwatch stop when watch buttons are locked +// Added SimpliciTI sources to project. Upgraded to Version 1.1.1. +// Changed button names from M1/M2/S1/S2/BL to STAR/NUM/UP/DOWN/BACKLIGHT +// +//Version: 1.4 +//Comments: Initial Release Version +//********************************************************************************** + +// ************************************************************************************************* +// Initialization and control of application. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" +#include + +// driver +#include "clock.h" +#include "display.h" +#include "vti_as.h" +#include "vti_ps.h" +#include "radio.h" +#include "buzzer.h" +#include "ports.h" +#include "timer.h" +#include "pmm.h" + +// logic +#include "menu.h" +#include "date.h" +#include "battery.h" +#include "temperature.h" +#include "altitude.h" +#include "battery.h" +#include "acceleration.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "datalog.h" +#include "rfbsl.h" + +// ************************************************************************************************* +// Prototypes section +void init_application(void); +void init_global_variables(void); +void wakeup_event(void); +void process_requests(void); +void display_update(void); +void idle_loop(void); +void configure_ports(void); +void read_calibration_values(void); + +// ************************************************************************************************* +// Defines section + +// Number of calibration data bytes in INFOA memory +#define CALIBRATION_DATA_LENGTH (13u) + +// ************************************************************************************************* +// Global Variable section + +// Variable holding system internal flags +volatile s_system_flags sys; + +// Variable holding flags set by logic modules +volatile s_request_flags request; + +// Variable holding message flags +volatile s_message_flags message; + +// Global radio frequency offset taken from calibration memory +// Compensates crystal deviation from 26MHz nominal value +u8 rf_frequoffset; + +// Function pointers for LINE1 and LINE2 display function +void (*fptr_lcd_function_line1)(u8 line, u8 update); +void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn main +// @brief Main routine +// @param none +// @return none +// ************************************************************************************************* +int main(void) +{ + // Init MCU + init_application(); + + // Assign initial value to global variables + init_global_variables(); + + // Main control loop: wait in low power mode until some event needs to be processed + while (1) + { + // When idle go to LPM3 + idle_loop(); + + // Process wake-up events + if (button.all_flags || sys.all_flags) + wakeup_event(); + + // Process actions requested by logic modules + if (request.all_flags) + process_requests(); + + // Before going to LPM3, update display + if (display.all_flags) + display_update(); + } +} + +// ************************************************************************************************* +// @fn init_application +// @brief Initialize the microcontroller. +// @param none +// @return none +// ************************************************************************************************* +void init_application(void) +{ + volatile unsigned char *ptr; + + // --------------------------------------------------------------------- + // Enable watchdog + + // Watchdog triggers after 16 seconds when not cleared +#ifdef USE_WATCHDOG + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK; +#else + WDTCTL = WDTPW + WDTHOLD; +#endif + + // --------------------------------------------------------------------- + // Configure PMM + SetVCore(3); + + // Set global high power request enable + PMMCTL0_H = 0xA5; + PMMCTL0_L |= PMMHPMRE; + PMMCTL0_H = 0x00; + + // --------------------------------------------------------------------- + // Enable 32kHz ACLK + P5SEL |= 0x03; // Select XIN, XOUT on P5.0 and P5.1 + UCSCTL6 &= ~XT1OFF; // XT1 On, Highest drive strength + UCSCTL6 |= XCAP_3; // Internal load cap + UCSCTL3 = SELA__XT1CLK; // Select XT1 as FLL reference + UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; + + // --------------------------------------------------------------------- + // Configure CPU clock for 12MHz + _BIS_SR(SCG0); // Disable the FLL control loop + UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx + UCSCTL1 = DCORSEL_5; // Select suitable range + UCSCTL2 = FLLD_1 + 0x16E; // Set DCO Multiplier + _BIC_SR(SCG0); // Enable the FLL control loop + + // Worst-case settling time for the DCO when the DCO range bits have been + // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx + // UG for optimization. + // 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle + __delay_cycles(375000); + + // Loop until XT1 & DCO stabilizes, use do-while to insure that + // body is executed at least once + do + { + UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); + SFRIFG1 &= ~OFIFG; // Clear fault flags + } + while ((SFRIFG1 & OFIFG)); + + // --------------------------------------------------------------------- + // Configure port mapping + + // Disable all interrupts + __disable_interrupt(); + // Get write-access to port mapping registers: + PMAPPWD = 0x02D52; + // Allow reconfiguration during runtime: + PMAPCTL = PMAPRECFG; + + // P2.7 = TA0CCR1A or TA1CCR0A output (buzzer output) + ptr = &P2MAP0; + *(ptr + 7) = PM_TA1CCR0A; + P2OUT &= ~BIT7; + P2DIR |= BIT7; + + // P1.5 = SPI MISO input + ptr = &P1MAP0; + *(ptr + 5) = PM_UCA0SOMI; + // P1.6 = SPI MOSI output + *(ptr + 6) = PM_UCA0SIMO; + // P1.7 = SPI CLK output + *(ptr + 7) = PM_UCA0CLK; + + // Disable write-access to port mapping registers: + PMAPPWD = 0; + // Re-enable all interrupts + __enable_interrupt(); + + // --------------------------------------------------------------------- + // Configure ports + + // --------------------------------------------------------------------- + // Reset radio core + radio_reset(); + radio_powerdown(); + + // --------------------------------------------------------------------- + // Init acceleration sensor + as_init(); + + // --------------------------------------------------------------------- + // Init LCD + lcd_init(); + + // --------------------------------------------------------------------- + // Init buttons + init_buttons(); + + // --------------------------------------------------------------------- + // Configure Timer0 for use by the clock and delay functions + Timer0_Init(); + + // --------------------------------------------------------------------- + // Init pressure sensor + ps_init(); +} + +// ************************************************************************************************* +// @fn init_global_variables +// @brief Initialize global variables. +// @param none +// @return none +// ************************************************************************************************* +void init_global_variables(void) +{ + // -------------------------------------------- + // Apply default settings + + // set menu pointers to default menu items + ptrMenu_L1 = &menu_L1_Time; + ptrMenu_L2 = &menu_L2_DataLog; + + // Assign LINE1 and LINE2 display functions + fptr_lcd_function_line1 = ptrMenu_L1->display_function; + fptr_lcd_function_line2 = ptrMenu_L2->display_function; + + // Init system flags + button.all_flags = 0; + sys.all_flags = 0; + request.all_flags = 0; + display.all_flags = 0; + message.all_flags = 0; + + // Force full display update when starting up + display.flag.full_update = 1; + +#ifndef ISM_US + // Use metric units for display + sys.flag.use_metric_units = 1; +#endif + + // Read calibration values from info memory + read_calibration_values(); + + // Set system time to default value + reset_clock(); + + // Set date to default value + reset_date(); + + // Set buzzer to default value + reset_buzzer(); + + // Reset altitude measurement + reset_altitude_measurement(); + + // Reset acceleration measurement + reset_acceleration(); + +#ifdef INCLUDE_BLUEROBIN_SUPPORT + // Reset BlueRobin stack + reset_bluerobin(); +#endif + + // Reset SimpliciTI stack + reset_rf(); + + // Reset battery measurement + reset_batt_measurement(); + + // Reset data logger + reset_datalog(); +} + +// ************************************************************************************************* +// @fn wakeup_event +// @brief Process external / internal wakeup events. +// @param none +// @return none +// ************************************************************************************************* +void wakeup_event(void) +{ + // Enable idle timeout + sys.flag.idle_timeout_enabled = 1; + + // If buttons are locked, only display "buttons are locked" message + if (button.all_flags && sys.flag.lock_buttons) + { + // Show "buttons are locked" message synchronously with next second tick + if (!(BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED)) + { + message.flag.prepare = 1; + message.flag.type_locked = 1; + } + + // Clear buttons + button.all_flags = 0; + } + // Process long button press event (while button is held) + else if (button.flag.star_long) + { + // Clear button event + button.flag.star_long = 0; + + // Call sub menu function + ptrMenu_L1->mx_function(LINE1); + + // Set display update flag + display.flag.full_update = 1; + } + else if (button.flag.num_long) + { + // Clear button event + button.flag.num_long = 0; + + // Call sub menu function + ptrMenu_L2->mx_function(LINE2); + + // Set display update flag + display.flag.full_update = 1; + } + // Process single button press event (after button was released) + else if (button.all_flags) + { + // STAR button event --------------------------------------------------------------------- + // (Short) Advance to next menu item + if (button.flag.star) + { + // Clean up display before activating next menu item + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + + // Go to next menu entry + ptrMenu_L1 = ptrMenu_L1->next; + + // Assign new display function + fptr_lcd_function_line1 = ptrMenu_L1->display_function; + + // Set Line1 display update flag + display.flag.line1_full_update = 1; + + // Clear button flag + button.flag.star = 0; + } + // NUM button event --------------------------------------------------------------------- + // (Short) Advance to next menu item + else if (button.flag.num) + { + // Clear rfBSL confirmation flag + rfBSL_button_confirmation = 0; + + // Clean up display before activating next menu item + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_CLEAR); + + // Go to next menu entry + ptrMenu_L2 = ptrMenu_L2->next; + + // Assign new display function + fptr_lcd_function_line2 = ptrMenu_L2->display_function; + + // Set Line2 display update flag + display.flag.line2_full_update = 1; + + // Clear button flag + button.flag.num = 0; + } + // UP button event --------------------------------------------------------------------- + // Activate user function for Line1 menu item + else if (button.flag.up) + { + // Call direct function + ptrMenu_L1->sx_function(LINE1); + + // Set Line1 display update flag + display.flag.line1_full_update = 1; + + // Clear button flag + button.flag.up = 0; + } + // DOWN button event --------------------------------------------------------------------- + // Activate user function for Line2 menu item + else if (button.flag.down) + { + // Call direct function + ptrMenu_L2->sx_function(LINE2); + + // Set Line1 display update flag + display.flag.line2_full_update = 1; + + // Clear button flag + button.flag.down = 0; + } + } + + // Process internal events + if (sys.all_flags) + { + // Idle timeout --------------------------------------------------------------------- + if (sys.flag.idle_timeout) + { + // Clear timeout flag + sys.flag.idle_timeout = 0; + + // Clear display + clear_display(); + + // Set display update flags + display.flag.full_update = 1; + } + } + + // Disable idle timeout + sys.flag.idle_timeout_enabled = 0; +} + +// ************************************************************************************************* +// @fn process_requests +// @brief Process requested actions outside ISR context. +// @param none +// @return none +// ************************************************************************************************* +void process_requests(void) +{ + // Do temperature and pressure measurement + if (request.flag.altitude_measurement) + do_altitude_measurement(FILTER_ON); + + // Add data to datalog buffer + if (request.flag.datalog) + do_datalog(); + + // Do voltage measurement + if (request.flag.voltage_measurement) + battery_measurement(); + + // Reset request flag + request.all_flags = 0; +} + +// ************************************************************************************************* +// @fn display_update +// @brief Process display flags and call LCD update routines. +// @param none +// @return none +// ************************************************************************************************* +void display_update(void) +{ + u8 line; + u8 string[8]; + + // --------------------------------------------------------------------- + // Call Line1 display function + if (display.flag.full_update || display.flag.line1_full_update) + { + clear_line(LINE1); + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_UPDATE_FULL); + } + else if (ptrMenu_L1->display_update()) + { + // Update line1 only when new data is available + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + + // --------------------------------------------------------------------- + // If message text should be displayed on Line2, skip normal update + if (message.flag.show) + { + // Select message to display + line = LINE2; + if (message.flag.type_locked) + memcpy(string, " LO?T", 6); + else if (message.flag.type_unlocked) + memcpy(string, " OPEN", 6); + else if (message.flag.type_lobatt) + memcpy(string, "LOBATT", 6); + else if (message.flag.type_nomem) + memcpy(string, " NOMEM", 6); + else + { + line = LINE1; + if (message.flag.type_on) + memcpy(string, " ON", 4); + else if (message.flag.type_off) + memcpy(string, " OFF", 4); + } + + // Clear previous content + clear_line(line); + fptr_lcd_function_line2(line, DISPLAY_LINE_CLEAR); + + if (line == LINE2) + display_chars(LCD_SEG_L2_5_0, string, SEG_ON); + else + display_chars(LCD_SEG_L1_3_0, string, SEG_ON); + + // Next second tick erases message and repaints original screen content + message.all_flags = 0; + message.flag.erase = 1; + } + // --------------------------------------------------------------------- + // Call Line2 display function + else if (display.flag.full_update || display.flag.line2_full_update) + { + clear_line(LINE2); + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_UPDATE_FULL); + } + else if (ptrMenu_L2->display_update() && !message.all_flags) + { + // Update line2 only when new data is available + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_UPDATE_PARTIAL); + } + + // --------------------------------------------------------------------- + // Restore blinking icons (blinking memory is cleared when calling set_value) + if (display.flag.full_update) + { + if (is_bluerobin() == BLUEROBIN_CONNECTED) + { + // Turn on beeper icon to show activity + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF); + } + } + + // Clear display flag + display.all_flags = 0; +} + +// ************************************************************************************************* +// @fn to_lpm +// @brief Go to LPM0/3. +// @param none +// @return none +// ************************************************************************************************* +void to_lpm(void) +{ + // Go to LPM3 + _BIS_SR(LPM3_bits + GIE); + __no_operation(); +} + +// ************************************************************************************************* +// @fn idle_loop +// @brief Go to LPM. Service watchdog timer when waking up. +// @param none +// @return none +// ************************************************************************************************* +void idle_loop(void) +{ + // To low power mode + to_lpm(); + +#ifdef USE_WATCHDOG + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; +#endif +} + +// ************************************************************************************************* +// @fn read_calibration_values +// @brief Read calibration values for temperature measurement, voltage measurement +// and radio from INFO memory. +// @param none +// @return none +// ************************************************************************************************* +void read_calibration_values(void) +{ + u8 cal_data[CALIBRATION_DATA_LENGTH]; // Temporary storage for constants + u8 i; + u8 *flash_mem; // Memory pointer + + // Read calibration data from Info D memory + flash_mem = (u8 *) 0x1800; + for (i = 0; i < CALIBRATION_DATA_LENGTH; i++) + { + cal_data[i] = *flash_mem++; + } + + if (cal_data[0] == 0xFF) + { + // If no values are available (i.e. INFO D memory has been erased by user), assign + // experimentally derived values + rf_frequoffset = 4; + sBatt.offset = -10; + simpliciti_ed_address[0] = 0x79; + simpliciti_ed_address[1] = 0x56; + simpliciti_ed_address[2] = 0x34; + simpliciti_ed_address[3] = 0x12; + sAlt.altitude_offset = 0; + } + else + { + // Assign calibration data to global variables + rf_frequoffset = cal_data[1]; + // Range check for calibrated FREQEST value (-20 .. + 20 is ok, else use default value) + if ((rf_frequoffset > 20) && (rf_frequoffset < (256 - 20))) + { + rf_frequoffset = 0; + } + sBatt.offset = (s16) ((cal_data[4] << 8) + cal_data[5]); + simpliciti_ed_address[0] = cal_data[6]; + simpliciti_ed_address[1] = cal_data[7]; + simpliciti_ed_address[2] = cal_data[8]; + simpliciti_ed_address[3] = cal_data[9]; + // S/W version byte set during calibration? + if (cal_data[12] != 0xFF) + { + sAlt.altitude_offset = (s16) ((cal_data[10] << 8) + cal_data[11]); + } + else + { + sAlt.altitude_offset = 0; + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Applications/application/End Device/main_ED_BM.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Applications/application/End Device/main_ED_BM.c new file mode 100755 index 0000000..3c3a5bb --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Applications/application/End Device/main_ED_BM.c @@ -0,0 +1,261 @@ +/********************************************************************************************** + * Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + * + * IMPORTANT: Your use of this Software is limited to those specific rights granted under + * the terms of a software license agreement between the user who downloaded the software, + * his/her employer (which must be your employer) and Texas Instruments Incorporated (the + * "License"). You may not use this Software unless you agree to abide by the terms of the + * License. The License limits your use, and you acknowledge, that the Software may not be + * modified, copied or distributed unless embedded on a Texas Instruments microcontroller + * or used solely and exclusively in conjunction with a Texas Instruments radio frequency + * transceiver, which is integrated into your product. Other than for the foregoing purpose, + * you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + * perform, display or sell this Software and/or its documentation for any purpose. + * + * YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + * NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + * THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + * INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + * DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + * THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + * + * Should you have any questions regarding your right to use this Software, + * contact Texas Instruments Incorporated at www.TI.com. + **************************************************************************************************/ + +// ************************************************************************************************* +// Include section +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "bsp_leds.h" +#include "bsp_buttons.h" +#include "simpliciti.h" + + +// ************************************************************************************************* +// Defines section +#define TIMEOUT (10u) + +// Conversion from msec to ACLK timer ticks +#define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000) + +// U16 +typedef unsigned short u16; + +// ************************************************************************************************* +// Prototypes section + + +// ************************************************************************************************* +// Extern section +extern uint8_t sInit_done; + +// SimpliciTI has no low power delay function, so we have to use ours +extern void Timer0_A4_Delay(u16 ticks); + + +// ************************************************************************************************* +// Global Variable section +static linkID_t sLinkID1; + + + +// ************************************************************************************************* +// @fn simpliciti_link +// @brief Init hardware and try to link to access point. +// @param none +// @return unsigned char 0 = Could not link, timeout or external cancel. +// 1 = Linked successful. +// ************************************************************************************************* +unsigned char simpliciti_link(void) +{ + uint8_t timeout; + addr_t lAddr; + uint8_t i; + uint8_t pwr; + + // Configure timer + BSP_InitBoard(); + + // Change network address to value set in calling function + for (i = 0; i < NET_ADDR_SIZE; i++) + { + lAddr.addr[i] = simpliciti_ed_address[i]; + } + SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr); + + // Set flag + simpliciti_flag = SIMPLICITI_STATUS_LINKING; + + /* Keep trying to join (a side effect of successful initialization) until + * successful. Toggle LEDS to indicate that joining has not occurred. + */ + timeout = 0; + while (SMPL_SUCCESS != SMPL_Init(0)) + { + NWK_DELAY(1000); + + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; + + // Stop connecting after defined numbers of seconds (15) + if (timeout++ > TIMEOUT) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + simpliciti_flag = SIMPLICITI_STATUS_ERROR; + return (0); + } + + // Break when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + return (0); + } + } + + // Set output power to +3.3dmB + pwr = IOCTL_LEVEL_2; + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &pwr); + + /* Unconditional link to AP which is listening due to successful join. */ + timeout = 0; + while (SMPL_SUCCESS != SMPL_Link(&sLinkID1)) + { + NWK_DELAY(1000); + + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; + + // Stop linking after timeout + if (timeout++ > TIMEOUT) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + simpliciti_flag = SIMPLICITI_STATUS_ERROR; + return (0); + } + + // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + return (0); + } + } + simpliciti_flag = SIMPLICITI_STATUS_LINKED; + + return (1); +} + +// ************************************************************************************************* +// @fn simpliciti_main_tx_only +// @brief Get data through callback. Transfer data when external trigger is set. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_main_tx_only(void) +{ + while (1) + { + // Get end device data from callback function + simpliciti_get_ed_data_callback(); + + // Send data when flag bit SIMPLICITI_TRIGGER_SEND_DATA is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA)) + { + // Get radio ready. Wakes up in IDLE state. + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); + + // Acceleration / button events packets are 4 bytes long + SMPL_SendOpt(sLinkID1, simpliciti_data, 4, SMPL_TXOPTION_NONE); + + // Put radio back to SLEEP state + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); + + clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA); + } + + // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + break; + } + } +} + +// ************************************************************************************************* +// @fn simpliciti_main_sync +// @brief Send ready-to-receive packets in regular intervals. Listen shortly for host reply. +// Decode received host command and trigger action. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_main_sync(void) +{ + uint8_t len, i; + uint8_t ed_data[2]; + + while (1) + { + // Sleep 0.5sec between ready-to-receive packets + // SimpliciTI has no low power delay function, so we have to use ours + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); + + // Get radio ready. Radio wakes up in IDLE state. + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); + + // Send 2 byte long ready-to-receive packet to stimulate host reply + ed_data[0] = SYNC_ED_TYPE_R2R; + ed_data[1] = 0xCB; + SMPL_SendOpt(sLinkID1, ed_data, 2, SMPL_TXOPTION_NONE); + + // Wait shortly for host reply + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); + NWK_DELAY(10); + + // Check if a command packet was received + while (SMPL_Receive(sLinkID1, simpliciti_data, &len) == SMPL_SUCCESS) + { + // Decode received data + if (len > 0) + { + // Use callback function in application to decode data and react + simpliciti_sync_decode_ap_cmd_callback(); + + // Get reply data and send out reply packet burst (19 bytes each) + for (i = 0; i < simpliciti_reply_count; i++) + { + NWK_DELAY(10); + simpliciti_sync_get_data_callback(i); + SMPL_SendOpt(sLinkID1, simpliciti_data, BM_SYNC_DATA_LENGTH, SMPL_TXOPTION_NONE); + } + } + } + + // Put radio back to sleep + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); + + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; + + // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + break; + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Applications/configuration/End Device/smpl_config.dat b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Applications/configuration/End Device/smpl_config.dat new file mode 100755 index 0000000..59bfa8a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Applications/configuration/End Device/smpl_config.dat @@ -0,0 +1,72 @@ +# +# Filename: smpl_config.dat +# Revised: $Date: 2008-11-18 16:54:54 -0800 (Tue, 18 Nov 2008) $ +# Revision: $Revision: 18453 $ +# Author: $Author: lfriedman $ +# +# Description: This file supports the SimpliciTI Customer Configuration for End Devices. +# +# Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. +# +# IMPORTANT: Your use of this Software is limited to those specific rights granted under +# the terms of a software license agreement between the user who downloaded the software, +# his/her employer (which must be your employer) and Texas Instruments Incorporated (the +# "License"). You may not use this Software unless you agree to abide by the terms of the +# License. The License limits your use, and you acknowledge, that the Software may not be +# modified, copied or distributed unless embedded on a Texas Instruments microcontroller +# or used solely and exclusively in conjunction with a Texas Instruments radio frequency +# transceiver, which is integrated into your product. Other than for the foregoing purpose, +# you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +# perform, display or sell this Software and/or its documentation for any purpose. +# +# YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +# IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +# NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +# THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +# INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +# DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +# THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +# +# Should you have any questions regarding your right to use this Software, +# contact Texas Instruments Incorporated at www.TI.com. + + +# Number of connections supported. Each connection supports bi-directional +# communication. Access Points and Range Extenders can set this to 0 if they +# do not host End Device objects. +#--define=NUM_CONNECTIONS=2 +# [BM] Only allow 1 connection to RF access point +--define=NUM_CONNECTIONS=1 + +# Size of low level queues for sent and received frames. Affects RAM usage + +# AP needs larger input frame queue if it is supporting store-and-forward +# clients because the forwarded messages are held here. +--define=SIZE_INFRAME_Q=2 + +# The output frame queue can be small since Tx is done synchronously. Actually +# 1 is probably enough. If an Access Point device is also hosting an End Device +# that sends to a sleeping peer the output queue should be larger -- the waiting +# frames in this case are held here. In that case the output frame queue should +# be bigger. +--define=SIZE_OUTFRAME_Q=2 + +# This device's address. The first byte is used as a filter on the CC1100/CC2500 +# radios so THE FIRST BYTE MUST NOT BE either 0x00 or 0xFF. Also, for these radios +# on End Devices the first byte should be the least significant byte so the filtering +# is maximally effective. Otherwise the frame has to be processed by the MCU before it +# is recognized as not intended for the device. APs and REs run in promiscuous mode so +# the filtering is not done. This macro intializes a static const array of unsigned +# characters of length NET_ADDR_SIZE (found in nwk_types.h). The quotes (") are +# necessary below unless the spaces are removed. +--define=THIS_DEVICE_ADDRESS="{0x79, 0x56, 0x34, 0x12}" + +--define=END_DEVICE + +# For polling End Devices we need to specify that they do so. Uncomment the +# macro definition below if this is a polling device. This field is used +# by the Access Point to know whether to reserve store-and-forward support +# for the polling End Device during the Join exchange. +# --define=RX_POLLS diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Applications/configuration/smpl_nwk_config.dat b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Applications/configuration/smpl_nwk_config.dat new file mode 100755 index 0000000..d14b792 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Applications/configuration/smpl_nwk_config.dat @@ -0,0 +1,77 @@ +# +# Filename: smpl_nwk_config.dat +# Revised: $Date: 2009-02-07 14:21:07 -0700 (Sat, 07 Feb 2009) $ +# Revision: $Revision: 19010 $ +# Author: $Author: lfriedman $ +# +# Description: This file supports the SimpliciTI Customer Configuration for overall network. +# +# Copyright 2009 Texas Instruments Incorporated. All rights reserved. +# +# IMPORTANT: Your use of this Software is limited to those specific rights granted under +# the terms of a software license agreement between the user who downloaded the software, +# his/her employer (which must be your employer) and Texas Instruments Incorporated (the +# "License"). You may not use this Software unless you agree to abide by the terms of the +# License. The License limits your use, and you acknowledge, that the Software may not be +# modified, copied or distributed unless embedded on a Texas Instruments microcontroller +# or used solely and exclusively in conjunction with a Texas Instruments radio frequency +# transceiver, which is integrated into your product. Other than for the foregoing purpose, +# you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +# perform, display or sell this Software and/or its documentation for any purpose. +# +# YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +# IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +# NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +# THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +# INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +# DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +# THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +# +# Should you have any questions regarding your right to use this Software, +# contact Texas Instruments Incorporated at www.TI.com. + + +# Max hop count +--define=MAX_HOPS=3 + +# Max hops away from and AP. Keeps hop count and therefore replay +# storms down for sending to and from polling End Devices. Also used +# when joining since the EDs can't be more than 1 hop away. +--define=MAX_HOPS_FROM_AP=1 + +# Maximum size of Network application payload. Do not change unless +# protocol changes are reflected in different maximum network +# application payload size. +--define=MAX_NWK_PAYLOAD=9 + +# Maximum size of application payload +#--define=MAX_APP_PAYLOAD=10 +# [BM] Need to increase max payload for sync application +--define=MAX_APP_PAYLOAD=19 + +# Default Link token +--define=DEFAULT_LINK_TOKEN=0x01020304 + +# Default Join token +--define=DEFAULT_JOIN_TOKEN=0x05060708 + +# Define Frequency Agility as active for this build +# [BM] No need for frequency hopping +#--define=FREQUENCY_AGILITY + +# Enable application autoacknowledge support. Requires extended API as well +--define=APP_AUTO_ACK + +# Enable Extended API +--define=EXTENDED_API + +# Remove '#' corruption to enable security. +#--define=SMPL_SECURE + +# Remove '#' to enable NV object support +#--define=NVOBJECT_SUPPORT + +# Insert '#' to disable software timer +--define=SW_TIMER diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/CC430_End_Device_433MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/CC430_End_Device_433MHz.lib new file mode 100755 index 0000000..39953df Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/CC430_End_Device_433MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/CC430_End_Device_868MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/CC430_End_Device_868MHz.lib new file mode 100755 index 0000000..dd55c0e Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/CC430_End_Device_868MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/CC430_End_Device_915MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/CC430_End_Device_915MHz.lib new file mode 100755 index 0000000..9363600 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/CC430_End_Device_915MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_board.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_board.c new file mode 100755 index 0000000..27f627b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_board.c @@ -0,0 +1,309 @@ +/************************************************************************************************** +* Filename: bsp_board.c +* Revised: $Date: 2009-10-11 16:48:20 -0700 (Sun, 11 Oct 2009) $ +* Revision: $Revision: 20896 $ +* +* Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Top-level board code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "bsp_config.h" + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +static void SetVCore(uint8_t level); +static void SetVCoreUp(uint8_t level); +static void SetVCoreDown(uint8_t level); +static void Bsp_SetVCore(void); +static void Bsp_SetClocks(void); + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_TIMER_CLK_MHZ 12 /* 12 MHz MCLKC and SMCLK */ +#define BSP_DELAY_MAX_USEC (0xFFFF / BSP_TIMER_CLK_MHZ) + +/************************************************************************************************** + * @fn SetVCore + * + * @brief SetVCore level is called from the user API. Change level by one step only. + * + * @param level - VcCore level + * + * @return none + ************************************************************************************************** + */ + +static void SetVCore(uint8_t level) +{ + uint8_t actLevel; + + do { + actLevel = PMMCTL0_L & PMMCOREV_3; + if (actLevel < level) + SetVCoreUp(++actLevel); /* Set VCore (step by step) */ + if (actLevel > level) + SetVCoreDown(--actLevel); /* Set VCore (step by step) */ + } while (actLevel != level); +} + +/************************************************************************************************** + * @fn SetVCoreUp + * + * @brief Set VCore up. Change level by one step only. + * + * @param level - VcCore level + * + * @return none + ************************************************************************************************* + */ + +static void SetVCoreUp(uint8_t level) +{ + PMMCTL0_H = 0xA5; /* Open PMM module registers + *for write access */ + + SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; /* Set SVS/M high side to new + *level */ + + SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; /* Set SVM new Level */ + while ((PMMIFG & SVSMLDLYIFG) == 0) ; /* Wait till SVM is settled + *(Delay) */ + PMMCTL0_L = PMMCOREV0 * level; /* Set VCore to x */ + PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); /* Clear already set flags */ + if ((PMMIFG & SVMLIFG)) + while ((PMMIFG & SVMLVLRIFG) == 0) ; /* Wait till level is reached + **/ + + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; /* Set SVS/M Low side to new + *level */ + PMMCTL0_H = 0x00; /* Lock PMM module registers + *for write access */ +} + +/************************************************************************************************** + * @fn SetVCoreDown + * + * @brief Set VCore down + * + * @param level - VcCore level + * + * @return none + ************************************************************************************************** + */ + +static void SetVCoreDown(uint8_t level) +{ + PMMCTL0_H = 0xA5; /* Open PMM module registers + *for write access */ + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; /* Set SVS/M Low side to new + *level */ + while ((PMMIFG & SVSMLDLYIFG) == 0) ; /* Wait till SVM is settled + *(Delay) */ + PMMCTL0_L = (level * PMMCOREV0); /* Set VCore to 1.85 V for Max + *Speed. */ + PMMCTL0_H = 0x00; /* Lock PMM module registers + *for write access */ +} + +/************************************************************************************************** + * @fn Bsp_SetVCore + * + * @brief Setup the core voltage. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Bsp_SetVCore(void) +{ + SetVCore(3); +} + +/************************************************************************************************** + * @fn Bsp_SetClocks + * + * @brief Set up system clocks. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Bsp_SetClocks(void) +{ + /* Configure CPU clock for 12MHz */ + + /* If clock settings are changed, remember to update BSP_TIMER_CLK_MHZ. + * Otherwise, all timer settings would be incorrect. + */ + UCSCTL3 |= SELREF_2; /* Set DCO FLL reference = REFO */ + UCSCTL4 |= SELA_2; /* Set ACLK = REFO */ + + __bis_SR_register(SCG0); /* Disable the FLL control loop */ + UCSCTL0 = 0x0000; /* Set lowest possible DCOx, MODx */ + UCSCTL1 = DCORSEL_5; /* Select DCO range 24MHz operation */ + UCSCTL2 = FLLD_1 + 374; /* Set DCO Multiplier for 12MHz + * (N + 1) * FLLRef = Fdco + * (374 + 1) * 32768 = 12MHz + * Set FLL Div = fDCOCLK/2 */ + __bic_SR_register(SCG0); /* Enable the FLL control loop */ + + /* Worst-case settling time for the DCO when the DCO range bits have been + * changed is n x 32 x 32 x f_MCLK / f_FLL_reference. + * 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle + */ + __delay_cycles(375000); + + /* Loop until XT1,XT2 & DCO fault flag is cleared */ + do + { + UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); + /* Clear XT2,XT1,DCO fault flags */ + SFRIFG1 &= ~OFIFG; /* Clear fault flags */ + } while (SFRIFG1 & OFIFG); /* Test oscillator fault flag */ + + /* Select REFO as ACLK source and DCOCLK as MCLK and SMCLK source */ + UCSCTL4 = SELA__REFOCLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; +} + +/************************************************************************************************** + * @fn BSP_EARLY_INIT + * + * @brief This function is called by start-up code before doing the normal initialization + * of data segments. If the return value is zero, initialization is not performed. + * The global macro label "BSP_EARLY_INIT" gets #defined in the bsp_msp430_defs.h + * file, according to the specific compiler environment (CCE or IAR). In the CCE + * environment this macro invokes "_system_pre_init()" and in the IAR environment + * this macro invokes "__low_level_init()". + * + * @param None + * + * @return 0 - don't intialize data segments / 1 - do initialization + ************************************************************************************************* + */ +BSP_EARLY_INIT(void) +{ + /* Disable watchdog timer */ + WDTCTL = WDTPW | WDTHOLD; + + /* Setup Vcore */ + Bsp_SetVCore(); + + /* Configure System clocks */ + Bsp_SetClocks(); + + /* Return 1 - run seg_init */ + return (1); +} + +/************************************************************************************************** + * @fn BSP_InitBoard + * + * @brief Initialize the board. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void BSP_InitBoard(void) +{ + /* Configure TimerA for use by the delay function */ + + /* Reset the timer */ + //TA0CTL |= TACLR; /* Set the TACLR */ + + /* Clear all settings */ + //TA0CTL = 0x0; + + /* Select the clk source to be - SMCLK (Sub-Main CLK)*/ + //TA0CTL |= TASSEL_2; + + // [BM] We need to use TA1 for delay function, because TA0 is already occupied + TA1CTL |= TACLR; /* Set the TACLR */ + TA1CTL = 0x0; + TA1CTL |= TASSEL_2; +} + +/************************************************************************************************** + * @fn BSP_Delay + * + * @brief Delay for the requested amount of time. + * + * @param # of microseconds to delay. + * + * @return none + ************************************************************************************************** + */ + +void BSP_Delay(uint16_t usec) +{ + BSP_ASSERT(usec < BSP_DELAY_MAX_USEC); + + //TA0R = 0; /* initial count */ + //TA0CCR0 = BSP_TIMER_CLK_MHZ*usec; /* compare count. (delay in ticks) */ + + /* Start the timer in UP mode */ + //TA0CTL |= MC_1; + + /* Loop till compare interrupt flag is set */ + //while(!(TA0CCTL0 & CCIFG)); + + /* Stop the timer */ + //TA0CTL &= ~(MC_1); + + /* Clear the interrupt flag */ + //TA0CCTL0 &= ~CCIFG; + + // [BM] We need to use TA1 for delay function, because TA0 is already occupied + TA1R = 0; + TA1CCR0 = BSP_TIMER_CLK_MHZ * usec; + TA1CTL |= MC_1; + while (!(TA1CCTL0 & CCIFG)) ; + TA1CTL &= ~(MC_1); + TA1CCTL0 &= ~CCIFG; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h new file mode 100755 index 0000000..ed67c36 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h @@ -0,0 +1,83 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Board definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BOARD_DEFS_H +#define BSP_BOARD_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Board Unique Define + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BOARD_CC430EM + + +/* ------------------------------------------------------------------------------------------------ + * Mcu + * ------------------------------------------------------------------------------------------------ + */ +#include "mcus/bsp_msp430_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Clock + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_config.h" +#define __bsp_CLOCK_MHZ__ BSP_CONFIG_CLOCK_MHZ + + +/* ------------------------------------------------------------------------------------------------ + * Board Initialization + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BOARD_C "bsp_board.c" +#define BSP_INIT_BOARD() BSP_InitBoard() +#define BSP_DELAY_USECS(x) BSP_Delay(x) + +void BSP_InitBoard(void); +void BSP_Delay(uint16_t usec); + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h new file mode 100755 index 0000000..beac8c7 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h @@ -0,0 +1,92 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Button definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BUTTON_DEFS_H +#define BSP_BUTTON_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Button Configuration + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_NUM_BUTTONS__ 1 +#define __bsp_BUTTON_DEBOUNCE_WAIT__(expr) st( \ + int i; for (i = 0; i < 500; i++){ if (!(expr)) i = 0; }) + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * BUTTON #1 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : S2 + * Description : Push Button + * Polarity : Active Low + * GPIO : P1.7 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_BUTTON1_BIT__ 7 +#define __bsp_BUTTON1_PORT__ P1IN +#define __bsp_BUTTON1_IS_ACTIVE_LOW__ 1 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Extended Configuration + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +/* Enable the internal PullUp for button #1. */ +#define __bsp_BUTTON_EXTENDED_CONFIG__() st(P1OUT |= BV(__bsp_BUTTON1_BIT__); /* PullUp */ \ + P1REN |= BV(__bsp_BUTTON1_BIT__); ) /* Enable PullUp */ + + +/* ------------------------------------------------------------------------------------------------ + * Include Generic Button Macros + * ------------------------------------------------------------------------------------------------ + */ +#include "code/bsp_generic_buttons.h" + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h new file mode 100755 index 0000000..fd29193 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h @@ -0,0 +1,47 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Board configuration file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_CONFIG_H +#define BSP_CONFIG_H + + +/* Nothing needed for this platform. */ + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h new file mode 100755 index 0000000..2dc5732 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h @@ -0,0 +1,54 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Driver definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_DRIVER_DEFS_H +#define BSP_DRIVER_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Driver Initialization + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_DRIVERS_C "bsp_drivers.c" +#define BSP_INIT_DRIVERS() BSP_InitDrivers() +void BSP_InitDrivers(void); + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c new file mode 100755 index 0000000..0e08bb2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c @@ -0,0 +1,88 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Top-level driver file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_driver_defs.h" +#include "bsp_leds.h" +#include "bsp_buttons.h" +#include "bsp_config.h" + + +/************************************************************************************************** + * @fn BSP_InitDrivers + * + * @brief Initialize all enabled BSP drivers. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void BSP_InitDrivers(void) +{ +#if (!defined BSP_NO_LEDS) + BSP_InitLeds(); +#endif + +#if (!defined BSP_NO_BUTTONS) + BSP_InitButtons(); +#endif +} + +/* ================================================================================================ + * C Code Includes + * ================================================================================================ + */ +#ifndef BSP_NO_LEDS +# include "drivers/code/bsp_leds.c" +#endif + +#ifndef BSP_NO_BUTTONS +# include "drivers/code/bsp_buttons.c" +#endif + + +/************************************************************************************************** + */ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h new file mode 100755 index 0000000..4e8ff55 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h @@ -0,0 +1,81 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Board definition file. + * Target : Texas Instruments CC430EM + * Radios : CC430 + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_BOARD_DEFS_H +#define MRFI_BOARD_DEFS_H + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + + +/* ------------------------------------------------------------------------------------------------ + * Radio Selection + * ------------------------------------------------------------------------------------------------ + */ +#if (!defined MRFI_CC430) +# error "ERROR: A compatible radio must be specified for the CC430EM board." +#endif + + +/* Radio Interface critical section macros */ +typedef bspIState_t mrfiRIFIState_t; +#define MRFI_RIF_ENTER_CRITICAL_SECTION(x) BSP_ENTER_CRITICAL_SECTION(x) +#define MRFI_RIF_EXIT_CRITICAL_SECTION(x) BSP_EXIT_CRITICAL_SECTION(x) + + +/************************************************************************************************** + * Compile Time Integrity Checks + ************************************************************************************************** + */ +#ifndef BSP_BOARD_CC430EM +# error "ERROR: Mismatch between specified board and MRFI configuration." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h new file mode 100755 index 0000000..e213c25 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h @@ -0,0 +1,97 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * LED definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_LED_DEFS_H +#define BSP_LED_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Configuration + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_NUM_LEDS__ 2 +#define __bsp_LED_BLINK_LOOP_COUNT__ 0x34000 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * LED #1 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : LED1 + * Color : Green + * Polarity : Active High + * GPIO : P1.0 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_LED1_BIT__ 0 +#define __bsp_LED1_PORT__ P1OUT +#define __bsp_LED1_DDR__ P1DIR +#define __bsp_LED1_IS_ACTIVE_LOW__ 0 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * LED #2 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : LED2 + * Color : Green + * Polarity : Active High + * GPIO : P3.6 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_LED2_BIT__ 6 +#define __bsp_LED2_PORT__ P3OUT +#define __bsp_LED2_DDR__ P3DIR +#define __bsp_LED2_IS_ACTIVE_LOW__ 0 + + +/* ------------------------------------------------------------------------------------------------ + * Include Generic LED Macros + * ------------------------------------------------------------------------------------------------ + */ +#include "code/bsp_generic_leds.h" + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/bsp.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/bsp.c new file mode 100755 index 0000000..c0bedd3 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/bsp.c @@ -0,0 +1,102 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Top-level BSP code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "bsp_driver_defs.h" + + +/************************************************************************************************** + * @fn BSP_Init + * + * @brief Initialize the board and drivers. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void BSP_Init(void) +{ + BSP_INIT_BOARD(); + BSP_INIT_DRIVERS(); + + /*------------------------------------------------------------- + * Run time integrity checks. Perform only if asserts + * are enabled. + */ +#ifdef BSP_ASSERTS_ARE_ON + /* verify endianess is correctly specified */ + { + uint16_t test = 0x00AA; /* first storage byte of 'test' is + *non-zero for little endian */ + BSP_ASSERT(!(*((uint8_t *)&test)) == !BSP_LITTLE_ENDIAN); /* endianess mismatch */ + } +#endif +} + +/* ================================================================================================ + * C Code Includes + * ================================================================================================ + */ +#ifdef BSP_BOARD_C +# include BSP_BOARD_C +#endif + +#ifdef BSP_DRIVERS_C +# include BSP_DRIVERS_C +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +BSP_STATIC_ASSERT(sizeof(uint8_t) == 1); +BSP_STATIC_ASSERT(sizeof(int8_t) == 1); +BSP_STATIC_ASSERT(sizeof(uint16_t) == 2); +BSP_STATIC_ASSERT(sizeof(int16_t) == 2); +BSP_STATIC_ASSERT(sizeof(uint32_t) == 4); +BSP_STATIC_ASSERT(sizeof(int32_t) == 4); + + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/bsp.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/bsp.h new file mode 100755 index 0000000..d249d39 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/bsp.h @@ -0,0 +1,184 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Include file for core BSP services. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_H +#define BSP_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + +/* ------------------------------------------------------------------------------------------------ + * BSP Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP +#define BSP_VER 100 /* BSP version 1.00a */ +#define BSP_SUBVER a + + +/* ------------------------------------------------------------------------------------------------ + * Clock + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CLOCK_MHZ __bsp_CLOCK_MHZ__ + + +/* ------------------------------------------------------------------------------------------------ + * Memory + * ------------------------------------------------------------------------------------------------ + */ +#ifndef __bsp_LITTLE_ENDIAN__ +# error ERROR: Endianess not defined +#endif + +#define BSP_LITTLE_ENDIAN __bsp_LITTLE_ENDIAN__ + +#define CODE __bsp_CODE_MEMSPACE__ +#define XDATA __bsp_XDATA_MEMSPACE__ + +/* ------------------------------------------------------------------------------------------------ + * Interrupts + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_ISR_FUNCTION(func, vect) __bsp_ISR_FUNCTION__(func, vect) + +#define BSP_ENABLE_INTERRUPTS() __bsp_ENABLE_INTERRUPTS__() +#define BSP_DISABLE_INTERRUPTS() __bsp_DISABLE_INTERRUPTS__() +#define BSP_INTERRUPTS_ARE_ENABLED() __bsp_INTERRUPTS_ARE_ENABLED__() + + +/* ------------------------------------------------------------------------------------------------ + * Critical Sections + * ------------------------------------------------------------------------------------------------ + */ +typedef __bsp_ISTATE_T__ bspIState_t; + +#define BSP_ENTER_CRITICAL_SECTION(x) st(x = __bsp_GET_ISTATE__(); __bsp_DISABLE_INTERRUPTS__(); ) +#define BSP_EXIT_CRITICAL_SECTION(x) __bsp_RESTORE_ISTATE__(x) +#define BSP_CRITICAL_STATEMENT(x) st(bspIState_t s; \ + BSP_ENTER_CRITICAL_SECTION(s); \ + x; \ + BSP_EXIT_CRITICAL_SECTION(s); ) + + +/* ------------------------------------------------------------------------------------------------ + * Asserts + * ------------------------------------------------------------------------------------------------ + */ + +/* + * BSP_ASSERT( expression ) - The given expression must evaluate as "true" or else the assert + * handler is called. From here, the call stack feature of the debugger can pinpoint where + * the problem occurred. + * + * BSP_FORCE_ASSERT() - If asserts are in use, immediately calls the assert handler. + * + * BSP_ASSERTS_ARE_ON - can use #ifdef to see if asserts are enabled + * + * Asserts can be disabled for optimum performance and minimum code size (ideal for + * finalized, debugged production code). + */ + +#if (!defined BSP_NO_DEBUG) +# ifndef BSP_ASSERT_HANDLER +# define BSP_ASSERT_HANDLER() st(__bsp_DISABLE_INTERRUPTS__(); while (1) ; ) +# endif +# define BSP_ASSERT(expr) st(if (!(expr)) BSP_ASSERT_HANDLER(); ) +# define BSP_FORCE_ASSERT() BSP_ASSERT_HANDLER() +# define BSP_ASSERTS_ARE_ON +#else +# define BSP_ASSERT(expr) /* empty */ +# define BSP_FORCE_ASSERT() /* empty */ +#endif + +/* static assert */ +#define BSP_STATIC_ASSERT(expr) void bspDummyPrototype(char dummy[1 / ((expr) != 0)]) + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_Init(void); + +/************************************************************************************************** + */ + +/**************************************************************************************** +* BEGIN ENDIAN SUPPORT +* +* Security encrypt/decrypt operates on unsigned long quantities. These must match on +* source and destination platforms. These macros enforce the standard conversions. +* Currently all platforms (CC2520/CC2x30 and MSP430) are little endian. +* +******************* Network order for encryption is LITTLE ENDIAN ****************** +* +****************************************************************************************/ + +#if (BSP_LITTLE_ENDIAN != 0) +# define ntohs(x) (x) +# define htons(x) (x) + +# define ntohl(x) (x) +# define htonl(x) (x) + +#else + +# define ntohs(x) (((x >> 8) & 0xFF) | ((x & 0xFF) << 8)) +# define htons(x) (((x >> 8) & 0xFF) | ((x & 0xFF) << 8)) + +# define ntohl(x) (((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | \ + ((x & 0xFF00) << 8) | ((x & 0xFF) << 24) \ + ) +# define htonl(x) (((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | \ + ((x & 0xFF00) << 8) | ((x & 0xFF) << 24) \ + ) + +#endif /* (BSP_LITTLE_ENDIAN != 0) */ + +/*************************************************************************************** +* END ENDIAN SUPPORT +***************************************************************************************/ + + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/bsp_macros.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/bsp_macros.h new file mode 100755 index 0000000..60392ba --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/bsp_macros.h @@ -0,0 +1,79 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Include file for BSP utility macros. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_MACROS_H +#define BSP_MACROS_H + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +/* bit value */ +#ifndef BV +# define BV(n) (1 << (n)) +#endif + +/* + * This macro is for use by other macros to form a fully valid C statement. + * Without this, the if/else conditionals could show unexpected behavior. + * + * For example, use... + * #define SET_REGS() st( ioreg1 = 0; ioreg2 = 0; ) + * instead of ... + * #define SET_REGS() { ioreg1 = 0; ioreg2 = 0; } + * or + * #define SET_REGS() ioreg1 = 0; ioreg2 = 0; + * The last macro would not behave as expected in the if/else construct. + * The second to last macro will cause a compiler error in certain uses + * of if/else construct + * + * It is not necessary, or recommended, to use this macro where there is + * already a valid C statement. For example, the following is redundant... + * #define CALL_FUNC() st( func(); ) + * This should simply be... + * #define CALL_FUNC() func() + * + * (The while condition below evaluates false without generating a + * constant-controlling-loop type of warning on most compilers.) + */ +#define st(x) do { x } while (__LINE__ == -1) + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/bsp_buttons.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/bsp_buttons.h new file mode 100755 index 0000000..6ec3d99 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/bsp_buttons.h @@ -0,0 +1,90 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Button driver include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BUTTONS_H +#define BSP_BUTTONS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_button_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_NUM_BUTTONS __bsp_NUM_BUTTONS__ + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BUTTON_DEBOUNCE_WAIT(expr) __bsp_BUTTON_DEBOUNCE_WAIT__(expr) + +#define BSP_BUTTON1() __bsp_BUTTON1__() +#define BSP_BUTTON2() __bsp_BUTTON2__() +#define BSP_BUTTON3() __bsp_BUTTON3__() +#define BSP_BUTTON4() __bsp_BUTTON4__() +#define BSP_BUTTON5() __bsp_BUTTON5__() +#define BSP_BUTTON6() __bsp_BUTTON6__() +#define BSP_BUTTON7() __bsp_BUTTON7__() +#define BSP_BUTTON8() __bsp_BUTTON8__() + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_InitButtons(void); + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +#ifdef BSP_NO_BUTTONS +# error "ERROR: The button driver is disabled. This file should not be included." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/bsp_leds.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/bsp_leds.h new file mode 100755 index 0000000..2d0195e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/bsp_leds.h @@ -0,0 +1,133 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * LED driver include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_LEDS_H +#define BSP_LEDS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_led_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_NUM_LEDS __bsp_NUM_LEDS__ + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ + +/* blink delay loop */ +#define BSP_LED_BLINK_DELAY() st({ volatile uint32_t i; \ + for (i = 0; i < __bsp_LED_BLINK_LOOP_COUNT__; i++){ }; }) + +/* LED1 */ +#define BSP_TURN_ON_LED1() __bsp_LED1_TURN_ON__() +#define BSP_TURN_OFF_LED1() __bsp_LED1_TURN_OFF__() +#define BSP_TOGGLE_LED1() __bsp_LED1_TOGGLE__() +#define BSP_LED1_IS_ON() __bsp_LED1_IS_ON__() + +/* LED2 */ +#define BSP_TURN_ON_LED2() __bsp_LED2_TURN_ON__() +#define BSP_TURN_OFF_LED2() __bsp_LED2_TURN_OFF__() +#define BSP_TOGGLE_LED2() __bsp_LED2_TOGGLE__() +#define BSP_LED2_IS_ON() __bsp_LED2_IS_ON__() + +/* LED3 */ +#define BSP_TURN_ON_LED3() __bsp_LED3_TURN_ON__() +#define BSP_TURN_OFF_LED3() __bsp_LED3_TURN_OFF__() +#define BSP_TOGGLE_LED3() __bsp_LED3_TOGGLE__() +#define BSP_LED3_IS_ON() __bsp_LED3_IS_ON__() + +/* LED4 */ +#define BSP_TURN_ON_LED4() __bsp_LED4_TURN_ON__() +#define BSP_TURN_OFF_LED4() __bsp_LED4_TURN_OFF__() +#define BSP_TOGGLE_LED4() __bsp_LED4_TOGGLE__() +#define BSP_LED4_IS_ON() __bsp_LED4_IS_ON__() + +/* LED5 */ +#define BSP_TURN_ON_LED5() __bsp_LED5_TURN_ON__() +#define BSP_TURN_OFF_LED5() __bsp_LED5_TURN_OFF__() +#define BSP_TOGGLE_LED5() __bsp_LED5_TOGGLE__() +#define BSP_LED5_IS_ON() __bsp_LED5_IS_ON__() + +/* LED6 */ +#define BSP_TURN_ON_LED6() __bsp_LED6_TURN_ON__() +#define BSP_TURN_OFF_LED6() __bsp_LED6_TURN_OFF__() +#define BSP_TOGGLE_LED6() __bsp_LED6_TOGGLE__() +#define BSP_LED6_IS_ON() __bsp_LED6_IS_ON__() + +/* LED7 */ +#define BSP_TURN_ON_LED7() __bsp_LED7_TURN_ON__() +#define BSP_TURN_OFF_LED7() __bsp_LED7_TURN_OFF__() +#define BSP_TOGGLE_LED7() __bsp_LED7_TOGGLE__() +#define BSP_LED7_IS_ON() __bsp_LED7_IS_ON__() + +/* LED8 */ +#define BSP_TURN_ON_LED8() __bsp_LED8_TURN_ON__() +#define BSP_TURN_OFF_LED8() __bsp_LED8_TURN_OFF__() +#define BSP_TOGGLE_LED8() __bsp_LED8_TOGGLE__() +#define BSP_LED8_IS_ON() __bsp_LED8_IS_ON__() + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_InitLeds(void); + + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +#ifdef BSP_NO_LEDS +# error "ERROR: The LED driver is disabled. This file should not be included." +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_buttons.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_buttons.c new file mode 100755 index 0000000..bff3d5d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_buttons.c @@ -0,0 +1,97 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic button driver code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_buttons.h" +#include "bsp_button_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CONFIG_BUTTON1() __bsp_BUTTON1_CONFIG__() +#define BSP_CONFIG_BUTTON2() __bsp_BUTTON2_CONFIG__() +#define BSP_CONFIG_BUTTON3() __bsp_BUTTON3_CONFIG__() +#define BSP_CONFIG_BUTTON4() __bsp_BUTTON4_CONFIG__() +#define BSP_CONFIG_BUTTON5() __bsp_BUTTON5_CONFIG__() +#define BSP_CONFIG_BUTTON6() __bsp_BUTTON6_CONFIG__() +#define BSP_CONFIG_BUTTON7() __bsp_BUTTON7_CONFIG__() +#define BSP_CONFIG_BUTTON8() __bsp_BUTTON8_CONFIG__() + +#ifdef __bsp_BUTTON_EXTENDED_CONFIG__ +# define BSP_BUTTON_EXTENDED_CONFIG() __bsp_BUTTON_EXTENDED_CONFIG__() +#else +# define BSP_BUTTON_EXTENDED_CONFIG() +#endif + + +/************************************************************************************************** + * @fn BSP_InitButtons + * + * @brief Initialize button hardware and driver code. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void BSP_InitButtons(void) +{ + /* configure LEDs */ + BSP_CONFIG_BUTTON1(); + BSP_CONFIG_BUTTON2(); + BSP_CONFIG_BUTTON3(); + BSP_CONFIG_BUTTON4(); + BSP_CONFIG_BUTTON5(); + BSP_CONFIG_BUTTON6(); + BSP_CONFIG_BUTTON7(); + BSP_CONFIG_BUTTON8(); + + /* peform extended configuration if needed */ + BSP_BUTTON_EXTENDED_CONFIG(); +} + +/************************************************************************************************** + */ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h new file mode 100755 index 0000000..5a244bd --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h @@ -0,0 +1,211 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic button macro include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_GENERIC_BUTTONS_H +#define BSP_GENERIC_BUTTONS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_BUTTON__(port, bit, low) ((low) ? (!((port) & BV(bit))) : ((port) & BV(bit))) + + +/* ------------------------- populate BUTTON #1 macros ------------------------- */ +#define __bsp_NUM_BUTTON1_DEFINES__ ((defined __bsp_BUTTON1_PORT__) + \ + (defined __bsp_BUTTON1_BIT__) + \ + (defined __bsp_BUTTON1_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON1_DEFINES__ == 3) +# define __bsp_BUTTON1__() __bsp_BUTTON__(__bsp_BUTTON1_PORT__, __bsp_BUTTON1_BIT__, \ + __bsp_BUTTON1_IS_ACTIVE_LOW__) +# define __bsp_BUTTON1_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON1_DEFINES__ == 0) +# define __bsp_BUTTON1__() /* no button */ 0 +# define __bsp_BUTTON1_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON1." +#endif + +/* ------------------------- populate BUTTON #2 macros ------------------------- */ +#define __bsp_NUM_BUTTON2_DEFINES__ ((defined __bsp_BUTTON2_PORT__) + \ + (defined __bsp_BUTTON2_BIT__) + \ + (defined __bsp_BUTTON2_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON2_DEFINES__ == 3) +# define __bsp_BUTTON2__() __bsp_BUTTON__(__bsp_BUTTON2_PORT__, __bsp_BUTTON2_BIT__, \ + __bsp_BUTTON2_IS_ACTIVE_LOW__) +# define __bsp_BUTTON2_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON2_DEFINES__ == 0) +# define __bsp_BUTTON2__() /* no button */ 0 +# define __bsp_BUTTON2_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON2." +#endif + +/* ------------------------- populate BUTTON #3 macros ------------------------- */ +#define __bsp_NUM_BUTTON3_DEFINES__ ((defined __bsp_BUTTON3_PORT__) + \ + (defined __bsp_BUTTON3_BIT__) + \ + (defined __bsp_BUTTON3_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON3_DEFINES__ == 3) +# define __bsp_BUTTON3__() __bsp_BUTTON__(__bsp_BUTTON3_PORT__, __bsp_BUTTON3_BIT__, \ + __bsp_BUTTON3_IS_ACTIVE_LOW__) +# define __bsp_BUTTON3_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON3_DEFINES__ == 0) +# define __bsp_BUTTON3__() /* no button */ 0 +# define __bsp_BUTTON3_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON3." +#endif + +/* ------------------------- populate BUTTON #4 macros ------------------------- */ +#define __bsp_NUM_BUTTON4_DEFINES__ ((defined __bsp_BUTTON4_PORT__) + \ + (defined __bsp_BUTTON4_BIT__) + \ + (defined __bsp_BUTTON4_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON4_DEFINES__ == 3) +# define __bsp_BUTTON4__() __bsp_BUTTON__(__bsp_BUTTON4_PORT__, __bsp_BUTTON4_BIT__, \ + __bsp_BUTTON4_IS_ACTIVE_LOW__) +# define __bsp_BUTTON4_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON4_DEFINES__ == 0) +# define __bsp_BUTTON4__() /* no button */ 0 +# define __bsp_BUTTON4_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON4." +#endif + +/* ------------------------- populate BUTTON #5 macros ------------------------- */ +#define __bsp_NUM_BUTTON5_DEFINES__ ((defined __bsp_BUTTON5_PORT__) + \ + (defined __bsp_BUTTON5_BIT__) + \ + (defined __bsp_BUTTON5_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON5_DEFINES__ == 3) +# define __bsp_BUTTON5__() __bsp_BUTTON__(__bsp_BUTTON5_PORT__, __bsp_BUTTON5_BIT__, \ + __bsp_BUTTON5_IS_ACTIVE_LOW__) +# define __bsp_BUTTON5_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON5_DEFINES__ == 0) +# define __bsp_BUTTON5__() /* no button */ 0 +# define __bsp_BUTTON5_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON5." +#endif + +/* ------------------------- populate BUTTON #6 macros ------------------------- */ +#define __bsp_NUM_BUTTON6_DEFINES__ ((defined __bsp_BUTTON6_PORT__) + \ + (defined __bsp_BUTTON6_BIT__) + \ + (defined __bsp_BUTTON6_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON6_DEFINES__ == 3) +# define __bsp_BUTTON6__() __bsp_BUTTON__(__bsp_BUTTON6_PORT__, __bsp_BUTTON6_BIT__, \ + __bsp_BUTTON6_IS_ACTIVE_LOW__) +# define __bsp_BUTTON6_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON6_DEFINES__ == 0) +# define __bsp_BUTTON6__() /* no button */ 0 +# define __bsp_BUTTON6_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON6." +#endif + +/* ------------------------- populate BUTTON #7 macros ------------------------- */ +#define __bsp_NUM_BUTTON7_DEFINES__ ((defined __bsp_BUTTON7_PORT__) + \ + (defined __bsp_BUTTON7_BIT__) + \ + (defined __bsp_BUTTON7_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON7_DEFINES__ == 3) +# define __bsp_BUTTON7__() __bsp_BUTTON__(__bsp_BUTTON7_PORT__, __bsp_BUTTON7_BIT__, \ + __bsp_BUTTON7_IS_ACTIVE_LOW__) +# define __bsp_BUTTON7_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON7_DEFINES__ == 0) +# define __bsp_BUTTON7__() /* no button */ 0 +# define __bsp_BUTTON7_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON7." +#endif + +/* ------------------------- populate BUTTON #8 macros ------------------------- */ +#define __bsp_NUM_BUTTON8_DEFINES__ ((defined __bsp_BUTTON8_PORT__) + \ + (defined __bsp_BUTTON8_BIT__) + \ + (defined __bsp_BUTTON8_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON8_DEFINES__ == 3) +# define __bsp_BUTTON8__() __bsp_BUTTON__(__bsp_BUTTON8_PORT__, __bsp_BUTTON8_BIT__, \ + __bsp_BUTTON8_IS_ACTIVE_LOW__) +# define __bsp_BUTTON8_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON8_DEFINES__ == 0) +# define __bsp_BUTTON8__() /* no button */ 0 +# define __bsp_BUTTON8_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON8." +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* -------------------- number of buttons defined -------------------- */ +#ifndef __bsp_NUM_BUTTONS__ +# error "ERROR: Number of buttons is not specified." +#else +# if ((__bsp_NUM_BUTTONS__ > 8) || (__bsp_NUM_BUTTONS__ < 0)) +# error "ERROR: Unsupported number of buttons specified. Maximum is eight." +# endif +#endif + +#if (((__bsp_NUM_BUTTON1_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON2_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON3_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON4_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON5_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON6_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON7_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON8_DEFINES__ != 0)) != __bsp_NUM_BUTTONS__) +# error "ERROR: Inconsistency between defined macros and specified number of buttons." +#endif + +/* -------------------- debounce macro -------------------- */ +#ifndef __bsp_BUTTON_DEBOUNCE_WAIT__ +# error "ERROR: Debounce delay macro is missing." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h new file mode 100755 index 0000000..f356d46 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h @@ -0,0 +1,358 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic LED macro include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_GENERIC_LEDS_H +#define BSP_GENERIC_LEDS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ + +/* + * Note : The conditionals in the following macros evaulate compile time constants. + * Any compiler worth its salt will optimize these conditionals out for the + * smallest possible code. + */ + +#define __bsp_LED_TURN_ON__(bit, port, ddr, low) \ + st(if (low){ port &= ~BV(bit); } else { port |= BV(bit); }) + +#define __bsp_LED_TURN_OFF__(bit, port, ddr, low) \ + st(if (low){ port |= BV(bit); } else { port &= ~BV(bit); }) + +#define __bsp_LED_IS_ON__(bit, port, ddr, low) \ + ((low) ? (!((port) & BV(bit))) : ((port) & BV(bit))) + +#define __bsp_LED_TOGGLE__(bit, port, ddr, low) st(port ^= BV(bit); ) +#define __bsp_LED_CONFIG__(bit, port, ddr, low) st(ddr |= BV(bit); ) + + + +/* ------------------------- populate LED1 macros ------------------------- */ +#define __bsp_NUM_LED1_DEFINES__ ((defined __bsp_LED1_BIT__) + \ + (defined __bsp_LED1_PORT__) + \ + (defined __bsp_LED1_DDR__) + \ + (defined __bsp_LED1_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED1_DEFINES__ == 4) +# define __bsp_LED1_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED1_BIT__, __bsp_LED1_PORT__, \ + __bsp_LED1_DDR__, \ + __bsp_LED1_IS_ACTIVE_LOW__) +# define __bsp_LED1_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED1_BIT__, __bsp_LED1_PORT__, \ + __bsp_LED1_DDR__, \ + __bsp_LED1_IS_ACTIVE_LOW__) +# define __bsp_LED1_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED1_BIT__, __bsp_LED1_PORT__, \ + __bsp_LED1_DDR__, \ + __bsp_LED1_IS_ACTIVE_LOW__) +# define __bsp_LED1_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED1_BIT__, __bsp_LED1_PORT__, \ + __bsp_LED1_DDR__, \ + __bsp_LED1_IS_ACTIVE_LOW__) +# define __bsp_LED1_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED1_BIT__, __bsp_LED1_PORT__, \ + __bsp_LED1_DDR__, \ + __bsp_LED1_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED1_DEFINES__ == 0) +# define __bsp_LED1_TURN_ON__() /* no LED */ +# define __bsp_LED1_TURN_OFF__() /* no LED */ +# define __bsp_LED1_TOGGLE__() /* no LED */ +# define __bsp_LED1_IS_ON__() /* no LED */ 0 +# define __bsp_LED1_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED1." +#endif + + +/* ------------------------- populate LED2 macros ------------------------- */ +#define __bsp_NUM_LED2_DEFINES__ ((defined __bsp_LED2_BIT__) + \ + (defined __bsp_LED2_PORT__) + \ + (defined __bsp_LED2_DDR__) + \ + (defined __bsp_LED2_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED2_DEFINES__ == 4) +# define __bsp_LED2_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED2_BIT__, __bsp_LED2_PORT__, \ + __bsp_LED2_DDR__, \ + __bsp_LED2_IS_ACTIVE_LOW__) +# define __bsp_LED2_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED2_BIT__, __bsp_LED2_PORT__, \ + __bsp_LED2_DDR__, \ + __bsp_LED2_IS_ACTIVE_LOW__) +# define __bsp_LED2_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED2_BIT__, __bsp_LED2_PORT__, \ + __bsp_LED2_DDR__, \ + __bsp_LED2_IS_ACTIVE_LOW__) +# define __bsp_LED2_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED2_BIT__, __bsp_LED2_PORT__, \ + __bsp_LED2_DDR__, \ + __bsp_LED2_IS_ACTIVE_LOW__) +# define __bsp_LED2_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED2_BIT__, __bsp_LED2_PORT__, \ + __bsp_LED2_DDR__, \ + __bsp_LED2_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED2_DEFINES__ == 0) +# define __bsp_LED2_TURN_ON__() /* no LED */ +# define __bsp_LED2_TURN_OFF__() /* no LED */ +# define __bsp_LED2_TOGGLE__() /* no LED */ +# define __bsp_LED2_IS_ON__() /* no LED */ 0 +# define __bsp_LED2_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED2." +#endif + + +/* ------------------------- populate LED3 macros ------------------------- */ +#define __bsp_NUM_LED3_DEFINES__ ((defined __bsp_LED3_BIT__) + \ + (defined __bsp_LED3_PORT__) + \ + (defined __bsp_LED3_DDR__) + \ + (defined __bsp_LED3_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED3_DEFINES__ == 4) +# define __bsp_LED3_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED3_BIT__, __bsp_LED3_PORT__, \ + __bsp_LED3_DDR__, \ + __bsp_LED3_IS_ACTIVE_LOW__) +# define __bsp_LED3_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED3_BIT__, __bsp_LED3_PORT__, \ + __bsp_LED3_DDR__, \ + __bsp_LED3_IS_ACTIVE_LOW__) +# define __bsp_LED3_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED3_BIT__, __bsp_LED3_PORT__, \ + __bsp_LED3_DDR__, \ + __bsp_LED3_IS_ACTIVE_LOW__) +# define __bsp_LED3_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED3_BIT__, __bsp_LED3_PORT__, \ + __bsp_LED3_DDR__, \ + __bsp_LED3_IS_ACTIVE_LOW__) +# define __bsp_LED3_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED3_BIT__, __bsp_LED3_PORT__, \ + __bsp_LED3_DDR__, \ + __bsp_LED3_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED3_DEFINES__ == 0) +# define __bsp_LED3_TURN_ON__() /* no LED */ +# define __bsp_LED3_TURN_OFF__() /* no LED */ +# define __bsp_LED3_TOGGLE__() /* no LED */ +# define __bsp_LED3_IS_ON__() /* no LED */ 0 +# define __bsp_LED3_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED3." +#endif + + +/* ------------------------- populate LED4 macros ------------------------- */ +#define __bsp_NUM_LED4_DEFINES__ ((defined __bsp_LED4_BIT__) + \ + (defined __bsp_LED4_PORT__) + \ + (defined __bsp_LED4_DDR__) + \ + (defined __bsp_LED4_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED4_DEFINES__ == 4) +# define __bsp_LED4_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED4_BIT__, __bsp_LED4_PORT__, \ + __bsp_LED4_DDR__, \ + __bsp_LED4_IS_ACTIVE_LOW__) +# define __bsp_LED4_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED4_BIT__, __bsp_LED4_PORT__, \ + __bsp_LED4_DDR__, \ + __bsp_LED4_IS_ACTIVE_LOW__) +# define __bsp_LED4_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED4_BIT__, __bsp_LED4_PORT__, \ + __bsp_LED4_DDR__, \ + __bsp_LED4_IS_ACTIVE_LOW__) +# define __bsp_LED4_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED4_BIT__, __bsp_LED4_PORT__, \ + __bsp_LED4_DDR__, \ + __bsp_LED4_IS_ACTIVE_LOW__) +# define __bsp_LED4_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED4_BIT__, __bsp_LED4_PORT__, \ + __bsp_LED4_DDR__, \ + __bsp_LED4_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED4_DEFINES__ == 0) +# define __bsp_LED4_TURN_ON__() /* no LED */ +# define __bsp_LED4_TURN_OFF__() /* no LED */ +# define __bsp_LED4_TOGGLE__() /* no LED */ +# define __bsp_LED4_IS_ON__() /* no LED */ 0 +# define __bsp_LED4_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED4." +#endif + +/* ------------------------- populate LED5 macros ------------------------- */ +#define __bsp_NUM_LED5_DEFINES__ ((defined __bsp_LED5_BIT__) + \ + (defined __bsp_LED5_PORT__) + \ + (defined __bsp_LED5_DDR__) + \ + (defined __bsp_LED5_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED5_DEFINES__ == 4) +# define __bsp_LED5_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED5_BIT__, __bsp_LED5_PORT__, \ + __bsp_LED5_DDR__, \ + __bsp_LED5_IS_ACTIVE_LOW__) +# define __bsp_LED5_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED5_BIT__, __bsp_LED5_PORT__, \ + __bsp_LED5_DDR__, \ + __bsp_LED5_IS_ACTIVE_LOW__) +# define __bsp_LED5_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED5_BIT__, __bsp_LED5_PORT__, \ + __bsp_LED5_DDR__, \ + __bsp_LED5_IS_ACTIVE_LOW__) +# define __bsp_LED5_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED5_BIT__, __bsp_LED5_PORT__, \ + __bsp_LED5_DDR__, \ + __bsp_LED5_IS_ACTIVE_LOW__) +# define __bsp_LED5_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED5_BIT__, __bsp_LED5_PORT__, \ + __bsp_LED5_DDR__, \ + __bsp_LED5_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED5_DEFINES__ == 0) +# define __bsp_LED5_TURN_ON__() /* no LED */ +# define __bsp_LED5_TURN_OFF__() /* no LED */ +# define __bsp_LED5_TOGGLE__() /* no LED */ +# define __bsp_LED5_IS_ON__() /* no LED */ 0 +# define __bsp_LED5_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED5." +#endif + +/* ------------------------- populate LED6 macros ------------------------- */ +#define __bsp_NUM_LED6_DEFINES__ ((defined __bsp_LED6_BIT__) + \ + (defined __bsp_LED6_PORT__) + \ + (defined __bsp_LED6_DDR__) + \ + (defined __bsp_LED6_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED6_DEFINES__ == 4) +# define __bsp_LED6_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED6_BIT__, __bsp_LED6_PORT__, \ + __bsp_LED6_DDR__, \ + __bsp_LED6_IS_ACTIVE_LOW__) +# define __bsp_LED6_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED6_BIT__, __bsp_LED6_PORT__, \ + __bsp_LED6_DDR__, \ + __bsp_LED6_IS_ACTIVE_LOW__) +# define __bsp_LED6_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED6_BIT__, __bsp_LED6_PORT__, \ + __bsp_LED6_DDR__, \ + __bsp_LED6_IS_ACTIVE_LOW__) +# define __bsp_LED6_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED6_BIT__, __bsp_LED6_PORT__, \ + __bsp_LED6_DDR__, \ + __bsp_LED6_IS_ACTIVE_LOW__) +# define __bsp_LED6_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED6_BIT__, __bsp_LED6_PORT__, \ + __bsp_LED6_DDR__, \ + __bsp_LED6_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED6_DEFINES__ == 0) +# define __bsp_LED6_TURN_ON__() /* no LED */ +# define __bsp_LED6_TURN_OFF__() /* no LED */ +# define __bsp_LED6_TOGGLE__() /* no LED */ +# define __bsp_LED6_IS_ON__() /* no LED */ 0 +# define __bsp_LED6_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED6." +#endif + +/* ------------------------- populate LED7 macros ------------------------- */ +#define __bsp_NUM_LED7_DEFINES__ ((defined __bsp_LED7_BIT__) + \ + (defined __bsp_LED7_PORT__) + \ + (defined __bsp_LED7_DDR__) + \ + (defined __bsp_LED7_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED7_DEFINES__ == 4) +# define __bsp_LED7_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED7_BIT__, __bsp_LED7_PORT__, \ + __bsp_LED7_DDR__, \ + __bsp_LED7_IS_ACTIVE_LOW__) +# define __bsp_LED7_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED7_BIT__, __bsp_LED7_PORT__, \ + __bsp_LED7_DDR__, \ + __bsp_LED7_IS_ACTIVE_LOW__) +# define __bsp_LED7_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED7_BIT__, __bsp_LED7_PORT__, \ + __bsp_LED7_DDR__, \ + __bsp_LED7_IS_ACTIVE_LOW__) +# define __bsp_LED7_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED7_BIT__, __bsp_LED7_PORT__, \ + __bsp_LED7_DDR__, \ + __bsp_LED7_IS_ACTIVE_LOW__) +# define __bsp_LED7_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED7_BIT__, __bsp_LED7_PORT__, \ + __bsp_LED7_DDR__, \ + __bsp_LED7_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED7_DEFINES__ == 0) +# define __bsp_LED7_TURN_ON__() /* no LED */ +# define __bsp_LED7_TURN_OFF__() /* no LED */ +# define __bsp_LED7_TOGGLE__() /* no LED */ +# define __bsp_LED7_IS_ON__() /* no LED */ 0 +# define __bsp_LED7_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED7." +#endif + +/* ------------------------- populate LED8 macros ------------------------- */ +#define __bsp_NUM_LED8_DEFINES__ ((defined __bsp_LED8_BIT__) + \ + (defined __bsp_LED8_PORT__) + \ + (defined __bsp_LED8_DDR__) + \ + (defined __bsp_LED8_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED8_DEFINES__ == 4) +# define __bsp_LED8_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED8_BIT__, __bsp_LED8_PORT__, \ + __bsp_LED8_DDR__, \ + __bsp_LED8_IS_ACTIVE_LOW__) +# define __bsp_LED8_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED8_BIT__, __bsp_LED8_PORT__, \ + __bsp_LED8_DDR__, \ + __bsp_LED8_IS_ACTIVE_LOW__) +# define __bsp_LED8_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED8_BIT__, __bsp_LED8_PORT__, \ + __bsp_LED8_DDR__, \ + __bsp_LED8_IS_ACTIVE_LOW__) +# define __bsp_LED8_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED8_BIT__, __bsp_LED8_PORT__, \ + __bsp_LED8_DDR__, \ + __bsp_LED8_IS_ACTIVE_LOW__) +# define __bsp_LED8_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED8_BIT__, __bsp_LED8_PORT__, \ + __bsp_LED8_DDR__, \ + __bsp_LED8_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED8_DEFINES__ == 0) +# define __bsp_LED8_TURN_ON__() /* no LED */ +# define __bsp_LED8_TURN_OFF__() /* no LED */ +# define __bsp_LED8_TOGGLE__() /* no LED */ +# define __bsp_LED8_IS_ON__() /* no LED */ 0 +# define __bsp_LED8_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED8." +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* -------------------- number of LEDs defined -------------------- */ +#ifndef __bsp_NUM_LEDS__ +# error "ERROR: Number of LEDs is not specified." +#else +# if ((__bsp_NUM_LEDS__ > 8) || (__bsp_NUM_LEDS__ < 0)) +# error "ERROR: Unsupported number of LEDs specified. Maximum is eight." +# endif +#endif + +#if (((__bsp_NUM_LED1_DEFINES__ != 0) + \ + (__bsp_NUM_LED2_DEFINES__ != 0) + \ + (__bsp_NUM_LED3_DEFINES__ != 0) + \ + (__bsp_NUM_LED4_DEFINES__ != 0) + \ + (__bsp_NUM_LED5_DEFINES__ != 0) + \ + (__bsp_NUM_LED6_DEFINES__ != 0) + \ + (__bsp_NUM_LED7_DEFINES__ != 0) + \ + (__bsp_NUM_LED8_DEFINES__ != 0)) != __bsp_NUM_LEDS__) +# error "ERROR: Inconsistency between defined macros and specified number of LEDs." +#endif + +/* -------------------- blink delay loop count -------------------- */ +#ifndef __bsp_LED_BLINK_LOOP_COUNT__ +# error "ERROR: Blink delay count is missing." +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_leds.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_leds.c new file mode 100755 index 0000000..eac9f5f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_leds.c @@ -0,0 +1,107 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic LED driver code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_leds.h" +#include "bsp_led_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CONFIG_LED1() __bsp_LED1_CONFIG__() +#define BSP_CONFIG_LED2() __bsp_LED2_CONFIG__() +#define BSP_CONFIG_LED3() __bsp_LED3_CONFIG__() +#define BSP_CONFIG_LED4() __bsp_LED4_CONFIG__() +#define BSP_CONFIG_LED5() __bsp_LED5_CONFIG__() +#define BSP_CONFIG_LED6() __bsp_LED6_CONFIG__() +#define BSP_CONFIG_LED7() __bsp_LED7_CONFIG__() +#define BSP_CONFIG_LED8() __bsp_LED8_CONFIG__() + +#ifdef __bsp_LED_EXTENDED_CONFIG__ +# define BSP_LED_EXTENDED_CONFIG() __bsp_LED_EXTENDED_CONFIG__() +#else +# define BSP_LED_EXTENDED_CONFIG() +#endif + + +/************************************************************************************************** + * @fn BSP_InitLeds + * + * @brief Initialize LED hardware and driver. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void BSP_InitLeds(void) +{ + /* configure LEDs */ + BSP_CONFIG_LED1(); + BSP_CONFIG_LED2(); + BSP_CONFIG_LED3(); + BSP_CONFIG_LED4(); + BSP_CONFIG_LED5(); + BSP_CONFIG_LED6(); + BSP_CONFIG_LED7(); + BSP_CONFIG_LED8(); + + /* peform extended configuration if needed */ + BSP_LED_EXTENDED_CONFIG(); + + /* turn all LEDs off as power-up default */ + BSP_TURN_OFF_LED1(); + BSP_TURN_OFF_LED2(); + BSP_TURN_OFF_LED3(); + BSP_TURN_OFF_LED4(); + BSP_TURN_OFF_LED5(); + BSP_TURN_OFF_LED6(); + BSP_TURN_OFF_LED7(); + BSP_TURN_OFF_LED8(); +} + +/************************************************************************************************** + */ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h new file mode 100755 index 0000000..9e08426 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h @@ -0,0 +1,142 @@ +/************************************************************************************************** +* Filename: bsp_msp430_defs.h +* Revised: $Date: 2009-10-11 18:52:46 -0700 (Sun, 11 Oct 2009) $ +* Revision: $Revision: 20897 $ +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * MCU : Texas Instruments MSP430 family + * Microcontroller definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_MSP430_DEFS_H +#define BSP_MSP430_DEFS_H + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_MCU_MSP430 + +/* ------------------------------------------------------------------------------------------------ + * Compiler Abstraction + * ------------------------------------------------------------------------------------------------ + */ + +/* ---------------------- IAR Compiler ---------------------- */ +#ifdef __IAR_SYSTEMS_ICC__ +# define BSP_COMPILER_IAR + +# if (__VER__ < 342) +# error "ERROR: This IAR compiler port requires at least revision v3.42A." + +/* + * Compiler versions previous to v3.42A do not have the universal msp430.h include file. + * To use an earlier version of the compiler, replace the above #error statement with + * the appropriate, device specific #include statement. + */ +# endif + +/* Workaround for release v3.42A - the msp430.h file did not include support for some devices */ +# if ((__VER__ == 342) && (__SUBVERSION__ == 'A')) && \ + (defined (__MSP430F1610__) || defined (__MSP430F1611__) || defined (__MSP430F1612__)) +# include +# else +# include +# endif + +# define __bsp_ISTATE_T__ istate_t +# define __bsp_ISR_FUNCTION__(f, v) __bsp_QUOTED_PRAGMA__(vector = v) __interrupt void f(void); \ + __bsp_QUOTED_PRAGMA__(vector = v) __interrupt void f(void) + +/* Initialization call provided in IAR environment before standard C-startup */ +# include +# define BSP_EARLY_INIT(void) __intrinsic int __low_level_init(void) + +/* ---------------------- Code Composer ---------------------- */ +#elif (defined __TI_COMPILER_VERSION__) && (defined __MSP430__) +# define BSP_COMPILER_CODE_COMPOSER + +/* At time of 1.1.0 release, CC430 support not in msp430.h */ +# if (__CC430F6137__) +# include +# else +# include +# endif + +# define __bsp_ISTATE_T__ unsigned short +# define __bsp_ISR_FUNCTION__(f, v) __bsp_QUOTED_PRAGMA__(vector = v) __interrupt void f(void) + +/* Initialization call provided in CCE environment before standard C-startup */ +// [BM] Cannot have a second low level init! Already done by application! +//#define BSP_EARLY_INIT(void) int _system_pre_init(void) + +/* ------------------ Unrecognized Compiler ------------------ */ +#else +# error "ERROR: Unknown compiler." +#endif + +#if (defined BSP_COMPILER_IAR) || (defined BSP_COMPILER_CODE_COMPOSER) +# include +# define __bsp_ENABLE_INTERRUPTS__() __enable_interrupt() +# define __bsp_DISABLE_INTERRUPTS__() __disable_interrupt() +# define __bsp_INTERRUPTS_ARE_ENABLED__() (__get_SR_register() & GIE) + +# define __bsp_GET_ISTATE__() __get_interrupt_state() +# define __bsp_RESTORE_ISTATE__(x) __set_interrupt_state(x) + +# define __bsp_QUOTED_PRAGMA__(x) _Pragma(# x) + +#endif + +/* ------------------------------------------------------------------------------------------------ + * Common + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_LITTLE_ENDIAN__ 1 +#define __bsp_CODE_MEMSPACE__ /* blank */ +#define __bsp_XDATA_MEMSPACE__ /* blank */ + +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed long int32_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; + +#ifndef NULL +# define NULL 0 +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/mrfi.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/mrfi.c new file mode 100755 index 0000000..a8b40cf --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/mrfi.c @@ -0,0 +1,87 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Top-level code file. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "mrfi_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * C Code Includes + * ------------------------------------------------------------------------------------------------ + */ + +/* ----- Radio Family 1 ----- */ +#if (defined MRFI_RADIO_FAMILY1) +# include "radios/family1/mrfi_radio.c" +# include "radios/family1/mrfi_spi.c" +# include "radios/common/mrfi_f1f2.c" +# include "bsp_external/mrfi_board.c" + +/* ----- Radio Family 2 ----- */ +#elif (defined MRFI_RADIO_FAMILY2) +# include "radios/family2/mrfi_radio.c" +# include "radios/common/mrfi_f1f2.c" + +/* ----- Radio Family 3 ----- */ +#elif (defined MRFI_RADIO_FAMILY3) +# include "bsp_external/mrfi_board.c" +# include "radios/family3/mrfi_spi.c" +# include "radios/family3/mrfi_radio.c" + +/* ----- Radio Family 4 ----- */ +#elif (defined MRFI_RADIO_FAMILY4) +# include "radios/family4/mrfi_radio.c" + +/* ----- Radio Family 5 ----- */ +#elif (defined MRFI_RADIO_FAMILY5) +# include "radios/family5/mrfi_radio.c" +# include "radios/family5/mrfi_radio_interface.c" + +/* ----- Radio Family 6 ----- */ +#elif (defined MRFI_RADIO_FAMILY6) +# include "radios/family6/mrfi_radio.c" + +#else +# error "ERROR: Radio family is not defined." +#endif + + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/mrfi.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/mrfi.h new file mode 100755 index 0000000..a976435 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/mrfi.h @@ -0,0 +1,190 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Include file for all MRFI services. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_H +#define MRFI_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "mrfi_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_NUM_LOGICAL_CHANS __mrfi_NUM_LOGICAL_CHANS__ + +#define MRFI_NUM_POWER_SETTINGS __mrfi_NUM_POWER_SETTINGS__ + +/* return values for MRFI_Transmit */ +#define MRFI_TX_RESULT_SUCCESS 0 +#define MRFI_TX_RESULT_FAILED 1 + +/* transmit type parameter for MRFI_Transmit */ +#define MRFI_TX_TYPE_FORCED 0 +#define MRFI_TX_TYPE_CCA 1 + +/* Network header size definition */ + +/* ********************************* NOTE **************************************** + * There is a dependency here that really shouldn't exist. A reimplementation + * is necessary to avoid it. + * + * MRFI allocates the frame buffer which means it needs to know at compile time + * how big the buffer is. This means in must know the NWK header size, the + * maximum NWK and User application payload sizes and whether Security is enabled. + * ******************************************************************************** + */ +#ifndef SMPL_SECURE +# define NWK_HDR_SIZE 3 +# define NWK_PAYLOAD MAX_NWK_PAYLOAD +#else +# define NWK_HDR_SIZE 6 +# define NWK_PAYLOAD (MAX_NWK_PAYLOAD + 4) +#endif + +/* if external code has defined a maximum payload, use that instead of default */ +#ifdef MAX_APP_PAYLOAD +# ifndef MAX_NWK_PAYLOAD +# error ERROR: MAX_NWK_PAYLOAD not defined +# endif +# if MAX_APP_PAYLOAD < NWK_PAYLOAD +# define MAX_PAYLOAD NWK_PAYLOAD +# else +# define MAX_PAYLOAD MAX_APP_PAYLOAD +# endif +# define MRFI_MAX_PAYLOAD_SIZE (MAX_PAYLOAD + NWK_HDR_SIZE) /* SimpliciTI payload size plus six + *byte overhead */ +#endif + + +/* frame definitions */ +#define MRFI_ADDR_SIZE __mrfi_ADDR_SIZE__ +#ifndef MRFI_MAX_PAYLOAD_SIZE +# define MRFI_MAX_PAYLOAD_SIZE __mrfi_MAX_PAYLOAD_SIZE__ +#endif +#define MRFI_MAX_FRAME_SIZE (MRFI_MAX_PAYLOAD_SIZE + __mrfi_FRAME_OVERHEAD_SIZE__) +#define MRFI_RX_METRICS_SIZE __mrfi_RX_METRICS_SIZE__ +#define MRFI_RX_METRICS_RSSI_OFS __mrfi_RX_METRICS_RSSI_OFS__ +#define MRFI_RX_METRICS_CRC_LQI_OFS __mrfi_RX_METRICS_CRC_LQI_OFS__ + +/* Radio States */ +#define MRFI_RADIO_STATE_UNKNOWN 0 +#define MRFI_RADIO_STATE_OFF 1 +#define MRFI_RADIO_STATE_IDLE 2 +#define MRFI_RADIO_STATE_RX 3 + +/* Platform constant used to calculate worst-case for an application + * acknowledgment delay. Used in the NWK_REPLY_DELAY() macro. + * + * + * processing time on peer + | round trip + | | max number of replays + | | | number of backoff opportunities + | | | | average number of backoffs + | | | | | */ +#define PLATFORM_FACTOR_CONSTANT (2 + 2 * \ + (MAX_HOPS * \ + (MRFI_CCA_RETRIES * (8 * MRFI_BACKOFF_PERIOD_USECS) / 1000))) + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_GET_PAYLOAD_LEN(p) __mrfi_GET_PAYLOAD_LEN__(p) +#define MRFI_SET_PAYLOAD_LEN(p, x) __mrfi_SET_PAYLOAD_LEN__(p, x) + +#define MRFI_P_DST_ADDR(p) __mrfi_P_DST_ADDR__(p) +#define MRFI_P_SRC_ADDR(p) __mrfi_P_SRC_ADDR__(p) +#define MRFI_P_PAYLOAD(p) __mrfi_P_PAYLOAD__(p) + +/* ------------------------------------------------------------------------------------------------ + * Typdefs + * ------------------------------------------------------------------------------------------------ + */ +typedef struct +{ + uint8_t frame[MRFI_MAX_FRAME_SIZE]; + uint8_t rxMetrics[MRFI_RX_METRICS_SIZE]; +} mrfiPacket_t; + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void MRFI_Init(void); + +uint8_t MRFI_Transmit(mrfiPacket_t *, uint8_t); +void MRFI_Receive(mrfiPacket_t *); +void MRFI_RxCompleteISR(void); /* populated by code using MRFI */ +uint8_t MRFI_GetRadioState(void); +void MRFI_RxOn(void); +void MRFI_RxIdle(void); +int8_t MRFI_Rssi(void); + +void MRFI_SetLogicalChannel(uint8_t); +uint8_t MRFI_SetRxAddrFilter(uint8_t *); +void MRFI_EnableRxAddrFilter(void); +void MRFI_DisableRxAddrFilter(void); +void MRFI_Sleep(void); +void MRFI_WakeUp(void); +uint8_t MRFI_RandomByte(void); + +void MRFI_DelayMs(uint16_t); +void MRFI_ReplyDelay(void); +void MRFI_PostKillSem(void); + +void MRFI_SetRFPwr(uint8_t); + +/* ------------------------------------------------------------------------------------------------ + * Global Constants + * ------------------------------------------------------------------------------------------------ + */ +extern const uint8_t mrfiBroadcastAddr[]; + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/mrfi_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/mrfi_defs.h new file mode 100755 index 0000000..60d1d72 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/mrfi_defs.h @@ -0,0 +1,233 @@ +/************************************************************************************************** +* Revised: $Date: 2009-01-13 16:32:00 -0700 (Wed, 13 Jan 2009) $ +* Revision: $Revision: 18768 $ +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Definition and abstraction for radio targets. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ +#ifndef MRFI_DEFS_H +#define MRFI_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + + +/* ------------------------------------------------------------------------------------------------ + * Common Defines + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_CCA_RETRIES 4 + +#define MRFI_ASSERT(x) BSP_ASSERT(x) +#define MRFI_FORCE_ASSERT() BSP_FORCE_ASSERT() +#define MRFI_ASSERTS_ARE_ON BSP_ASSERTS_ARE_ON + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family Assigment + * ------------------------------------------------------------------------------------------------ + */ + +/* ------ Radio Family 1 ------ */ +#if (defined MRFI_CC1100) /* Sub 1 GHz RF Transceiver */ || \ + (defined MRFI_CC1101) /* Sub 1 GHz RF Transceiver */ || \ + (defined MRFI_CC1100E_470) /* Sub 1 GHz RF Transceiver (CC1100E Asia) */ || \ + (defined MRFI_CC1100E_950) /* Sub 1 GHz RF Transceiver (CC1100E Asia) */ || \ + (defined MRFI_CC2500) /* 2.4 GHz RF Transceiver */ +# define MRFI_RADIO_FAMILY1 + +/* ------ Radio Family 2 ------ */ +#elif (defined MRFI_CC1110) /* Sub 1 GHz SoC */ || \ + (defined MRFI_CC1111) /* Sub 1 GHz SoC with USB controller */ || \ + (defined MRFI_CC2510) /* 2.4 GHz SoC */ || \ + (defined MRFI_CC2511) /* 2.4 GHz SoC with USB controller */ +# define MRFI_RADIO_FAMILY2 + +/* ------ Radio Family 3 ------ */ +#elif (defined MRFI_CC2420) /* 2.4 GHz IEEE 802.15.4 RF Transceiver */ || \ + (defined MRFI_CC2520) /* 2.4 GHz IEEE 802.15.4 RF Transceiver */ + +# define MRFI_RADIO_FAMILY3 + +/* ------ Radio Family 4 ------ */ +#elif (defined MRFI_CC2430) /* 2.4 GHz IEEE 802.15.4 SoC */ || \ + (defined MRFI_CC2431) /* 2.4 GHz IEEE 802.15.4 SoC */ +# define MRFI_RADIO_FAMILY4 + +/* ------ Radio Family 5 ------ */ +#elif (defined MRFI_CC430) /* Sub 1 GHz MSP SoC */ +# define MRFI_RADIO_FAMILY5 + +/* ------ Radio Family 6 ------ */ +#elif (defined MRFI_CC2530) /* 2.4 GHz IEEE 802.15.4 SoC */ + +# define MRFI_RADIO_FAMILY6 + +#else +# error "ERROR: Unknown or missing radio selection." +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family 1 / Radio Family 2 / Radio Family 5 + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_RADIO_FAMILY1) || (defined MRFI_RADIO_FAMILY2) || (defined MRFI_RADIO_FAMILY5) + +# define __mrfi_LENGTH_FIELD_SIZE__ 1 +# define __mrfi_ADDR_SIZE__ 4 +# define __mrfi_MAX_PAYLOAD_SIZE__ 20 + +# define __mrfi_RX_METRICS_SIZE__ 2 +# define __mrfi_RX_METRICS_RSSI_OFS__ 0 +# define __mrfi_RX_METRICS_CRC_LQI_OFS__ 1 +# define __mrfi_RX_METRICS_CRC_OK_MASK__ 0x80 +# define __mrfi_RX_METRICS_LQI_MASK__ 0x7F + +# define __mrfi_NUM_LOGICAL_CHANS__ 4 +# define __mrfi_NUM_POWER_SETTINGS__ 3 + +# define __mrfi_BACKOFF_PERIOD_USECS__ 250 + +# define __mrfi_LENGTH_FIELD_OFS__ 0 +# define __mrfi_DST_ADDR_OFS__ (__mrfi_LENGTH_FIELD_OFS__ + __mrfi_LENGTH_FIELD_SIZE__) +# define __mrfi_SRC_ADDR_OFS__ (__mrfi_DST_ADDR_OFS__ + __mrfi_ADDR_SIZE__) +# define __mrfi_PAYLOAD_OFS__ (__mrfi_SRC_ADDR_OFS__ + __mrfi_ADDR_SIZE__) + +# define __mrfi_HEADER_SIZE__ (2 * __mrfi_ADDR_SIZE__) +# define __mrfi_FRAME_OVERHEAD_SIZE__ (__mrfi_LENGTH_FIELD_SIZE__ + __mrfi_HEADER_SIZE__) + +# define __mrfi_GET_PAYLOAD_LEN__(p) ((p)->frame[__mrfi_LENGTH_FIELD_OFS__] - \ + __mrfi_HEADER_SIZE__) +# define __mrfi_SET_PAYLOAD_LEN__(p, x) st( \ + (p)->frame[__mrfi_LENGTH_FIELD_OFS__] = x + __mrfi_HEADER_SIZE__; ) + +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family 3 / Radio Family 4 / Radio Family 6 + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_RADIO_FAMILY3) || (defined MRFI_RADIO_FAMILY4) || (defined MRFI_RADIO_FAMILY6) + +# define __mrfi_LENGTH_FIELD_SIZE__ 1 +# define __mrfi_FCF_SIZE__ 2 +# define __mrfi_DSN_SIZE__ 1 +# define __mrfi_ADDR_SIZE__ 4 +# define __mrfi_MAX_PAYLOAD_SIZE__ 20 + +# define __mrfi_RX_METRICS_SIZE__ 2 +# define __mrfi_RX_METRICS_RSSI_OFS__ 0 +# define __mrfi_RX_METRICS_CRC_LQI_OFS__ 1 +# define __mrfi_RX_METRICS_CRC_OK_MASK__ 0x80 +# define __mrfi_RX_METRICS_LQI_MASK__ 0x7F + +# define __mrfi_NUM_LOGICAL_CHANS__ 4 +# define __mrfi_NUM_POWER_SETTINGS__ 3 + +# define __mrfi_BACKOFF_PERIOD_USECS__ 250 + +# define __mrfi_LENGTH_FIELD_OFS__ 0 +# define __mrfi_FCF_OFS__ (__mrfi_LENGTH_FIELD_OFS__ + \ + __mrfi_LENGTH_FIELD_SIZE__) +# define __mrfi_DSN_OFS__ (__mrfi_FCF_OFS__ + __mrfi_FCF_SIZE__) +# define __mrfi_DST_ADDR_OFS__ (__mrfi_DSN_OFS__ + __mrfi_DSN_SIZE__) +# define __mrfi_SRC_ADDR_OFS__ (__mrfi_DST_ADDR_OFS__ + __mrfi_ADDR_SIZE__) +# define __mrfi_PAYLOAD_OFS__ (__mrfi_SRC_ADDR_OFS__ + __mrfi_ADDR_SIZE__) + +# define __mrfi_HEADER_SIZE__ ((2 * \ + __mrfi_ADDR_SIZE__) + __mrfi_FCF_SIZE__ + \ + __mrfi_DSN_SIZE__) +# define __mrfi_FRAME_OVERHEAD_SIZE__ (__mrfi_LENGTH_FIELD_SIZE__ + __mrfi_HEADER_SIZE__) + +# define __mrfi_GET_PAYLOAD_LEN__(p) ((p)->frame[__mrfi_LENGTH_FIELD_OFS__] - \ + __mrfi_HEADER_SIZE__) +# define __mrfi_SET_PAYLOAD_LEN__(p, x) st( \ + (p)->frame[__mrfi_LENGTH_FIELD_OFS__] = x + __mrfi_HEADER_SIZE__; ) + +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family Commonality + * ------------------------------------------------------------------------------------------------ + */ +#define __mrfi_P_DST_ADDR__(p) (&((p)->frame[__mrfi_DST_ADDR_OFS__])) +#define __mrfi_P_SRC_ADDR__(p) (&((p)->frame[__mrfi_SRC_ADDR_OFS__])) +#define __mrfi_P_PAYLOAD__(p) (&((p)->frame[__mrfi_PAYLOAD_OFS__])) + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* verify that only one supported radio is selected */ +#define MRFI_NUM_SUPPORTED_RADIOS_SELECTED ((defined MRFI_CC1100) + \ + (defined MRFI_CC1101) + \ + (defined MRFI_CC1110) + \ + (defined MRFI_CC1111) + \ + (defined MRFI_CC1100E_470) + \ + (defined MRFI_CC1100E_950) + \ + (defined MRFI_CC2500) + \ + (defined MRFI_CC2510) + \ + (defined MRFI_CC2511) + \ + (defined MRFI_CC2430) + \ + (defined MRFI_CC2431) + \ + (defined MRFI_CC2520) + \ + (defined MRFI_CC430) + \ + (defined MRFI_CC2530)) +#if (MRFI_NUM_SUPPORTED_RADIOS_SELECTED == 0) +# error "ERROR: A valid radio is not selected." +#elif (MRFI_NUM_SUPPORTED_RADIOS_SELECTED > 1) +# error "ERROR: More than one radio is selected." +#endif + +/* verify that a radio family is selected */ +#if (!defined MRFI_RADIO_FAMILY1) && \ + (!defined MRFI_RADIO_FAMILY2) && \ + (!defined MRFI_RADIO_FAMILY3) && \ + (!defined MRFI_RADIO_FAMILY4) && \ + (!defined MRFI_RADIO_FAMILY5) && \ + (!defined MRFI_RADIO_FAMILY6) +# error "ERROR: A radio family has not been assigned." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c new file mode 100755 index 0000000..5569553 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c @@ -0,0 +1,1824 @@ +/************************************************************************************************** +* Revised: $Date: 2009-11-23 07:50:43 -0800 (Mon, 23 Nov 2009) $ +* Revision: $Revision: 21225 $ +* +* Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS? +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radios: CC430 + * Primary code file for supported radios. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include +#include "mrfi.h" +#include "bsp.h" +#include "bsp_macros.h" +#include "bsp_external/mrfi_board_defs.h" +#include "mrfi_defs.h" +#include "mrfi_radio_interface.h" +#include "smartrf/CC430/smartrf_CC430.h" + +/* ------------------------------------------------------------------------------------------------ + * Global Constants + * ------------------------------------------------------------------------------------------------ + */ +const uint8_t mrfiBroadcastAddr[] = { 0xFF, 0xFF, 0xFF, 0xFF }; + +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(MRFI_ADDR_SIZE == + ((sizeof(mrfiBroadcastAddr) / + sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0]))); + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_CC430) +# define MRFI_RSSI_OFFSET 74 /* no units */ +#else +# error "ERROR: RSSI offset value not defined for this radio" +#endif + +#define MRFI_LENGTH_FIELD_OFS __mrfi_LENGTH_FIELD_OFS__ +#define MRFI_LENGTH_FIELD_SIZE __mrfi_LENGTH_FIELD_SIZE__ +#define MRFI_HEADER_SIZE __mrfi_HEADER_SIZE__ +#define MRFI_FRAME_BODY_OFS __mrfi_DST_ADDR_OFS__ +#define MRFI_BACKOFF_PERIOD_USECS __mrfi_BACKOFF_PERIOD_USECS__ + +#define MRFI_RANDOM_OFFSET 67 +#define MRFI_RANDOM_MULTIPLIER 109 +#define MRFI_MIN_SMPL_FRAME_SIZE (MRFI_HEADER_SIZE + NWK_HDR_SIZE) + +/* rx metrics definitions, known as appended "packet status bytes" in datasheet parlance */ +#define MRFI_RX_METRICS_CRC_OK_MASK __mrfi_RX_METRICS_CRC_OK_MASK__ +#define MRFI_RX_METRICS_LQI_MASK __mrfi_RX_METRICS_LQI_MASK__ + + +/* ---------- Radio Abstraction ---------- */ + +#define MRFI_RADIO_PARTNUM 0x00 +#define MRFI_RADIO_VERSION 0x06 + +/* GDO0 == PA_PD signal */ +#define MRFI_SETTING_IOCFG0 27 + +/* GDO1 == RSSI_VALID signal */ +#define MRFI_SETTING_IOCFG1 30 + +/* Main Radio Control State Machine control configuration: + * Auto Calibrate - when going from IDLE to RX/TX + * XOSC is OFF in Sleep state. + */ +#define MRFI_SETTING_MCSM0 (0x10) + +/* Main Radio Control State Machine control configuration: + * - Remain RX state after RX + * - Go to IDLE after TX + * - RSSI below threshold and NOT receiving. + */ +#define MRFI_SETTING_MCSM1 0x3C + +/* + * Packet Length - Setting for maximum allowed packet length. + * The PKTLEN setting does not include the length field but maximum frame size does. + * Subtract length field size from maximum frame size to get value for PKTLEN. + */ +#define MRFI_SETTING_PKTLEN (MRFI_MAX_FRAME_SIZE - MRFI_LENGTH_FIELD_SIZE) + +/* Packet automation control - Original value except WHITE_DATA is extracted from SmartRF setting. + **/ +#define MRFI_SETTING_PKTCTRL0 (0x05 | (SMARTRF_SETTING_PKTCTRL0 & BV(6))) + +/* FIFO threshold - this register has fields that need to be configured for the CC1101 */ +#define MRFI_SETTING_FIFOTHR (0x07 | (SMARTRF_SETTING_FIFOTHR & (BV(4) | BV(5) | BV(6) | BV(7)))) + +/* Max time we can be in a critical section within the delay function. + * This could be fine-tuned by observing the overhead is calling the bsp delay + * function. The overhead should be very small compared to this value. + */ +#define MRFI_MAX_DELAY_US 16 /* usec */ + +/* Packet automation control - base value is power up value whick has APPEND_STATUS enabled; no CRC + *autoflush */ +#define PKTCTRL1_BASE_VALUE BV(2) +#define PKTCTRL1_ADDR_FILTER_OFF PKTCTRL1_BASE_VALUE +#define PKTCTRL1_ADDR_FILTER_ON (PKTCTRL1_BASE_VALUE | (BV(0) | BV(1))) + +#ifdef MRFI_ASSERTS_ARE_ON +# define RX_FILTER_ADDR_INITIAL_VALUE 0xFF +#endif + +/* The SW timer is calibrated by adjusting the call to the microsecond delay + * routine. This allows maximum calibration control with repects to the longer + * times requested by applicationsd and decouples internal from external calls + * to the microsecond routine which can be calibrated independently. + */ +#if defined(SW_TIMER) +# define APP_USEC_VALUE 1000 +#else +# define APP_USEC_VALUE 1000 +#endif + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_ENABLE_SYNC_PIN_INT() (RF1AIE |= BV(9)) +#define MRFI_DISABLE_SYNC_PIN_INT() (RF1AIE &= ~BV(9)) +#define MRFI_CLEAR_SYNC_PIN_INT_FLAG() (RF1AIFG &= ~BV(9)) +#define MRFI_SYNC_PIN_INT_IS_ENABLED() (RF1AIE & BV(9)) +#define MRFI_SYNC_PIN_IS_HIGH() (RF1AIN & BV(9)) +#define MRFI_SYNC_PIN_INT_FLAG_IS_SET() (RF1AIFG & BV(9)) + + +#define MRFI_CLEAR_PAPD_PIN_INT_FLAG() (RF1AIFG &= ~BV(0)) +#define MRFI_PAPD_PIN_IS_HIGH() (RF1AIN & BV(0)) +#define MRFI_PAPD_INT_FLAG_IS_SET() (RF1AIFG & BV(0)) + + +/* RSSI valid signal is available on the GDO_1 */ +#define MRFI_RSSI_VALID_WAIT() while (!(RF1AIN & BV(1))) ; + + +/* Abstract radio interface calls. Could use these later to + * merge code from similar radio but different interface. + */ +#define MRFI_STROBE(cmd) mrfiRadioInterfaceCmdStrobe(cmd) +#define MRFI_RADIO_REG_READ(reg) mrfiRadioInterfaceReadReg(reg) +#define MRFI_RADIO_REG_WRITE(reg, value) mrfiRadioInterfaceWriteReg(reg, value) +#define MRFI_RADIO_WRITE_TX_FIFO(pData, len) mrfiRadioInterfaceWriteTxFifo(pData, len) +#define MRFI_RADIO_READ_RX_FIFO(pData, len) mrfiRadioInterfaceReadRxFifo(pData, len) + + +#define MRFI_STROBE_IDLE_AND_WAIT() \ + { \ + MRFI_STROBE(SIDLE); \ + /* Wait for XOSC to be stable and radio in IDLE state */ \ + while (MRFI_STROBE(SNOP) & 0xF0) ; \ + } + + +/* ------------------------------------------------------------------------------------------------ + * Local Constants + * ------------------------------------------------------------------------------------------------ + */ +const uint8_t mrfiRadioCfg[][2] = +{ + /* internal radio configuration */ + { IOCFG0, MRFI_SETTING_IOCFG0 }, /* Configure GDO_0 to output PA_PD signal (low during + *TX, high otherwise). */ + { IOCFG1, MRFI_SETTING_IOCFG1 }, /* Configure GDO_1 to output RSSI_VALID signal (high + *when RSSI is valid, low otherwise). */ + { MCSM1, MRFI_SETTING_MCSM1 }, /* CCA mode, RX_OFF_MODE and TX_OFF_MODE */ + { MCSM0, MRFI_SETTING_MCSM0 }, /* AUTO_CAL and XOSC state in sleep */ + { PKTLEN, MRFI_SETTING_PKTLEN }, + { PKTCTRL0, MRFI_SETTING_PKTCTRL0 }, + { FIFOTHR, MRFI_SETTING_FIFOTHR }, + + /* imported SmartRF radio configuration */ + + { FSCTRL1, SMARTRF_SETTING_FSCTRL1 }, + { FSCTRL0, SMARTRF_SETTING_FSCTRL0 }, + { FREQ2, SMARTRF_SETTING_FREQ2 }, + { FREQ1, SMARTRF_SETTING_FREQ1 }, + { FREQ0, SMARTRF_SETTING_FREQ0 }, + { MDMCFG4, SMARTRF_SETTING_MDMCFG4 }, + { MDMCFG3, SMARTRF_SETTING_MDMCFG3 }, + { MDMCFG2, SMARTRF_SETTING_MDMCFG2 }, + { MDMCFG1, SMARTRF_SETTING_MDMCFG1 }, + { MDMCFG0, SMARTRF_SETTING_MDMCFG0 }, + { DEVIATN, SMARTRF_SETTING_DEVIATN }, + { FOCCFG, SMARTRF_SETTING_FOCCFG }, + { BSCFG, SMARTRF_SETTING_BSCFG }, + { AGCCTRL2, SMARTRF_SETTING_AGCCTRL2 }, + { AGCCTRL1, SMARTRF_SETTING_AGCCTRL1 }, + { AGCCTRL0, SMARTRF_SETTING_AGCCTRL0 }, + { FREND1, SMARTRF_SETTING_FREND1 }, + { FREND0, SMARTRF_SETTING_FREND0 }, + { FSCAL3, SMARTRF_SETTING_FSCAL3 }, + { FSCAL2, SMARTRF_SETTING_FSCAL2 }, + { FSCAL1, SMARTRF_SETTING_FSCAL1 }, + { FSCAL0, SMARTRF_SETTING_FSCAL0 }, + { TEST2, SMARTRF_SETTING_TEST2 }, + { TEST1, SMARTRF_SETTING_TEST1 }, + { TEST0, SMARTRF_SETTING_TEST0 }, +}; + + +/* + * Logical channel table - this table translates logical channel into + * actual radio channel number. Channel 0, the default channel, is + * determined by the channel exported from SmartRF Studio. The other + * table entries are derived from that default. Each derived channel is + * masked with 0xFF to prevent generation of an illegal channel number. + * + * This table is easily customized. Just replace or add entries as needed. + * If the number of entries changes, the corresponding #define must also + * be adjusted. It is located in mrfi_defs.h and is called __mrfi_NUM_LOGICAL_CHANS__. + * The static assert below ensures that there is no mismatch. + */ +// [BM] Changed channel assignment to comply with local regulations +#ifdef ISM_EU +static const uint8_t mrfiLogicalChanTable[] = +{ + 0, + 50, + 80, + 110 +}; +#else +# ifdef ISM_US +static const uint8_t mrfiLogicalChanTable[] = +{ + 20, + 50, + 80, + 110 +}; +# else +# ifdef ISM_LF +static const uint8_t mrfiLogicalChanTable[] = +{ + 0, + 50, + 80, + 110 +}; +# else +# error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" +# endif +# endif +#endif +//static const uint8_t mrfiLogicalChanTable[] = +//{ +// SMARTRF_SETTING_CHANNR, +// 50, +// 80, +// 110 +//}; +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(__mrfi_NUM_LOGICAL_CHANS__ == + ((sizeof(mrfiLogicalChanTable) / + sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0]))); + +/* + * RF Power setting table - this table translates logical power value + * to radio register setting. The logical power value is used directly + * as an index into the power setting table. The values in the table are + * from low to high. The default settings set 3 values: -20 dBm, -10 dBm, + * and 0 dBm. The default at startup is the highest value. Note that these + * are approximate depending on the radio. Information is taken from the + * data sheet. + * + * This table is easily customized. Just replace or add entries as needed. + * If the number of entries changes, the corresponding #define must also + * be adjusted. It is located in mrfi_defs.h and is called __mrfi_NUM_POWER_SETTINGS__. + * The static assert below ensures that there is no mismatch. + * + * For the CC430 use the CC1100 values. + */ +static const uint8_t mrfiRFPowerTable[] = +{ + // [BM] Changed default output power to comply with dongle settings + 0x0F, + 0x27, + // [BM] Increase output power from -0.3dBm to +1.4dBm (433MHz) / +1.1dBm (868MHz) / +1.3dBm + // (915MHz) to compensate antenna loss +#ifdef ISM_EU + 0x8C +#else +# ifdef ISM_US + 0x8B +# else +# ifdef ISM_LF + 0x8D +# else +# error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" +# endif +# endif +#endif +}; +//static const uint8_t mrfiRFPowerTable[] = +//{ +// 0x0D, +// 0x34, +// 0x8E +//}; + +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(__mrfi_NUM_POWER_SETTINGS__ == + ((sizeof(mrfiRFPowerTable) / + sizeof(mrfiRFPowerTable[0])) * sizeof(mrfiRFPowerTable[0]))); + +/* ------------------------------------------------------------------------------------------------ + * Local Prototypes + * ------------------------------------------------------------------------------------------------ + */ +static void Mrfi_SyncPinRxIsr(void); +static void Mrfi_RxModeOn(void); +static void Mrfi_RandomBackoffDelay(void); +static void Mrfi_RxModeOff(void); +static void Mrfi_DelayUsec(uint16_t howLong); +static void Mrfi_DelayUsecSem(uint16_t howLong); +static int8_t Mrfi_CalculateRssi(uint8_t rawValue); +static uint8_t Mrfi_RxAddrIsFiltered(uint8_t * pAddr); + + +/* ------------------------------------------------------------------------------------------------ + * Local Variables + * ------------------------------------------------------------------------------------------------ + */ +static uint8_t mrfiRadioState = MRFI_RADIO_STATE_UNKNOWN; +static mrfiPacket_t mrfiIncomingPacket; +static uint8_t mrfiRndSeed = 0; + +/* reply delay support */ +static volatile uint8_t sKillSem = 0; +static volatile uint8_t sReplyDelayContext = 0; +static uint16_t sReplyDelayScalar = 0; +static uint16_t sBackoffHelper = 0; + +static uint8_t mrfiRxFilterEnabled = 0; +static uint8_t mrfiRxFilterAddr[MRFI_ADDR_SIZE] = { RX_FILTER_ADDR_INITIAL_VALUE }; + +/* These counters are only for diagnostic purpose */ +static uint32_t crcFail = 0; +static uint32_t crcPass = 0; +static uint32_t noFrame = 0; + +// [BM] Radio frequency offset read from calibration memory +// Compensates crystal deviation from 26MHz nominal value +extern unsigned char rf_frequoffset; + +/************************************************************************************************** + * @fn MRFI_Init + * + * @brief Initialize MRFI. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_Init(void) +{ + /* ------------------------------------------------------------------ + * Radio power-up reset + * ---------------------- + */ + memset(&mrfiIncomingPacket, 0x0, sizeof(mrfiIncomingPacket)); + + /* Initialize the radio interface */ + mrfiRadioInterfaceInit(); + + /* Strobe Reset: Resets the radio and puts it in SLEEP state. */ + MRFI_STROBE(SRES); + + /* verify the correct radio is installed */ + MRFI_ASSERT(MRFI_RADIO_REG_READ(PARTNUM) == MRFI_RADIO_PARTNUM); /* incorrect radio specified + **/ + MRFI_ASSERT(MRFI_RADIO_REG_READ(VERSION) == MRFI_RADIO_VERSION); /* incorrect radio specified + * */ + + /* Put radio in Idle state */ + MRFI_STROBE_IDLE_AND_WAIT(); + + + /* ------------------------------------------------------------------ + * Configure radio + * ----------------- + */ + + /* Configure Radio interrupts: + * + * RF1AIN_0 => Programmed to PA_PD signal. + * Configure it to interrupt on falling edge. + * + * RF1AIN_1 => Programmed to RSSI Valid signal. + * No need to configure for interrupt. This value will be read + * through polling. + * + * RF1AIN_9 => Rising edge indicates SYNC sent/received and + * Falling edge indicates end of packet. + * Configure it to interrupt on falling edge. + */ + + /* Select Interrupt edge for PA_PD and SYNC signal: + * Interrupt Edge select register: 1 == Interrupt on High to Low transition. + */ + RF1AIES = BV(0) | BV(9); + + /* Write the power output to the PA_TABLE and verify the write operation. */ + { + uint8_t readbackPATableValue = 0; + bspIState_t s; + + BSP_ENTER_CRITICAL_SECTION(s); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRW = 0x7E51; /* PA Table write (burst) */ + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; /* reset pointer */ + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = 0xFE; /* PA Table read (burst) */ + + while (!(RF1AIFCTL1 & RFDINIFG)) ; + RF1ADINB = 0x00; /* dummy write */ + + while (!(RF1AIFCTL1 & RFDOUTIFG)) ; + readbackPATableValue = RF1ADOUT0B; + + MRFI_ASSERT(readbackPATableValue == 0x51); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; + + BSP_EXIT_CRITICAL_SECTION(s); + } + + /* initialize radio registers */ + { + uint8_t i; + + for (i = 0; i < (sizeof(mrfiRadioCfg) / sizeof(mrfiRadioCfg[0])); i++) + { + MRFI_RADIO_REG_WRITE(mrfiRadioCfg[i][0], mrfiRadioCfg[i][1]); + } + } + + /* Confirm that the values were written correctly. + */ + { + uint8_t i; + + for (i = 0; i < (sizeof(mrfiRadioCfg) / sizeof(mrfiRadioCfg[0])); i++) + { + MRFI_ASSERT(mrfiRadioCfg[i][1] == MRFI_RADIO_REG_READ(mrfiRadioCfg[i][0])); + } + } + + // [BM] Apply global frequency offset to FSCTRL0 + MRFI_STROBE_IDLE_AND_WAIT(); + MRFI_RADIO_REG_WRITE(FSCTRL0, rf_frequoffset); + + /* set default channel */ + MRFI_SetLogicalChannel(0); + + /* Set default power level */ + MRFI_SetRFPwr(MRFI_NUM_POWER_SETTINGS - 1); + + /* Generate Random seed: + * We will use the RSSI value to generate our random seed. + */ + + /* Put the radio in RX state */ + MRFI_STROBE(SRX); + + /* delay for the rssi to be valid */ + MRFI_RSSI_VALID_WAIT(); + + { + uint8_t i; + for (i = 0; i < 16; i++) + { + /* use most random bit of rssi to populate the random seed */ + mrfiRndSeed = (mrfiRndSeed << 1) | (MRFI_RADIO_REG_READ(RSSI) & 0x01); + } + } + + /* Force the seed to be non-zero by setting one bit, just in case... */ + mrfiRndSeed |= 0x0080; + + /* Turn off RF. */ + Mrfi_RxModeOff(); + + /* Strobe Power Down (SPWD): puts the radio in SLEEP state. */ + + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + MRFI_STROBE(SXOFF); + + /* Initial radio state is IDLE state */ + mrfiRadioState = MRFI_RADIO_STATE_OFF; + + /***************************************************************************************** + * Compute reply delay scalar + * + * Formula from data sheet for all the narrow band radios is: + * + * (256 + DATAR_Mantissa) * 2^(DATAR_Exponent) + * DATA_RATE = ------------------------------------------ * f(xosc) + * 2^28 + * + * To try and keep some accuracy we change the exponent of the denominator + * to (28 - (exponent from the configuration register)) so we do a division + * by a smaller number. We find the power of 2 by shifting. + * + * The maximum delay needed depends on the MAX_APP_PAYLOAD parameter. Figure + * out how many bits that will be when overhead is included. Bits/bits-per-second + * is seconds to transmit (or receive) the maximum frame. We multiply this number + * by 1000 to find the time in milliseconds. We then additionally multiply by + * 10 so we can add 5 and divide by 10 later, thus rounding up to the number of + * milliseconds. This last won't matter for slow transmissions but for faster ones + * we want to err on the side of being conservative and making sure the radio is on + * to receive the reply. The semaphore monitor will shut it down. The delay adds in + * a fudge factor that includes processing time on peer plus lags in Rx and processing + * time on receiver's side. + * + * Note that we assume a 26 MHz clock for the radio... + * *************************************************************************************** + */ +#define MRFI_RADIO_OSC_FREQ 26000000 +#define PHY_PREAMBLE_SYNC_BYTES 8 + + { + uint32_t dataRate, bits; + uint16_t exponent, mantissa; + + /* mantissa is in MDMCFG3 */ + mantissa = 256 + SMARTRF_SETTING_MDMCFG3; + + /* exponent is lower nibble of MDMCFG4. */ + exponent = 28 - (SMARTRF_SETTING_MDMCFG4 & 0x0F); + + /* we can now get data rate */ + dataRate = mantissa * (MRFI_RADIO_OSC_FREQ >> exponent); + + bits = ((uint32_t)((PHY_PREAMBLE_SYNC_BYTES + MRFI_MAX_FRAME_SIZE) * 8)) * 10000; + + /* processing on the peer + the Tx/Rx time plus more */ + sReplyDelayScalar = PLATFORM_FACTOR_CONSTANT + (((bits / dataRate) + 5) / 10); + + /* This helper value is used to scale the backoffs during CCA. At very + * low data rates we need to backoff longer to prevent continual sampling + * of valid frames which take longer to send at lower rates. Use the scalar + * we just calculated divided by 32. With the backoff algorithm backing + * off up to 16 periods this will result in waiting up to about 1/2 the total + * scalar value. For high data rates this does not contribute at all. Value + * is in microseconds. + */ + sBackoffHelper = MRFI_BACKOFF_PERIOD_USECS + (sReplyDelayScalar >> 5) * 1000; + } + + /* Clean out buffer to protect against spurious frames */ + memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame)); + memset(mrfiIncomingPacket.rxMetrics, 0x00, sizeof(mrfiIncomingPacket.rxMetrics)); + + /* enable global interrupts */ + BSP_ENABLE_INTERRUPTS(); +} + +/************************************************************************************************** + * @fn MRFI_Transmit + * + * @brief Transmit a packet using CCA algorithm. + * + * @param pPacket - pointer to packet to transmit + * + * @return Return code indicates success or failure of transmit: + * MRFI_TX_RESULT_SUCCESS - transmit succeeded + * MRFI_TX_RESULT_FAILED - transmit failed because CCA failed + ************************************************************************************************** + */ + +uint8_t MRFI_Transmit(mrfiPacket_t * pPacket, uint8_t txType) +{ + uint8_t ccaRetries; + uint8_t txBufLen; + uint8_t returnValue = MRFI_TX_RESULT_SUCCESS; + + /* radio must be awake to transmit */ + MRFI_ASSERT(mrfiRadioState != MRFI_RADIO_STATE_OFF); + + /* Turn off reciever. We can ignore/drop incoming packets during transmit. */ + Mrfi_RxModeOff(); + + /* compute number of bytes to write to transmit FIFO */ + txBufLen = pPacket->frame[MRFI_LENGTH_FIELD_OFS] + MRFI_LENGTH_FIELD_SIZE; + + /* ------------------------------------------------------------------ + * Write packet to transmit FIFO + * -------------------------------- + */ + MRFI_RADIO_WRITE_TX_FIFO(&(pPacket->frame[0]), txBufLen); + + + /* ------------------------------------------------------------------ + * Immediate transmit + * --------------------- + */ + if (txType == MRFI_TX_TYPE_FORCED) + { + /* Issue the TX strobe. */ + MRFI_STROBE(STX); + + /* Wait for transmit to complete */ + while (!MRFI_SYNC_PIN_INT_FLAG_IS_SET()) ; + + /* Clear the interrupt flag */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + } + else + { + /* ------------------------------------------------------------------ + * CCA transmit + * --------------- + */ + + MRFI_ASSERT(txType == MRFI_TX_TYPE_CCA); + + /* set number of CCA retries */ + ccaRetries = MRFI_CCA_RETRIES; + + + /* =============================================================================== + * Main Loop + * ============= + */ + for (;;) + { + /* Radio must be in RX mode for CCA to happen. + * Otherwise it will transmit without CCA happening. + */ + + /* Can not use the Mrfi_RxModeOn() function here since it turns on the + * Rx interrupt, which we don't want in this case. + */ + MRFI_STROBE(SRX); + + /* wait for the rssi to be valid. */ + MRFI_RSSI_VALID_WAIT(); + + /* + * Clear the PA_PD pin interrupt flag. This flag, not the interrupt itself, + * is used to capture the transition that indicates a transmit was started. + * The pin level cannot be used to indicate transmit success as timing may + * prevent the transition from being detected. The interrupt latch captures + * the event regardless of timing. + */ + MRFI_CLEAR_PAPD_PIN_INT_FLAG(); + + /* send strobe to initiate transmit */ + MRFI_STROBE(STX); + + /* Delay long enough for the PA_PD signal to indicate a + * successful transmit. This is the 250 XOSC periods + * (9.6 us for a 26 MHz crystal). + * Found out that we need a delay of atleast 25 us on CC1100 to see + * the PA_PD signal change. Hence keeping the same for CC430 + */ + Mrfi_DelayUsec(25); + + + /* PA_PD signal goes from HIGH to LOW when going from RX to TX state. + * This transition is trapped as a falling edge interrupt flag + * to indicate that CCA passed and the transmit has started. + */ + if (MRFI_PAPD_INT_FLAG_IS_SET()) + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment passed. + * ---------------------------------- + */ + + /* Clear the PA_PD int flag */ + MRFI_CLEAR_PAPD_PIN_INT_FLAG(); + + /* PA_PD signal stays LOW while in TX state and goes back to HIGH when + * the radio transitions to RX state. + */ + /* wait for transmit to complete */ + while (!MRFI_PAPD_PIN_IS_HIGH()) ; + + /* transmit done, break */ + break; + } + else + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment failed. + * ---------------------------------- + */ + + /* Turn off radio and save some power during backoff */ + + /* NOTE: Can't use Mrfi_RxModeOff() - since it tries to update the + * sync signal status which we are not using during the TX operation. + */ + MRFI_STROBE_IDLE_AND_WAIT(); + + /* flush the receive FIFO of any residual data */ + MRFI_STROBE(SFRX); + + /* Retry ? */ + if (ccaRetries != 0) + { + /* delay for a random number of backoffs */ + Mrfi_RandomBackoffDelay(); + + /* decrement CCA retries before loop continues */ + ccaRetries--; + } + else /* No CCA retries are left, abort */ + { + /* set return value for failed transmit and break */ + returnValue = MRFI_TX_RESULT_FAILED; + break; + } + } /* CCA Failed */ + } /* CCA loop */ + } /* txType is CCA */ + + + /* Done with TX. Clean up time... */ + + /* Radio is already in IDLE state */ + + /* + * Flush the transmit FIFO. It must be flushed so that + * the next transmit can start with a clean slate. + */ + MRFI_STROBE(SFTX); + + /* If the radio was in RX state when transmit was attempted, + * put it back to Rx On state. + */ + if (mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOn(); + } + + return (returnValue); +} + +/************************************************************************************************** + * @fn MRFI_Receive + * + * @brief Copies last packet received to the location specified. + * This function is meant to be called after the ISR informs + * higher level code that there is a newly received packet. + * + * @param pPacket - pointer to location of where to copy received packet + * + * @return none + ************************************************************************************************** + */ + +void MRFI_Receive(mrfiPacket_t * pPacket) +{ + *pPacket = mrfiIncomingPacket; +} + +/************************************************************************************************** + * @fn Mrfi_SyncPinRxIsr + * + * @brief This interrupt is called when the SYNC signal transition from high to low. + * The sync signal is routed to the sync pin which is a GPIO pin. This high-to-low + * transition signifies a receive has completed. The SYNC signal also goes from + * high to low when a transmit completes. This is protected against within the + * transmit function by disabling sync pin interrupts until transmit completes. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Mrfi_SyncPinRxIsr(void) +{ + uint8_t frameLen = 0x00; + uint8_t rxBytes; + + /* We should receive this interrupt only in RX state + * Should never receive it if RX was turned On only for + * some internal mrfi processing like - during CCA. + * Otherwise something is terribly wrong. + */ + MRFI_ASSERT(mrfiRadioState == MRFI_RADIO_STATE_RX); + + /* ------------------------------------------------------------------ + * Get RXBYTES + * ------------- + */ + + /* + * Read the RXBYTES register from the radio. + * Bit description of RXBYTES register: + * bit 7 - RXFIFO_OVERFLOW, set if receive overflow occurred + * bits 6:0 - NUM_BYTES, number of bytes in receive FIFO + * + * Due a chip bug, the RXBYTES register must read the same value twice + * in a row to guarantee an accurate value. + */ + { + uint8_t rxBytesVerify; + + rxBytesVerify = MRFI_RADIO_REG_READ(RXBYTES); + + do + { + rxBytes = rxBytesVerify; + rxBytesVerify = MRFI_RADIO_REG_READ(RXBYTES); + } + while (rxBytes != rxBytesVerify); + } + + + /* ------------------------------------------------------------------ + * FIFO empty? + * ------------- + */ + + /* + * See if the receive FIFIO is empty before attempting to read from it. + * It is possible nothing the FIFO is empty even though the interrupt fired. + * This can happen if address check is enabled and a non-matching packet is + * received. In that case, the radio automatically removes the packet from + * the FIFO. + */ + if (rxBytes == 0) + { + /* receive FIFO is empty - do nothing, skip to end */ + } + else + { + /* receive FIFO is not empty, continue processing */ + + /* ------------------------------------------------------------------ + * Process frame length + * ---------------------- + */ + + /* read the first byte from FIFO - the packet length */ + MRFI_RADIO_READ_RX_FIFO(&frameLen, MRFI_LENGTH_FIELD_SIZE); + + + /* + * Make sure that the frame length just read corresponds to number of bytes in the buffer. + * If these do not match up something is wrong. + * + * This can happen for several reasons: + * 1) Incoming packet has an incorrect format or is corrupted. + * 2) The receive FIFO overflowed. Overflow is indicated by the high + * bit of rxBytes. This guarantees the value of rxBytes value will not + * match the number of bytes in the FIFO for overflow condition. + * 3) Interrupts were blocked for an abnormally long time which + * allowed a following packet to at least start filling the + * receive FIFO. In this case, all received and partially received + * packets will be lost - the packet in the FIFO and the packet coming in. + * This is the price the user pays if they implement a giant + * critical section. + * 4) A failed transmit forced radio to IDLE state to flush the transmit FIFO. + * This could cause an active receive to be cut short. + * + * Also check the sanity of the length to guard against rogue frames. + */ + if ((rxBytes != (frameLen + MRFI_LENGTH_FIELD_SIZE + MRFI_RX_METRICS_SIZE)) || + ((frameLen + MRFI_LENGTH_FIELD_SIZE) > MRFI_MAX_FRAME_SIZE) || + (frameLen < MRFI_MIN_SMPL_FRAME_SIZE) + ) + { + bspIState_t s; + noFrame++; + + /* mismatch between bytes-in-FIFO and frame length */ + + /* + * Flush receive FIFO to reset receive. Must go to IDLE state to do this. + * The critical section guarantees a transmit does not occur while cleaning up. + */ + BSP_ENTER_CRITICAL_SECTION(s); + MRFI_STROBE_IDLE_AND_WAIT(); + MRFI_STROBE(SFRX); + MRFI_STROBE(SRX); + BSP_EXIT_CRITICAL_SECTION(s); + + /* flush complete, skip to end */ + } + else + { + /* bytes-in-FIFO and frame length match up - continue processing */ + + /* ------------------------------------------------------------------ + * Get packet + * ------------ + */ + + /* clean out buffer to help protect against spurious frames */ + memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame)); + + /* set length field */ + mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFS] = frameLen; + + /* get packet from FIFO */ + MRFI_RADIO_READ_RX_FIFO(&(mrfiIncomingPacket.frame[MRFI_FRAME_BODY_OFS]), frameLen); + + /* get receive metrics from FIFO */ + MRFI_RADIO_READ_RX_FIFO(&(mrfiIncomingPacket.rxMetrics[0]), MRFI_RX_METRICS_SIZE); + + + /* ------------------------------------------------------------------ + * CRC check + * ------------ + */ + + /* + * Note! Automatic CRC check is not, and must not, be enabled. This feature + * flushes the *entire* receive FIFO when CRC fails. If this feature is + * enabled it is possible to be reading from the FIFO and have a second + * receive occur that fails CRC and automatically flushes the receive FIFO. + * This could cause reads from an empty receive FIFO which puts the radio + * into an undefined state. + */ + + /* determine if CRC failed */ + if (!(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & + MRFI_RX_METRICS_CRC_OK_MASK)) + { + /* CRC failed - do nothing, skip to end */ + crcFail++; + } + else + { + /* CRC passed - continue processing */ + crcPass++; + + /* ------------------------------------------------------------------ + * Filtering + * ----------- + */ + + /* if address is not filtered, receive is successful */ + if (!Mrfi_RxAddrIsFiltered(MRFI_P_DST_ADDR(&mrfiIncomingPacket))) + { + { + /* ------------------------------------------------------------------ + * Receive successful + * -------------------- + */ + + /* Convert the raw RSSI value and do offset compensation for this radio */ + mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS] = + Mrfi_CalculateRssi(mrfiIncomingPacket.rxMetrics[ + MRFI_RX_METRICS_RSSI_OFS]); + + /* Remove the CRC valid bit from the LQI byte */ + mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] = + (mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & + MRFI_RX_METRICS_LQI_MASK); + + + /* call external, higher level "receive complete" processing routine */ + MRFI_RxCompleteISR(); + } + } + } + } + } + + /* ------------------------------------------------------------------ + * End of function + * ------------------- + */ + +} + +/************************************************************************************************** + * @fn Mrfi_RxModeOn + * + * @brief Put radio into receive mode. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Mrfi_RxModeOn(void) +{ + /* clear any residual receive interrupt */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + + /* send strobe to enter receive mode */ + MRFI_STROBE(SRX); + + /* enable receive interrupts */ + MRFI_ENABLE_SYNC_PIN_INT(); +} + +/************************************************************************************************** + * @fn MRFI_RxOn + * + * @brief Turn on the receiver. No harm is done if this function is called when + * receiver is already on. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_RxOn(void) +{ + /* radio must be awake before we can move it to RX state */ + MRFI_ASSERT(mrfiRadioState != MRFI_RADIO_STATE_OFF); + + /* if radio is off, turn it on */ + if (mrfiRadioState != MRFI_RADIO_STATE_RX) + { + mrfiRadioState = MRFI_RADIO_STATE_RX; + Mrfi_RxModeOn(); + } +} + +/************************************************************************************************** + * @fn Mrfi_RxModeOff + * + * @brief - + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Mrfi_RxModeOff(void) +{ + /* disable receive interrupts */ + MRFI_DISABLE_SYNC_PIN_INT(); + + /* turn off radio */ + MRFI_STROBE_IDLE_AND_WAIT(); + + /* flush the receive FIFO of any residual data */ + MRFI_STROBE(SFRX); + + /* clear receive interrupt */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); +} + +/************************************************************************************************** + * @fn MRFI_RxIdle + * + * @brief Put radio in idle mode (receiver if off). No harm is done this function is + * called when radio is already idle. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_RxIdle(void) +{ + /* radio must be awake to move it to idle mode */ + MRFI_ASSERT(mrfiRadioState != MRFI_RADIO_STATE_OFF); + + /* if radio is on, turn it off */ + if (mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOff(); + mrfiRadioState = MRFI_RADIO_STATE_IDLE; + } +} + +/************************************************************************************************** + * @fn MRFI_Sleep + * + * @brief Request radio go to sleep. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_Sleep(void) +{ + bspIState_t s; + + /* Critical section necessary for watertight testing and + * setting of state variables. + */ + BSP_ENTER_CRITICAL_SECTION(s); + + /* If radio is not asleep, put it to sleep */ + if (mrfiRadioState != MRFI_RADIO_STATE_OFF) + { + /* go to idle so radio is in a known state before sleeping */ + MRFI_RxIdle(); + + /* Strobe Power Down (SPWD): puts the radio in SLEEP state. */ + + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + MRFI_STROBE(SXOFF); + + /* Our new state is OFF */ + mrfiRadioState = MRFI_RADIO_STATE_OFF; + } + + BSP_EXIT_CRITICAL_SECTION(s); +} + +/************************************************************************************************** + * @fn MRFI_WakeUp + * + * @brief Wake up radio from sleep state. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_WakeUp(void) +{ + /* if radio is already awake, just ignore wakeup request */ + if (mrfiRadioState != MRFI_RADIO_STATE_OFF) + { + return; + } + + MRFI_STROBE_IDLE_AND_WAIT(); + + /* enter idle mode */ + mrfiRadioState = MRFI_RADIO_STATE_IDLE; +} + +/************************************************************************************************** + * @fn MRFI_RadioIsr + * + * @brief Radio Interface interrupts as well as Radio interrupts are + * mapped to this interrupt vector. + * + * @param - + * + * @return - + ************************************************************************************************** + */ +// [BM] Changed because CC1101_VECTOR ISR is declared of source code and this handler is called +// indirect +//BSP_ISR_FUNCTION( MRFI_RadioIsr, CC1101_VECTOR ) +void MRFI_RadioIsr(void) +{ + uint16_t coreIntSource = RF1AIV; /* Radio Core interrupt register */ + uint16_t interfaceIntSource = RF1AIFIV; /* Radio Interface interrupt register */ + + /* Interface interrupt */ + if (interfaceIntSource) + { + if (interfaceIntSource == RF1AIFIV_RFERRIFG) + { + uint16_t interfaceError = RF1AIFERRV; + + if (interfaceError == RF1AIFERRV_LVERR) + { + /* Low core voltage error */ + } + else if (interfaceError == RF1AIFERRV_OPERR) + { + /* Operand error */ + } + else if (interfaceError == RF1AIFERRV_OUTERR) + { + /* output data not available error */ + } + else if (interfaceError == RF1AIFERRV_OPOVERR) + { + /* Operand overwrite error */ + } + else + { + /* Can't possibly happen. If interface error flag was set, + * then one of the interface errors must be set. + */ + MRFI_FORCE_ASSERT(); + } + + /* Assert anyways. No error handling implemented. */ + MRFI_FORCE_ASSERT(); + } + else + { + /* Not expecting any other interface interrupts (data in/out, status/instr in, fifo + *rx/tx) */ + MRFI_FORCE_ASSERT(); + } + } + + /* Radio Core interrupt */ + if (coreIntSource) + { + /* Check for SYNC interrupt */ + if (coreIntSource == RF1AIV_RFIFG9) + { + if (MRFI_SYNC_PIN_INT_IS_ENABLED()) + { + /* clear the sync pin interrupt, run sync pin ISR */ + + /* + * NOTE! The following macro clears the interrupt flag but it also *must* + * reset the interrupt capture. In other words, if a second interrupt + * occurs after the flag is cleared it must be processed, i.e. this interrupt + * exits then immediately starts again. Most microcontrollers handle this + * naturally but it must be verified for every target. + */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + + Mrfi_SyncPinRxIsr(); + } + else + { + /* Fatal error. SYNC interrupt is not supposed to happen at this time. */ + MRFI_FORCE_ASSERT(); + } + } + else + { + /* Fatal error. No other Radio interurpt is enabled. */ + MRFI_FORCE_ASSERT(); + } + } +} + +/************************************************************************************************** + * @fn MRFI_Rssi + * + * @brief Returns "live" RSSI value + * + * @param none + * + * @return RSSI value in units of dBm. + ************************************************************************************************** + */ + +int8_t MRFI_Rssi(void) +{ + uint8_t regValue; + + /* Radio must be in RX state to measure rssi. */ + MRFI_ASSERT(mrfiRadioState == MRFI_RADIO_STATE_RX); + + /* Wait for the RSSI to be valid: + * Just having the Radio ON is not enough to read + * the correct RSSI value. The Radio must in RX mode for + * a certain duration. This duration depends on + * the baud rate and the received signal strength itself. + */ + MRFI_RSSI_VALID_WAIT(); + + /* Read the RSSI value */ + regValue = MRFI_RADIO_REG_READ(RSSI); + + /* convert and do offset compensation */ + return (Mrfi_CalculateRssi(regValue)); +} + +/************************************************************************************************** + * @fn Mrfi_CalculateRssi + * + * @brief Does binary to decimal conversion and offset compensation. + * + * @param none + * + * @return RSSI value in units of dBm. + ************************************************************************************************** + */ + +int8_t Mrfi_CalculateRssi(uint8_t rawValue) +{ + int16_t rssi; + + /* The raw value is in 2's complement and in half db steps. Convert it to + * decimal taking into account the offset value. + */ + if (rawValue >= 128) + { + rssi = (int16_t)(rawValue - 256) / 2 - MRFI_RSSI_OFFSET; + } + else + { + rssi = (rawValue / 2) - MRFI_RSSI_OFFSET; + } + + /* Restrict this value to least value can be held in an 8 bit signed int */ + if (rssi < -128) + { + rssi = -128; + } + + return rssi; +} + +/************************************************************************************************** + * @fn MRFI_RandomByte + * + * @brief Returns a random byte. This is a pseudo-random number generator. + * The generated sequence will repeat every 256 values. + * The sequence itself depends on the initial seed value. + * + * @param none + * + * @return a random byte + ************************************************************************************************** + */ + +uint8_t MRFI_RandomByte(void) +{ + mrfiRndSeed = (mrfiRndSeed * MRFI_RANDOM_MULTIPLIER) + MRFI_RANDOM_OFFSET; + + return mrfiRndSeed; +} + +/************************************************************************************************** + * @fn Mrfi_RandomBackoffDelay + * + * @brief - + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Mrfi_RandomBackoffDelay(void) +{ + uint8_t backoffs; + uint8_t i; + + /* calculate random value for backoffs - 1 to 16 */ + backoffs = (MRFI_RandomByte() & 0x0F) + 1; + + /* delay for randomly computed number of backoff periods */ + for (i = 0; i < backoffs; i++) + { + Mrfi_DelayUsec(sBackoffHelper); + } +} + +/**************************************************************************************************** + * @fn Mrfi_DelayUsec + * + * @brief Execute a delay loop using HW timer. The macro actually used to do the delay + * is not thread-safe. This routine makes the delay execution thread-safe by breaking + * up the requested delay up into small chunks and executing each chunk as a critical + * section. The chunk size is choosen to be the smallest value used by MRFI. The delay + * is only approximate because of the overhead computations. It errs on the side of + * being too long. + * + * input parameters + * @param howLong - number of microseconds to delay + * + * @return none + **************************************************************************************************** + */ + +static void Mrfi_DelayUsec(uint16_t howLong) +{ + bspIState_t s; + uint16_t count = howLong / MRFI_MAX_DELAY_US; + + if (howLong) + { + do + { + BSP_ENTER_CRITICAL_SECTION(s); + BSP_DELAY_USECS(MRFI_MAX_DELAY_US); + BSP_EXIT_CRITICAL_SECTION(s); + } while (count--); + } + + return; +} + +/**************************************************************************************************** + * @fn Mrfi_DelayUsecSem + * + * @brief Execute a delay loop using a HW timer. See comments for Mrfi_DelayUsec(). + * Delay specified number of microseconds checking semaphore for + * early-out. Run in a separate thread when the reply delay is + * invoked. Cleaner then trying to make MRFI_DelayUsec() thread-safe + * and reentrant. + * + * input parameters + * @param howLong - number of microseconds to delay + * + * @return none + **************************************************************************************************** + */ + +static void Mrfi_DelayUsecSem(uint16_t howLong) +{ + bspIState_t s; + uint16_t count = howLong / MRFI_MAX_DELAY_US; + + if (howLong) + { + do + { + BSP_ENTER_CRITICAL_SECTION(s); + BSP_DELAY_USECS(MRFI_MAX_DELAY_US); + BSP_EXIT_CRITICAL_SECTION(s); + if (sKillSem) + { + break; + } + } while (count--); + } + + return; +} + +/************************************************************************************************** + * @fn MRFI_DelayMs + * + * @brief Delay the specified number of milliseconds. + * + * @param milliseconds - delay time + * + * @return none + ************************************************************************************************** + */ + +void MRFI_DelayMs(uint16_t milliseconds) +{ + while (milliseconds) + { + Mrfi_DelayUsec(APP_USEC_VALUE); + milliseconds--; + } +} + +/************************************************************************************************** + * @fn MRFI_ReplyDelay + * + * @brief Delay number of milliseconds scaled by data rate. Check semaphore for + * early-out. Run in a separate thread when the reply delay is + * invoked. Cleaner then trying to make MRFI_DelayMs() thread-safe + * and reentrant. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_ReplyDelay(void) +{ + bspIState_t s; + uint16_t milliseconds = sReplyDelayScalar; + + BSP_ENTER_CRITICAL_SECTION(s); + sReplyDelayContext = 1; + BSP_EXIT_CRITICAL_SECTION(s); + + while (milliseconds) + { + Mrfi_DelayUsecSem(APP_USEC_VALUE); + if (sKillSem) + { + break; + } + milliseconds--; + } + + BSP_ENTER_CRITICAL_SECTION(s); + sKillSem = 0; + sReplyDelayContext = 0; + BSP_EXIT_CRITICAL_SECTION(s); +} + +/************************************************************************************************** + * @fn MRFI_PostKillSem + * + * @brief Post to the loop-kill semaphore that will be checked by the iteration loops + * that control the delay thread. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_PostKillSem(void) +{ + + if (sReplyDelayContext) + { + sKillSem = 1; + } + + return; +} + +/************************************************************************************************** + * @fn MRFI_GetRadioState + * + * @brief Returns the current radio state. + * + * @param none + * + * @return radio state - off/idle/rx + ************************************************************************************************** + */ + +uint8_t MRFI_GetRadioState(void) +{ + return mrfiRadioState; +} + +/************************************************************************************************** + * @fn MRFI_SetLogicalChannel + * + * @brief Set logical channel. + * + * @param chan - logical channel number + * + * @return none + ************************************************************************************************** + */ + +void MRFI_SetLogicalChannel(uint8_t chan) +{ + /* logical channel is not valid? */ + MRFI_ASSERT(chan < MRFI_NUM_LOGICAL_CHANS); + + /* make sure radio is off before changing channels */ + Mrfi_RxModeOff(); + + MRFI_RADIO_REG_WRITE(CHANNR, mrfiLogicalChanTable[chan]); + + /* turn radio back on if it was on before channel change */ + if (mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOn(); + } +} + +/************************************************************************************************** + * @fn MRFI_SetRFPwr + * + * @brief Set ouput RF power level. + * + * @param level - power level to be set + * + * @return none + ************************************************************************************************** + */ + +void MRFI_SetRFPwr(uint8_t level) +{ + /* Power level is not valid? */ + MRFI_ASSERT(level < MRFI_NUM_POWER_SETTINGS); + + MRFI_RADIO_REG_WRITE(PATABLE, mrfiRFPowerTable[level]); + + return; +} + +/************************************************************************************************** + * @fn MRFI_SetRxAddrFilter + * + * @brief Set the address used for filtering received packets. + * + * @param pAddr - pointer to address to use for filtering + * + * @return zero : successfully set filter address + * non-zero : illegal address + ************************************************************************************************** + */ + +uint8_t MRFI_SetRxAddrFilter(uint8_t * pAddr) +{ + /* + * If first byte of filter address match fir byte of broadcast address, + * there is a conflict with hardware filtering. + */ + if (pAddr[0] == mrfiBroadcastAddr[0]) + { + /* unable to set filter address */ + return (1); + } + + /* + * Set the hardware address register. The hardware address filtering only recognizes + * a single byte but this does provide at least some automatic hardware filtering. + */ + MRFI_RADIO_REG_WRITE(ADDR, pAddr[0]); + + /* save a copy of the filter address */ + { + uint8_t i; + + for (i = 0; i < MRFI_ADDR_SIZE; i++) + { + mrfiRxFilterAddr[i] = pAddr[i]; + } + } + + /* successfully set filter address */ + return (0); +} + +/************************************************************************************************** + * @fn MRFI_EnableRxAddrFilter + * + * @brief Enable received packet filtering. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_EnableRxAddrFilter(void) +{ + MRFI_ASSERT(mrfiRxFilterAddr[0] != mrfiBroadcastAddr[0]); /* filter address must be set before + *enabling filter */ + + /* set flag to indicate filtering is enabled */ + mrfiRxFilterEnabled = 1; + + /* enable hardware filtering on the radio */ + MRFI_RADIO_REG_WRITE(PKTCTRL1, PKTCTRL1_ADDR_FILTER_ON); +} + +/************************************************************************************************** + * @fn MRFI_DisableRxAddrFilter + * + * @brief Disable received packet filtering. + * + * @param pAddr - pointer to address to test for filtering + * + * @return none + ************************************************************************************************** + */ + +void MRFI_DisableRxAddrFilter(void) +{ + /* clear flag that indicates filtering is enabled */ + mrfiRxFilterEnabled = 0; + + /* disable hardware filtering on the radio */ + MRFI_RADIO_REG_WRITE(PKTCTRL1, PKTCTRL1_ADDR_FILTER_OFF); +} + +/************************************************************************************************** + * @fn Mrfi_RxAddrIsFiltered + * + * @brief Determine if address is filtered. + * + * @param none + * + * @return zero : address is not filtered + * non-zero : address is filtered + ************************************************************************************************** + */ + +uint8_t Mrfi_RxAddrIsFiltered(uint8_t * pAddr) +{ + uint8_t i; + uint8_t addrByte; + uint8_t filterAddrMatches; + uint8_t broadcastAddrMatches; + + /* first check to see if filtering is even enabled */ + if (!mrfiRxFilterEnabled) + { + /* + * Filtering is not enabled, so by definition the address is + * not filtered. Return zero to indicate address is not filtered. + */ + return (0); + } + + /* clear address byte match counts */ + filterAddrMatches = 0; + broadcastAddrMatches = 0; + + /* loop through address to see if there is a match to filter address of broadcast address */ + for (i = 0; i < MRFI_ADDR_SIZE; i++) + { + /* get byte from address to check */ + addrByte = pAddr[i]; + + /* compare byte to filter address byte */ + if (addrByte == mrfiRxFilterAddr[i]) + { + filterAddrMatches++; + } + if (addrByte == mrfiBroadcastAddr[i]) + { + broadcastAddrMatches++; + } + } + + /* + * If address is *not* filtered, either the "filter address match count" or + * the "broadcast address match count" will equal the total number of bytes + * in the address. + */ + if ((broadcastAddrMatches == MRFI_ADDR_SIZE) || (filterAddrMatches == MRFI_ADDR_SIZE)) + { + /* address *not* filtered, return zero */ + return (0); + } + else + { + /* address filtered, return non-zero */ + return (1); + } +} + +/************************************************************************************************** + * Compile Time Integrity Checks + ************************************************************************************************** + */ + +/* calculate maximum value for PKTLEN and verify it directly */ +#define MRFI_RADIO_TX_FIFO_SIZE 64 /* from datasheet */ +#define MRFI_RADIO_MAX_PKTLEN (MRFI_RADIO_TX_FIFO_SIZE - MRFI_LENGTH_FIELD_SIZE - \ + MRFI_RX_METRICS_SIZE) +#if (MRFI_RADIO_MAX_PKTLEN != 61) +# error "ERROR: The maximum value for PKTLEN is not correct." +#endif + +/* verify setting for PKTLEN does not exceed maximum */ +#if (MRFI_SETTING_PKTLEN > MRFI_RADIO_MAX_PKTLEN) +# error \ + "ERROR: Maximum possible value for PKTLEN exceeded. Decrease value of maximum payload." +#endif + +/* verify largest possible packet fits within FIFO buffer */ +#if ((MRFI_MAX_FRAME_SIZE + MRFI_RX_METRICS_SIZE) > MRFI_RADIO_TX_FIFO_SIZE) +# error \ + "ERROR: Maximum possible packet length exceeds FIFO buffer. Decrease value of maximum payload." +#endif + +/* verify that the SmartRF file supplied is compatible */ +#if ((!defined SMARTRF_RADIO_CC430)) +# error "ERROR: The SmartRF export file is not compatible." +#endif + +/* + * These asserts happen if there is extraneous compiler padding of arrays. + * Modify compiler settings for no padding, or, if that is not possible, + * comment out the offending asserts. + */ +BSP_STATIC_ASSERT(sizeof(mrfiRadioCfg) == + ((sizeof(mrfiRadioCfg) / sizeof(mrfiRadioCfg[0])) * sizeof(mrfiRadioCfg[0]))); + + +/* + * These asserts happen if there is extraneous compiler padding of arrays. + * Modify compiler settings for no padding, or, if that is not possible, + * comment out the offending asserts. + */ +BSP_STATIC_ASSERT(sizeof(mrfiLogicalChanTable) == + ((sizeof(mrfiLogicalChanTable) / + sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0]))); +BSP_STATIC_ASSERT(sizeof(mrfiBroadcastAddr) == + ((sizeof(mrfiBroadcastAddr) / + sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0]))); + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c new file mode 100755 index 0000000..a8a85f6 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c @@ -0,0 +1,373 @@ +/************************************************************************************************** +* Revised: $Date: 2009-11-23 07:50:43 -0800 (Mon, 23 Nov 2009) $ +* Revision: $Revision: 21225 $ +* +* Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS? +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radios: CC430 + * Radio Interface (RIF) code. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "mrfi_radio_interface.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_RADIO_STATUS_READ_CLEAR() RF1AIFCTL1 &= ~(RFSTATIFG); + +#define MRFI_RADIO_STATUS_READ_WAIT() while (!(RF1AIFCTL1 & RFSTATIFG)) ; +#define MRFI_RADIO_INST_WRITE_WAIT() while (!(RF1AIFCTL1 & RFINSTRIFG)) ; +#define MRFI_RADIO_DATA_WRITE_WAIT() while (!(RF1AIFCTL1 & RFDINIFG)) ; +#define MRFI_RADIO_DATA_READ_WAIT() while (!(RF1AIFCTL1 & RFDOUTIFG)) ; + +#define MRFI_RIF_DEBUG +#ifdef MRFI_RIF_DEBUG +# define MRFI_RIF_ASSERT(x) BSP_ASSERT(x) +#else +# define MRFI_RIF_ASSERT(x) +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Local Prototypes + * ------------------------------------------------------------------------------------------------ + */ + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceInit + * + * @brief Initialize the Radio Interface + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void mrfiRadioInterfaceInit(void) +{ + /* Enable interrupt on interface error. + * The code behaves differently between different runs on the debugger, and seemingly fails + * due to error flags on the bench. The code does not fail, however, on functional tests. + * This points to problems with the debugger that need to be sorted through carefully. + * For the time being, remove the following line, since it will likely cause operational + * failures. + */ + // RF1AIFCTL1 |= RFERRIE; +} + +/************************************************************************************************** + * @fn mrfiRadioInterfaceCmdStrobe + * + * @brief Send command strobe to the radio. Returns status byte read during transfer + * of strobe command. + * + * @param addr - address of register to strobe + * + * @return status byte of radio + ************************************************************************************************** + */ + +uint8_t mrfiRadioInterfaceCmdStrobe(uint8_t addr) +{ + uint8_t statusByte, gdoState; + mrfiRIFIState_t s; + + /* Check for invalid address. + * 0xBD is for SNOP with MSP set to read the bytes available in RX FIFO. + */ + MRFI_RIF_ASSERT((addr == 0xBD) || (addr >= RF_SRES) && (addr <= RF_SNOP)); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Clear the Status read flag */ + MRFI_RADIO_STATUS_READ_CLEAR(); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + if ((addr > RF_SRES) && (addr < RF_SNOP)) + { + /* buffer IOCFG2 state */ + gdoState = MRFI_RADIO_REG_READ(IOCFG2); + + /* c-ready to GDO2 */ + MRFI_RADIO_REG_WRITE(IOCFG2, 0x29); + + RF1AINSTRB = addr; + + /* chip at sleep mode */ + if ((RF1AIN & 0x04) == 0x04) + { + if ((addr == RF_SXOFF) || (addr == RF_SPWD) || (addr == RF_SWOR)) + { + /* Do nothing */ + } + else + { + /* c-ready */ + while ((RF1AIN & 0x04) == 0x04) ; + + /* Delay should be 760us */ + Mrfi_DelayUsec(760); + } + } + + /* restore IOCFG2 setting */ + MRFI_RADIO_REG_WRITE(IOCFG2, gdoState); + } + else + { + /* chip active mode */ + RF1AINSTRB = addr; + } + + /* Read status byte */ + statusByte = RF1ASTAT0B; + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); + + /* return the status byte */ + return statusByte; +} + +/************************************************************************************************** + * @fn mrfiRadioInterfaceReadReg + * + * @brief Read value from radio register. + * + * @param addr - address of register + * + * @return register value + ************************************************************************************************** + */ + +uint8_t mrfiRadioInterfaceReadReg(uint8_t addr) +{ + mrfiRIFIState_t s; + uint8_t regValue; + + /* Check for valid range. 0x3E is for PATABLE access */ + MRFI_RIF_ASSERT((addr <= 0x3B) || (addr == 0x3E)); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + if ((addr <= 0x2E) || (addr == 0x3E)) + { + /* Write cmd: read the Configuration register */ + RF1AINSTR1B = (0x80 | addr); + } + else + { + /* Write cmd: read the Status register */ + RF1AINSTR1B = (0xC0 | addr); + } + + /* Read out the register value */ + regValue = RF1ADOUT1B; //auto read + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); + + return (regValue); +} + +/************************************************************************************************** + * @fn mrfiRadioInterfaceWriteReg + * + * @brief Write value to radio register. + * + * @param addr - address of register + * @param value - register value to write + * + * @return none + ************************************************************************************************** + */ + +void mrfiRadioInterfaceWriteReg(uint8_t addr, uint8_t value) +{ + mrfiRIFIState_t s; + + /* Check for valid range. 0x3E is for PATABLE access */ + MRFI_RIF_ASSERT((addr <= 0x2E) || (addr == 0x3E)); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: 'write to register' */ + RF1AINSTRB = (0x00 | addr); + + /* Wait for radio to be ready to accept the data */ + MRFI_RADIO_DATA_WRITE_WAIT(); + + /* Write the register value */ + RF1ADINB = value; /* value to be written to the radio register */ + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + +/************************************************************************************************** + * @fn mrfiRadioInterfaceWriteTxFifo + * + * @brief Write data to radio transmit FIFO. + * + * @param pData - pointer for storing write data + * @param len - length of data in bytes + * + * @return none + ************************************************************************************************** + */ + +void mrfiRadioInterfaceWriteTxFifo(uint8_t * pData, uint8_t len) +{ + mrfiRIFIState_t s; + + MRFI_RIF_ASSERT(len != 0); /* zero length is not allowed */ + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: TXFIFOWR */ + RF1AINSTRB = 0x7F; + + do + { + /* Wait for radio to be ready to accept the data */ + MRFI_RADIO_DATA_WRITE_WAIT(); + + /* Write one byte to FIFO */ + RF1ADINB = *pData; + + pData++; + len--; + + } while (len); + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + +/************************************************************************************************** + * @fn mrfiRadioInterfaceReadRxFifo + * + * @brief Read data from radio receive FIFO. + * + * @param pData - pointer for storing read data + * @param len - length of data in bytes + * + * @return none + ************************************************************************************************** + */ +uint8_t method = 2; +void mrfiRadioInterfaceReadRxFifo(uint8_t * pData, uint8_t len) +{ + mrfiRIFIState_t s; + + MRFI_RIF_ASSERT(len != 0); /* zero length is not allowed */ + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + if (method == 1) + { + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: RXFIFORD */ + RF1AINSTRB = 0xFF; + + do + { + /* dummy write */ + RF1ADINB = 0; + + /* Wait for data to be available for reading */ + MRFI_RADIO_DATA_READ_WAIT(); + + /* Read one byte from FIFO */ + *pData = RF1ADOUT0B; + + pData++; + len--; + + } while (len); + } + + if (method == 2) + { + do + { + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: SNGLRXRD */ + RF1AINSTR1B = 0xBF; + + /* Read byte from FIFO */ + *pData = RF1ADOUT1B; //auto read register + + pData++; + len--; + + } while (len); + } + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h new file mode 100755 index 0000000..ae46724 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h @@ -0,0 +1,151 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radio interface code for CC430 + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_RADIO_INTERFACE_H +#define MRFI_RADIO_INTERFACE_H + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + +/* configuration registers */ +#define IOCFG2 0x00 /* IOCFG2 - GDO2 output pin configuration */ +#define IOCFG1 0x01 /* IOCFG1 - GDO1 output pin configuration */ +#define IOCFG0 0x02 /* IOCFG1 - GDO0 output pin configuration */ +#define FIFOTHR 0x03 /* FIFOTHR - RX FIFO and TX FIFO thresholds */ +#define SYNC1 0x04 /* SYNC1 - Sync word, high byte */ +#define SYNC0 0x05 /* SYNC0 - Sync word, low byte */ +#define PKTLEN 0x06 /* PKTLEN - Packet length */ +#define PKTCTRL1 0x07 /* PKTCTRL1 - Packet automation control */ +#define PKTCTRL0 0x08 /* PKTCTRL0 - Packet automation control */ +#define ADDR 0x09 /* ADDR - Device address */ +#define CHANNR 0x0A /* CHANNR - Channel number */ +#define FSCTRL1 0x0B /* FSCTRL1 - Frequency synthesizer control */ +#define FSCTRL0 0x0C /* FSCTRL0 - Frequency synthesizer control */ +#define FREQ2 0x0D /* FREQ2 - Frequency control word, high byte */ +#define FREQ1 0x0E /* FREQ1 - Frequency control word, middle byte */ +#define FREQ0 0x0F /* FREQ0 - Frequency control word, low byte */ +#define MDMCFG4 0x10 /* MDMCFG4 - Modem configuration */ +#define MDMCFG3 0x11 /* MDMCFG3 - Modem configuration */ +#define MDMCFG2 0x12 /* MDMCFG2 - Modem configuration */ +#define MDMCFG1 0x13 /* MDMCFG1 - Modem configuration */ +#define MDMCFG0 0x14 /* MDMCFG0 - Modem configuration */ +#define DEVIATN 0x15 /* DEVIATN - Modem deviation setting */ +#define MCSM2 0x16 /* MCSM2 - Main Radio Control State Machine configuration */ +#define MCSM1 0x17 /* MCSM1 - Main Radio Control State Machine configuration */ +#define MCSM0 0x18 /* MCSM0 - Main Radio Control State Machine configuration */ +#define FOCCFG 0x19 /* FOCCFG - Frequency Offset Compensation configuration */ +#define BSCFG 0x1A /* BSCFG - Bit Synchronization configuration */ +#define AGCCTRL2 0x1B /* AGCCTRL2 - AGC control */ +#define AGCCTRL1 0x1C /* AGCCTRL1 - AGC control */ +#define AGCCTRL0 0x1D /* AGCCTRL0 - AGC control */ +#define WOREVT1 0x1E /* WOREVT1 - High byte Event0 timeout */ +#define WOREVT0 0x1F /* WOREVT0 - Low byte Event0 timeout */ +#define WORCTRL 0x20 /* WORCTRL - Wake On Radio control */ +#define FREND1 0x21 /* FREND1 - Front end RX configuration */ +#define FREND0 0x22 /* FREDN0 - Front end TX configuration */ +#define FSCAL3 0x23 /* FSCAL3 - Frequency synthesizer calibration */ +#define FSCAL2 0x24 /* FSCAL2 - Frequency synthesizer calibration */ +#define FSCAL1 0x25 /* FSCAL1 - Frequency synthesizer calibration */ +#define FSCAL0 0x26 /* FSCAL0 - Frequency synthesizer calibration */ +#define RCCTRL1 0x27 /* RCCTRL1 - RC oscillator configuration */ +#define RCCTRL0 0x28 /* RCCTRL0 - RC oscillator configuration */ +#define FSTEST 0x29 /* FSTEST - Frequency synthesizer calibration control */ +#define PTEST 0x2A /* PTEST - Production test */ +#define AGCTEST 0x2B /* AGCTEST - AGC test */ +#define TEST2 0x2C /* TEST2 - Various test settings */ +#define TEST1 0x2D /* TEST1 - Various test settings */ +#define TEST0 0x2E /* TEST0 - Various test settings */ + +/* status registers */ +#define PARTNUM 0x30 /* PARTNUM - Chip ID */ +#define VERSION 0x31 /* VERSION - Chip ID */ +#define FREQEST 0x32 /* FREQEST – Frequency Offset Estimate from demodulator */ +#define LQI 0x33 /* LQI – Demodulator estimate for Link Quality */ +#define RSSI 0x34 /* RSSI – Received signal strength indication */ +#define MARCSTATE 0x35 /* MARCSTATE – Main Radio Control State Machine state */ +#define WORTIME1 0x36 /* WORTIME1 – High byte of WOR time */ +#define WORTIME0 0x37 /* WORTIME0 – Low byte of WOR time */ +#define PKTSTATUS 0x38 /* PKTSTATUS – Current GDOx status and packet status */ +#define VCO_VC_DAC 0x39 /* VCO_VC_DAC – Current setting from PLL calibration module */ +#define TXBYTES 0x3A /* TXBYTES – Underflow and number of bytes */ +#define RXBYTES 0x3B /* RXBYTES – Overflow and number of bytes */ + +/* burst write registers */ +#define PATABLE 0x3E /* PATABLE - PA control settings table */ + +/* command strobe registers */ +#define SRES 0x30 /* SRES - Reset chip. */ +#define SFSTXON 0x31 /* SFSTXON - Enable and calibrate frequency synthesizer. */ +#define SXOFF 0x32 /* SXOFF - Turn off crystal oscillator. */ +#define SCAL 0x33 /* SCAL - Calibrate frequency synthesizer and turn it off. */ +#define SRX 0x34 /* SRX - Enable RX. Perform calibration if enabled. */ +#define STX 0x35 /* STX - Enable TX. If in RX state, only enable TX if CCA passes. + **/ +#define SIDLE 0x36 /* SIDLE - Exit RX / TX, turn off frequency synthesizer. */ +#define SRSVD 0x37 /* SRVSD - Reserved. Do not use. */ +#define SWOR 0x38 /* SWOR - Start automatic RX polling sequence (Wake-on-Radio) */ +#define SPWD 0x39 /* SPWD - Enter power down mode when CSn goes high. */ +#define SFRX 0x3A /* SFRX - Flush the RX FIFO buffer. */ +#define SFTX 0x3B /* SFTX - Flush the TX FIFO buffer. */ +#define SWORRST 0x3C /* SWORRST - Reset real time clock. */ +#define SNOP 0x3D /* SNOP - No operation. Returns status byte. */ + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void mrfiRadioInterfaceInit(void); +void mrfiRadioInterfaceWriteReg(uint8_t addr, uint8_t value); +void mrfiRadioInterfaceWriteTxFifo(uint8_t * pWriteData, uint8_t len); +void mrfiRadioInterfaceReadRxFifo(uint8_t * pReadData, uint8_t len); + +uint8_t mrfiRadioInterfaceCmdStrobe(uint8_t addr); +uint8_t mrfiRadioInterfaceReadReg(uint8_t addr); + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/smartrf/CC1101/smartrf_CC1101.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/smartrf/CC1101/smartrf_CC1101.h new file mode 100755 index 0000000..65030e5 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/smartrf/CC1101/smartrf_CC1101.h @@ -0,0 +1,168 @@ +/*************************************************************** +* SmartRF Studio(tm) Export +* +* Radio register settings specifed with C-code +* compatible #define statements. +* +***************************************************************/ + +#ifndef SMARTRF_CC1101_H +#define SMARTRF_CC1101_H + +// ISM_LF configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 433.92 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first +// received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at +// the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_EU configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 869.524963 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first +// received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at +// the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_US configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 905.998993 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first +// received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at +// the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +#define SMARTRF_RADIO_CC1101 + +#define SMARTRF_SETTING_FSCTRL1 0x08 +#define SMARTRF_SETTING_FSCTRL0 0x00 +#ifdef ISM_EU +// 869.50MHz +# define SMARTRF_SETTING_FREQ2 0x21 +# define SMARTRF_SETTING_FREQ1 0x71 +# define SMARTRF_SETTING_FREQ0 0x7A +#else +# ifdef ISM_US +// 902MHz (CHANNR=20->906MHz) +# define SMARTRF_SETTING_FREQ2 0x22 +# define SMARTRF_SETTING_FREQ1 0xB1 +# define SMARTRF_SETTING_FREQ0 0x3B +# else +# ifdef ISM_LF +// 433.92MHz +# define SMARTRF_SETTING_FREQ2 0x10 +# define SMARTRF_SETTING_FREQ1 0xB0 +# define SMARTRF_SETTING_FREQ0 0x71 +# else +# error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" +# endif // ISM_LF +# endif // ISM_US +#endif // ISM_EU +#define SMARTRF_SETTING_MDMCFG4 0x7B +#define SMARTRF_SETTING_MDMCFG3 0x83 +#define SMARTRF_SETTING_MDMCFG2 0x13 +#define SMARTRF_SETTING_MDMCFG1 0x22 +#define SMARTRF_SETTING_MDMCFG0 0xF8 +#define SMARTRF_SETTING_CHANNR 0x00 +#define SMARTRF_SETTING_DEVIATN 0x42 +#define SMARTRF_SETTING_FREND1 0xB6 +#define SMARTRF_SETTING_FREND0 0x10 +#define SMARTRF_SETTING_MCSM0 0x18 +#define SMARTRF_SETTING_FOCCFG 0x1D +#define SMARTRF_SETTING_BSCFG 0x1C +#define SMARTRF_SETTING_AGCCTRL2 0xC7 +#define SMARTRF_SETTING_AGCCTRL1 0x00 +#define SMARTRF_SETTING_AGCCTRL0 0xB2 +#define SMARTRF_SETTING_FSCAL3 0xEA +#define SMARTRF_SETTING_FSCAL2 0x2A +#define SMARTRF_SETTING_FSCAL1 0x00 +#define SMARTRF_SETTING_FSCAL0 0x1F +#define SMARTRF_SETTING_FSTEST 0x59 +#define SMARTRF_SETTING_TEST2 0x81 +#define SMARTRF_SETTING_TEST1 0x35 +#define SMARTRF_SETTING_TEST0 0x09 +#define SMARTRF_SETTING_FIFOTHR 0x47 +#define SMARTRF_SETTING_IOCFG2 0x29 +#define SMARTRF_SETTING_IOCFG0D 0x06 +#define SMARTRF_SETTING_PKTCTRL1 0x04 +#define SMARTRF_SETTING_PKTCTRL0 0x05 +#define SMARTRF_SETTING_ADDR 0x00 +#define SMARTRF_SETTING_PKTLEN 0xFF + +#endif // SMARTRF_CC1101_H diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h new file mode 100755 index 0000000..2c4aebc --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h @@ -0,0 +1,170 @@ +/*************************************************************** +* SmartRF Studio(tm) Export +* +* Radio register settings specifed with C-code +* compatible #define statements. +* +***************************************************************/ + +#ifndef SMARTRF_CC430_H +#define SMARTRF_CC430_H + +// [BM] Modified radio settings for 433MHz, 868MHz, 915MHz + +// ISM_LF configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 433.92 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first +// received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at +// the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_EU configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 869.524963 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first +// received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at +// the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_US configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 905.998993 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first +// received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at +// the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +#define SMARTRF_RADIO_CC430 + +#define SMARTRF_SETTING_FSCTRL1 0x08 +#define SMARTRF_SETTING_FSCTRL0 0x00 +#ifdef ISM_EU +// 869.50MHz +# define SMARTRF_SETTING_FREQ2 0x21 +# define SMARTRF_SETTING_FREQ1 0x71 +# define SMARTRF_SETTING_FREQ0 0x7A +#else +# ifdef ISM_US +// 902MHz (CHANNR=20->906MHz) +# define SMARTRF_SETTING_FREQ2 0x22 +# define SMARTRF_SETTING_FREQ1 0xB1 +# define SMARTRF_SETTING_FREQ0 0x3B +# else +# ifdef ISM_LF +// 433.92MHz +# define SMARTRF_SETTING_FREQ2 0x10 +# define SMARTRF_SETTING_FREQ1 0xB0 +# define SMARTRF_SETTING_FREQ0 0x71 +# else +# error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" +# endif // ISM_LF +# endif // ISM_US +#endif // ISM_EU +#define SMARTRF_SETTING_MDMCFG4 0x7B +#define SMARTRF_SETTING_MDMCFG3 0x83 +#define SMARTRF_SETTING_MDMCFG2 0x13 +#define SMARTRF_SETTING_MDMCFG1 0x22 +#define SMARTRF_SETTING_MDMCFG0 0xF8 +#define SMARTRF_SETTING_CHANNR 0x00 +#define SMARTRF_SETTING_DEVIATN 0x42 +#define SMARTRF_SETTING_FREND1 0xB6 +#define SMARTRF_SETTING_FREND0 0x10 +#define SMARTRF_SETTING_MCSM0 0x18 +#define SMARTRF_SETTING_FOCCFG 0x1D +#define SMARTRF_SETTING_BSCFG 0x1C +#define SMARTRF_SETTING_AGCCTRL2 0xC7 +#define SMARTRF_SETTING_AGCCTRL1 0x00 +#define SMARTRF_SETTING_AGCCTRL0 0xB2 +#define SMARTRF_SETTING_FSCAL3 0xEA +#define SMARTRF_SETTING_FSCAL2 0x2A +#define SMARTRF_SETTING_FSCAL1 0x00 +#define SMARTRF_SETTING_FSCAL0 0x1F +#define SMARTRF_SETTING_FSTEST 0x59 +#define SMARTRF_SETTING_TEST2 0x81 +#define SMARTRF_SETTING_TEST1 0x35 +#define SMARTRF_SETTING_TEST0 0x09 +#define SMARTRF_SETTING_FIFOTHR 0x47 +#define SMARTRF_SETTING_IOCFG2 0x29 +#define SMARTRF_SETTING_IOCFG0D 0x06 +#define SMARTRF_SETTING_PKTCTRL1 0x04 +#define SMARTRF_SETTING_PKTCTRL0 0x05 +#define SMARTRF_SETTING_ADDR 0x00 +#define SMARTRF_SETTING_PKTLEN 0xFF + +#endif // SMARTRF_CC430_H diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk.c new file mode 100755 index 0000000..526df8d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk.c @@ -0,0 +1,1112 @@ +/************************************************************************************************** +* Filename: nwk.c +* Revised: $Date: 2009-03-11 15:29:07 -0700 (Wed, 11 Mar 2009) $ +* Revision: $Revision: 19382 $ +* Author $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI network layer. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "nwk_globals.h" +#include "nwk_QMgmt.h" + +/****************************************************************************** + * MACROS + */ +/************************* NETWORK MANIFEST CONSTANT SANITY CHECKS ****************************/ +#if !defined(ACCESS_POINT) && !defined(RANGE_EXTENDER) && !defined(END_DEVICE) +# error ERROR: No SimpliciTI device type defined +#endif + +#if defined(END_DEVICE) && !defined(RX_POLLS) +# define RX_USER +#endif + +#ifndef MAX_HOPS +# define MAX_HOPS 3 +#elif MAX_HOPS > 4 +# error ERROR: MAX_HOPS must be 4 or fewer +#endif + +#ifndef MAX_APP_PAYLOAD +# error ERROR: MAX_APP_PAYLOAD must be defined +#endif + +#if (MAX_PAYLOAD < MAX_FREQ_APP_FRAME) +# error ERROR: Application payload size too small for Frequency frame +#endif + +#if (MAX_PAYLOAD < MAX_JOIN_APP_FRAME) +# error ERROR: Application payload size too small for Join frame +#endif + +#if (MAX_PAYLOAD < MAX_LINK_APP_FRAME) +# error ERROR: Application payload size too small for Link frame +#endif + +#if (MAX_PAYLOAD < MAX_MGMT_APP_FRAME) +# error ERROR: Application payload size too small for Management frame +#endif + +#if (MAX_PAYLOAD < MAX_SEC_APP_FRAME) +# error ERROR: Application payload size too small for Security frame +#endif + +#if (MAX_PAYLOAD < MAX_PING_APP_FRAME) +# error ERROR: Application payload size too small for Ping frame +#endif + +#if NWK_FREQ_TBL_SIZE < 1 +# error ERROR: NWK_FREQ_TBL_SIZE must be > 0 +#endif + +/************************* END NETWORK MANIFEST CONSTANT SANITY CHECKS ************************/ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ +#define SYS_NUM_CONNECTIONS (NUM_CONNECTIONS + 1) + +/* Increment this if the persistentContext_t structure is changed. It will help + * detect the upgrade context: any saved values will have a version with a + * lower number. + */ +#define CONNTABLEINFO_STRUCTURE_VERSION 1 + +#define SIZEOF_NV_OBJ sizeof(sPersistInfo) + +/****************************************************************************** + * TYPEDEFS + */ + +/* This structure aggregates eveything necessary to save if we want to restore + * the connection information later. + */ +typedef struct +{ + const uint8_t structureVersion; /* to dectect upgrades... */ + uint8_t numConnections; /* count includes the UUD port/link ID */ + + /* The next two are used to detect overlapping port assignments. When _sending_ a + * link frame the local port is assigned from the top down. When sending a _reply_ + * the assignment is bottom up. Overlapping assignments are rejected. That said it + * is extremely unlikely that this will ever happen. If it does the test implemented + * here is overly cautious (it will reject assignments when it needn't). But we leave + * it that way on the assumption that it will never happen anyway. + */ + uint8_t curNextLinkPort; + uint8_t curMaxReplyPort; + linkID_t nextLinkID; +#ifdef ACCESS_POINT + sfInfo_t sSandFContext; +#endif + /* Connection table entries last... */ + connInfo_t connStruct[SYS_NUM_CONNECTIONS]; +} persistentContext_t; + +/****************************************************************************** + * LOCAL VARIABLES + */ + +/* This will be overwritten if we restore the structure from NV for example. + * Note that restoring will not permit overwriting the version element as it + * is declared 'const'. + */ +static persistentContext_t sPersistInfo = {CONNTABLEINFO_STRUCTURE_VERSION}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static uint8_t map_lid2idx(linkID_t, uint8_t *); +static void initializeConnection(connInfo_t *); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_nwkInit + * + * @brief Initialize NWK conext. + * + * input parameters + * + * output parameters + * + * @return Status of operation. + */ + +smplStatus_t nwk_nwkInit(uint8_t (*f)(linkID_t)) +{ + // [BM] Added variable + uint8_t i; + + /* Truly ugly initialization because CCE won't initialize properly. Must + * skip first const element. Yuk. + */ + memset((((uint8_t *)&sPersistInfo) + 1), 0x0, (sizeof(sPersistInfo) - 1)); + /* OK. The zeroed elements are set. Now go back and do fixups... */ + + sPersistInfo.numConnections = SYS_NUM_CONNECTIONS; + sPersistInfo.curNextLinkPort = SMPL_PORT_USER_MAX; + sPersistInfo.curMaxReplyPort = PORT_BASE_NUMBER; + sPersistInfo.nextLinkID = 1; + + /* initialize globals */ + nwk_globalsInit(); + + /* initialize frame processing */ + nwk_frameInit(f); + + /* initialize queue manager */ + nwk_QInit(); + + /* initialize each network application. */ + nwk_freqInit(); + nwk_pingInit(); + nwk_joinInit(f); + nwk_mgmtInit(); + nwk_linkInit(); + nwk_securityInit(); + + // [BM] Workaround to enable stack restarting + for (i = 0; i < SYS_NUM_CONNECTIONS; ++i) + { + sPersistInfo.connStruct[i].connState = CONNSTATE_FREE; + } + + /* set up the last connection as the broadcast port mapped to the broadcast Link ID */ + if (CONNSTATE_FREE == sPersistInfo.connStruct[NUM_CONNECTIONS].connState) + { + sPersistInfo.connStruct[NUM_CONNECTIONS].connState = CONNSTATE_CONNECTED; + sPersistInfo.connStruct[NUM_CONNECTIONS].hops2target = MAX_HOPS; + sPersistInfo.connStruct[NUM_CONNECTIONS].portRx = SMPL_PORT_USER_BCAST; + sPersistInfo.connStruct[NUM_CONNECTIONS].portTx = SMPL_PORT_USER_BCAST; + sPersistInfo.connStruct[NUM_CONNECTIONS].thisLinkID = SMPL_LINKID_USER_UUD; + /* set peer address to broadcast so it is used when Application sends to the broadcast Link + *ID */ + memcpy(sPersistInfo.connStruct[NUM_CONNECTIONS].peerAddr, + nwk_getBCastAddress(), NET_ADDR_SIZE); + } + + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_getNextConnection + * + * @brief Return the next free connection structure if on is available. + * + * input parameters + * + * output parameters + * The returned structure has the Rx port number populated based on the + * free strucure found. This is the port queried when the app wants to + * do a receive. + * + * @return pointer to the new connInfo_t structure. NULL if there is + * no room in connection structure array. + */ + +connInfo_t *nwk_getNextConnection() +{ + uint8_t i; + + for (i = 0; i < SYS_NUM_CONNECTIONS; ++i) + { + if (sPersistInfo.connStruct[i].connState == CONNSTATE_CONNECTED) + { + continue; + } + break; + } + + if (SYS_NUM_CONNECTIONS == i) + { + return (connInfo_t *)0; + } + + initializeConnection(&sPersistInfo.connStruct[i]); + + return &sPersistInfo.connStruct[i]; +} + +/************************************************************************************ + * @fn initializeConnection + * + * @brief Initialize some elements of a Connection table entry. + * + * input parameters + * @param pCInfo - pointer to Connection Table entry to initialize. The file + * scope variable holding the next link ID value is also updated. + * + * output parameters + * @param pCInfo - certain elements are set to specific values. + * + * + * @return void + */ + +static void initializeConnection(connInfo_t *pCInfo) +{ + linkID_t *locLID = &sPersistInfo.nextLinkID; + uint8_t tmp; + + /* this element will be populated during the exchange with the peer. */ + pCInfo->portTx = 0; + + pCInfo->connState = CONNSTATE_CONNECTED; + pCInfo->thisLinkID = *locLID; + + /* Generate the next Link ID. This isn't foolproof. If the count wraps + * we can end up with confusing duplicates. We can protect aginst using + * one that is already in use but we can't protect against a stale Link ID + * remembered by an application that doesn't know its connection has been + * torn down. The test for 0 will hopefully never be true (indicating a wrap). + */ + (*locLID)++; + + while (!*locLID || (*locLID == SMPL_LINKID_USER_UUD) || map_lid2idx(*locLID, &tmp)) + { + (*locLID)++; + } + + return; +} + +/****************************************************************************** + * @fn nwk_freeConnection + * + * @brief Return the connection structure to the free pool. Currently + * this routine is only called when a link freame is sent and + * no reply is received so the freeing steps are pretty simple. + * But eventually this will be more complex so this place-holder + * is introduced. + * + * input parameters + * @param pCInfo - pointer to entry to be freed + * + * output parameters + * + * @return None. + */ + +void nwk_freeConnection(connInfo_t *pCInfo) +{ +#if NUM_CONNECTIONS > 0 + pCInfo->connState = CONNSTATE_FREE; +#endif +} + +/****************************************************************************** + * @fn nwk_getConnInfo + * + * @brief Return the connection info structure to which the input Link ID maps. + * + * input parameters + * @param port - port for which mapping desired + * + * output parameters + * + * @return pointer to connInfo_t structure found. NULL if no mapping + * found or entry not valid. + */ + +connInfo_t *nwk_getConnInfo(linkID_t linkID) +{ + uint8_t idx, rc; + + rc = map_lid2idx(linkID, &idx); + + return (rc && + (CONNSTATE_CONNECTED == + sPersistInfo.connStruct[idx].connState)) ? &sPersistInfo.connStruct[idx] : (connInfo_t *)0; +} + +/****************************************************************************** + * @fn nwk_isLinkDuplicate + * + * @brief Help determine if the link has already been established.. Defense + * against duplicate link frames. This file owns the data structure + * so the comparison is done here. + * + * input parameters + * @param addr - pointer to address of linker in question + * @param remotePort - remote port number provided by linker + * + * output parameters + * + * @return Returns pointer to connection entry if the address and remote Port + * match an existing entry, otherwise 0. + */ + +connInfo_t *nwk_isLinkDuplicate(uint8_t *addr, uint8_t remotePort) +{ +#if NUM_CONNECTIONS > 0 + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < NUM_CONNECTIONS; ++i, ++ptr) + { + if (CONNSTATE_CONNECTED == ptr->connState) + { + if (!(memcmp(ptr->peerAddr, addr, NET_ADDR_SIZE)) && + (ptr->portTx == remotePort)) + { + return ptr; + } + } + } +#endif + + return (connInfo_t *)NULL; +} + +/****************************************************************************** + * @fn nwk_findAddressMatch + * + * @brief Used to look for an address match in the Connection table. + * Match is based on source address in frame. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns non-zero if a match is found, otherwise 0. + */ + +uint8_t nwk_findAddressMatch(mrfiPacket_t *frame) +{ +#if NUM_CONNECTIONS > 0 + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < NUM_CONNECTIONS; ++i, ++ptr) + { + + if (CONNSTATE_CONNECTED == ptr->connState) + { + if (!(memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + return 1; + } + } + } +#endif + + return 0; +} + +#ifdef ACCESS_POINT + +/****************************************************************************** + * @fn nwk_getSFInfoPtr + * + * @brief Get pointer to store-and-forward information object kept in the + * NV object aggregate. + * + * input parameters + * + * output parameters + * + * @return Returns pointer to the store-nad-forward object. + */ + +sfInfo_t *nwk_getSFInfoPtr(void) +{ + return &sPersistInfo.sSandFContext; +} + +# if defined(AP_IS_DATA_HUB) + +/*************************************************************************************** + * @fn nwk_saveJoinedDevice + * + * @brief Save the address of a joining device on the Connection Table expecting + * a Link frame to follow. Only for when AP is a data hub. We want to + * use the space already allocated for a connection able entry instead + * of having redundant arrays for alread-joined devices in the data hub + * case. + * + * input parameters + * @param frame - pointer to frame containing address or joining device. + * + * output parameters + * + * @return Returns non-zero if this is a new device and it is saved. Returns + * 0 if device already there or there is no room in the Connection + * Table. + */ + +uint8_t nwk_saveJoinedDevice(mrfiPacket_t *frame) +{ + uint8_t i; + connInfo_t *avail = 0; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < NUM_CONNECTIONS; ++i, ++ptr) + { + if ((ptr->connState == CONNSTATE_CONNECTED) || (ptr->connState == CONNSTATE_JOINED)) + { + if (!memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + return 0; + } + } + else + { + avail = ptr; + } + } + + if (!avail) + { + return 0; + } + + avail->connState = CONNSTATE_JOINED; + memcpy(avail->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + return 1; +} + +/*********************************************************************************** + * @fn nwk_findAlreadyJoined + * + * @brief Used when AP is a data hub to look for an address match in the + * Connection table for a device that is already enterd in the joined + * state. This means that the Connection Table resource is already + * allocated so the link-listen doesn't have to do it again. Match is + * based on source address in frame. Thsi shoudl only be called from + * the Link-listen context during the link frame reply. + * + * If found the Connection Table entry is initialized as if it were + * found using the nwk_getNextConnection() method. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns pointer to Connection Table entry if match is found, otherwise + * 0. This call will only fail if the Connection Table was full when the + * device tried to join initially. + */ + +connInfo_t *nwk_findAlreadyJoined(mrfiPacket_t *frame) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < NUM_CONNECTIONS; ++i, ++ptr) + { + /* Look for an entry in the JOINED state */ + if (CONNSTATE_JOINED == ptr->connState) + { + /* Is this it? */ + if (!(memcmp(&ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + /* Yes. Initilize tabel entry and return the pointer. */ + initializeConnection(ptr); + return ptr; + } + } + } + + /* Nothing found... */ + return (connInfo_t *)NULL; +} + +# endif /* AP_IS_DATA_HUB */ +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_checkConnInfo + * + * @brief Do a sanity/validity check on the connection info + * + * input parameters + * @param ptr - pointer to a valid connection info structure to validate + * @param which - Tx or Rx port checked + * + * output parameters + * + * @return Status of operation. + */ + +smplStatus_t nwk_checkConnInfo(connInfo_t *ptr, uint8_t which) +{ + uint8_t port; + + /* make sure port isn't null and that the entry is active */ + port = (CHK_RX == which) ? ptr->portRx : ptr->portTx; + if (!port || (CONNSTATE_FREE == ptr->connState)) + { + return SMPL_BAD_PARAM; + } + + /* validate port number */ + if (port < PORT_BASE_NUMBER) + { + return SMPL_BAD_PARAM; + } + + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_isConnectionValid + * + * @brief Do a sanity/validity check on the frame target address by + * validating frame against connection info + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * @param lid - link ID of found connection + * + * @return 0 if connection specified in frame is not valid, otherwise non-zero. + */ + +uint8_t nwk_isConnectionValid(mrfiPacket_t *frame, linkID_t *lid) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + uint8_t port = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_PORT_OS); + + for (i = 0; i < SYS_NUM_CONNECTIONS; ++i, ++ptr) + { + if (CONNSTATE_CONNECTED == ptr->connState) + { + /* check port first since we're done if the port is the user bcast port. */ + if (port == ptr->portRx) + { + /* yep...ports match. */ + if ((SMPL_PORT_USER_BCAST == port) || + !(memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + uint8_t rc = 1; + + /* we're done. */ + *lid = ptr->thisLinkID; +#ifdef APP_AUTO_ACK + /* can't ack the broadcast port... */ + if (!(SMPL_PORT_USER_BCAST == port)) + { + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_ACK_REQ)) + { + /* Ack requested. Send ack now */ + nwk_sendAckReply(frame, ptr->portTx); + } + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_ACK_RPLY)) + { + /* This is a reply. Signal that it was received by resetting the + * saved transaction ID in the connection object if they match. The + * main thread is polling this value. The setting here is in the + * Rx ISR thread. + */ + if (ptr->ackTID == GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS)) + { + ptr->ackTID = 0; + } + + /* This causes the frame to be dropped. All ack frames are + * dropped. + */ + rc = 0; + } + } +#endif /* APP_AUTO_ACK */ + + /* Unconditionally kill the reply delay semaphore. This used to be done + * unconditionally in the calling routine. + */ + MRFI_PostKillSem(); + return rc; + } + } + } + } + + /* no matches */ + return 0; +} + +/****************************************************************************** + * @fn nwk_allocateLocalRxPort + * + * @brief Allocate a local port on which to receive frames from a peer. + * + * Allocation differs depending on whether the allocation is for + * a link reply frame or a link frame. In the former case we + * know the address of the peer so we can ensure allocating a + * unique port number for that address. The same port number can be + * used mulitple times for distinct peers. Allocations are done from + * the bottom of the namespace upward. + * + * If allocation is for a link frame we do not yet know the peer + * address so we must ensure the port number is unique now. + * Allocations are done from the top of the namespace downward. + * + * The two allocation methods track the extreme values used in each + * case to detect overlap, i.e., exhausted namespace. This can only + * happen if the number of connections supported is greater than the + * total namespace available. + * + * input parameters + * @param which - Sending a link frame or a link reply frame + * @param newPtr - pointer to connection info structure to be populated + * + * output parameters + * @param newPtr->portRx - element is populated with port number. + * + * @return Non-zero if port number assigned. 0 if no port available. + */ + +uint8_t nwk_allocateLocalRxPort(uint8_t which, connInfo_t *newPtr) +{ +#if NUM_CONNECTIONS > 0 + uint8_t num, i; + uint8_t marker[NUM_CONNECTIONS]; + connInfo_t *ptr = sPersistInfo.connStruct; + + memset(&marker, 0x0, sizeof(marker)); + + for (i = 0; i < NUM_CONNECTIONS; ++i, ++ptr) + { + /* Mark the port number as used unless it's a statically allocated port */ + if ((ptr != newPtr) && (CONNSTATE_CONNECTED == ptr->connState) && + (ptr->portRx <= SMPL_PORT_USER_MAX)) + { + if (LINK_SEND == which) + { + if (ptr->portRx > sPersistInfo.curNextLinkPort) + { + marker[SMPL_PORT_USER_MAX - ptr->portRx] = 1; + } + } + else if (!memcmp(ptr->peerAddr, newPtr->peerAddr, NET_ADDR_SIZE)) + { + marker[ptr->portRx - PORT_BASE_NUMBER] = 1; + } + } + } + + num = 0; + for (i = 0; i < NUM_CONNECTIONS; ++i) + { + if (!marker[i]) + { + if (LINK_REPLY == which) + { + num = PORT_BASE_NUMBER + i; + } + else + { + num = SMPL_PORT_USER_MAX - i; + } + break; + } + } + + if (LINK_REPLY == which) + { + /* if the number we have doesn't overlap the assignment of ports used + * for sending link frames, use it. + */ + if (num <= sPersistInfo.curNextLinkPort) + { + if (num > sPersistInfo.curMaxReplyPort) + { + /* remember maximum port number used */ + sPersistInfo.curMaxReplyPort = num; + } + } + else + { + /* the port number we need has already been used in the other context. It may or + * may not have been used for the same address but we don't bother to check...we + * just reject the asignment. This is the overly cautious part but is extermely + * unlikely to ever occur. + */ + num = 0; + } + } + else + { + /* if the number we have doesn't overlap the assignment of ports used + * for sending link frame replies, use it. + */ + if (num >= sPersistInfo.curMaxReplyPort) + { + if (num == sPersistInfo.curNextLinkPort) + { + sPersistInfo.curNextLinkPort--; + } + } + else + { + /* the port number we need has already been used in the other context. It may or + * may not have been used for the same address but we don't bother to check...we + * just reject the asignment. This is the overly cautious part but is extermely + * unlikely to ever occur. + */ + num = 0; + } + } + + newPtr->portRx = num; + + return num; +#else + return 0; +#endif /* NUM_CONNECTIONS > 0 */ + +} + +/******************************************************************************* + * @fn nwk_isValidReply + * + * @brief Examine a frame to see if it is a valid reply when compared with + * expected parameters. + * + * input parameters + * @param frame - pointer to frmae being examined + * @param tid - expected transaction ID in application payload + * @param infoOffset - offset to payload information containing reply hint + * @param tidOffset - offset to transaction ID in payload + * + * output parameters + * + * @return reply category: + * SMPL_NOT_REPLY: not a reply + * SMPL_MY_REPLY : a reply that matches input parameters + * SMPL_A_REPLY : a reply but does not match input parameters + */ + +uint8_t nwk_isValidReply(mrfiPacket_t *frame, uint8_t tid, uint8_t infoOffset, uint8_t tidOffset) +{ + uint8_t rc = SMPL_NOT_REPLY; + + if ((*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + infoOffset) & NWK_APP_REPLY_BIT)) + { + if ((*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + tidOffset) == tid) && + !memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + rc = SMPL_MY_REPLY; + } + else + { + rc = SMPL_A_REPLY; + } + } + + return rc; +} + +/****************************************************************************** + * @fn map_lid2idx + * + * @brief Map link ID to index into connection table. + * + * input parameters + * @param lid - Link ID to be matched + * + * output parameters + * @param idx - populated with index into connection table + * + * @return Non-zero if Link ID found and output is valid else 0. + */ + +static uint8_t map_lid2idx(linkID_t lid, uint8_t *idx) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < SYS_NUM_CONNECTIONS; ++i, ++ptr) + { + if ((CONNSTATE_CONNECTED == ptr->connState) && (ptr->thisLinkID == lid)) + { + *idx = i; + return 1; + } + } + + return 0; +} + +/****************************************************************************** + * @fn nwk_findPeer + * + * @brief Find connection entry for a peer + * + * input parameters + * @param peerAddr - address of peer + * @param peerPort - port on which this device was sending to peer. + * + * output parameters + * + * @return Pointer to matching connection table entry else 0. + */ + +connInfo_t *nwk_findPeer(addr_t *peerAddr, uint8_t peerPort) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < SYS_NUM_CONNECTIONS; ++i, ++ptr) + { + if (CONNSTATE_CONNECTED == ptr->connState) + { + if (!memcmp(peerAddr, ptr->peerAddr, NET_ADDR_SIZE)) + { + if (peerPort == ptr->portTx) + { + return ptr; + } + } + } + } + + return (connInfo_t *)NULL; +} + +/****************************************************************************** + * @fn nwk_checkAppMsgTID + * + * @brief Compare received TID to last-seen TID to decide whether the + * received message is a duplicate or we missed some. + * + * input parameters + * @param lastTID - last-seen TID + * @param appMsgTID - TID from current application payload. + * + * output parameters + * + * @return Returns zero if message with supplied TID should be discarded. + * Otherwise returns non-zero. In this case the message should be + * processed. The last-seen TID should be updated with the current + * application payload TID. + * + */ + +uint8_t nwk_checkAppMsgTID(appPTid_t lastTID, appPTid_t appMsgTID) +{ + uint8_t rc = 0; + + /* If the values are equal this is a duplicate. We're done. */ + if (lastTID != appMsgTID) + { + /* Is the new TID bigger? */ + if (appMsgTID > lastTID) + { + /* In this case the current payload is OK unless we've received a late + * (duplicate) message that occurred just before the TID wrapped. This is + * considered a duplicate and we should discard it. + */ + if (!(DUP_TID_AFTER_WRAP(lastTID, appMsgTID))) + { + rc = 1; + } + } + else + { + /* New TID is smaller. Accept the payload if this is the wrap case or we missed + * the specific wrap frame but are still within the range in which we assume + * we missed it. Otherwise is a genuine late frame so we should ignore it. + */ + if (CHECK_TID_WRAP(lastTID, appMsgTID)) + { + rc = 1; + } + } + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_getNumObjectFromMsg + * + * @brief Get a numeric object from a message buffer. Take care of + * alignment and endianess issues. + * + * input parameters + * @param src - pointer to object location in message buffer + * @param objSize - size of numeric object + * + * output parameters + * @param dest - pointer to numeric type variable receiving the object + * contains aligned number in correct endian order on return. + * + * @return void. There is no warning if there is no case for the supplied + * object size. A simple copy is then done. Alignment is + * guaranteed only for object size cases defined (and + * vacuously size 1). + * + */ + +void nwk_getNumObjectFromMsg(void *src, void *dest, uint8_t objSize) +{ + /* Take care of alignment */ + memmove(dest, src, objSize); + + /* Take care of endianess */ + switch (objSize) + { + case 2: + *((uint16_t *)dest) = ntohs(*((uint16_t *)dest)); + break; + + case 4: + *((uint32_t *)dest) = ntohl(*((uint32_t *)dest)); + break; + } + + return; +} + +/****************************************************************************** + * @fn nwk_putNumObjectIntoMsg + * + * @brief Put a numeric object into a message buffer. Take care of + * alignment and endianess issues. + * + * input parameters + * @param src - pointer to numeric type variable providing the object + * @param objSize - size of numeric object. Fuction works for object size 1. + * + * output parameters + * @param dest - pointer to object location in message buffer where the + * correct endian order representation will be placed. + * + * @return void. There is no warning if there is no case for the supplied + * object size. A simple copy is then done. + * + */ + +void nwk_putNumObjectIntoMsg(void *src, void *dest, uint8_t objSize) +{ + + uint8_t *ptr; + uint16_t u16; + uint32_t u32; + + /* Take care of endianess */ + switch (objSize) + { + case 1: + ptr = (uint8_t *)src; + break; + + case 2: + u16 = htons(*((uint16_t *)src)); + ptr = (uint8_t *)&u16; + break; + + case 4: + u32 = htonl(*((uint32_t *)src)); + ptr = (uint8_t *)&u32; + break; + + default: + ptr = (uint8_t *)src; + break; + } + + /* Take care of alignment */ + memmove(dest, ptr, objSize); + + return; +} + +/****************************************************************************** + * @fn nwk_NVObj + * + * @brief GET and SET support for NV object (connection context). + * + * input parameters + * @param action - GET or SET + * @param val - (GET/SET) pointer to NV IOCTL object. + * (SET) NV length and version values to be used for sanity + * checks. + * + * output parameters + * @param val - (GET) Version number of NV object, size of NV object and + * pointer to the connection context memory. + * - (SET) Pointer to the connection context memory. + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Object version or size do not conform on a SET call + * or illegal action specified. + */ + +smplStatus_t nwk_NVObj(ioctlAction_t action, ioctlNVObj_t *val) +{ +#ifdef NVOBJECT_SUPPORT + smplStatus_t rc = SMPL_SUCCESS; + + if (IOCTL_ACT_GET == action) + { + /* Populate helper objects */ + val->objLen = SIZEOF_NV_OBJ; + val->objVersion = sPersistInfo.structureVersion; + /* Set pointer to connection context if address of pointer is not null */ + if (val->objPtr) + { + *(val->objPtr) = (uint8_t *)&sPersistInfo; + } + } + else + { + rc = SMPL_BAD_PARAM; + } + + return rc; +#else /* NVOBJECT_SUPPORT */ + return SMPL_BAD_PARAM; +#endif +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk.h new file mode 100755 index 0000000..4fffc01 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk.h @@ -0,0 +1,164 @@ +/************************************************************************************************** +* Filename: nwk.h +* Revised: $Date: 2008-12-01 11:58:33 -0800 (Mon, 01 Dec 2008) $ +* Revision: $Revision: 18551 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI network layer. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_H +#define NWK_H + + +/* well known ports*/ +#define SMPL_PORT_PING 0x01 +#define SMPL_PORT_LINK 0x02 +#define SMPL_PORT_JOIN 0x03 +#define SMPL_PORT_SECURITY 0x04 +#define SMPL_PORT_FREQ 0x05 +#define SMPL_PORT_MGMT 0x06 + +#define SMPL_PORT_NWK_BCAST 0x1F +#define SMPL_PORT_USER_BCAST 0x3F + +/* Unconnected User Datagram Link ID */ +#define SMPL_LINKID_USER_UUD ((linkID_t) ~0) + +#define PORT_BASE_NUMBER 0x20 + +/* Reserve the top of the User port namespace below the broadcast + * address for static allocation. + */ +#define PORT_USER_STATIC_NUM 1 +#define SMPL_PORT_STATIC_MAX 0x3E +#define SMPL_PORT_USER_MAX (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM) + + +/* to check connection info sanity */ +#define CHK_RX 0 +#define CHK_TX 1 + +/* return types for validating a reply frame */ +#define SMPL_MY_REPLY 0 +#define SMPL_A_REPLY 1 +#define SMPL_NOT_REPLY 2 + +/* when allocating local Rx port it depends on whether the allocation + * is being done as a result of a link or a link reply + */ +#define LINK_SEND 1 +#define LINK_REPLY 2 + +#define CONNSTATE_FREE (0x00) +#define CONNSTATE_JOINED (0x01) +#define CONNSTATE_CONNECTED (0x02) + +typedef struct +{ + volatile uint8_t connState; + uint8_t hops2target; +#ifdef APP_AUTO_ACK + volatile uint8_t ackTID; +#endif + uint8_t peerAddr[NET_ADDR_SIZE]; + rxMetrics_t sigInfo; + uint8_t portRx; + uint8_t portTx; + linkID_t thisLinkID; +#ifdef SMPL_SECURE + uint32_t connTxCTR; + uint32_t connRxCTR; +#endif +} connInfo_t; + +/**************************************************************************************** + * Application Payload TID support + * + * Sometimes the receiving application uses a payload TID to determine if either it + * missed frames (received TID > (last-seen TID+1)) or is seeing a duplicate (received + * TID <= last-seen TID). Typically the TID simply increments for each successive frame. + * But when the count wraps there is a problem. The received TID should always be one + * more than the last TID. If it's equal, it's a duplicate. If it's less it's late. If + * it's one more it's the one we expect. If it's more than 1 more then we missed frames. + * Simple increments work for the wrap arithmetically. If the received TID is 0 and the last + * seen ID is the biggest number in the world -- 0xFF... depending on type we can detect + * the wrap. But if the receiver misses the 0 TID value for any reason or the biggest + * number in the world TID is missed then susbequent testing for missed or duplicate + * frames can get confused. We resolve this by allowing some leeway in the wrap testing. + * this testing is assisted by the following macros. Setting TID_VALID_WINDOW to 0 + * will enforce a no leniency policy. In this case you'd better not miss either the + * biggest number or the 0. The CHECK_TID_WRAP macro is only needed if the received + * TID is less than the last-seen TID. The DUP_TID_AFTER_WRAP macro is only needed if the + * received TID is greater than 1 more than the last-seen TID. + ***************************************************************************************/ +#define MAX_APT ((appPTid_t) ~0) /* max value of application payload TID type */ +#define TID_VALID_WINDOW 2 /* window around max and 0 */ + +#define CHECK_TID_WRAP(lastTID, newTID) ((lastTID >= (MAX_APT - TID_VALID_WINDOW)) && \ + (newTID <= TID_VALID_WINDOW) \ + ) +#define DUP_TID_AFTER_WRAP(lastTID, newTID) ((newTID >= (MAX_APT - TID_VALID_WINDOW)) && \ + (lastTID <= TID_VALID_WINDOW) \ + ) + +/* prototypes */ +smplStatus_t nwk_nwkInit(uint8_t (*)(linkID_t)); +connInfo_t *nwk_getNextConnection(void); +void nwk_freeConnection(connInfo_t *); +uint8_t nwk_getNextClientPort(void); +connInfo_t *nwk_getConnInfo(linkID_t port); + +connInfo_t *nwk_isLinkDuplicate(uint8_t *, uint8_t); +uint8_t nwk_findAddressMatch(mrfiPacket_t *); + +smplStatus_t nwk_checkConnInfo(connInfo_t *, uint8_t); +uint8_t nwk_isConnectionValid(mrfiPacket_t *, linkID_t *); + +uint8_t nwk_allocateLocalRxPort(uint8_t, connInfo_t *); +uint8_t nwk_isValidReply(mrfiPacket_t *, uint8_t, uint8_t, uint8_t); +connInfo_t *nwk_findPeer(addr_t *, uint8_t); +smplStatus_t nwk_NVObj(ioctlAction_t, ioctlNVObj_t *); + + +uint8_t nwk_checkAppMsgTID(appPTid_t, appPTid_t); +void nwk_getNumObjectFromMsg(void *, void *, uint8_t); +void nwk_putNumObjectIntoMsg(void *, void *, uint8_t); +#ifdef ACCESS_POINT +sfInfo_t *nwk_getSFInfoPtr(void); + +# ifdef AP_IS_DATA_HUB +uint8_t nwk_saveJoinedDevice(mrfiPacket_t *); +connInfo_t *nwk_findAlreadyJoined(mrfiPacket_t *); + +# endif +#endif + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.c new file mode 100755 index 0000000..721cad7 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.c @@ -0,0 +1,422 @@ +/************************************************************************************************** +* Filename: nwk_QMgmt.c +* Revised: $Date: 2009-03-10 17:01:56 -0700 (Tue, 10 Mar 2009) $ +* Revision: $Revision: 19372 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI input and output frame queues +* +* Copyright 2007-2008 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk.h" +#include "nwk_frame.h" +#include "nwk_QMgmt.h" +#include "nwk_mgmt.h" /* need offsets for poll frames */ + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +#if SIZE_INFRAME_Q > 0 +static frameInfo_t sInFrameQ[SIZE_INFRAME_Q]; +#else +static frameInfo_t *sInFrameQ = NULL; +#endif /* SIZE_INFRAME_Q > 0 */ + +static frameInfo_t sOutFrameQ[SIZE_OUTFRAME_Q]; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_QInit + * + * @brief Initialize the input and output frame queues to hold no packets. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_QInit(void) +{ +#if SIZE_INFRAME_Q > 0 + memset(sInFrameQ, 0, sizeof(sInFrameQ)); +#endif // SIZE_INFRAME_Q > 0 + memset(sOutFrameQ, 0, sizeof(sOutFrameQ)); +} + +/****************************************************************************** + * @fn nwk_QfindSlot + * + * @brief Finds a slot to use to retrieve the frame from the radio. It + * uses a LRU cast-out scheme. It is possible that this routine + * finds no slot. This can happen if the queue is of size 1 or 2 + * and the Rx interrupt occurs during a retrieval call from an + * application. There are meta-states for frames as the application + * looks for the oldest frame on the port being requested. + * + * This routine is running in interrupt context. + * + * input parameters + * @param which - INQ or OUTQ to search + * + * output parameters + * + * @return Pointer to oldest available frame in the queue + */ + +frameInfo_t *nwk_QfindSlot(uint8_t which) +{ + frameInfo_t *pFI, *oldest = 0, *newFI = 0; + uint8_t i, num, newOrder = 0, orderTest; + + if (INQ == which) + { + pFI = sInFrameQ; + num = SIZE_INFRAME_Q; + } + else + { + pFI = sOutFrameQ; + num = SIZE_OUTFRAME_Q; + } + + orderTest = num + 1; + + for (i = 0; i < num; ++i, ++pFI) + { + /* if frame is available it's a candidate. */ + if (pFI->fi_usage != FI_AVAILABLE) + { + if (INQ == which) /* TODO: do cast-out for Tx as well */ + { + + /* need to know the number of occupied slots so we know the age value + * for the unoccupied slot (if there is one). + */ + newOrder++; + + /* make sure nwk_retrieveFrame() is not processing this frame */ + if (FI_INUSE_TRANSITION == pFI->fi_usage) + { + continue; + } + /* is this frame older than any we've seen? */ + if (orderTest > pFI->orderStamp) + { + /* yes. */ + oldest = pFI; + orderTest = pFI->orderStamp; + } + } + } + else + { + if (OUTQ == which) /* TODO: do cast-out for Tx as well */ + { + return pFI; + } + newFI = pFI; + } + } + + /* did we find anything? */ + if (!newFI) + { + /* queue was full. cast-out happens here...unless... */ + if (!oldest) + { + /* This can happen if the queue is only of size 1 or 2 and all + * the frames are in transition when the Rx interrupt occurs. + */ + return (frameInfo_t *)0; + } + newFI = oldest; + nwk_QadjustOrder(which, newFI->orderStamp); + newFI->orderStamp = i; + } + else + { + /* mark the available slot. */ + newFI->orderStamp = ++newOrder; + } + + return newFI; +} + +/****************************************************************************** + * @fn nwk_QadjustOrder + * + * @brief Adjusts the age of everyone in the queue newer than the frame + * being removed. + * + * input parameters + * @param which - INQ or OUTQ to adjust + * @param stamp - value of frame being removed + * + * output parameters + * + * @return void + */ + +void nwk_QadjustOrder(uint8_t which, uint8_t stamp) +{ + frameInfo_t *pFI; + uint8_t i, num; + bspIState_t intState; + + if (INQ == which) + { + pFI = sInFrameQ; + num = SIZE_INFRAME_Q; + } + else + { + /* pFI = sOutFrameQ; + * num = SIZE_OUTFRAME_Q; */ + return; + } + + BSP_ENTER_CRITICAL_SECTION(intState); + + for (i = 0; i < num; ++i, ++pFI) + { + if ((pFI->fi_usage != FI_AVAILABLE) && (pFI->orderStamp > stamp)) + { + pFI->orderStamp--; + } + } + + BSP_EXIT_CRITICAL_SECTION(intState); + + return; +} + +/****************************************************************************** + * @fn nwk_QfindOldest + * + * @brief Look through frame queue and find the oldest available frame + * in the context in question. Supports connection-based (user), + * non-connection based (NWK applications), and the special case + * of store-and-forward. + * + * input parameters + * @param which - INQ or OUTQ to adjust + * @param rcvContext - context information for finding the oldest + * @param usage - normal usage or store-and-forward usage + * + * output parameters + * + * @return Pointer to frame that is the oldsest on the requested port, or + * 0 if there are none. + */ + +frameInfo_t *nwk_QfindOldest(uint8_t which, rcvContext_t *rcv, uint8_t fi_usage) +{ + uint8_t i, oldest, num, port; + uint8_t uType, addr12Compare; + bspIState_t intState; + frameInfo_t *fPtr = 0, *wPtr; + connInfo_t *pCInfo = 0; + uint8_t *pAddr1, *pAddr2, *pAddr3 = 0; + + if (INQ == which) + { + wPtr = sInFrameQ; + num = SIZE_INFRAME_Q; + oldest = SIZE_INFRAME_Q + 1; + } + else + { + /* pFI = sOutFrameQ; + * num = SIZE_OUTFRAME_Q; */ + return 0; + } + + if (RCV_APP_LID == rcv->type) + { + pCInfo = nwk_getConnInfo(rcv->t.lid); + if (!pCInfo) + { + return (frameInfo_t *)0; + } + port = pCInfo->portRx; + pAddr2 = pCInfo->peerAddr; + } + else if (RCV_NWK_PORT == rcv->type) + { + port = rcv->t.port; + } +#ifdef ACCESS_POINT + else if (RCV_RAW_POLL_FRAME == rcv->type) + { + port = *(MRFI_P_PAYLOAD(rcv->t.pkt) + F_APP_PAYLOAD_OS + M_POLL_PORT_OS); + pAddr2 = MRFI_P_SRC_ADDR(rcv->t.pkt); + pAddr3 = MRFI_P_PAYLOAD(rcv->t.pkt) + F_APP_PAYLOAD_OS + M_POLL_ADDR_OS; + } +#endif + else + { + return (frameInfo_t *)0; + } + + uType = (USAGE_NORMAL == fi_usage) ? FI_INUSE_UNTIL_DEL : FI_INUSE_UNTIL_FWD; + + for (i = 0; i < num; ++i, ++wPtr) + { + + BSP_ENTER_CRITICAL_SECTION(intState); /* protect the frame states */ + + /* only check entries in use and waiting for this port */ + if (uType == wPtr->fi_usage) + { + wPtr->fi_usage = FI_INUSE_TRANSITION; + + BSP_EXIT_CRITICAL_SECTION(intState); /* release hold */ + /* message sent to this device? */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&wPtr->mrfiPkt), F_PORT_OS) == port) + { + /* Port matches. If the port of interest is a NWK applicaiton we're a + * match...the NWK applications are not connection-based. If it is a + * NWK application we need to check the source address for disambiguation. + * Also need to check source address if it's a raw frame lookup (S&F frame) + */ + if (RCV_APP_LID == rcv->type) + { + if (SMPL_PORT_USER_BCAST == port) + { + /* guarantee a match... */ + pAddr1 = pCInfo->peerAddr; + } + else + { + pAddr1 = MRFI_P_SRC_ADDR(&wPtr->mrfiPkt); + } + } +#ifdef ACCESS_POINT + else if (RCV_RAW_POLL_FRAME == rcv->type) + { + pAddr1 = MRFI_P_DST_ADDR(&wPtr->mrfiPkt); + } +#endif + + addr12Compare = memcmp(pAddr1, pAddr2, NET_ADDR_SIZE); + if ((RCV_NWK_PORT == rcv->type) || + (!pAddr3 && !addr12Compare) || + (pAddr3 && !memcmp(pAddr3, MRFI_P_SRC_ADDR(&wPtr->mrfiPkt), NET_ADDR_SIZE)) + ) + { + if (wPtr->orderStamp < oldest) + { + if (fPtr) + { + /* restore previous oldest one */ + fPtr->fi_usage = uType; + } + oldest = wPtr->orderStamp; + fPtr = wPtr; + continue; + } + else + { + /* not oldest. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + /* not a match. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + /* wrong port. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + BSP_EXIT_CRITICAL_SECTION(intState); + } + } + + return fPtr; +} + +/****************************************************************************** + * @fn nwk_getQ + * + * @brief Get location of teh specified frame queue. + * + * input parameters + * @param which - INQ or OUTQ to get + * + * output parameters + * + * @return Pointer to frame queue + */ + +frameInfo_t *nwk_getQ(uint8_t which) +{ + return (INQ == which) ? sInFrameQ : sOutFrameQ; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.h new file mode 100755 index 0000000..c66e141 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.h @@ -0,0 +1,54 @@ +/************************************************************************************************** +* Filename: nwk_QMgmt.h +* Revised: $Date: 2009-01-17 15:14:16 -0800 (Sat, 17 Jan 2009) $ +* Revision: $Revision: 18788 $ +* Author: $Author: rlord $ +* +* Description: This header file supports the SimpliciTI input and output frame queues. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_QMGMT_H +#define NWK_QMGMT_H + + +#define INQ 1 +#define OUTQ 2 + +#define USAGE_NORMAL 1 +#define USAGE_FWD 2 + +/* prototypes */ +void nwk_QInit(void); + +frameInfo_t *nwk_QfindSlot(uint8_t); +void nwk_QadjustOrder(uint8_t, uint8_t); +frameInfo_t *nwk_QfindOldest(uint8_t, rcvContext_t *, uint8_t); +frameInfo_t *nwk_getQ(uint8_t); + +#endif /* NWK_QMGMT_H */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_api.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_api.c new file mode 100755 index 0000000..caa6093 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_api.c @@ -0,0 +1,876 @@ +/************************************************************************************************** +* Filename: nwk_api.c +* Revised: $Date: 2009-01-28 18:27:38 -0800 (Wed, 28 Jan 2009) $ +* Revision: $Revision: 18875 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI appliction layer API. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "mrfi.h" +#include "nwk_globals.h" +#include "nwk_freq.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/* These defines are in support an application listening for a link frame to + * terminate after some amount of time. The intention is that this guard be + * the exception. The intention of the SimpliciTI design is that the + * temporal contiguity between the listen and the reception of the link frame + * from the peer be very tight. The SMPL_LinkListen() should be termninated + * by the reception of the link frame. But in case it does not receive the frame + * the support below allows intervention by the application. + */ + +/* The intention is for user to modify just the following single value */ +#define LINKLISTEN_MILLISECONDS_2_WAIT (5000) + +#define LINKLISTEN_POLL_PERIOD_MS (10) +#define LINKLISTEN_POLL_COUNT ((LINKLISTEN_MILLISECONDS_2_WAIT) / \ + (LINKLISTEN_POLL_PERIOD_MS)) + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +// [BM] Workaround to enable multiple stack restarts +// static uint8_t sInit_done = 0; +uint8_t sInit_done = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static uint8_t ioctlPreInitAccessIsOK(ioctlObject_t); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/*********************************************************************************** + * @fn SMPL_Init + * + * @brief Initialize the SimpliciTI stack. + * + * input parameters + * @param f - Pointer to call back function. Function called by NWK when + * user application frame received. The callback is done in the + * ISR thread. Argument is Link ID associated with frame. Function + * returns 0 if frame is to be kept by NWK, otherwise 1. Frame + * should be kept if application will do a SMPL_Receive() in the + * user thread (recommended). Pointer may be NULL. + * + * output parameters + * + * @return Status of operation: + * SMPL_SUCCESS + * SMPL_NO_JOIN No Join reply. AP possibly not yet up. + * SMPL_NO_CHANNEL Only if Frequency Agility enabled. Channel scan + * failed. AP possibly not yet up. + */ + +smplStatus_t SMPL_Init(uint8_t (*f)(linkID_t)) +{ + smplStatus_t rc; + + if (!sInit_done) + { + /* set up radio. */ + MRFI_Init(); + + /* initialize network */ + if ((rc = nwk_nwkInit(f)) != SMPL_SUCCESS) + { + return rc; + } + + MRFI_WakeUp(); +#if defined(FREQUENCY_AGILITY) + { + freqEntry_t chan; + + chan.logicalChan = 0; + /* ok to set default channel explicitly now that MRFI initialized. */ + nwk_setChannel(&chan); + } +#endif + /* don't turn Rx on if we're an end device that isn't always on. */ +#if !defined(END_DEVICE) + MRFI_RxOn(); +#endif + +#if defined(END_DEVICE) + /* All except End Devices are in promiscuous mode */ + MRFI_SetRxAddrFilter((uint8_t *)nwk_getMyAddress()); + MRFI_EnableRxAddrFilter(); +#endif + } + sInit_done = 1; + + /* Join. if no AP or Join fails that status is returned. */ + rc = nwk_join(); + + return rc; +} + +/****************************************************************************** + * @fn SMPL_LinkListen + * + * @brief Listen for a link frame from a 'client' device. + * + * input parameters + * + * output parameters + * @param linkID - pointer to Link ID to be used by application to + * read and write to the linked peer. + * + * @return status of operation. + * SMPL_SUCCESS + * SMPL_TIMEOUT No link frame received during listen interval. + * Interval set in #defines above. linkID not valid. + * + */ + +smplStatus_t SMPL_LinkListen(linkID_t *linkID) +{ + uint8_t radioState = MRFI_GetRadioState(); + uint16_t i; + linkID_t locLinkID; + + /* Set the context. We want to reject any link frames received if + * we're not listening. For example if we're an AP we are in + * promiscuous mode and we'll see any broadcast link frames. + */ + nwk_setListenContext(LINK_LISTEN_ON); + + NWK_CHECK_FOR_SETRX(radioState); + + for (i = 0; i < LINKLISTEN_POLL_COUNT; ++i) + { + /* check the semaphore. local port is assigned when the reply is sent. */ + if ((locLinkID = nwk_getLocalLinkID())) + { + break; + } + NWK_DELAY(LINKLISTEN_POLL_PERIOD_MS); + } + + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + /* If the listen is terminated without hearing a message and setting a + * link ID the listen context must be explicitly turned off. + */ + if (!(locLinkID)) + { + nwk_setListenContext(LINK_LISTEN_OFF); + return SMPL_TIMEOUT; + } + + *linkID = locLinkID; + + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn SMPL_Send + * + * @brief Send a message to a peer application. Old API kept for + * backward compatibility. Calls the new SMPL_SendOpt() with + * no options. + * + * input parameters + * @param lid - Link ID (port) from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * + * output parameters + * + * @return Status of operation. On a filaure the frame buffer is discarded + * and the Send call must be redone by the app. + * SMPL_SUCCESS + * SMPL_BAD_PARAM No valid Connection Table entry for Link ID + * Data in Connection Table entry bad + * No message or message too long + * SMPL_NOMEM No room in output frame queue + * SMPL_TX_CCA_FAIL CCA failure. + */ + +smplStatus_t SMPL_Send(linkID_t lid, uint8_t *msg, uint8_t len) +{ + return SMPL_SendOpt(lid, msg, len, SMPL_TXOPTION_NONE); +} + +/****************************************************************************** + * @fn SMPL_SendOpt + * + * @brief Send a message to a peer application. + * + * input parameters + * @param lid - Link ID (port) from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param options - Transmit options (bit map) + * + * output parameters + * + * @return Status of operation. On a filaure the frame buffer is discarded + * and the Send call must be redone by the app. + * SMPL_SUCCESS + * SMPL_BAD_PARAM No valid Connection Table entry for Link ID + * Data in Connection Table entry bad + * No message or message too long + * SMPL_NOMEM No room in output frame queue + * SMPL_TX_CCA_FAIL CCA failure. + * SMPL_NO_ACK If application auto acknowledgement enabled + * and no acknowledgement is received + */ + +smplStatus_t SMPL_SendOpt(linkID_t lid, uint8_t *msg, uint8_t len, txOpt_t options) +{ + frameInfo_t *pFrameInfo; + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + uint8_t radioState = MRFI_GetRadioState(); + uint8_t ackreq = 0; + +#if defined(ACCESS_POINT) + uint8_t loc; +#endif + + /* we have the connection info for this Link ID. make sure it is valid. */ + if (!pCInfo || ((rc = nwk_checkConnInfo(pCInfo, CHK_TX)) != SMPL_SUCCESS)) + { + return rc; + } + + /* parameter sanity check... */ + if (!msg || (len > MAX_APP_PAYLOAD)) + { + return rc; + } + + /* Build an outgoing message frame destined for the port from the + * connection info using the destination address also from the + * connection info. + */ + if (SMPL_TXOPTION_NONE == options) + { + pFrameInfo = nwk_buildFrame(pCInfo->portTx, msg, len, pCInfo->hops2target); + } +#if defined(APP_AUTO_ACK) + else if (options & SMPL_TXOPTION_ACKREQ) + { + if (SMPL_LINKID_USER_UUD != lid) + { + pFrameInfo = nwk_buildAckReqFrame(pCInfo->portTx, msg, len, pCInfo->hops2target, + &pCInfo->ackTID); + ackreq = 1; + } + else + { + /* can't request an ack on the UUD link ID */ + return SMPL_BAD_PARAM; + } + } +#endif /* APP_AUTO_ACK */ + else + { + return SMPL_BAD_PARAM; + } + + if (!pFrameInfo) + { + return SMPL_NOMEM; + } + memcpy(MRFI_P_DST_ADDR(&pFrameInfo->mrfiPkt), pCInfo->peerAddr, NET_ADDR_SIZE); + +#if defined(SMPL_SECURE) + { + uint32_t *pUL = 0; + + if (pCInfo->thisLinkID != SMPL_LINKID_USER_UUD) + { + pUL = &pCInfo->connTxCTR; + } + nwk_setSecureFrame(&pFrameInfo->mrfiPkt, len, pUL); + } +#endif /* SMPL_SECURE */ + +#if defined(ACCESS_POINT) + + /* If we are an AP trying to send to a polling device, don't do it. + * See if the target is a store-and-forward client. + */ + if (nwk_isSandFClient(MRFI_P_DST_ADDR(&pFrameInfo->mrfiPkt), &loc)) + { + pFrameInfo->fi_usage = FI_INUSE_UNTIL_FWD; + return SMPL_SUCCESS; + } + else +#endif /* ACCESS_POINT */ + { + rc = nwk_sendFrame(pFrameInfo, MRFI_TX_TYPE_CCA); + } + +#if !defined(APP_AUTO_ACK) + /* save a little code space with this #if */ + (void) ackreq; /* keep compiler happy */ + return rc; +#else + /* we're done if the send failed or no ack requested. */ + if (SMPL_SUCCESS != rc || !ackreq) + { + return rc; + } + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + { + bspIState_t intState; + + /* If the saved TID hasn't been reset then we never got the ack. */ + BSP_ENTER_CRITICAL_SECTION(intState); + if (pCInfo->ackTID) + { + pCInfo->ackTID = 0; + rc = SMPL_NO_ACK; + } + BSP_EXIT_CRITICAL_SECTION(intState); + } + + return rc; +#endif /* APP_AUTO_ACK */ +} + +/************************************************************************************** + * @fn SMPL_Receive + * + * @brief Receive a message from a peer application. + * + * input parameters + * @param lid - Link ID (port) from application + * + * + * output parameters + * @param msg - pointer to where received message should be copied. + * buffer should be of size == MAX_APP_PAYLOAD + * @param len - pointer to receive length of received message + * + * @return Status of operation. + * Caller should not use the value returned in 'len' to decide + * whether there is a frame or not. It could be useful to the + * Caller to distinguish between no frame and a frame with no data. + * For example, in the polling case a frame with no application payload + * is the way the AP conveys that there are no frames waiting. + * + * SMPL_SUCCESS + * + * SMPL_BAD_PARAM No valid Connection Table entry for Link ID + * Data in Connection Table entry bad + * SMPL_NO_FRAME No frame received. + * SMPL_NO_PAYLOAD Frame received with no payload (not necessarily + * an error and could be deduced by application + * because the returned length will be 0) + * + * Polling device only: + * + * SMPL_TIMEOUT No response from Access Point + * SMPL_NO_AP_ADDRESS Access Point address unknown + * SMPL_TX_CCA_FAIL Could not send poll frame + * SMPL_NOMEM No memory in output frame queue + * SMPL_NO_CHANNEL Frequency Agility enabled and could not find channel + */ + +smplStatus_t SMPL_Receive(linkID_t lid, uint8_t *msg, uint8_t *len) +{ + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + rcvContext_t rcv; + + if (!pCInfo || ((rc = nwk_checkConnInfo(pCInfo, CHK_RX)) != SMPL_SUCCESS)) + { + return rc; + } + + rcv.type = RCV_APP_LID; + rcv.t.lid = lid; + +#if defined(RX_POLLS) + { + uint8_t numChans = 1; +# if defined(FREQUENCY_AGILITY) + freqEntry_t chans[NWK_FREQ_TBL_SIZE]; + uint8_t scannedB4 = 0; +# endif + + do + { + uint8_t radioState = MRFI_GetRadioState(); + + /* I'm polling. Do the poll to stimulate the sending of a frame. If the + * frame has application length of 0 it means there were no frames. If + * no reply is received infer that the channel is changed. We then need + * to scan and then retry the poll on each channel returned. + */ + if (SMPL_SUCCESS != (rc = nwk_poll(pCInfo->portRx, pCInfo->peerAddr))) + { + /* for some reason couldn't send the poll out. */ + return rc; + } + + /* do this before code block below which may reset it. */ + numChans--; + + /* Wait until there's a frame. if the len is 0 then return SMPL_NO_FRAME + * to the caller. In the poll case the AP always sends something. + */ + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + /* TODO: deal with pending */ + rc = nwk_retrieveFrame(&rcv, msg, len, 0, 0); + +# if defined(FREQUENCY_AGILITY) + if (SMPL_SUCCESS == rc) + { + /* we received something... */ + return (*len) ? SMPL_SUCCESS : SMPL_NO_PAYLOAD; + } + + /* No reply. scan for other channel(s) if we haven't already. Then set + * one and try again. + */ + if (!scannedB4) + { + numChans = nwk_scanForChannels(chans); + scannedB4 = 1; + } + if (numChans) + { + nwk_setChannel(&chans[numChans - 1]); + } +# else /* FREQUENCY_AGILITY */ + return (*len) ? rc : ((SMPL_SUCCESS == rc) ? SMPL_NO_PAYLOAD : SMPL_TIMEOUT); +# endif + } while (numChans); + } + +# if defined(FREQUENCY_AGILITY) + return SMPL_NO_CHANNEL; +# endif + +#else /* RX_POLLS */ + return nwk_retrieveFrame(&rcv, msg, len, 0, 0); +#endif /* RX_POLLS */ +} + +/****************************************************************************** + * @fn SMPL_Link + * + * @brief Link to a peer. + * + * input parameters + * + * output parameters + * @param lid - pointer to where we should write the link ID to which the + * application will read and write. + * + * @return Status of operation. + * SMPL_SUCCESS + * SMPL_NOMEM No room to allocate local Rx port, no more + * room in Connection Table, or no room in + * output frame queue. + * SMPL_NO_LINK No reply frame during wait window. + * SMPL_TX_CCA_FAIL Could not send Link frame. + */ + +smplStatus_t SMPL_Link(linkID_t *lid) +{ + return nwk_link(lid); +} + +#if defined(EXTENDED_API) + +/************************************************************************************** + * @fn SMPL_Unlink + * + * @brief Tear down connection to a peer. + * + * input parameters + * @param lid - Link ID whose connection is to be terminated. + * + * output parameters + * + * @return Status of operation. The Connection Table entry for the Link ID + * is always freed successfuly. The returned status value is the + * status of the _peer's_ connection tear-down as a result of the + * message sent here. + * SMPL_SUCCESS Local and remote connection destroyed. + * SMPL_BAD_PARAM No local connection table entry for this Link ID + * SMPL_TIMEOUT No reply from peer. + * SMPL_NO_PEER_UNLINK Peer did not have a Connection Table entry for me. + */ + +smplStatus_t SMPL_Unlink(linkID_t lid) +{ + return nwk_unlink(lid); +} + +/************************************************************************************** + * @fn SMPL_Ping + * + * @brief Ping a peer. Synchronous call. Although a link ID is used it is the + * NWK Ping application that is pinged, not the peer of this Link ID. The + * peer is not expected to be the responder to the frame sent from here. + * This API is a proxy for a real ping since the application doesn't + * have direct access to SimpliciTI device addresses. Kind of hokey but a + * useful keep-alive mechanism without having to support it with + * user application service. + * + * input parameters + * @param lid - The link ID whose peer device address is used to direct the NWK Ping + * + * output parameters + * + * @return Status of operation. + */ + +smplStatus_t SMPL_Ping(linkID_t lid) +{ + return nwk_ping(lid); +} + +/************************************************************************************** + * @fn SMPL_Commission + * + * @brief Commission a connection. + * + * input parameters + * @param peerAddr - Pointer to address of the peer for this connection + * @param locPort - Port on which to listen for messages from the peer + * @param rmtPort - Port on which to send messages to the peer. + * @param lid - Pointer to Link ID object. If content of location is + * non-zero on input the value is placed in the Connection + * object. + * + * output parameters + * @param lid - Pointer to Link ID object. If content of location is zero + * on input the value in the Connection object is stored there. + * + * @return SMPL_SUCCESS + * SMPL_NOMEM - No room left in Connection table. + * SMPL_BAD_PARAM - A pointer to a Link object was not supplied. + */ + +smplStatus_t SMPL_Commission(addr_t *peerAddr, uint8_t locPort, uint8_t rmtPort, linkID_t *lid) +{ + connInfo_t *pCInfo = nwk_getNextConnection(); + smplStatus_t rc = SMPL_BAD_PARAM; + + do { + if (pCInfo) + { + /* sanity checks... */ + + /* Check port info. */ + if ((locPort > SMPL_PORT_STATIC_MAX) || + (locPort < (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM + 1))) + { + continue; + } + + if ((rmtPort > SMPL_PORT_STATIC_MAX) || + (rmtPort < (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM + 1))) + { + continue; + } + + /* Must supply a pointer to the Link ID object */ + if (!lid) + { + /* No Link ID pointer supplied */ + continue; + } + + /* we're sane */ + + /* Use the value generated at connection object assign time. */ + *lid = pCInfo->thisLinkID; + + /* store peer's address */ + memcpy(pCInfo->peerAddr, peerAddr, NET_ADDR_SIZE); + + /* store port info */ + pCInfo->portRx = locPort; + pCInfo->portTx = rmtPort; + + pCInfo->hops2target = MAX_HOPS; + + rc = SMPL_SUCCESS; + } + else + { + /* No room in Connection table */ + rc = SMPL_NOMEM; + } + } while (0); + + if ((SMPL_SUCCESS != rc) && pCInfo) + { + nwk_freeConnection(pCInfo); + } + + return rc; +} + +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn SMPL_Ioctl + * + * @brief This routine supplies the SimpliciTI IOCTL support. + * + * input parameters + * @param object - The IOCTL target object + * @param action - The IOCTL target action on the object + * @param val - pointer to value. exact forn depends on object type. + * + * output parameters + * + * @return Status of action. Value depends on object, action, and result. + * + * SMPL_BAD_PARAM is returned if this API is called before + * initialization and the object is not one of + * the valid exceptions. + */ + +smplStatus_t SMPL_Ioctl(ioctlObject_t object, ioctlAction_t action, void *val) +{ + smplStatus_t rc; + + /* if init hasn't occurred see if access is still valid */ + if (!sInit_done && !ioctlPreInitAccessIsOK(object)) + { + return SMPL_BAD_PARAM; + } + + switch (object) + { +#if defined(EXTENDED_API) + case IOCTL_OBJ_TOKEN: + { + ioctlToken_t *t = (ioctlToken_t *)val; + + rc = SMPL_SUCCESS; + if (TT_LINK == t->tokenType) + { + if (IOCTL_ACT_SET == action) + { + nwk_setLinkToken(t->token.linkToken); + } + else if (IOCTL_ACT_GET == action) + { + nwk_getLinkToken(&t->token.linkToken); + } + else + { + rc = SMPL_BAD_PARAM; + } + } + else if (TT_JOIN == t->tokenType) + { + if (IOCTL_ACT_SET == action) + { + nwk_setJoinToken(t->token.joinToken); + } + else if (IOCTL_ACT_GET == action) + { + nwk_getJoinToken(&t->token.joinToken); + } + else + { + rc = SMPL_BAD_PARAM; + } + } + else + { + rc = SMPL_BAD_PARAM; + } + } + break; + + case IOCTL_OBJ_NVOBJ: + rc = nwk_NVObj(action, (ioctlNVObj_t *)val); + break; +#endif /* EXTENDED_API */ + + case IOCTL_OBJ_CONNOBJ: + rc = nwk_connectionControl(action, val); + break; + + case IOCTL_OBJ_ADDR: + if ((IOCTL_ACT_GET == action) || (IOCTL_ACT_SET == action)) + { + rc = nwk_deviceAddress(action, (addr_t *)val); + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_RAW_IO: + if (IOCTL_ACT_WRITE == action) + { + rc = nwk_rawSend((ioctlRawSend_t *)val); + } + else if (IOCTL_ACT_READ == action) + { + rc = nwk_rawReceive((ioctlRawReceive_t *)val); + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_RADIO: + rc = nwk_radioControl(action, val); + break; + +#if defined(ACCESS_POINT) + case IOCTL_OBJ_AP_JOIN: + rc = nwk_joinContext(action); + break; +#endif +#if defined(FREQUENCY_AGILITY) + case IOCTL_OBJ_FREQ: + rc = nwk_freqControl(action, val); + break; +#endif + case IOCTL_OBJ_FWVER: + if (IOCTL_ACT_GET == action) + { + memcpy(val, nwk_getFWVersion(), SMPL_FWVERSION_SIZE); + rc = SMPL_SUCCESS; + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_PROTOVER: + if (IOCTL_ACT_GET == action) + { + *((uint8_t *)val) = nwk_getProtocolVersion(); + rc = SMPL_SUCCESS; + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + default: + rc = SMPL_BAD_PARAM; + break; + } + + return rc; +} + +/****************************************************************************** + * @fn ioctlPreInitAccessIsOK + * + * @brief Is the request legal yet? Most requests are not legal before + * SMPL_Init(). + * + * input parameters + * @param object - The IOCTL target object + * + * output parameters + * + * @return Returns non-zero if request should be honored for further + * processing, otherwise returns 0. This function does not + * determine of the object-action pair are valid. It only knows + * about exceptions, i.e., those that are valid before the + * SMPL_Init() call. + * + */ + +static uint8_t ioctlPreInitAccessIsOK(ioctlObject_t object) +{ + uint8_t rc; + + /* Currently the only legal pre-init accesses are the address and + * the token objects. + */ + switch (object) + { + case IOCTL_OBJ_ADDR: + case IOCTL_OBJ_TOKEN: + rc = 1; /* legal */ + break; + + default: + rc = 0; /* not legal when init not done */ + break; + } + + return rc; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_api.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_api.h new file mode 100755 index 0000000..104f031 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_api.h @@ -0,0 +1,58 @@ +/************************************************************************************************** +* Filename: nwk_api.h +* Revised: $Date: 2008-11-24 12:09:31 -0800 (Mon, 24 Nov 2008) $ +* Revision: $Revision: 18508 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI appliction layer API. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_API_H +#define NWK_API_H + +/* Tx options (bit map) */ +#define SMPL_TXOPTION_NONE ((txOpt_t)0x00) +#define SMPL_TXOPTION_ACKREQ ((txOpt_t)0x01) + +smplStatus_t SMPL_Init(uint8_t (*)(linkID_t)); +smplStatus_t SMPL_Link(linkID_t *); +smplStatus_t SMPL_LinkListen(linkID_t *); +smplStatus_t SMPL_Send(linkID_t lid, uint8_t *msg, uint8_t len); + +smplStatus_t SMPL_SendOpt(linkID_t lid, uint8_t * msg, uint8_t len, txOpt_t); +smplStatus_t SMPL_Receive(linkID_t lid, uint8_t *msg, uint8_t *len); + +smplStatus_t SMPL_Ioctl(ioctlObject_t, ioctlAction_t, void *); +#ifdef EXTENDED_API +smplStatus_t SMPL_Ping(linkID_t); +smplStatus_t SMPL_Unlink(linkID_t); +smplStatus_t SMPL_Commission(addr_t *, uint8_t, uint8_t, linkID_t *); +#endif /* EXTENDED_API */ + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_app.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_app.h new file mode 100755 index 0000000..4aa942b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_app.h @@ -0,0 +1,53 @@ + +/************************************************************************************************** +* Filename: nwk_app.h +* Revised: $Date: 2007-07-10 11:21:35 -0700 (Tue, 10 Jul 2007) $ +* Revision: $Revision: 14865 $ +* Author: $Author: lfriedman $ +* +* Description: This header file is for convenience and includes the headers for all the +* network applications. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + + + +#ifndef NWK_APP_H +#define NWK_APP_H + +#include "nwk_freq.h" +#include "nwk_ping.h" +#include "nwk_link.h" +#include "nwk_mgmt.h" +#include "nwk_join.h" +#include "nwk_security.h" +#include "nwk_ioctl.h" + +#endif + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_frame.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_frame.c new file mode 100755 index 0000000..1726d13 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_frame.c @@ -0,0 +1,984 @@ +/************************************************************************************************** +* Filename: nwk_frame.c +* Revised: $Date: 2009-03-10 16:21:40 -0700 (Tue, 10 Mar 2009) $ +* Revision: $Revision: 19368 $ +* Author $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI frame handling functions. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "nwk_QMgmt.h" +#include "nwk_globals.h" +#include "nwk_mgmt.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +#if SIZE_INFRAME_Q > 0 +/* array of function pointers to handle NWK application frames */ +static fhStatus_t(*const func[]) (mrfiPacket_t *) = { nwk_processPing, + nwk_processLink, + nwk_processJoin, + nwk_processSecurity, + nwk_processFreq, + nwk_processMgmt}; +#endif /* SIZE_INFRAME_Q > 0 */ + +static uint8_t sTRACTID = 0; + +static addr_t const *sMyAddr = NULL; + +static uint8_t sMyRxType = 0, sMyTxType = 0; + +#if !defined(RX_POLLS) +static uint8_t (*spCallback)(linkID_t) = NULL; +#endif + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +#if SIZE_INFRAME_Q > 0 +/* local helper functions for Rx devices */ +static void dispatchFrame(frameInfo_t *); + +# if !defined(END_DEVICE) +# if defined(ACCESS_POINT) +/* only Access Points need to worry about duplicate S&F frames */ +uint8_t isDupSandFFrame(mrfiPacket_t *); + +# endif /* ACCESS_POINT */ +# endif /* !END_DEVICE */ +#endif /* SIZE_INFRAME_Q > 0 */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_frameInit + * + * @brief Initialize network context. + * + * input parameters + * pF - Pointer to callback function. If none intended should be NULL. + * + * output parameters + * + * @return void + */ + +void nwk_frameInit(uint8_t (*pF)(linkID_t)) +{ + + /****** Fill static values for the DEVICEINFO byte that will go in each frame ***** + * Rx type when frame originates from this device. Set in nwk_buildFrame() + * Tx type when frame sent from this device. Set in nwk_sendframe() */ +#if !defined(END_DEVICE) + sMyRxType = F_RX_TYPE_USER_CTL; +# if defined(ACCESS_POINT) + sMyTxType = F_TX_DEVICE_AP; +# else + sMyTxType = F_TX_DEVICE_RE; +# endif +#else + sMyTxType = F_TX_DEVICE_ED; +# if defined(RX_POLLS) + sMyRxType = F_RX_TYPE_POLLS; +# endif +# if defined(RX_USER) + sMyRxType = F_RX_TYPE_USER_CTL; +# endif +#endif + /****** DONE fill static values for the DEVICEINFO byte that will go in each frame ******/ + +#if !defined(RX_POLLS) + spCallback = pF; +#else + (void) pF; +#endif + + sMyAddr = nwk_getMyAddress(); + + while (!(sTRACTID = MRFI_RandomByte())) ; + + return; +} + +/****************************************************************************** + * @fn nwk_buildFrame + * + * @brief Builds an output frame for the port and message enclosed. + * This routine prepends the frame header and populates the + * frame in the output queue. + * + * input parameters + * @param port - port from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param hops - number of hops allowed. this is less than MAX_HOPS + * whenever the frame is being sent to the AP. this is to + * help mitigate the (short) broadcast storms + * + * output parameters + * + * @return pointer to frameInfo_t structure created. NULL if there is + * no room in output queue. + */ + +frameInfo_t *nwk_buildFrame(uint8_t port, uint8_t *msg, uint8_t len, uint8_t hops) +{ + frameInfo_t *fInfoPtr; + + if (!(fInfoPtr = nwk_QfindSlot(OUTQ))) + { + return (frameInfo_t *)NULL; + } + + MRFI_SET_PAYLOAD_LEN(&fInfoPtr->mrfiPkt, len + F_APP_PAYLOAD_OS); + + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ENCRYPT_OS, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_PORT_OS, port); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_TRACTID_OS, sTRACTID); + while (!(++sTRACTID)) ; /* transaction ID can't be 0 */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_RX_TYPE, sMyRxType); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_HOP_COUNT, hops); + + /* reset ack-relevant bits */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_REQ, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_RPLY, 0); + + /* reset forwarding bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_FWD_FRAME, 0); + + memcpy(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt) + F_APP_PAYLOAD_OS, msg, len); + memcpy(MRFI_P_SRC_ADDR(&fInfoPtr->mrfiPkt), sMyAddr, NET_ADDR_SIZE); + + return fInfoPtr; +} + +#if defined(APP_AUTO_ACK) + +/****************************************************************************** + * @fn nwk_buildAckReqFrame + * + * @brief Builds an output frame for the port and message enclosed. + * This routine prepends the frame header and populates the + * frame in the output queue. The frame is set to request that + * an ack frame be sent by the peer. + * + * input parameters + * @param port - port from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param hops - number of hops allowed. this is less than MAX_HOPS + * whenever the frame is being sent to the AP. this is to + * help mitigate the (short) broadcast storms + * @param tid - Transaction ID to insert in NWK header used to match + * the ack reply. + * + * output parameters + * + * @return pointer to frameInfo_t structure created. NULL if there is + * no room in output queue. + */ + +frameInfo_t *nwk_buildAckReqFrame(uint8_t port, uint8_t *msg, uint8_t len, uint8_t hops, + volatile uint8_t *tid) +{ + frameInfo_t *fInfoPtr; + + /* Build a normal frame first. */ + if (!(fInfoPtr = nwk_buildFrame(port, msg, len, hops))) + { + return (frameInfo_t *)NULL; + } + + /* save TID */ + *tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_TRACTID_OS); + /* Set REQ_ACK bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_REQ, F_ACK_REQ_TYPE); + + return fInfoPtr; +} + +#endif /* APP_AUTO_ACK */ + +#if SIZE_INFRAME_Q > 0 + +/****************************************************************************** + * @fn MRFI_RxCompleteISR + * + * @brief Here on Rx interrupt from radio. Process received frame from the + * radio Rx FIFO. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void MRFI_RxCompleteISR() +{ + frameInfo_t *fInfoPtr; + + /* room for more? */ + if (fInfoPtr = nwk_QfindSlot(INQ)) + { + MRFI_Receive(&fInfoPtr->mrfiPkt); + + dispatchFrame(fInfoPtr); + } + + return; +} + +/****************************************************************************** + * @fn nwk_retrieveFrame + * + * @brief Retrieve frame from Rx frame queue. Invoked by application-level + * code either app through SMPL_Receive() or IOCTL through raw Rx. This + * should run in a user thread, not an ISR thread. + * + * input parameters + * @param port - port on which to get a frame + * + * output parameters + * @param msg - pointer to where app payload should be copied. Buffer + * allocated should be == MAX_APP_PAYLOAD. + * + * @param len - pointer to where payload length should be stored. Caller + * can check for non-zero when polling the port. initialized + * to 0 even if no frame is retrieved. + * @param srcAddr - if non-NULL, a pointer to where to copy the source address + * of the retrieved message. + * @param hopCount - if non-NULL, a pointer to where to copy the hop count + * of the retrieved message. + * + * @return SMPL_SUCCESS + * SMPL_NO_FRAME - no frame found for specified destination + * SMPL_BAD_PARAM - no valid connection info for the Link ID + * + */ + +smplStatus_t nwk_retrieveFrame(rcvContext_t *rcv, uint8_t *msg, uint8_t *len, addr_t *srcAddr, + uint8_t *hopCount) +{ + frameInfo_t *fPtr; + uint8_t done; + + do { + /* look for a frame on requested port. */ + *len = 0; + done = 1; + + fPtr = nwk_QfindOldest(INQ, rcv, USAGE_NORMAL); + if (fPtr) + { + connInfo_t *pCInfo = 0; + + if (RCV_APP_LID == rcv->type) + { + pCInfo = nwk_getConnInfo(rcv->t.lid); + if (!pCInfo) + { + return SMPL_BAD_PARAM; + } +# if defined(SMPL_SECURE) + /* decrypt here...we have all the context we need. */ + { + uint32_t ctr = pCInfo->connRxCTR; + uint32_t *pctr = &ctr; + uint8_t len = MRFI_GET_PAYLOAD_LEN(&fPtr->mrfiPkt) - F_SEC_CTR_OS; + + if (pCInfo->thisLinkID == SMPL_LINKID_USER_UUD) + { + pctr = NULL; + } +# if defined(RX_POLLS) + else if ((F_APP_PAYLOAD_OS - F_SEC_CTR_OS) == len) + { + /* This was an empty poll reply frame generated by the AP. + * It uses the single-byte CTR value like network applications. + * We do not want to use the application layer counter in this case. + */ + pctr = NULL; + } +# endif + if (nwk_getSecureFrame(&fPtr->mrfiPkt, len, pctr)) + { + if (pctr) + { + /* Update connection's counter. */ + pCInfo->connRxCTR = ctr; + } + } + else + { + /* Frame bogus. Check for another frame. */ + done = 0; + continue; + } + } +# endif /* SMPL_SECURE */ + } + + /* it's on the requested port. */ + *len = MRFI_GET_PAYLOAD_LEN(&fPtr->mrfiPkt) - F_APP_PAYLOAD_OS; + memcpy(msg, MRFI_P_PAYLOAD(&fPtr->mrfiPkt) + F_APP_PAYLOAD_OS, *len); + /* save signal info */ + if (pCInfo) + { + /* Save Rx metrics... */ + pCInfo->sigInfo.rssi = fPtr->mrfiPkt.rxMetrics[MRFI_RX_METRICS_RSSI_OFS]; + pCInfo->sigInfo.lqi = fPtr->mrfiPkt.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS]; + } + if (srcAddr) + { + /* copy source address if requested */ + memcpy(srcAddr, MRFI_P_SRC_ADDR(&fPtr->mrfiPkt), NET_ADDR_SIZE); + } + if (hopCount) + { + /* copy hop count if requested */ + *hopCount = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fPtr->mrfiPkt), F_HOP_COUNT); + } + /* input frame no longer needed. free it. */ + nwk_QadjustOrder(INQ, fPtr->orderStamp); + + fPtr->fi_usage = FI_AVAILABLE; + return SMPL_SUCCESS; + } + } while (!done); + + return SMPL_NO_FRAME; +} + +/****************************************************************************** + * @fn dispatchFrame + * + * @brief Received frame looks OK so far. Dispatch to either NWK app by + * invoking the handler or the user's app by simply leaving the + * frame in the queue and letting the app poll the port. + * + * input parameters + * @param fiPtr - frameInfo_t pointer to received frame + * + * output parameters + * + * @return void + */ + +static void dispatchFrame(frameInfo_t *fiPtr) +{ + uint8_t port = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_PORT_OS); + uint8_t nwkAppSize = sizeof(func) / sizeof(func[0]); + fhStatus_t rc; + linkID_t lid; + +# if defined(ACCESS_POINT) + uint8_t loc; +# endif +# if !defined(END_DEVICE) + uint8_t isForMe; +# endif + + /* be sure it's not an echo... */ + if (!memcmp(MRFI_P_SRC_ADDR(&fiPtr->mrfiPkt), sMyAddr, NET_ADDR_SIZE)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + + /* Make sure encyrption bit conforms to our security support context. */ +# if defined(SMPL_SECURE) + if (!(GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ENCRYPT_OS))) + { + /* Encyrption bit is not on when when it should be */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +# else + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ENCRYPT_OS)) + { + /* Encyrption bit is on when when it should not be */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +# endif /* SMPL_SECURE */ + + /* If it's a network application port dispatch to service routine. Dispose + * of frame depending on return code. + */ + if (port && (port <= nwkAppSize)) + { +# if defined(SMPL_SECURE) + /* Non-connection-based frame. We can decode here if it was encrypted */ + if (!nwk_getSecureFrame(&fiPtr->mrfiPkt, MRFI_GET_PAYLOAD_LEN(&fiPtr->mrfiPkt) - + F_SEC_CTR_OS, 0)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +# endif + rc = func[port - 1](&fiPtr->mrfiPkt); + if (FHS_KEEP == rc) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + } +# if !defined(END_DEVICE) + else if (FHS_REPLAY == rc) + { + /* an AP or an RE could be relaying a NWK application frame... */ + nwk_replayFrame(fiPtr); + } +# endif + else /* rc == FHS_RELEASE (default...) */ + { + fiPtr->fi_usage = FI_AVAILABLE; + } + return; + } + /* sanity check */ + else if ((port != SMPL_PORT_USER_BCAST) && + ((port < PORT_BASE_NUMBER) || (port > SMPL_PORT_STATIC_MAX))) + { + /* bogus port. drop frame */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + + /* At this point we know the target is a user app. If this is an end device + * and we got this far save the frame and we're done. If we're an AP there + * are 3 cases: it's for us, it's for s store-and-forward client, or we need + * to replay the frame. If we're and RE and the frame didn't come from an RE + * and it's not for us, replay the frame. + */ + +# if defined(END_DEVICE) + + /* If we're s polling end device we only accept application frames from + * the AP. This prevents duplicate reception if we happen to be on when + * a linked peer sends. + */ +# if defined(RX_POLLS) + if (F_TX_DEVICE_ED != GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE)) + { + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } +# else + /* it's destined for a user app. */ + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + if (spCallback && spCallback(lid)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } +# endif /* RX_POLLS */ + +# else /* END_DEVICE */ + + /* We have an issue if the frame is broadcast to the UUD port. The AP (or RE) must + * handle this frame as if it were the target in case there is an application + * running that is listening on that port. But if it's a broadcast it must also be + * replayed. It isn't enough just to test for the UUD port because it could be a + * directed frame to another device. We must check explicitly for broadcast + * destination address. + */ + isForMe = !memcmp(sMyAddr, MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), NET_ADDR_SIZE); + if (isForMe || + ((port == SMPL_PORT_USER_BCAST) && + !memcmp(nwk_getBCastAddress(), MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), NET_ADDR_SIZE))) + { + /* The folllowing test will succeed for the UUD port regardless of the + * source address. + */ + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + /* If this is for the UUD port and we are here then the device is either + * an AP or an RE. In either case it must replay the UUD port frame if the + * frame is not "for me". But it also must handle it since it could have a + * UUD-listening application. Do the reply first and let the subsequent code + * correctly set the frame usage state. Note that the routine return can be + * from this code block. If not it will drop through to the bottom without + * doing a replay. + */ + /* Do I need to replay it? */ + if (!isForMe) + { + /* must be a broadcast for the UUD port */ + nwk_replayFrame(fiPtr); + } + /* OK. Now I handle it... */ + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + if (spCallback && spCallback(lid)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } +# if defined(ACCESS_POINT) + + /* Check to see if we need to save this for a S and F client. Otherwise, + * if it's not for us, get rid of it. + */ + else if (nwk_isSandFClient(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), &loc)) + { + /* Don't bother if it is a duplicate frame or if it's a forwarded frame + * echoed back from an RE. + */ + if (!isDupSandFFrame(&fiPtr->mrfiPkt) && + !(GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_FWD_FRAME)) + ) + { +# if defined(APP_AUTO_ACK) + /* Make sure ack request bit is off. Sender will have gone away. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ACK_REQ, 0); +# endif + fiPtr->fi_usage = FI_INUSE_UNTIL_FWD; + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE) == F_TX_DEVICE_AP) + { + /* I'm an AP and this frame came from an AP. Don't replay. */ + fiPtr->fi_usage = FI_AVAILABLE; + } +# elif defined(RANGE_EXTENDER) + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE) == F_TX_DEVICE_RE) + { + /* I'm an RE and this frame came from an RE. Don't replay. */ + fiPtr->fi_usage = FI_AVAILABLE; + } +# endif + else + { + /* It's not for me and I'm either an AP or I'm an RE and the frame + * didn't come from an RE. Replay the frame. + */ + nwk_replayFrame(fiPtr); + } +# endif /* !END_DEVICE */ + return; +} + +#endif /* SIZE_INFRAME_Q > 0 */ + +/****************************************************************************** + * @fn nwk_sendFrame + * + * @brief Send a frame by copying it to the radio Tx FIFO. + * + * input parameters + * @param pFrameInfo - pointer to frame to be sent + * @param txOption - do CCA or force frame out. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_TX_CCA_FAIL Tx failed because of CCA failure. + * Tx FIFO flushed in this case. + */ + +smplStatus_t nwk_sendFrame(frameInfo_t *pFrameInfo, uint8_t txOption) +{ + smplStatus_t rc; + + /* set the type of device sending the frame in the header */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_TX_DEVICE, sMyTxType); + + if (MRFI_TX_RESULT_SUCCESS == MRFI_Transmit(&pFrameInfo->mrfiPkt, txOption)) + { + rc = SMPL_SUCCESS; + } + else + { + /* Tx failed -- probably CCA. free up frame buffer. We do not have NWK + * level retries. Let application do it. + */ + rc = SMPL_TX_CCA_FAIL; + } + + /* TX is done. free up the frame buffer */ + pFrameInfo->fi_usage = FI_AVAILABLE; + + return rc; +} + +/****************************************************************************** + * @fn nwk_getMyRxType + * + * @brief Get my Rx type. Used to help populate the hops count in the + * frame header to try and limit the broadcast storm. Info is + * exchanged when linking. + * + * input parameters + * + * output parameters + * + * @return The address LSB. + */ + +uint8_t nwk_getMyRxType(void) +{ + return sMyRxType; +} + +#if defined(APP_AUTO_ACK) + +/****************************************************************************** + * @fn nwk_sendAckReply + * + * @brief Send an acknowledgement reply frame. + * + * input parameters + * @param frame - pointer to frame with ack request. + * @param port - port on whcih reply expected. + * + * output parameters + * + * @return void + */ + +void nwk_sendAckReply(mrfiPacket_t *frame, uint8_t port) +{ + mrfiPacket_t dFrame; + uint8_t tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS); + + /* set the type of device sending the frame in the header */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, sMyTxType); + + /* set the listen type of device sending the frame in the header. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); + + /* destination address from received frame */ + memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + /* source address */ + memcpy(MRFI_P_SRC_ADDR(&dFrame), sMyAddr, NET_ADDR_SIZE); + + /* port is the source the Tx port from the connection object */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); + + /* frame length... */ + MRFI_SET_PAYLOAD_LEN(&dFrame, F_APP_PAYLOAD_OS); + + /* transaction ID taken from source frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, tid); + + /* hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS); + + /* set ACK field */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, F_ACK_RPLY_TYPE); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); + + /* This is not a forwarded frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, 0); + + /* Encryption state */ +# if !defined(SMPL_SECURE) + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); +# else + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + nwk_setSecureFrame(&dFrame, 0, 0); +# endif + + MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +#endif /* APP_AUTO_ACK */ + +#if !defined(END_DEVICE) + +/****************************************************************************** + * @fn nwk_replayFrame + * + * @brief Deal with hop count on a Range Extender or Access Point replay. + * Queue entry usage always left as available when done. + * + * input parameters + * @param pFrameInfo - pointer to frame information structure + * + * output parameters + * + * @return void + */ + +void nwk_replayFrame(frameInfo_t *pFrameInfo) +{ + uint8_t hops = GET_FROM_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_HOP_COUNT); + + /* if hops are zero, drop frame. othewise send it. */ + if (hops--) + { + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_HOP_COUNT, hops); + + /* Don't care if the Tx fails because of TO. Either someone else + * will retransmit or the application itself will recover. + */ +# if defined(SMPL_SECURE) + + /* If the frame was targeted to a NWK port it was decrypted on spec in + * the 'dispatchFrame()' method. It must be re-encypted in this case. + */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_PORT_OS) <= SMPL_PORT_NWK_BCAST) + { + nwk_setSecureFrame(&pFrameInfo->mrfiPkt, MRFI_GET_PAYLOAD_LEN( + &pFrameInfo->mrfiPkt) - F_APP_PAYLOAD_OS, 0); + } +# endif + MRFI_DelayMs(1); + nwk_sendFrame(pFrameInfo, MRFI_TX_TYPE_CCA); + } + else + { + pFrameInfo->fi_usage = FI_AVAILABLE; + } + return; +} + +# if defined(ACCESS_POINT) + +/****************************************************************************** + * @fn nwk_getSandFFrame + * + * @brief Get any frame waiting for the client on the port supplied in + * the frame payload. + * TODO: support returning NWK application frames always. the + * port requested in the call should be an user application port. + * NWK app ports will never be in the called frame. + * TODO: deal with broadcast NWK frames from AP. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return pointer to frame if there is one, otherwise 0. + */ + +frameInfo_t *nwk_getSandFFrame(mrfiPacket_t *frame, uint8_t osPort) +{ + uint8_t i, port = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + osPort); + frameInfo_t *fiPtr; + rcvContext_t rcv; + + rcv.type = RCV_RAW_POLL_FRAME; + rcv.t.pkt = frame; + /* check the input queue for messages sent by others. */ + if (fiPtr = nwk_QfindOldest(INQ, &rcv, USAGE_FWD)) + { + return fiPtr; + } + + /* Check the output queue to see if we ourselves need to send anything. + * TODO: use the cast-out scheme for output queue so this routine finds + * the oldest in either queue. + */ + fiPtr = nwk_getQ(OUTQ); + for (i = 0; i < SIZE_OUTFRAME_Q; ++i, fiPtr++) + { + if (FI_INUSE_UNTIL_FWD == fiPtr->fi_usage) + { + if (!memcmp(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_PORT_OS) == port) + { + return fiPtr; + } + } + } + } + return 0; +} + +/****************************************************************************** + * @fn nwk_SendEmptyPollRspFrame + * + * @brief There are no frames waiting for the requester on the specified + * port. Send a frame back to that port with no payload. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return void + */ + +void nwk_SendEmptyPollRspFrame(mrfiPacket_t *frame) +{ + mrfiPacket_t dFrame; + uint8_t port = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + M_POLL_PORT_OS); + + /* set the type of device sending the frame in the header. we know it's an AP */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, F_TX_DEVICE_AP); + + /* set the listen type of device sending the frame in the header. we know it's + * an AP is is probably always on...but use the static variable anyway. + */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); + /* destination address from received frame (polling device) */ + memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + /* source address */ + memcpy(MRFI_P_SRC_ADDR(&dFrame), MRFI_P_PAYLOAD( + frame) + F_APP_PAYLOAD_OS + M_POLL_ADDR_OS, NET_ADDR_SIZE); + /* port is the port requested */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); + /* frame length... */ + MRFI_SET_PAYLOAD_LEN(&dFrame, F_APP_PAYLOAD_OS); + /* transaction ID... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, sTRACTID); + sTRACTID++; + /* hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS_FROM_AP); + + /* Ack fields */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); + + /* This is logically a forwarded frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, F_FRAME_FWD_TYPE); + + /* Encryption state */ +# if !defined(SMPL_SECURE) + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); +# else + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + nwk_setSecureFrame(&dFrame, 0, 0); +# endif + + MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +/****************************************************************************** + * @fn isDupSandFFrame + * + * @brief Have we already stored this frame on behalf of a client? + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns 1 if the frame is a duplicate, otherwise 0. + */ + +uint8_t isDupSandFFrame(mrfiPacket_t *frame) +{ + uint8_t i, plLen = MRFI_GET_PAYLOAD_LEN(frame); + frameInfo_t *fiPtr; + + /* check the input queue for duplicate S&F frame. */ + fiPtr = nwk_getQ(INQ); + for (i = 0; i < SIZE_INFRAME_Q; ++i, fiPtr++) + { + if (FI_INUSE_UNTIL_FWD == fiPtr->fi_usage) + { + /* compare everything except the DEVICE INFO byte. */ + if (MRFI_GET_PAYLOAD_LEN(&fiPtr->mrfiPkt) == plLen && + !memcmp(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), MRFI_P_DST_ADDR(frame), NET_ADDR_SIZE) && + !memcmp(MRFI_P_SRC_ADDR(&fiPtr->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE) && + !memcmp(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), MRFI_P_PAYLOAD(frame), 1) && + !memcmp(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt) + F_TRACTID_OS, MRFI_P_PAYLOAD(frame) + + F_TRACTID_OS, plLen - F_TRACTID_OS) + ) + { + return 1; + } + } + } + return 0; +} + +# endif /* ACCESS_POINT */ + +#endif /* !END_DEVICE */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_frame.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_frame.h new file mode 100755 index 0000000..f169911 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_frame.h @@ -0,0 +1,155 @@ +/************************************************************************************************** +* Filename: nwk_frame.h +* Revised: $Date: 2008-12-23 13:49:41 -0800 (Tue, 23 Dec 2008) $ +* Revision: $Revision: 18651 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI frame handling functions. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_FRAME_H +#define NWK_FRAME_H + +/* Frame field defines and masks. Mask name must be field name with '_MSK' appended + * so the GET and PUT macros work correctly -- they use token pasting. Offset values + * are with respect to the MRFI payload and not the entire frame. + */ +#define F_PORT_OS 0 +#define F_PORT_OS_MSK (0x3F) +#define F_ENCRYPT_OS 0 +#define F_ENCRYPT_OS_MSK (0x40) +#define F_FWD_FRAME 0 +#define F_FWD_FRAME_MSK (0x80) +#define F_RX_TYPE 1 +#define F_RX_TYPE_MSK (0x40) +#define F_ACK_REQ 1 +#define F_ACK_REQ_MSK (0x80) +#define F_ACK_RPLY 1 +#define F_ACK_RPLY_MSK (0x08) +#define F_TX_DEVICE 1 +#define F_TX_DEVICE_MSK (0x30) +#define F_HOP_COUNT 1 +#define F_HOP_COUNT_MSK (0x07) +#define F_TRACTID_OS 2 +#define F_TRACTID_OS_MSK (0xFF) +#define SMPL_NWK_HDR_SIZE 3 + +#ifdef SMPL_SECURE + +# define F_SECURE_OS 3 + +# define F_SEC_CTR_OS 3 /* counter hint */ +# define F_SEC_CTR_OS_MSK (0xFF) +# define F_SEC_ICHK_OS 4 /* Message integrity check */ +# define F_SEC_ICHK_OS_MSK (0xFF) +# define F_SEC_MAC_OS 5 /* Message authentication code */ +# define F_SEC_MAC_OS_MSK (0xFF) + +#else + +# define F_SECURE_OS 0 + +#endif /* SMPL_SECURE */ + +#define F_APP_PAYLOAD_OS (SMPL_NWK_HDR_SIZE + F_SECURE_OS) + +/* sub field details. they are in the correct bit locations (already shifted) */ +#define F_RX_TYPE_USER_CTL 0x00 /* does not poll... */ +#define F_RX_TYPE_POLLS 0x40 /* polls for held messages */ + +#define F_ACK_REQ_TYPE 0x80 +#define F_ACK_RPLY_TYPE 0x08 +#define F_FRAME_FWD_TYPE 0x80 +#define F_FRAME_ENCRYPT_TYPE 0x40 + +/* device type fields */ +#define F_TX_DEVICE_ED 0x00 /* End Device */ +#define F_TX_DEVICE_RE 0x10 /* Range Extender */ +#define F_TX_DEVICE_AP 0x20 /* Access Point */ + +/* macro to get a field from a frame buffer */ +#define GET_FROM_FRAME(b, f) ((b)[f] & (f##_MSK)) + +/* Macro to put a value 'v' into a frame buffer 'b'. 'v' value must already be shifted + * if necessary. 'b' is a byte array + */ +#define PUT_INTO_FRAME(b, f, v) do {(b)[f] = ((b)[f] & ~(f##_MSK)) | (v); } while (0) + + +/* **** frame information objects + * info kept on each frame object + */ +#define FI_AVAILABLE 0 /* entry available for use */ +#define FI_INUSE_UNTIL_DEL 1 /* in use. will be explicitly reclaimed */ +#define FI_INUSE_UNTIL_TX 2 /* in use. will be reclaimed after Tx */ +#define FI_INUSE_UNTIL_FWD 3 /* in use until forwarded by AP */ +#define FI_INUSE_TRANSITION 4 /* being retrieved. do not delete in Rx ISR thread. */ + +typedef struct +{ + uint8_t rssi; + uint8_t lqi; +} sigInfo_t; + +typedef struct +{ + volatile uint8_t fi_usage; + uint8_t orderStamp; + mrfiPacket_t mrfiPkt; +} frameInfo_t; + + +/* prototypes */ +frameInfo_t *nwk_buildFrame(uint8_t, uint8_t * msg, uint8_t len, uint8_t hops); +#ifdef APP_AUTO_ACK +frameInfo_t *nwk_buildAckReqFrame(uint8_t, uint8_t *, uint8_t, uint8_t, volatile uint8_t *); +#endif +void nwk_receiveFrame(void); + +void nwk_frameInit(uint8_t (*)(linkID_t)); +smplStatus_t nwk_retrieveFrame(rcvContext_t *, uint8_t *, uint8_t *, addr_t *, uint8_t *); +smplStatus_t nwk_sendFrame(frameInfo_t *, uint8_t txOption); + +frameInfo_t *nwk_getSandFFrame(mrfiPacket_t *, uint8_t); +uint8_t nwk_getMyRxType(void); +void nwk_SendEmptyPollRspFrame(mrfiPacket_t *); + +#ifdef APP_AUTO_ACK +void nwk_sendAckReply(mrfiPacket_t *, uint8_t); +#endif + +#ifndef END_DEVICE +/* only APs and REs repeat frames */ +void nwk_replayFrame(frameInfo_t *); + +#endif + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_globals.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_globals.c new file mode 100755 index 0000000..b63cf67 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_globals.c @@ -0,0 +1,267 @@ +/************************************************************************************************** +* Filename: nwk_globals.c +* Revised: $Date: 2009-10-27 20:48:11 -0700 (Tue, 27 Oct 2009) $ +* Revision: $Revision: 20995 $ +* +* Description: This file manages global NWK data. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_globals.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static const addr_t sMyROMAddress = THIS_DEVICE_ADDRESS; +static addr_t sAPAddress; +static addr_t sMyRAMAddress; +static uint8_t sRAMAddressIsSet = 0; + +/* Version number set as a 4 byte quantity. Each byte is a revision number + * in the form w.x.y.z. The subfields are each limited to values 0x0-0xFF. + */ +static const smplVersionInfo_t sVersionInfo = { + 0x02, /* protocol version */ + 0x01, /* major revision number */ + 0x01, /* minor revision number */ + 0x01, /* maintenance release number */ + 0x00 /* special release */ +}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_globalsInit + * + * @brief Initialization of global symbols + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_globalsInit(void) +{ + + memset(&sAPAddress, 0x00, sizeof(addr_t)); + + /* populate RAM address from ROM default if it hasn't laready been set + * using the IOCTL interface. + */ + if (!sRAMAddressIsSet) + { + memcpy(&sMyRAMAddress, &sMyROMAddress, sizeof(addr_t)); + sRAMAddressIsSet = 1; /* RAM address is now valid */ + } + + return; +} + +/****************************************************************************** + * @fn nwk_getMyAddress + * + * @brief Return a pointer to my address. It comes either from ROM as + * set in the configuration file or it was set using the IOCTL + * interface -- probably from random bytes. + * + * input parameters + * + * output parameters + * + * @return pointer to a constant address type object. + */ + +addr_t const *nwk_getMyAddress(void) +{ + /* This call supports returning a valid pointer before either the + * initialization or external setting of the address. But caller needs + * to be careful -- if this routine is called immediately it will return + * the ROM address. If the application then sets the address using the + * IOCTL before doing the SMPL_Init() the original pointer is no longer + * valid as it points to the wrong address. + */ + return sRAMAddressIsSet ? &sMyRAMAddress : &sMyROMAddress; +} + +/****************************************************************************** + * @fn nwk_getFWVersion + * + * @brief Return a pointer to the current firmware version string. + * + * input parameters + * + * output parameters + * + * @return pointer to a constant uint16_t object. + */ + +uint8_t const *nwk_getFWVersion() +{ + return sVersionInfo.fwVerString; +} + +/****************************************************************************** + * @fn nwk_getProtocolVersion + * + * @brief Return the current protocol version. + * + * input parameters + * + * output parameters + * + * @return Protocol version. + */ + +uint8_t nwk_getProtocolVersion(void) +{ + return sVersionInfo.protocolVersion; +} + +/****************************************************************************** + * @fn nwk_setMyAddress + * + * @brief Set my address object if it hasn't already been set. This call + * is referenced by the IOCTL support used to change the device + * address. It is effective only if the address has not already + * been set. + * + * input parameters + * + * @param addr - pointer to the address object to be used to set my address. + * + * output parameters + * + * @return Returns non-zero if request is respected, otherwise returns 0. + */ + +uint8_t nwk_setMyAddress(addr_t *addr) +{ + uint8_t rc = 0; + + if (!sRAMAddressIsSet) + { + memcpy(&sMyRAMAddress, addr, sizeof(addr_t)); + sRAMAddressIsSet = 1; /* RAM address is now valid */ + rc = 1; + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_setAPAddress + * + * @brief Set the AP's address. Called after the AP address is gleaned + * from the Join reply. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_setAPAddress(addr_t *addr) +{ + + memcpy((void *)&sAPAddress, (void *)addr, NET_ADDR_SIZE); + + return; +} + +/****************************************************************************** + * @fn nwk_getAPAddress + * + * @brief Get the AP's address. + * + * input parameters + * + * output parameters + * + * @return Pointer to a constant address object or null if the address has not + * yet been set. + */ + +addr_t const *nwk_getAPAddress(void) +{ + addr_t addr; + + memset(&addr, 0x0, sizeof(addr)); + + return !memcmp(&sAPAddress, &addr, NET_ADDR_SIZE) ? 0 : &sAPAddress; +} + +/****************************************************************************** + * @fn nwk_getBCastAddress + * + * @brief Get the network broadcast address. + * + * input parameters + * + * output parameters + * + * @return Pointer to a constant address object. + */ + +addr_t const *nwk_getBCastAddress(void) +{ + return (addr_t const *)mrfiBroadcastAddr; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_globals.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_globals.h new file mode 100755 index 0000000..7f349c7 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_globals.h @@ -0,0 +1,51 @@ +/************************************************************************************************** +* Filename: nwk_globals.h +* Revised: $Date: 2008-07-30 11:22:21 -0700 (Wed, 30 Jul 2008) $ +* Revision: $Revision: 17655 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the management of NWK global symbols. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_GLOBALS_H +#define NWK_GLOBALS_H + + +/* Prototypes */ +void nwk_globalsInit(void); +addr_t const *nwk_getMyAddress(void); +uint8_t nwk_setMyAddress(addr_t *addr); +void nwk_setAPAddress(addr_t *addr); +addr_t const *nwk_getAPAddress(void); +addr_t const *nwk_getBCastAddress(void); +uint8_t const *nwk_getFWVersion(void); +uint8_t nwk_getProtocolVersion(void); + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_types.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_types.h new file mode 100755 index 0000000..79d4e03 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk/nwk_types.h @@ -0,0 +1,344 @@ +/************************************************************************************************** +* Filename: nwk_types.h +* Revised: $Date: 2009-01-13 11:31:14 -0800 (Tue, 13 Jan 2009) $ +* Revision: $Revision: 18744 $ +* Author: $Author: lfriedman $ +* +* Description: This header file defines the SimpliciTI typedefs. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_TYPES_H +#define NWK_TYPES_H + +#define NWK_TX_RETRY_COUNT 10 +#define NWK_RX_RETRY_COUNT 10 + +#define NWK_APP_REPLY_BIT (0x80) + +#define NET_ADDR_SIZE MRFI_ADDR_SIZE /* size of address in bytes */ + +#ifdef FREQUENCY_AGILITY +# define NWK_FREQ_TBL_SIZE MRFI_NUM_LOGICAL_CHANS +#else +# define NWK_FREQ_TBL_SIZE 1 +#endif + +typedef struct +{ + uint8_t addr[NET_ADDR_SIZE]; +} addr_t; + +typedef uint8_t linkID_t; +typedef uint8_t ccRadioStatus_t; + + +/* *********************************************** + * Begin IOCTL Support + * *********************************************** + */ +enum ioctlObject { + IOCTL_OBJ_FREQ, + IOCTL_OBJ_CRYPTKEY, + IOCTL_OBJ_RAW_IO, + IOCTL_OBJ_RADIO, + IOCTL_OBJ_AP_JOIN, + IOCTL_OBJ_ADDR, + IOCTL_OBJ_CONNOBJ, + IOCTL_OBJ_FWVER, + IOCTL_OBJ_PROTOVER, + IOCTL_OBJ_NVOBJ, + IOCTL_OBJ_TOKEN +}; + +enum ioctlAction { + IOCTL_ACT_SET, + IOCTL_ACT_GET, + IOCTL_ACT_READ, + IOCTL_ACT_WRITE, + IOCTL_ACT_RADIO_SLEEP, + IOCTL_ACT_RADIO_AWAKE, + IOCTL_ACT_RADIO_SIGINFO, + IOCTL_ACT_RADIO_RSSI, + IOCTL_ACT_RADIO_RXON, + IOCTL_ACT_RADIO_RXIDLE, + IOCTL_ACT_RADIO_SETPWR, + IOCTL_ACT_ON, + IOCTL_ACT_OFF, + IOCTL_ACT_SCAN, + IOCTL_ACT_DELETE +}; + +typedef enum ioctlObject ioctlObject_t; +typedef enum ioctlAction ioctlAction_t; + +enum ioctlLevel +{ + IOCTL_LEVEL_0, + IOCTL_LEVEL_1, + IOCTL_LEVEL_2 +}; + +typedef enum ioctlLevel ioctlLevel_t; + +typedef struct +{ + addr_t *addr; + uint8_t *msg; + uint8_t len; + uint8_t port; +} ioctlRawSend_t; + +typedef struct +{ + addr_t *addr; + uint8_t *msg; + uint8_t len; + uint8_t port; + uint8_t hopCount; +} ioctlRawReceive_t; + +/* + * Signal information support + */ +typedef int8_t rssi_t; + +typedef struct +{ + rssi_t rssi; + uint8_t lqi; +} rxMetrics_t; + +typedef struct +{ + linkID_t lid; /* input: Link ID for which signal info desired */ + rxMetrics_t sigInfo; +} ioctlRadioSiginfo_t; + + +/* *** Begin SET/GET token support *** */ +enum tokenType +{ + TT_LINK, /* Token Type is Link */ + TT_JOIN /* Token Type is Join */ +}; + +typedef enum tokenType tokenType_t; + +/* Create a union. If either token ever changes type it will make things easier. */ +typedef union +{ + uint32_t linkToken; + uint32_t joinToken; +} token_t; + +typedef struct +{ + tokenType_t tokenType; + token_t token; +} ioctlToken_t; +/* *** End SET/GET token support *** */ + + +/* + * Frequency Agility support + */ +typedef struct +{ + uint8_t logicalChan; +} freqEntry_t; + +typedef struct +{ + uint8_t numChan; + freqEntry_t *freq; +} ioctlScanChan_t; + +/* Security typedefs to make things easier if they change types */ +typedef uint8_t secMAC_t; +typedef uint8_t secFCS_t; + +/*************************************************************************************** + * ** NV Object support ** + * + * The following object supports saving and restoring the information + * necessary to save and restore a device connection context. + * + * On a GET interface populates the IOCTL object with the version and length (in bytes) + * of the current static connection iformation area. In addition it populates the address + * pointed to by 'objPtr' with the base address of the connection context. At this point + * the caller can either copy to or from the address. Note that this is a dangerous + * interface, as the caller is provided with direct access to the connection context. + * + * When restoring the connection context some sanity checks are possible. If the + * version or length elements of the saved context do not match those of the current + * static object the static object should not be populated. If this sanity fails the + * caller is not provided with the pointer to the conneciton ocntext. + * + * This interface is fairly simple and it is possible to get the address of the + * connection context to do a restore by simply doing a GET call. This avoids the + * sanity checks. However, this is not recommended because there may be other side + * effects of doing a SET that are necessary when restoring a context and are done + * only when the proper option is used to restore the connection context. + * + *************************************************************************************/ +typedef struct +{ + uint8_t objVersion; + uint16_t objLen; + uint8_t **objPtr; +} ioctlNVObj_t; + +/* *********************************************** + * End IOCTL Support + * *********************************************** + */ + +enum smplStatus { + SMPL_SUCCESS, + SMPL_TIMEOUT, + SMPL_BAD_PARAM, + SMPL_NOMEM, + SMPL_NO_FRAME, + SMPL_NO_LINK, + SMPL_NO_JOIN, + SMPL_NO_CHANNEL, + SMPL_NO_PEER_UNLINK, + SMPL_TX_CCA_FAIL, + SMPL_NO_PAYLOAD, + SMPL_NO_AP_ADDRESS, + SMPL_NO_ACK +}; + +typedef enum smplStatus smplStatus_t; + +/* NWK application frame handling status codes */ +enum fhStatus +{ + FHS_RELEASE, /* handled in interrupt thread */ + FHS_KEEP, /* handled by background application */ + FHS_REPLAY /* non-ED case: NWK frame not for me that should be replayed */ +}; + +typedef enum fhStatus fhStatus_t; + +/******** BEGIN: Object support for parameter context in queue management *********/ +enum rcvType +{ + RCV_NWK_PORT, + RCV_APP_LID, + RCV_RAW_POLL_FRAME +}; + +typedef enum rcvType rcvType_t; + +/* Tx options type */ +typedef uint16_t txOpt_t; + +typedef struct +{ + rcvType_t type; + union + { + linkID_t lid; + uint8_t port; + mrfiPacket_t *pkt; + } t; +} rcvContext_t; +/******** END: Object support for parameter context in queue management *********/ + +#define SMPL_FWVERSION_SIZE 4 + +typedef struct +{ + uint8_t protocolVersion; + uint8_t fwVerString[SMPL_FWVERSION_SIZE]; +} smplVersionInfo_t; + +/* The following typedef is used to standardize the application Transaction ID field. + * This field can be used for detection of out-of-order application payloads if this + * is an issue. There is no real reason to use more than a byte for this support. But + * if this typedef is anything other than uint8_t be sure to attend to alignment and + * endian issues. + */ +typedef uint8_t appPTid_t; + +#ifdef ACCESS_POINT +/* Store-and-forward client info object */ +typedef struct +{ + addr_t clientAddr; + appPTid_t lastTID; +} sfClientInfo_t; + +typedef struct +{ + uint8_t curNumSFClients; + sfClientInfo_t sfClients[NUM_STORE_AND_FWD_CLIENTS]; +} sfInfo_t; +#endif + +/**************************************************************************************** +* SOME USEFUL MACROS +****************************************************************************************/ + +/* Delay loop support. Requires mrfi.h */ +#define NWK_DELAY(spin) MRFI_DelayMs(spin) +#define NWK_REPLY_DELAY() MRFI_ReplyDelay(); + +/* Network applications may need to remember radio state because the user + * application may choose to turn Rx off. These macros help get and restore + * the radio Rx state. The macros should be in the same code block at the same level. + * The argument 's' is the 'current' radio state and should be set in the code block + * with a call to MRFI_GetRadioState() _before_ using the macros. + * + * Used extensively by NWK but user applications may use them as well. But it is + * much more liekly that an application will know the radio state since it likely + * will have set it with IOCTL calls. Requires mrfi.h. + */ +#define NWK_CHECK_FOR_SETRX(s) if (MRFI_RADIO_STATE_RX != s) \ + { \ + if (MRFI_RADIO_STATE_OFF == s) \ + { \ + MRFI_WakeUp(); \ + } \ + MRFI_RxOn(); \ + } + +#define NWK_CHECK_FOR_RESTORE_STATE(s) if (MRFI_RADIO_STATE_RX != s) \ + { \ + if (MRFI_RADIO_STATE_OFF == s) \ + { \ + MRFI_Sleep(); \ + } \ + else \ + { \ + MRFI_RxIdle(); \ + } \ + } +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.c new file mode 100755 index 0000000..ed18428 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.c @@ -0,0 +1,649 @@ +/************************************************************************************************** +* Filename: nwk_freq.c +* Revised: $Date: 2008-12-10 13:50:46 -0800 (Wed, 10 Dec 2008) $ +* Revision: $Revision: 18594 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Freq network application. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk.h" +#include "nwk_frame.h" +#include "nwk_freq.h" +#include "nwk_globals.h" +#include "nwk_api.h" +#include "nwk_security.h" + +#if defined(FREQUENCY_AGILITY) + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static freqEntry_t sCurLogicalChan; +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +static fhStatus_t handle_freq_cmd(mrfiPacket_t *); +static fhStatus_t send_ping_reply(mrfiPacket_t *); + +# ifndef ACCESS_POINT +static uint8_t change_channel_cmd_is_valid(mrfiPacket_t *); + +# endif +# ifdef RANGE_EXTENDER +/* REs must replay frame before changing channels */ +static void replayFirst(mrfiPacket_t *); + +# endif +# ifdef ACCESS_POINT +/* only the AP can broadcast this command */ +static void broadcast_channel_change(uint8_t); + +# else +/* APs do not process this frame */ +static void change_channel_cmd(mrfiPacket_t *); + +# endif + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_freqInit + * + * @brief Initialize NWK Frequency application. + * + * @return none. + */ + +void nwk_freqInit(void) +{ + + memset(&sCurLogicalChan, 0x0, sizeof(sCurLogicalChan)); + + /* pick a random value to start the transaction ID for this app. */ + sTid = MRFI_RandomByte(); + + return; +} + +/*************************************************************************** + * @fn nwk_setChannel + * + * @brief Set requested logical channel. Accessed by application + * through IOCTL interface + * + * input parameters + * @param chan - pointer to channel object of requested channel + * + * @return status of operation: + * SMPL_SUCCESS if channel set + * SMPL_BAD_PARAM if requested channel is out of range + */ + +smplStatus_t nwk_setChannel(freqEntry_t *chan) +{ + smplStatus_t rc = SMPL_BAD_PARAM; + + if (chan->logicalChan < NWK_FREQ_TBL_SIZE) + { + MRFI_SetLogicalChannel(chan->logicalChan); + sCurLogicalChan = *chan; + rc = SMPL_SUCCESS; + } + return rc; +} + +/****************************************************************************** + * @fn nwk_getChannel + * + * @brief Get current logical channel. Accessed by application through + * IOCTL interface + * + * input parameters + * @param chan - pointer to channel object of requested channel + * + * output parameters + * @param chan - populated channel object + * + * @return none. + */ + +void nwk_getChannel(freqEntry_t *chan) +{ + *chan = sCurLogicalChan; + + return; +} + +/****************************************************************************** + * @fn handle_freq_cmd + * + * @brief Handle a Frequency application command. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return Return FHS_RELEASE if caller should release frame otherwise + * return FHS_REPLAY. + */ + +static fhStatus_t handle_freq_cmd(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + + switch (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS)) + { + case FREQ_REQ_PING: + rc = send_ping_reply(frame); + break; + +# ifndef ACCESS_POINT + case FREQ_REQ_MOVE: +# ifdef RANGE_EXTENDER + replayFirst(frame); +# endif + + /* Make sure the change channel Freq command came from + * a valid source before obeying. + */ + if (change_channel_cmd_is_valid(frame)) + { + change_channel_cmd(frame); + } + break; +# endif + +# ifdef ACCESS_POINT + case FREQ_REQ_REQ_MOVE: + break; +# endif + default: + break; + } + + return rc; +} + +# ifndef ACCESS_POINT + +/****************************************************************************** + * @fn change_channel_cmd_is_valid + * + * @brief Check validity of a change channel command frame. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return Returns non-zero if command is valid, otherwise returns 0. + * Command is valid if either: + * - frame is directed + * - frame is from an AP and we know about that AP + * + * It is possible that either we don't know about an AP or that + * we do but this frame comes from another AP in range. + */ + +static uint8_t change_channel_cmd_is_valid(mrfiPacket_t *frame) +{ + uint8_t rc = 0; + addr_t const *apAddr; + + /* If this was a directed frame obey the command. */ + if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + rc = 1; + } + else + { + /* Do we know about an AP? If not assume frame bogus. */ + apAddr = nwk_getAPAddress(); + if (apAddr) + { + /* Yes, we know about an AP. Is that who sent it? */ + if (!memcmp(apAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + /* OK. We obey. */ + rc = 1; + } + } + } + + return rc; +} + +# endif /* !ACCESS_POINT */ + +# ifdef RANGE_EXTENDER + +/****************************************************************************** + * @fn replayFirst + * + * @brief Range Extenders must replay the change-channel boradcast + * frame before actually changing its own channel. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return void + */ + +/* This routine takes care of some awkwardness. From the dispatch thread all + * we have is a pointer to the mrfiPacket_t element in the frame buffer into + * which the frame was retrieved. But to call the replay routine we need the + * entire frame information structure frameInfo_t. This routine regenerates + * the frame information structure pointer and then calls the replay routine. + * + * This approach requires that the disptach thread guarantee that it will + * always pass a pointer to the mrfiPacket_t structure in the frame + * information structure and not a copy of the mrfipacket_t element. It is + * either the approach here or change all the NWK application dispatch routine + * argument types. This latter has the downside of interfering with any + * user-implemented NWK applications. It also needlessly complicates the argument + * handling: except for this instance all any routine needs is the mrfiPacket_t + * pointer. + */ + +static void replayFirst(mrfiPacket_t *frame) +{ + frameInfo_t *fiptr; + uint16_t offset = (uint16_t)&(((frameInfo_t *)0)->mrfiPkt); + + fiptr = (frameInfo_t *)(((uint8_t *)frame) - ((uint8_t *)offset)); + + nwk_replayFrame(fiptr); + + return; +} + +# endif /* RANGE_EXTENDER */ + +# ifndef ACCESS_POINT + +/******************************************************************************** + * @fn change_channel_cmd + * + * @brief Change to channel specified in received frame. Polling devices + * might be awake when the broadcast occurs but we want the channel + * change recovery to occur in a disciplined manner using the + * polling code. Also, with certain Test sceanrios in which a + * sleeping device is emulated we want to emulate 'missing' the + * broadcast change-channel command. + * + * input parameters + * @param frame - pointer to frame containing target logical channel. + * + * @return none. + */ + +static void change_channel_cmd(mrfiPacket_t *frame) +{ +# if !defined(RX_POLLS) + freqEntry_t chan; + + chan.logicalChan = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + F_CHAN_OS); + + nwk_setChannel(&chan); +# endif + return; +} + +# endif /* !ACCESS_POINT */ + +/****************************************************************************** + * @fn send_ping_reply + * + * @brief Send Frequency application ping reply. + * + * input parameters + * @param frame - pointer to frame from pinger. + * + * @return FHS_RELEASE unless this isn't an Access Point. In this case for + * flow to et this far it is a Range Extender, so replay the frame + * by returning FHW_REPLAY + */ + +static fhStatus_t send_ping_reply(mrfiPacket_t *frame) +{ +# ifdef ACCESS_POINT + uint8_t msg[FREQ_REQ_PING_FRAME_SIZE]; + frameInfo_t *pOutFrame; + + /* original request with reply bit on */ + msg[FB_APP_INFO_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS) | NWK_APP_REPLY_BIT; + msg[FB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + FB_TID_OS); + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_FREQ, msg, sizeof(msg), MAX_HOPS_FROM_AP)) + { + /* destination address is the source address of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + /* must use transaction ID of source frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_TRACTID_OS, + (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS))); +# ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +# endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + + return FHS_RELEASE; +# else + return FHS_REPLAY; +# endif /* ACCESS_POINT */ +} + +/**************************************************************************************** + * @fn nwk_processFreq + * + * @brief Process a Frequency application frame. + * + * input parameters + * @param frame - pointer to frame + * + * @return Disposition for frame: either release (FHS_RELEASE) or replay (FHS_REPLAY). + */ + +fhStatus_t nwk_processFreq(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + uint8_t replyType; + + /* Make sure this is a reply and see if we sent this. Validate the + * packet for reception by client app. + */ + if (SMPL_MY_REPLY == (replyType = nwk_isValidReply(frame, sTid, FB_APP_INFO_OS, FB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +# if !defined(END_DEVICE) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +# endif /* !END_DEVICE */ + else if (SMPL_NOT_REPLY == replyType) + { + rc = handle_freq_cmd(frame); + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_scanForChannels + * + * @brief Scan for channels by sending a ping frame on each channel in the + * channel table and listen for a reply. + * + * input parameters + * @param channels - pointer to area to receive list of channels from which + * ping replies were received. + * + * output parameters + * @param channels - populated list of channels. + * + * @return statuis of operation.. + */ + +uint8_t nwk_scanForChannels(freqEntry_t *channels) +{ + uint8_t msg[FREQ_REQ_PING_FRAME_SIZE], i, num = 0, notBcast = 1; + addr_t *apAddr, retAddr; + uint8_t radioState = MRFI_GetRadioState(); + freqEntry_t chan; + freqEntry_t curChan; + + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + nwk_getChannel(&curChan); + + /* send to AP. If we don't know AP address, broadcast. */ + apAddr = (addr_t *)nwk_getAPAddress(); + if (!apAddr) + { + apAddr = (addr_t *)nwk_getBCastAddress(); + notBcast = 0; + } + + for (i = 0; i < NWK_FREQ_TBL_SIZE; ++i) + { + chan.logicalChan = i; + + nwk_setChannel(&chan); + + ioctl_info.send.addr = apAddr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_FREQ; + + msg[FB_APP_INFO_OS] = FREQ_REQ_PING; + msg[FB_TID_OS] = sTid; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + ioctl_info.recv.port = SMPL_PORT_FREQ; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = &retAddr; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + /* Once we know the Access Point we're related to we only accept + * ping replies from that one. + */ + if (!notBcast || (notBcast && !memcmp(&retAddr, apAddr, NET_ADDR_SIZE))) + { + channels[num++].logicalChan = i; + } + } + + sTid++; + if (num && notBcast) + { + /* we're done...only one possible channel if we know the AP address. */ + break; + } + /* TODO: process encryption stuff */ + } + + /* reset original channel */ + nwk_setChannel(&curChan); + + return num; +} + +/****************************************************************************** + * @fn nwk_freqControl + * + * @brief Handle application requests received through IOCTL interface. + * + * input parameters + * @param action - requested action + * @param val - pointer to parameters required/returned for action + * + * output parameters + * @param val - populated values if action was a retrieval action. + * + * @return status of operation. + */ + +smplStatus_t nwk_freqControl(ioctlAction_t action, void *val) +{ + smplStatus_t rc; + + switch (action) + { + case IOCTL_ACT_SET: +# ifdef ACCESS_POINT + broadcast_channel_change(((freqEntry_t *)val)->logicalChan); +# endif /* ACCESS_POINT */ + rc = nwk_setChannel((freqEntry_t *)val); + break; + + case IOCTL_ACT_GET: + nwk_getChannel((freqEntry_t *)val); + rc = SMPL_SUCCESS; + break; + + case IOCTL_ACT_SCAN: + { + ioctlScanChan_t *sc = (ioctlScanChan_t *)val; + + sc->numChan = nwk_scanForChannels(sc->freq); + rc = SMPL_SUCCESS; + } + break; + + default: + rc = SMPL_BAD_PARAM; + break; + } + + return rc; +} + +/****************************************************************************** + * @fn broadcast_channel_change + * + * @brief For Access Point only: broadcast a channel change frame. + * + * input parameters + * @param idx - index into channel table of new (logical) channel + * + * @return none. + */ +# ifdef ACCESS_POINT +# define CC_REDUNDANCY 1 /* Change-channel redundancy count */ +static void broadcast_channel_change(uint8_t idx) +{ + ioctlRawSend_t send; + uint8_t msg[FREQ_REQ_MOVE_FRAME_SIZE]; + uint8_t repeat = CC_REDUNDANCY; + + if (idx >= NWK_FREQ_TBL_SIZE) + { + return; + } + + msg[FB_APP_INFO_OS] = FREQ_REQ_MOVE; + msg[F_CHAN_OS] = idx; + + send.addr = (addr_t *)nwk_getBCastAddress(); + send.msg = msg; + send.len = sizeof(msg); + send.port = SMPL_PORT_FREQ; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); + + /* Redundancy addresses the fact that an RE (or any always-listening + * device) might miss the command + */ + while (repeat--) + { + NWK_DELAY(250); + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); + } +} + +# endif /* ACCESS_POINT */ + +#else /* FREQUENCY_AGILITY */ + +/********************************************************************************** + * @fn nwk_freqInit + * + * @brief Initialize NWK Frequency application. Stub when Frequency Agility + * not supported. + * + * @return none. + */ + +void nwk_freqInit(void) +{ + return; +} + +/**************************************************************************************** + * @fn nwk_processFreq + * + * @brief Process a Frequency application frame. Stub when Frequency Agility + * not supported. + * + * input parameters + * @param frame - pointer to frame + * + * @return Disposition for frame: either release (FHS_RELEASE) or replay (FHS_REPLAY). + */ + +fhStatus_t nwk_processFreq(mrfiPacket_t *frame) +{ + return FHS_RELEASE; +} + +#endif /* FREQUENCY_AGILITY */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.h new file mode 100755 index 0000000..05c9b41 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.h @@ -0,0 +1,74 @@ +/************************************************************************************************** +* Filename: nwk_freq.h +* Revised: $Date: 2008-05-06 16:48:33 -0700 (Tue, 06 May 2008) $ +* Revision: $Revision: 17025 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI Freq network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_FREQ_H +#define NWK_FREQ_H + +/* application payload offsets + * both */ +#define FB_APP_INFO_OS 0 +#define FB_TID_OS 1 + +/* Logical channel number for MOVE request. Frame brodcast so no TID + * is used. Channel number can occupy the TID location. Same offset + * used for channel change request. No reply to that frame. + */ +#define F_CHAN_OS 1 + +/* MGMT frame application requests */ +#define FREQ_REQ_MOVE 0x01 +#define FREQ_REQ_PING 0x02 +#define FREQ_REQ_REQ_MOVE 0x03 + +/* change the following as protocol developed */ +#define MAX_FREQ_APP_FRAME 2 + +/* set the out frame sizes */ +#define FREQ_REQ_MOVE_FRAME_SIZE 2 +#define FREQ_REQ_PING_FRAME_SIZE 2 + +/* prototypes */ +void nwk_freqInit(void); +fhStatus_t nwk_processFreq(mrfiPacket_t *); + +#if defined(FREQUENCY_AGILITY) +smplStatus_t nwk_setChannel(freqEntry_t *); +void nwk_getChannel(freqEntry_t *); +uint8_t nwk_scanForChannels(freqEntry_t *); + +smplStatus_t nwk_freqControl(ioctlAction_t, void *); +#endif + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.c new file mode 100755 index 0000000..9d88be2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.c @@ -0,0 +1,356 @@ + +/************************************************************************************************** +* Filename: nwk_ioctl.c +* Revised: $Date: 2009-01-13 11:31:14 -0800 (Tue, 13 Jan 2009) $ +* Revision: $Revision: 18744 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI IOCTL implmentation. This interface +* gives applications access to the "driver" network level functions +* when necessary. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_ioctl.h" +#include "nwk_globals.h" +#include "nwk_security.h" +#ifdef ACCESS_POINT +# include "nwk_join.h" +#endif + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + + +/****************************************************************************** + * @fn nwk_rawSend + * + * @brief Builds an outut frame based on information provided by the + * caller. This function allows a raw transmission to the target + * if the network address is known. this function is used a lot + * to support NWK applications. + * + * input parameters + * @param info - pointer to strcuture containing info on how to build + * the outgoing frame. + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_NOMEM - no room in output frame queue + * SMPL_TX_CCA_FAIL - CCA failure + */ + +smplStatus_t nwk_rawSend(ioctlRawSend_t *info) +{ + frameInfo_t *pOutFrame; + uint8_t hops; + + /* If we know frame is going to or from the AP then we can reduce the hop + * count. + */ + switch (info->port) + { + case SMPL_PORT_JOIN: + case SMPL_PORT_FREQ: + case SMPL_PORT_MGMT: + hops = MAX_HOPS_FROM_AP; + break; + + default: + hops = MAX_HOPS; + break; + } + + if (pOutFrame = nwk_buildFrame(info->port, info->msg, info->len, hops)) + { + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), info->addr, NET_ADDR_SIZE); +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, info->len, 0); +#endif /* SMPL_SECURE */ + return nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_CCA); + } + return SMPL_NOMEM; +} + +/****************************************************************************** + * @fn nwk_rawReceive + * + * @brief Retriievs specified from from the input frame queue. Additional + * information such as source address and hop count may also be + * retrieved + * + * input parameters + * @param info - pointer to structure containing info on what to retrieve + * + * output parameters - actually populated by nwk_retrieveFrame() + * info->msg - application payload copied here + * info->len - length of received application payload + * info->addr - if non-NULL points to memory to be populated with + * source address of retrieved frame. + * info->hopCount - if non-NULL points to memory to be populated with + * hop count of retrieved frame. + * + * @return Status of operation. + */ + +smplStatus_t nwk_rawReceive(ioctlRawReceive_t *info) +{ + rcvContext_t rcv; + + rcv.type = RCV_NWK_PORT; + rcv.t.port = info->port; + + return nwk_retrieveFrame(&rcv, info->msg, &info->len, info->addr, &info->hopCount); +} + +/****************************************************************************** + * @fn nwk_radioControl + * + * @brief Handle radio control functions. + * + * input parameters + * @param action - radio operation to perform. currently suppoerted: + * sleep/unsleep + * output parameters + * + * @return Status of operation. + */ + +smplStatus_t nwk_radioControl(ioctlAction_t action, void *val) +{ + smplStatus_t rc = SMPL_SUCCESS; + + if (IOCTL_ACT_RADIO_SLEEP == action) + { + /* go to sleep mode. */ + MRFI_RxIdle(); + MRFI_Sleep(); + } + else if (IOCTL_ACT_RADIO_AWAKE == action) + { + MRFI_WakeUp(); + +#if !defined(END_DEVICE) + MRFI_RxOn(); +#endif + + } + else if (IOCTL_ACT_RADIO_SIGINFO == action) + { + ioctlRadioSiginfo_t *pSigInfo = (ioctlRadioSiginfo_t *)val; + connInfo_t *pCInfo = nwk_getConnInfo(pSigInfo->lid); + + if (!pCInfo) + { + return SMPL_BAD_PARAM; + } + memcpy(&pSigInfo->sigInfo, &pCInfo->sigInfo, sizeof(pCInfo->sigInfo)); + } + else if (IOCTL_ACT_RADIO_RSSI == action) + { + *((rssi_t *)val) = MRFI_Rssi(); + } + else if (IOCTL_ACT_RADIO_RXON == action) + { + MRFI_RxOn(); + } + else if (IOCTL_ACT_RADIO_RXIDLE == action) + { + MRFI_RxIdle(); + } +#ifdef EXTENDED_API + else if (IOCTL_ACT_RADIO_SETPWR == action) + { + uint8_t idx; + + switch (*(ioctlLevel_t *)val) + { + case IOCTL_LEVEL_2: + idx = 2; + break; + + case IOCTL_LEVEL_1: + idx = 1; + break; + + case IOCTL_LEVEL_0: + idx = 0; + break; + + default: + return SMPL_BAD_PARAM; + } + MRFI_SetRFPwr(idx); + return SMPL_SUCCESS; + } +#endif /* EXTENDED_API */ + else + { + rc = SMPL_BAD_PARAM; + } + return rc; +} + +/****************************************************************************** + * @fn nwk_joinContext + * + * @brief For Access Points we need a way to support changing the Join + * context. This will allow arbitration bewteen potentially nearby + * Access Points when a new device is joining. + * + * input parameters + * @param action - Join context is either on or off. + * + * output parameters + * + * @return Status of operation. Currently always succeeds. + */ +#ifdef ACCESS_POINT +smplStatus_t nwk_joinContext(ioctlAction_t action) +{ + nwk_setJoinContext((IOCTL_ACT_ON == action) ? JOIN_CONTEXT_ON : JOIN_CONTEXT_OFF); + + return SMPL_SUCCESS; +} + +#endif + +/****************************************************************************** + * @fn nwk_deviceAddress + * + * @brief Set or Get this device address. The Set must be done before + * SMPL_Init() for it to take effect. The Get is always legal but + * the value could be invalid if it is called before a valid set + * call is made. + * + * input parameters + * @param action - Gte or Set + * @param addr - pointer to address object containing value on Set + * + * output parameters + * @param addr - pointer to address object to receive value on Get. + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Action request illegal or a Set request + * was not respected. + */ + +smplStatus_t nwk_deviceAddress(ioctlAction_t action, addr_t *addr) +{ + smplStatus_t rc = SMPL_BAD_PARAM; + + if (IOCTL_ACT_GET == action) + { + memcpy(addr, nwk_getMyAddress(), sizeof(addr_t)); + rc = SMPL_SUCCESS; + } + else if (IOCTL_ACT_SET == action) + { + if (nwk_setMyAddress(addr)) + { + rc = SMPL_SUCCESS; + } + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_connectionControl + * + * @brief Access to connection table. Currently supports only deleting + * a connection from the table. + * + * input parameters + * @param action - Connection control action (only delete is curently valid). + * @param val - pointer to Link ID of connection on which to operate. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Action is not delete + * Link ID is the UUD Link ID + * No connection table info for Link ID + */ + +smplStatus_t nwk_connectionControl(ioctlAction_t action, void *val) +{ + connInfo_t *pCInfo; + linkID_t lid = *((linkID_t *)val); + + if (IOCTL_ACT_DELETE != action) + { + return SMPL_BAD_PARAM; + } + + if ((SMPL_LINKID_USER_UUD == lid) || + (!(pCInfo = nwk_getConnInfo(lid)))) + { + return SMPL_BAD_PARAM; + } + + nwk_freeConnection(pCInfo); + + return SMPL_SUCCESS; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.h new file mode 100755 index 0000000..3b583a9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.h @@ -0,0 +1,54 @@ +/************************************************************************************************** +* Filename: nwk_ioctl.h +* Revised: $Date: 2008-04-29 15:47:05 -0700 (Tue, 29 Apr 2008) $ +* Revision: $Revision: 16972 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI IOCTL implmentation. This interface +* gives applications access to the "driver" network level functions +* when necessary. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + + +#ifndef NWK_IOCTL_H +#define NWK_IOCTL_H + +/* prototypes */ +smplStatus_t nwk_rawSend(ioctlRawSend_t *); +smplStatus_t nwk_rawReceive(ioctlRawReceive_t *); + +smplStatus_t nwk_radioControl(ioctlAction_t, void *); +smplStatus_t nwk_deviceAddress(ioctlAction_t, addr_t *); +smplStatus_t nwk_connectionControl(ioctlAction_t, void *); +#ifdef ACCESS_POINT +smplStatus_t nwk_joinContext(ioctlAction_t); +#endif + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_join.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_join.c new file mode 100755 index 0000000..039bddd --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_join.c @@ -0,0 +1,599 @@ +/************************************************************************************************** +* Filename: nwk_join.c +* Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ +* Revision: $Revision: 18697 $ +* +* Description: This file supports the SimpliciTI Join network application. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_link.h" +#include "nwk_join.h" +#include "nwk_globals.h" +#include "nwk_freq.h" +#include "nwk_security.h" +#include "nwk_mgmt.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +static uint32_t sJoinToken = 0; +static uint8_t (*spCallback)(linkID_t) = NULL; +static volatile uint8_t sTid = 0; + +#ifdef ACCESS_POINT +static sfInfo_t *spSandFContext = NULL; +static uint8_t sJoinOK = 0; +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +#ifdef ACCESS_POINT +static void smpl_send_join_reply(mrfiPacket_t *frame); +static uint32_t generateLinkToken(void); +static void handleJoinRequest(mrfiPacket_t *); + +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_joinInit + * + * @brief Initialize Join application. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_joinInit(uint8_t (*pf)(linkID_t)) +{ + if (!sJoinToken) + { + sJoinToken = DEFAULT_JOIN_TOKEN; + } + + spCallback = pf; + (void) spCallback; /* keep compiler happy if we don't use this */ + + sTid = MRFI_RandomByte(); + +#ifdef ACCESS_POINT + /* set link token to something other than deafult if desired */ + nwk_setLinkToken(generateLinkToken()); +# if defined(STARTUP_JOINCONTEXT_ON) + sJoinOK = 1; +# elif defined(STARTUP_JOINCONTEXT_OFF) + sJoinOK = 0; +# else +# error ERROR: Must define either STARTUP_JOINCONTEXT_ON or STARTUP_JOINCONTEXT_OFF +# endif + spSandFContext = nwk_getSFInfoPtr(); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_setJoinToken + * + * @brief Sets the join token. + * + * input parameters + * @param token - join token to be used on this network. + * + * output parameters + * no room in output queue. + * + * @return void + */ + +void nwk_setJoinToken(uint32_t token) +{ + /* only set if the supplied token is non-zero. */ + if (token) + { + sJoinToken = token; + } + + return; +} + +/****************************************************************************** + * @fn nwk_getJoinToken + * + * @brief Gets the current join token. + * + * input parameters + * + * output parameters + * @param pToken - pointer to the returned value. + * + * @return Current link token + */ + +void nwk_getJoinToken(uint32_t *pToken) +{ + /* only set if the supplied token is non-zero. */ + if (pToken) + { + *pToken = sJoinToken; + } + + return; +} + +/****************************************************************************** + * @fn generateLinkToken + * + * @brief Generate the link token to be used for the network controlled + * by this Access Point. + * + * input parameters + * + * output parameters + * + * @return void + */ +#ifdef ACCESS_POINT +static uint32_t generateLinkToken(void) +{ + return 0xDEADBEEF; +} + +/****************************************************************************** + * @fn smpl_send_join_reply + * + * @brief Send the Join reply. Include the Link token. If the device is + * a polling sleeper put it into the list of store-and-forward + * clients. + * + * input parameters + * @param frame - join frame for which a reply is needed...maybe + * + * output parameters + * + * @return void + */ + +static void smpl_send_join_reply(mrfiPacket_t *frame) +{ + frameInfo_t *pOutFrame; + uint8_t msg[JOIN_REPLY_FRAME_SIZE]; + + /* Is this a legacy frame? If so continue. Otherwise check verion.*/ + if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > JOIN_LEGACY_MSG_LENGTH) + { + /* see if protocol version is correct... */ + if (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + J_PROTOCOL_VERSION_OS) != + nwk_getProtocolVersion()) + { + /* Accommodation of protocol version differences can be noted or accomplished here. + * Otherwise, no match and the board goes back + */ + return; + } + } + + + /* see if join token is correct */ + { + uint32_t jt; + + nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD( + frame) + F_APP_PAYLOAD_OS + J_JOIN_TOKEN_OS, &jt, sizeof(jt)); + if (jt != sJoinToken) + { + return; + } + } + + /* send reply with tid, the link token, and the encryption context */ + { + uint32_t linkToken; + + nwk_getLinkToken(&linkToken); + nwk_putNumObjectIntoMsg((void *)&linkToken, msg + JR_LINK_TOKEN_OS, sizeof(linkToken)); + } + msg[JR_CRYPTKEY_SIZE_OS] = SEC_CRYPT_KEY_SIZE; + msg[JB_REQ_OS] = JOIN_REQ_JOIN | NWK_APP_REPLY_BIT; + /* sender's tid... */ + msg[JB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + JB_TID_OS); + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_JOIN, msg, sizeof(msg), MAX_HOPS_FROM_AP)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + +# ifdef AP_IS_DATA_HUB + /* if source device supports ED objects save source address to detect duplicate joins */ + if (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + J_NUMCONN_OS)) + { + if (nwk_saveJoinedDevice(frame) && spCallback) + { + spCallback(0); + } + } +# endif + } + else + { + /* oops -- no room left for Tx frame. Don't send reply. */ + return; + } + + /* If this device polls we need to provide store-and-forward support */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_RX_TYPE) == F_RX_TYPE_POLLS) + { + uint8_t loc; + + /* Check duplicate status */ + if (!nwk_isSandFClient(MRFI_P_SRC_ADDR(frame), &loc)) + { + uint8_t *pNumc = &spSandFContext->curNumSFClients; + sfClientInfo_t *pClient = &spSandFContext->sfClients[*pNumc]; + + /* It's not a duplicate. Save it if there's room */ + if (*pNumc < NUM_STORE_AND_FWD_CLIENTS) + { + memcpy(pClient->clientAddr.addr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + *pNumc = *pNumc + 1; + } + else + { + /* No room left. Just return and don't send reply. */ + return; + } + } + else + { + /* We get here if it's a duplicate. We drop through and send reply. + * Reset the S&F marker in the Management application -- we should + * assume that the Client reset so the TID will be random. If this is + * simply a duplicate frame it causes no harm. + */ + nwk_resetSFMarker(loc); + } + } + +# ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +# endif /* SMPL_SECURE */ + + /* It's not S&F or it is but we're OK to send reply. */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +/****************************************************************************** + * @fn nwk_join + * + * @brief Stub Join function for Access Points. + * + * input parameters + * + * output parameters + * + * @return Always returns SMPL_SUCCESS. + */ + +smplStatus_t nwk_join(void) +{ + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_isSandFClient + * + * @brief Helper function to see if the destination of a frame we have is + * one of AP's store-and-forward clients. + * + * input parameters + * @param fPtr - pointer to address in frame in question + * + * output parameters + * @param entLoc - pointer to receive entry location in array of clients. + * + * @return Returns client info structure pointer if the destination is a + * store-and-forward client, else 0. + */ + +sfClientInfo_t *nwk_isSandFClient(uint8_t *pAddr, uint8_t *entLoc) +{ + uint8_t i; + sfClientInfo_t *pSFClient = spSandFContext->sfClients; + + for (i = 0; i < spSandFContext->curNumSFClients; ++i, ++pSFClient) + { + if (!memcmp(&pSFClient->clientAddr.addr, pAddr, NET_ADDR_SIZE)) + { + *entLoc = i; + return pSFClient; + } + } + + return 0; +} + +/****************************************************************************** + * @fn nwk_setJoinContext + * + * @brief Helper function to set Join context for Access Point. This will + * allow arbitration bewteen potentially nearby Access Points when + * a new device is joining. + * + * input parameters + * @param which - Join context is either off or on + * + * output parameters + * + * @return void + */ + +void nwk_setJoinContext(uint8_t which) +{ + sJoinOK = (JOIN_CONTEXT_ON == which) ? 1 : 0; + + return; +} + +/****************************************************************************** + * @fn handleJoinRequest + * + * @brief Dispatches handler for specfic join request + * + * input parameters + * + * @param frame - Join frame received + * + * output parameters + * + * @return void + */ + +static void handleJoinRequest(mrfiPacket_t *frame) +{ + if (JOIN_LEGACY_MSG_LENGTH == (MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS)) + { + /* Legacy frame. Spoof a join request */ + *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS) = JOIN_REQ_JOIN; + } + + switch (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS)) + { + case JOIN_REQ_JOIN: + smpl_send_join_reply(frame); + break; + + default: + break; + } + + return; +} + +#else /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_join + * + * @brief Join functioanlity for non-AP devices. Send the Join token + * and wait for the reply. + * + * input parameters + * + * output parameters + * + * @return Status of operation. + */ + +smplStatus_t nwk_join(void) +{ + uint8_t msg[JOIN_FRAME_SIZE]; + uint32_t linkToken; + addr_t apAddr; + uint8_t radioState = MRFI_GetRadioState(); + smplStatus_t rc = SMPL_NO_JOIN; + + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + +# if defined(FREQUENCY_AGILITY) + uint8_t i, numChan; + freqEntry_t channels[NWK_FREQ_TBL_SIZE]; + + if (!(numChan = nwk_scanForChannels(channels))) + { + return SMPL_NO_CHANNEL; + } + + for (i = 0; i < numChan; ++i) + { + nwk_setChannel(&channels[i]); +# else + { +# endif + + ioctl_info.send.addr = (addr_t *)nwk_getBCastAddress(); + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_JOIN; + + /* Put join token in */ + nwk_putNumObjectIntoMsg((void *)&sJoinToken, msg + J_JOIN_TOKEN_OS, sizeof(sJoinToken)); + /* set app info byte */ + msg[JB_REQ_OS] = JOIN_REQ_JOIN; + msg[JB_TID_OS] = sTid; + + /* Set number of connections supported. Used only by AP if it is + * a data hub. + */ + msg[J_NUMCONN_OS] = NUM_CONNECTIONS; + /* protocol version number */ + msg[J_PROTOCOL_VERSION_OS] = nwk_getProtocolVersion(); + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + ioctl_info.recv.port = SMPL_PORT_JOIN; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = &apAddr; /* save AP address from reply */ + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + uint8_t firstByte = msg[JB_REQ_OS] & (~NWK_APP_REPLY_BIT); + + /* Sanity check for correct reply frame. Older version + * has the length instead of the request as the first byte. + */ + if ((firstByte == JOIN_REQ_JOIN) || + (firstByte == JOIN_REPLY_LEGACY_MSG_LENGTH) + ) + { + /* join reply returns link token */ + memcpy(&linkToken, msg + JR_LINK_TOKEN_OS, sizeof(linkToken)); + + nwk_setLinkToken(linkToken); + /* save AP address */ + nwk_setAPAddress(&apAddr); + sTid++; /* guard against duplicates */ + rc = SMPL_SUCCESS; +# if defined(FREQUENCY_AGILITY) + break; +# endif + } + } + /* TODO: process encryption stuff */ + } + + return rc; + +} + +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_processJoin + * + * @brief Processes a Join frame. If this is a reply let it go to the + * application. Otherwise generate and send the reply. + * + * input parameters + * @param frame - Pointer to Join frame + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ + +fhStatus_t nwk_processJoin(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + uint8_t replyType; + + /* Make sure this is a reply and see if we sent this. Validate the + * packet for reception by client app. + */ + if (SMPL_MY_REPLY == (replyType = nwk_isValidReply(frame, sTid, JB_REQ_OS, JB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if defined(ACCESS_POINT) + else if (SMPL_A_REPLY == replyType) + { + /* No match. If I'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } + else + { + /* Send reply if we're an Access Point otherwise ignore the frame. */ + if ((SMPL_NOT_REPLY == replyType) && sJoinOK) + { + handleJoinRequest(frame); + } + } +#elif defined(RANGE_EXTENDER) + else + { + /* Either a reply that has to be replayed or a request that + * also must be replayed. + */ + rc = FHS_REPLAY; + } +#endif /* not END_DEVICE */ + + (void) replyType; /* keep compiler happy */ + + return rc; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_join.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_join.h new file mode 100755 index 0000000..63ff2c4 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_join.h @@ -0,0 +1,94 @@ +/************************************************************************************************** +* Filename: nwk_join.h +* Revised: $Date: 2009-01-06 12:26:02 -0800 (Tue, 06 Jan 2009) $ +* Revision: $Revision: 18693 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI Join network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_JOIN_H +#define NWK_JOIN_H + +#define JOIN_CONTEXT_ON (0x01) +#define JOIN_CONTEXT_OFF (0x02) + +/* Macros needed for protocol backward compatibility */ +#define JOIN_LEGACY_MSG_LENGTH 7 +#define JOIN_REPLY_LEGACY_MSG_LENGTH 6 + +/* place holder... */ +#define SEC_CRYPT_KEY_SIZE 0 + +/* application payload offsets + * both */ +#define JB_REQ_OS 0 +#define JB_TID_OS 1 +/* join frame */ +#define J_JOIN_TOKEN_OS 2 +#define J_NUMCONN_OS 6 +#define J_PROTOCOL_VERSION_OS 7 +/* join reply frame */ +#define JR_LINK_TOKEN_OS 2 +#define JR_CRYPTKEY_SIZE_OS 6 +#define JR_CRYPTKEY_OS 7 + +/* change the following as protocol developed */ +#define MAX_JOIN_APP_FRAME (JR_CRYPTKEY_OS + SEC_CRYPT_KEY_SIZE) + +/* set out frame size */ +#define JOIN_FRAME_SIZE 8 +#define JOIN_REPLY_FRAME_SIZE MAX_JOIN_APP_FRAME + +/* join requests + * NOTE: If aditional command codes are required do _not_ use the + * value JOIN_REPLY_LEGACY_MSG_LENGTH. This numeral is used + * to guarantee that legacy Join frames (from before release + * 1.0.6) work correctly. Don't ask. + */ +#define JOIN_REQ_JOIN 1 + +/* prototypes */ +void nwk_joinInit(uint8_t (*)(linkID_t)); +smplStatus_t nwk_join(void); +fhStatus_t nwk_processJoin(mrfiPacket_t *); +void nwk_getJoinToken(uint32_t *); + +void nwk_setJoinContext(uint8_t); +void nwk_setJoinToken(uint32_t); +void nwk_getJoinToken(uint32_t *); + +#ifdef ACCESS_POINT +sfClientInfo_t *nwk_isSandFClient(uint8_t *, uint8_t *); + +#endif + +#endif + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_link.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_link.c new file mode 100755 index 0000000..8188970 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_link.c @@ -0,0 +1,886 @@ +/************************************************************************************************** +* Filename: nwk_link.c +* Revised: $Date: 2008-12-23 13:54:27 -0800 (Tue, 23 Dec 2008) $ +* Revision: $Revision: 18652 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Link network application. +* +* Copyright 2007-2008 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_link.h" +#include "nwk_globals.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static uint32_t sLinkToken = 0; +static volatile uint8_t sListenActive = 0; +#if NUM_CONNECTIONS > 0 +static volatile linkID_t sServiceLinkID[NUM_CONNECTIONS]; +#endif +static volatile uint8_t sNumLinkers = 0; +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +#define SENT_REPLY 1 +#define SENT_NO_REPLY 2 +static uint8_t smpl_send_link_reply(mrfiPacket_t *); +static fhStatus_t handleLinkRequest(mrfiPacket_t *); + +#if defined(EXTENDED_API) +static void smpl_send_unlink_reply(mrfiPacket_t *); + +#endif + + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_linkInit + * + * @brief Initialize link app. Set link token to the default. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_linkInit(void) +{ + if (!sLinkToken) + { + /* if the link token has not been set externally by the time we get here + * (such as by the ioctl token-setting interface) assign the default + */ + sLinkToken = DEFAULT_LINK_TOKEN; + } + + /* set a non-zero TID. */ + while (!(sTid = MRFI_RandomByte())) ; + +#if NUM_CONNECTIONS > 0 + memset((void *)&sServiceLinkID, 0x0, sizeof(sServiceLinkID)); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_setLinkToken + * + * @brief Sets the link token received in a Join reply. + * + * input parameters + * @param token - Link token to be used on this network to link to any peer. + * + * output parameters + * + * @return void + */ + +void nwk_setLinkToken(uint32_t token) +{ + /* only set if the supplied token is non-zero. */ + if (token) + { + sLinkToken = token; + } + + return; +} + +/****************************************************************************** + * @fn nwk_getLinkToken + * + * @brief Gets the current link token. + * + * input parameters + * + * output parameters + * @param pToken - pointer to the returned value. + * + * @return Current link token + */ + +void nwk_getLinkToken(uint32_t *pToken) +{ + /* only set if the supplied token is non-zero. */ + if (pToken) + { + *pToken = sLinkToken; + } + + return; +} + +#if defined(EXTENDED_API) + +/****************************************************************************** + * @fn nwk_unlink + * + * @brief Called from the application level to tear down a link. + * + * input parameters + * + * output parameters + * @param lid - Link ID assigned for this link + * + * @return Status of the operation. + * SMPL_SUCCESS + * SMPL_BAD_PARAM No connection table entry for this Link ID; + * SMPL_LINKID_USER_UUD not valid since it is not + * connection-based. + * SMPL_TIMEOUT No reply from peer. + * SMPL_NO_PEER_UNLINK Peer did not have a Connection Table entry for me. + */ + +smplStatus_t nwk_unlink(linkID_t lid) +{ + uint8_t msg[UNLINK_FRAME_SIZE]; + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_SUCCESS; + addr_t addr; + + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + /* is there connection info? */ + if (!pCInfo || (lid == SMPL_LINKID_USER_UUD)) + { + return SMPL_BAD_PARAM; + } + + /* set request byte */ + msg[LB_REQ_OS] = LINK_REQ_UNLINK; + + /* set the transaction ID. this allows target to figure out duplicates */ + msg[LB_TID_OS] = sTid; + + /* remote port to be sent in message to help match connection */ + msg[UL_RMT_PORT_OS] = pCInfo->portRx; + + /* setup for ioctl raw I/O */ + memcpy(addr.addr, pCInfo->peerAddr, NET_ADDR_SIZE); + ioctl_info.send.addr = &addr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_LINK; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + { + uint8_t spin = NWK_RX_RETRY_COUNT; + uint8_t radioState = MRFI_GetRadioState(); + + ioctl_info.recv.port = SMPL_PORT_LINK; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = (addr_t *)0; + + do + { + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + if ((msg[LB_REQ_OS] & (~NWK_APP_REPLY_BIT)) == LINK_REQ_UNLINK) + { + rc = (smplStatus_t)msg[ULR_RESULT_OS]; + break; + } + } + if (!spin) + { + rc = SMPL_TIMEOUT; + break; + } + --spin; + } while (1); + + /* it's ok to unconditionally invalidate connection object */ + nwk_freeConnection(pCInfo); + } + return rc; +} + +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn nwk_link + * + * @brief Called from the application level to accomplish the link + * + * input parameters + * + * output parameters + * @param lid - pointer to Link ID (port) assigned for this link + * + * @return Status of the operation. + */ + +smplStatus_t nwk_link(linkID_t *lid) +{ + uint8_t msg[LINK_FRAME_SIZE]; + connInfo_t *pCInfo = nwk_getNextConnection(); + smplStatus_t rc; + + if (pCInfo) + { + addr_t addr; + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + if (!nwk_allocateLocalRxPort(LINK_SEND, pCInfo)) + { + nwk_freeConnection(pCInfo); + return SMPL_NOMEM; + } + + memcpy(addr.addr, nwk_getBCastAddress(), NET_ADDR_SIZE); + ioctl_info.send.addr = &addr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_LINK; + + /* Put link token in */ + nwk_putNumObjectIntoMsg((void *)&sLinkToken, msg + L_LINK_TOKEN_OS, sizeof(sLinkToken)); + + /* set port to which the remote device should send */ + msg[L_RMT_PORT_OS] = pCInfo->portRx; + + /* set the transaction ID. this allows target to figure out duplicates */ + msg[LB_TID_OS] = sTid; + + /* set my Rx type */ + msg[L_MY_RXTYPE_OS] = nwk_getMyRxType(); + + /* set request byte */ + msg[LB_REQ_OS] = LINK_REQ_LINK; + + /* protocol version number */ + msg[L_PROTOCOL_VERSION_OS] = nwk_getProtocolVersion(); + +#if defined(SMPL_SECURE) + pCInfo->connTxCTR = MRFI_RandomByte() | \ + ((uint32_t)(MRFI_RandomByte()) << 8) | \ + ((uint32_t)(MRFI_RandomByte()) << 16) | \ + ((uint32_t)(MRFI_RandomByte()) << 24); + + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[L_CTR_OS], 4); +#endif + + + if (SMPL_SUCCESS != (rc = SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send))) + { + return rc; + } + + { + uint8_t radioState = MRFI_GetRadioState(); + + ioctl_info.recv.port = SMPL_PORT_LINK; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = (addr_t *)pCInfo->peerAddr; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + uint8_t firstByte = msg[LB_REQ_OS] & (~NWK_APP_REPLY_BIT); + + /* Sanity check for correct reply frame. Older version + * has the length instead of the request as the first byte. + */ + if ((firstByte != LINK_REQ_LINK) && + (firstByte != LINK_REPLY_LEGACY_MSG_LENGTH) + ) + { + /* invalidate connection object */ + nwk_freeConnection(pCInfo); + return SMPL_NO_LINK; + + } + } + else + { + /* no successful receive */ + nwk_freeConnection(pCInfo); + return SMPL_TIMEOUT; + } + + pCInfo->connState = CONNSTATE_CONNECTED; + pCInfo->portTx = msg[LR_RMT_PORT_OS]; /* link reply returns remote port */ + *lid = pCInfo->thisLinkID; /* return our local port number */ + + /* Set hop count. If it's a polling device set the count to the + * distance to the AP. Otherwise, set it to the max less the remaining + * which will be the path taken for this frame. It will be no worse + * then tha max and probably will be better. + */ + if (F_RX_TYPE_POLLS == msg[LR_MY_RXTYPE_OS]) + { + pCInfo->hops2target = MAX_HOPS_FROM_AP; + } + else + { + /* Can't really use this trick because the device could move. If the + * devices are all static this may work unless the initial reception + * was marginal. + */ +#if defined(DEVICE_DOES_NOT_MOVE) + pCInfo->hops2target = MAX_HOPS - ioctl_info.recv.hopCount; +#else + pCInfo->hops2target = MAX_HOPS; +#endif + } + +#if defined(SMPL_SECURE) + nwk_getNumObjectFromMsg((void *)&msg[LR_CTR_OS], (void *)&pCInfo->connRxCTR, 4); +#endif + } + + /* guard against duplicates... */ + ++sTid; + if (!sTid) + { + sTid = 1; + } + return SMPL_SUCCESS; + } + + return SMPL_NOMEM; +} + +#if defined(EXTENDED_API) + +/****************************************************************************** + * @fn smpl_send_unlink_reply + * + * @brief Send the unlink reply to the device trying to unlink + * + * input parameters + * @param frame - frame received from linker + * + * output parameters + * + * @return void + */ + +static void smpl_send_unlink_reply(mrfiPacket_t *frame) +{ + connInfo_t *pCInfo; + frameInfo_t *pOutFrame; + uint8_t msg[UNLINK_REPLY_FRAME_SIZE]; + smplStatus_t rc = SMPL_NO_PEER_UNLINK; + + /* match the remote port and source address with a connection table entry */ + if (pCInfo = + nwk_findPeer((addr_t *)MRFI_P_SRC_ADDR(frame), + *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + UL_RMT_PORT_OS))) + { + /* Note we unconditionally free the connection resources */ + nwk_freeConnection(pCInfo); + rc = SMPL_SUCCESS; + } + + /* set reply bit */ + msg[LB_REQ_OS] = LINK_REQ_UNLINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + LB_TID_OS); + + /* result of freeing local connection */ + msg[ULR_RESULT_OS] = rc; + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +# if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +# endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } +} + +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn smpl_send_link_reply + * + * @brief Send the link reply to the device trying to link. This routine + * will handle duplicates. + * + * input parameters + * @param frame - frame received from linker + * + * output parameters + * + * @return Returns SENT_REPLY if reply sent, else SENT_NO_REPLY. + * The return value is used as this routine unwinds to know + * whether to replay the frame. An RE or AP can host an ED + * object in which case it might send a reply (possibly from + * a duplicate frame). If we do reply we do not want to replay. + */ + +static uint8_t smpl_send_link_reply(mrfiPacket_t *frame) +{ +#if NUM_CONNECTIONS > 0 + frameInfo_t *pOutFrame; + connInfo_t *pCInfo; + uint8_t remotePort; + uint8_t msg[LINK_REPLY_FRAME_SIZE]; + + /* Is this a legacy frame? If so continue. Otherwise check version.*/ + if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > LINK_LEGACY_MSG_LENGTH) + { + /* see if protocol version is correct... */ + if (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_PROTOCOL_VERSION_OS) != + nwk_getProtocolVersion()) + { + /* Accommodation of protocol version differences can be noted or accomplished here. + * This field was also checked in the join transaction but it is checked again here + * because that check may not have occurred if thre is no AP in this topology. + * Otherwise, no match and the board goes back + */ + return SENT_NO_REPLY; + } + } + + /* see if token is correct */ + { + uint32_t lt; + + nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD( + frame) + F_APP_PAYLOAD_OS + L_LINK_TOKEN_OS, <, sizeof(lt)); + if (lt != sLinkToken) + { + return SENT_NO_REPLY; + } + } + + /* if we get here the token matched. */ + + /* is this a duplicate request? */ + remotePort = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_RMT_PORT_OS); + if (pCInfo = nwk_isLinkDuplicate(MRFI_P_SRC_ADDR(frame), remotePort)) + { + /* resend reply */ + msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + LB_TID_OS); + + /* Send reply with the local port number so the remote device knows where to + * send packets. + */ + msg[LR_RMT_PORT_OS] = pCInfo->portRx; + + /* put my Rx type in there. used to know how to set hops when sending back. */ + msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); +# if defined(SMPL_SECURE) + /* Set the Tx counter value for peer's Rx counter object */ + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); + /* We also need to save the newly generated Rx counter value. */ + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_CTR_OS), + (void *)&pCInfo->connRxCTR, 4); +# endif + if (pOutFrame = + nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS - + (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT)))) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +# if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +# endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + return SENT_REPLY; + } + + if (!sListenActive) + { + /* We've checked for duplicate and resent reply. In that case we weren't listening + * so just go back`. + */ + return SENT_NO_REPLY; + } + + /* room to link? */ +# if defined(AP_IS_DATA_HUB) + pCInfo = nwk_findAlreadyJoined(frame); + + if (!pCInfo) +# endif + { + pCInfo = nwk_getNextConnection(); + } + + if (pCInfo) + { + /* yes there's room and it's not a dup. address. */ + memcpy(&pCInfo->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + if (!nwk_allocateLocalRxPort(LINK_REPLY, pCInfo)) + { + nwk_freeConnection(pCInfo); + /* we're done with the packet */ + return SENT_REPLY; + } + + /* The local Rx port is the one returned in the connection structure. The + * caller is waiting on this to be set. The code here is running in an ISR + * thread so the caller will see this change after RETI. + */ + if (NUM_CONNECTIONS == sNumLinkers) + { + /* Something is wrong -- no room to stack Link request */ + nwk_freeConnection(pCInfo); + /* we're done with the packet */ + return SENT_REPLY; + } + sServiceLinkID[sNumLinkers++] = pCInfo->thisLinkID; + + /* save the remote Tx port */ + pCInfo->portTx = remotePort; + + /* connection is valid... */ + pCInfo->connState = CONNSTATE_CONNECTED; + + /* Set hop count. If it's a polling device set the count to the + * distance to the AP. otherwise, set it to the max less the remaining + * which will be the path taken for this frame. It will be no worse + * then tha max and probably will be better. + */ + if (F_RX_TYPE_POLLS == *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_MY_RXTYPE_OS)) + { + /* It polls. so. we'll be sending to the AP which will store the + * frame. The AP is only MAX_HOPS_FROM_AP hops away from us. + */ + pCInfo->hops2target = MAX_HOPS_FROM_AP; + } + else + { + /* Can't really use this trick because the device could move. If the + * devices are all static this may work unless the initial reception + * was marginal. + */ +# if defined(DEVICE_DOES_NOT_MOVE) + pCInfo->hops2target = MAX_HOPS - GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT); +# else + pCInfo->hops2target = MAX_HOPS; +# endif + } + + /* Send reply with the local port number so the remote device knows where to + * send packets. + */ + msg[LR_RMT_PORT_OS] = pCInfo->portRx; + + /* put my Rx type in there. used to know how to set hops when sending back. */ + msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); + + msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + LB_TID_OS); +# if defined(SMPL_SECURE) + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_CTR_OS), + (void *)&pCInfo->connRxCTR, 4); + pCInfo->connTxCTR = MRFI_RandomByte() | \ + ((uint32_t)(MRFI_RandomByte()) << 8) | \ + ((uint32_t)(MRFI_RandomByte()) << 16) | \ + ((uint32_t)(MRFI_RandomByte()) << 24); + + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); +# endif + if (pOutFrame = + nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS - + (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT)))) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +# if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +# endif + if (SMPL_SUCCESS != nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED)) + { + /* better release the connection structure */ + nwk_freeConnection(pCInfo); + } + } + else + { + /* better release the connection structure */ + nwk_freeConnection(pCInfo); + } + } + /* we're done with the packet */ + return SENT_REPLY; +#else + return SENT_NO_REPLY; +#endif /* NUM_CONNECTIONS */ +} + +/****************************************************************************** + * @fn nwk_processLink + * + * @brief Process Link frame. Just save the frame for the Link app if it + * a reply. If it isn't a reply, send the reply in this thread. + * + * input parameters + * @param frame - pointer to frame to be processed + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame.. + */ + +fhStatus_t nwk_processLink(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. send the reply. + */ + if (SMPL_MY_REPLY == (replyType = nwk_isValidReply(frame, sTid, LB_REQ_OS, LB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined(END_DEVICE) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* No, we didn't send it. Process request assuming it's + * intended for us. + */ + rc = handleLinkRequest(frame); + } + + (void) replyType; /* keep compiler happy when ED built... */ + + return rc; +} + +/****************************************************************************** + * @fn nwk_getLocalLinkID + * + * @brief This routine checks to see if a service port has been assigned + * as a result of a link reply frame being received. It is the means + * by which the user thread knows that the waiting is over for the + * link listen. the value is set in an interrupt thread. + * + * input parameters + * + * output parameters + * + * @return Local port assigned when the link reply was received. + */ + +linkID_t nwk_getLocalLinkID(void) +{ + linkID_t lid = 0; + +#if NUM_CONNECTIONS > 0 + uint8_t i; + bspIState_t intState; + + + BSP_ENTER_CRITICAL_SECTION(intState); + if (sNumLinkers) + { + sNumLinkers--; + BSP_EXIT_CRITICAL_SECTION(intState); + + nwk_setListenContext(LINK_LISTEN_OFF); + lid = sServiceLinkID[0]; + + /* If more than one Link frame has been processed without an intervening + * Listen assume that there will be another Link Listen call that will + * poll for completion which has already occurred. Age any existing entries. + * This code was added to deal with the possibility of mulitple EDs being + * activated simultaneously in the AP-as-data-hub example. This opens a + * window of opportunity for a "typical" scenario to get hosed. But for + * a "typical" scenario to get hosed a number of improbable events have to + * occur. These are deemed far less likely than the multiple-ED-activation + * scenario in the AP-as-dat-hub case. + */ + for (i = 0; i < sNumLinkers; ++i) + { + sServiceLinkID[i] = sServiceLinkID[i + 1]; + } + } + else + { + BSP_EXIT_CRITICAL_SECTION(intState); + } +#endif /* NUM_CONNECTIONS */ + + return lid; +} + +/****************************************************************************** + * @fn nwk_setListenContext + * + * @brief Sets the context when a LinkListen is executed. This prevents + * processing other link frames from being confused with the real + * one. Without this semaphore other broadcast link messages + * could wait int the input queue and accidently be processed if + * a listen is done later. + * + * input parameters + * + * @param context - listen on or off + * + * output parameters + * + * @return void + */ + +void nwk_setListenContext(uint8_t context) +{ + sListenActive = (context == LINK_LISTEN_ON) ? 1 : 0; +} + +/****************************************************************************** + * @fn handleLinkRequest + * + * @brief Dispatches handler for specfic link request + * + * input parameters + * + * @param frame - Link frame received + * + * output parameters + * + * @return void + */ + +static fhStatus_t handleLinkRequest(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + uint8_t isReplySent; + + if (LINK_LEGACY_MSG_LENGTH == (MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS)) + { + /* Legacy frame. Spoof a link request */ + *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS) = LINK_REQ_LINK; + } + + switch (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS)) + { + case LINK_REQ_LINK: + isReplySent = smpl_send_link_reply(frame); +#if !defined(END_DEVICE) + + /* If I am an AP or RE and not listening I need to replay frame. + * The exception is if I am an AP or RE hosting an End Device + * object and I just sent a reply frame to a duplicate link frame + * for which I was not listening. In this case don't replay. + */ + if (!sListenActive && (SENT_REPLY != isReplySent)) + { + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + break; + +#if defined(EXTENDED_API) + case LINK_REQ_UNLINK: + smpl_send_unlink_reply(frame); + break; +#endif + + default: + break; + } + + /* keep compiler happy if I'm compiled as an End Device */ + (void) isReplySent; + + return rc; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_link.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_link.h new file mode 100755 index 0000000..64ed033 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_link.h @@ -0,0 +1,108 @@ +/************************************************************************************************** +* Filename: nwk_link.h +* Revised: $Date: 2008-12-10 16:52:14 -0800 (Wed, 10 Dec 2008) $ +* Revision: $Revision: 18596 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI Join network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_LINK_H +#define NWK_LINK_H + +/* Macros needed for protocol backward compatibility */ +#define LINK_LEGACY_MSG_LENGTH 8 +#define LINK_REPLY_LEGACY_MSG_LENGTH 3 + + +#define LINK_LISTEN_ON 0 +#define LINK_LISTEN_OFF 1 + +/* application payload offsets + * both */ +#define LB_REQ_OS 0 +#define LB_TID_OS 1 + +/* link frame */ +#define L_LINK_TOKEN_OS 2 +#define L_RMT_PORT_OS 6 +#define L_MY_RXTYPE_OS 7 +#define L_PROTOCOL_VERSION_OS 8 +#define L_CTR_OS 9 +/* link reply frame */ +#define LR_RMT_PORT_OS 2 +#define LR_MY_RXTYPE_OS 3 +#define LR_CTR_OS 4 + +/* unlink frame */ +#define UL_RMT_PORT_OS 2 +/* unlink reply frame */ +#define ULR_RESULT_OS 2 + +/* change the following as protocol developed */ +#ifndef SMPL_SECURE +# define MAX_LINK_APP_FRAME 9 +#else +# define MAX_LINK_APP_FRAME 13 +#endif + +/* frame sizes */ +#ifndef SMPL_SECURE +# define LINK_FRAME_SIZE 9 +# define LINK_REPLY_FRAME_SIZE 4 +#else +# define LINK_FRAME_SIZE 13 +# define LINK_REPLY_FRAME_SIZE 8 +#endif +#define UNLINK_FRAME_SIZE 3 +#define UNLINK_REPLY_FRAME_SIZE 3 + +/* link requests + * NOTE: If aditional command codes are required do _not_ use the + * value LINK_REPLY_LEGACY_MSG_LENGTH. This numeral is used + * to guarantee that legacy Link frames (from before release + * 1.0.6) work correctly. Don't ask. + */ + +#define LINK_REQ_LINK 1 +#define LINK_REQ_UNLINK 2 + +/* prototypes */ +fhStatus_t nwk_processLink(mrfiPacket_t *); +linkID_t nwk_getLocalLinkID(void); +void nwk_linkInit(void); +smplStatus_t nwk_link(linkID_t *); + +smplStatus_t nwk_unlink(linkID_t); +void nwk_setLinkToken(uint32_t); +void nwk_getLinkToken(uint32_t *); + +void nwk_setListenContext(uint8_t); + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_mgmt.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_mgmt.c new file mode 100755 index 0000000..51253ac --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_mgmt.c @@ -0,0 +1,357 @@ +/************************************************************************************************** +* Filename: nwk_mgmt.c +* Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ +* Revision: $Revision: 18697 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Mgmt network application. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_mgmt.h" +#include "nwk_join.h" +#include "nwk_globals.h" +#include "nwk_QMgmt.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +#ifndef ACCESS_POINT +static addr_t const *sAPAddr = NULL; +#else +static uint8_t sSFMarker[NUM_STORE_AND_FWD_CLIENTS] = {0}; +#endif + +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static void smpl_send_mgmt_reply(mrfiPacket_t *); + +#ifdef ACCESS_POINT +static void send_poll_reply(mrfiPacket_t *); + +#endif + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_mgmtInit + * + * @brief Initialize Management functions. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_mgmtInit(void) +{ + sTid = MRFI_RandomByte(); + +#ifdef ACCESS_POINT + memset(&sSFMarker, 0x0, sizeof(sSFMarker)); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_processMgmt + * + * @brief Process Management frame. Just save the frame for the Management + * app it it is a reply. If it isn't a reply, send the reply in this + * thread. + * + * input parameters + * @param frame - pointer to frame to be processed + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ + +fhStatus_t nwk_processMgmt(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. send the reply. + */ + if (SMPL_MY_REPLY == (replyType = nwk_isValidReply(frame, sTid, MB_APP_INFO_OS, MB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined(END_DEVICE) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* no, we didn't send it. send reply if it's intended for us */ + if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + smpl_send_mgmt_reply(frame); + + /* we're done with the frame. */ + rc = FHS_RELEASE; + } + else + { + rc = FHS_REPLAY; + } + } + + (void) replyType; /* keep compiler happy */ + + return rc; +} + +/****************************************************************************** + * @fn smpl_send_mgmt_reply + * + * @brief Send appropriate reply to Management frame. + * + * input parameters + * @param frame - Pointer to frame for which reply required. + * + * output parameters + * + * @return void + */ + +static void smpl_send_mgmt_reply(mrfiPacket_t *frame) +{ +#ifdef ACCESS_POINT + /* what kind of management frame is this? */ + switch (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + MB_APP_INFO_OS)) + { + case MGMT_REQ_POLL: + send_poll_reply(frame); + break; + + default: + break; + } +#endif /* ACCESS_POINT */ + return; +} + +#ifdef ACCESS_POINT + +/****************************************************************************** + * @fn send_poll_reply + * + * @brief Send reply to polling frame. + * + * input parameters + * @param frame - Pointer to frame for which reply required. + * + * output parameters + * + * @return void + */ + +static void send_poll_reply(mrfiPacket_t *frame) +{ + uint8_t msgtid = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + MB_TID_OS); + frameInfo_t *pOutFrame; + sfClientInfo_t *pClientInfo; + uint8_t loc; + + /* Make sure this guy is really a client. We can tell from the source address. */ + if (!(pClientInfo = nwk_isSandFClient(MRFI_P_SRC_ADDR(frame), &loc))) + { + /* TODO: maybe send an error frame? */ + return; + } + + /* If we have to resync the TID then do it based on the first + * poll frame we see + */ + if (!sSFMarker[loc]) + { + /* If the marker flag is null then it has been initialized, i.e., + * there has been a reset. In this case infer that we need to update + * a (probably) stale last TID. The test will always be true the first + * time through after a client is established even when an NV restore + * did not take place but this does no harm. + */ + pClientInfo->lastTID = msgtid; + sSFMarker[loc] = 1; + } + + /* If we've seen this poll frame before ignore it. Otherwise we + * may send a stored frame when we shouldn't. + */ + else if (nwk_checkAppMsgTID(pClientInfo->lastTID, msgtid)) + { + pClientInfo->lastTID = msgtid; + } + else + { + return; + } + + if (pOutFrame = nwk_getSandFFrame(frame, M_POLL_PORT_OS)) + { + /* We need to adjust the order in the queue in this case. Currently + * we know it is in the input queue and that this adjustment is safe + * because we're in an ISR thread. This is a fragile fix, though, and + * should be revisited when time permits. + */ + nwk_QadjustOrder(INQ, pOutFrame->orderStamp); + + /* reset hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_HOP_COUNT, MAX_HOPS_FROM_AP); + /* It's gonna be a forwarded frame. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_FWD_FRAME, 0x80); + + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + else + { + nwk_SendEmptyPollRspFrame(frame); + } + + return; +} + +/****************************************************************************** + * @fn nwk_resetSFMarker + * + * @brief Reset S&F cklient marker so the TIDs resync. + * + * input parameters + * @param idx - index of the client that should be reset. + * + * output parameters + * + * @return void + */ + +void nwk_resetSFMarker(uint8_t idx) +{ + sSFMarker[idx] = 0; + + return; +} + +#else /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_poll + * + * @brief Poll S&F server for any waiting frames. + * + * input parameters + * @param port - Port on peer. + * @param addr - SimpliciTI address of peer. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_NO_AP_ADDRESS - We don't know Access Point's address + * SMPL_NOMEM - no room in output frame queue + * SMPL_TX_CCA_FAIL - CCA failure + */ + +smplStatus_t nwk_poll(uint8_t port, uint8_t *addr) +{ + uint8_t msg[MGMT_POLL_FRAME_SIZE]; + ioctlRawSend_t send; + + msg[MB_APP_INFO_OS] = MGMT_REQ_POLL; + msg[MB_TID_OS] = sTid; + msg[M_POLL_PORT_OS] = port; + memcpy(msg + M_POLL_ADDR_OS, addr, NET_ADDR_SIZE); + + /* it's OK to increment the TID here because the reply will not be + * matched based on this number. The reply to the poll comes back + * to the client port, not the Management port. + */ + sTid++; + + if (!sAPAddr) + { + sAPAddr = nwk_getAPAddress(); + if (!sAPAddr) + { + return SMPL_NO_AP_ADDRESS; + } + } + send.addr = (addr_t *)sAPAddr; + send.msg = msg; + send.len = sizeof(msg); + send.port = SMPL_PORT_MGMT; + + return SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); +} + +#endif /* ACCESS_POINT */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_mgmt.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_mgmt.h new file mode 100755 index 0000000..13bff76 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_mgmt.h @@ -0,0 +1,68 @@ +/************************************************************************************************** +* Filename: nwk_mgmt.h +* Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ +* Revision: $Revision: 18697 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI Mgmt network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_MGMT_H +#define NWK_MGMT_H + +/* MGMT frame application requests */ +#define MGMT_REQ_POLL 0x01 + +/* change the following as protocol developed */ +#define MAX_MGMT_APP_FRAME 7 + +/* application payload offsets + * both */ +#define MB_APP_INFO_OS 0 +#define MB_TID_OS 1 + +/* Poll frame */ +#define M_POLL_PORT_OS 2 +#define M_POLL_ADDR_OS 3 + +/* change the following as protocol developed */ +#define MAX_MGMT_APP_FRAME 7 + +/* frame sizes */ +#define MGMT_POLL_FRAME_SIZE 7 + +/* prototypes */ +void nwk_mgmtInit(void); +fhStatus_t nwk_processMgmt(mrfiPacket_t *); + +smplStatus_t nwk_poll(uint8_t, uint8_t *); +void nwk_resetSFMarker(uint8_t); + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.c new file mode 100755 index 0000000..a257e62 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.c @@ -0,0 +1,323 @@ +/************************************************************************************************** +* Filename: nwk_ping.c +* Revised: $Date: 2009-01-18 16:01:08 -0800 (Sun, 18 Jan 2009) $ +* Revision: $Revision: 18796 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Ping network application. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_ping.h" +#include "nwk_globals.h" +#include "nwk_api.h" +#include "nwk_freq.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static void smpl_send_ping_reply(mrfiPacket_t *); +static void handlePingRequest(mrfiPacket_t *); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_pingInit + * + * @brief Initialize Ping application. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_pingInit(void) +{ + sTid = MRFI_RandomByte(); + + return; +} + +/****************************************************************************** + * @fn nwk_ping + * + * @brief Called from the application level to ping a peer. A small + * payload is sent that includes a tid to detect correct reply. + * Caller does not supply payload. + * + * input parameters + * @param lid - Link ID representing peer to ping + * + * output parameters + * + * @return SMPL_SUCCESS valid reply received + * SMPL_TIMEOUT no valid reply received + * SMPL_NO_CHANNEL no channels returned on a scan + */ + +smplStatus_t nwk_ping(linkID_t lid) +{ + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + uint8_t done = 0; + uint8_t repeatIt = 2; + uint8_t msg[MAX_PING_APP_FRAME]; + uint8_t radioState = MRFI_GetRadioState(); + + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + if (!pCInfo || (SMPL_LINKID_USER_UUD == lid)) + { + /* either link ID bogus or tried to ping the unconnected user datagram link ID. */ + return rc; + } + + do + { +#if defined(FREQUENCY_AGILITY) && !defined(ACCESS_POINT) + uint8_t i, numChan; + freqEntry_t channels[NWK_FREQ_TBL_SIZE]; + + if (repeatIt == 2) + { + /* If FA enabled, first time through set up so that the 'for' + * loop checks the current channel. This saves time (no scan) + * and is very likely to succeed. Populate the proper strucure. + */ + SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_GET, channels); + numChan = 1; + } + else + { + /* If we get here we must scan for the channel we're now on */ + if (!(numChan = nwk_scanForChannels(channels))) + { + return SMPL_NO_CHANNEL; + } + } + /* Either we scan next time through or we're done */ + repeatIt--; + + /* this loop Pings on each channel (probably only 1) looking + * for peer. + */ + for (i = 0; i < numChan && !done; ++i) + { + nwk_setChannel(&channels[i]); +#else + { + repeatIt = 0; +#endif /* defined(FREQUENCY_AGILITY) && !defined(ACCESS_POINT) */ + + ioctl_info.send.addr = (addr_t *)pCInfo->peerAddr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_PING; + + /* fill in msg */ + msg[PB_REQ_OS] = PING_REQ_PING; + msg[PB_TID_OS] = sTid; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + ioctl_info.recv.port = SMPL_PORT_PING; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = 0; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + repeatIt = 0; + done = 1; + sTid++; /* guard against duplicates */ + } + } + } while (repeatIt); + + return done ? SMPL_SUCCESS : SMPL_TIMEOUT; + +} + +/****************************************************************************** + * @fn smpl_send_ping_reply + * + * @brief Send a reply to a ping request. + * + * input parameters + * @param frame - pointer to frame containing request + * + * output parameters + * + * @return void + */ + +static void smpl_send_ping_reply(mrfiPacket_t *frame) +{ + frameInfo_t *pOutFrame; + + /* Build the reply frame. The application payload is the one included in the + * received frame payload. + */ + if (pOutFrame = + nwk_buildFrame(SMPL_PORT_PING, MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS, + MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS, MAX_HOPS)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + /* turn on the reply bit in the application payload */ + *(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt) + F_APP_PAYLOAD_OS + PB_REQ_OS) |= NWK_APP_REPLY_BIT; +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS, 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } +} + +/****************************************************************************** + * @fn nwk_processPing + * + * @brief Ping network application frame handler. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ + +fhStatus_t nwk_processPing(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. Send the reply. + */ + replyType = nwk_isValidReply(frame, sTid, PB_REQ_OS, PB_TID_OS); + if (SMPL_MY_REPLY == replyType) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined(END_DEVICE) + else if (SMPL_A_REPLY == replyType) + { + /* no match. If I'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* No, we didn't send it. Send reply assuming it's a Ping intended for us. */ + handlePingRequest(frame); + + rc = FHS_RELEASE; + } + + return rc; +} + +/****************************************************************************** + * @fn handlePingRequest + * + * @brief Dispatches handler for specfic Ping request + * + * input parameters + * + * @param frame - Ping frame received + * + * output parameters + * + * @return void + */ + +static void handlePingRequest(mrfiPacket_t *frame) +{ + switch (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS)) + { + case PING_REQ_PING: + smpl_send_ping_reply(frame); + break; + + default: + break; + } + + return; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.h new file mode 100755 index 0000000..6f49bbf --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.h @@ -0,0 +1,59 @@ +/************************************************************************************************** +* Filename: nwk_ping.h +* Revised: $Date: 2008-05-14 14:22:31 -0700 (Wed, 14 May 2008) $ +* Revision: $Revision: 17075 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Ping network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_PING_H +#define NWK_PING_H + +/* change the following as protocol developed */ +#define MAX_PING_APP_FRAME 2 + +/* application payload offsets + * both */ +#define PB_REQ_OS 0 +#define PB_TID_OS 1 + + +/* ping requests */ +#define PING_REQ_PING 1 + +/* prototypes */ +fhStatus_t nwk_processPing(mrfiPacket_t *); +void nwk_pingInit(void); + +smplStatus_t nwk_ping(linkID_t); + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_security.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_security.c new file mode 100755 index 0000000..d53a558 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_security.c @@ -0,0 +1,565 @@ +/************************************************************************************************** +* Filename: nwk_security.c +* Revised: $Date: 2009-01-20 14:05:46 -0800 (Tue, 20 Jan 2009) $ +* Revision: $Revision: 18816 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Security network application. +* +* Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include /* needed for NULL */ +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_security.h" +#include "nwk_frame.h" +#include "nwk.h" + +#ifdef SMPL_SECURE + +/* *** GENERAL SECURITY OUTLINE *** + * + * We are using XTEA (eXtended Tiny Encryption Algorithm) with a fixed + * number of rounds (32). We have removed the parameters from the API + * we harvested from the public domain. + * + * We are using a CTR-like mode. We use the 64-bit block cipher function of the + * XTEA code to encipher a concatenation of the 32-bit initialization vector and + * a 32-bit counter that increments each block. We encrypt using a fixed 128-bit + * key. The resulting 64-bit output is XOR'ed with the message. If the message is + * longer than 64 bits we encipher the next block (incrementing the counter) and + * continue until the message is exhausted. If the last cipher block is longer + * than the message we simply discard the remaining cipher block. + */ + + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/* The counter can be off by quite a bit because the number of cipher + * blocks can easily be more than 1 per frame. Value limited to a + * maximum of 255. + */ +# define CTR_WINDOW 255 + +# if (CTR_WINDOW > 255) || (CTR_WINDOW < 0) +# error ERROR: 0 <= CTR_WINDOW < 256 +# endif + +/* Number of rounds for XTEA algorithm. A parameter in the public domain code + * but we fix it here at 32. + */ +# define NUM_ROUNDS 32 + +/* Key and cipher block size constants */ +# define SMPL_KEYSIZE_BYTES 16 +# define SMPL_KEYSIZE_LONGS 4 + +/****************************************************************************** + * TYPEDEFS + */ +/* Union used to access key as both a string and as unsigned longs */ +typedef union +{ + uint8_t keyS[SMPL_KEYSIZE_BYTES]; + uint32_t keyL[SMPL_KEYSIZE_LONGS]; +} key_t; + + +/****************************************************************************** + * LOCAL VARIABLES + */ +/* 32-bit Initialization vector */ +static uint32_t const sIV = 0x87654321; + +/* 128-bit (16 byte) key. Initialized as string but fetched and used in XTEA + * encryption as 4 unsigned longs. Endianess could count if the peers are on + * two different MCUs. Endianess is rectified in initialization code. + * + * Initialization _MUST_ be done as a string (or character array). Though it + * won't matter how the initialization is done if both peers are the same + * endianness, good prectice will initialize these as a string (or character + * array) so that the endianess reconciliation works properly for all cases. + */ +static key_t sKey = {"SimpliciTI's Key"}; + +/* Constant set as an authentication code. Note that since it is a + * fixed value as opposed to a hash of the message it does not provide + * an integrity check. It will only differentiate two message encryptions + * with the same LSB but different MSB components. Thus it helps guard + * against replays. + */ +static secMAC_t const sMAC = 0xA5; + +/* This is the 64-bit cipher block target. It is this 64-bit block that + * is XOR'ed with the actual message to be encrypted. + */ +static uint32_t sMsg[2] = {0, 0}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static secFCS_t calcFCS(uint8_t *, uint8_t); +static void msg_encipher(uint8_t *, uint8_t, uint32_t *); +static void msg_decipher(uint8_t *, uint8_t, uint32_t *); +static void xtea_encipher(void); + +#endif /* SMPL_SECURE */ + +/****************************************************************************** + * @fn nwk_securityInit + * + * @brief Initialize Security network application. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_securityInit(void) +{ +#ifdef SMPL_SECURE + uint8_t i; + + /* The key is set as a string. But the XTEA routines operate on 32-bit + * unsigned longs. Endianess should be taken into account and we do that + * here by treating the key as being an array of unsigned longs in + * network order. + */ + for (i = 0; i < sizeof(sKey.keyL) / sizeof(uint32_t); ++i) + { + sKey.keyL[i] = ntohl(sKey.keyL[i]); + } + +#endif /* SMPL_SECURE */ + return; +} + +/****************************************************************************** + * @fn nwk_processSecurity + * + * @brief Security network application frame handler. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ + +fhStatus_t nwk_processSecurity(mrfiPacket_t *frame) +{ + return FHS_RELEASE; +} + +/****************************************************************************** + * @fn msg_encipher + * + * @brief Encipher a message using the XTEA algorithm and the modified + * CTR mode method. + * + * input parameters + * @param msg - pointer to message to encipher + * @param len - length of message + * @param cntStart - pointer to the counter used in the cipher block. + * + * output parameters + * @param cntStart - counter is updated during encryption. + * + * @return void + */ +#ifdef SMPL_SECURE +static void msg_encipher(uint8_t *msg, uint8_t len, uint32_t *cntStart) +{ + uint8_t i, idx, done; + uint8_t *mptr = (uint8_t *)&sMsg[0]; + uint32_t ctr; + + if ((NULL == msg) || !len) + { + return; + } + + /* set local counter from input */ + ctr = *cntStart; + + idx = 0; + done = 0; + do + { + /* Set block to be enciphered. 1st 32 bits are the IV. The second + * 32 bits are the current CTR value. + */ + sMsg[0] = sIV; + sMsg[1] = ctr; + /* encrypt */ + xtea_encipher(); + /* increment counter for next time. */ + ctr++; + + /* XOR ciphered block with message to be sent. Only operate + * up to and including the last message byte which may not + * be on a cipher block boundary (64 bits == 8 bytes). + */ + for (i = 0; i < sizeof(sMsg) && idx < len; ++i, ++idx) + { + msg[idx] ^= mptr[i]; + } + + if (idx >= len) + { + /* we're done */ + done = 1; + } + } while (!done); + + /* return counter value start for next time */ + *cntStart = ctr; + + return; +} + +/****************************************************************************** + * @fn msg_decipher + * + * @brief Decipher a message using the XTEA algorithm and the modified + * CTR mode method. + * + * input parameters + * @param msg - pointer to message to decipher + * @param len - length of message + * @param cntStart - pointer to the counter used in the cipher block. + * + * output parameters + * @param cntStart - counter is updated during decryption. + * + * @return void + */ + +static void msg_decipher(uint8_t *msg, uint8_t len, uint32_t *cntStart) +{ + msg_encipher(msg, len, cntStart); + + return; +} + +/****************************************************************************** + * @fn xtea_encipher + * + * @brief XTEA encipher algorithm. Calling arguments removed from public + * domain code and static-scope values used instead. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void xtea_encipher(void) +{ + uint32_t v0 = sMsg[0], v1 = sMsg[1]; + uint16_t i; + uint32_t sum = 0, delta = 0x9E3779B9; + + for (i = 0; i < NUM_ROUNDS; i++) + { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + sKey.keyL[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + sKey.keyL[(sum >> 11) & 3]); + } + + sMsg[0] = v0; + sMsg[1] = v1; +} + +/****************************************************************************** + * @fn nwk_setSecureFrame + * + * @brief Called from NWK to secure a frame. + * + * input parameters + * @param frame - pointer to frame to secure + * @param msglen - length of message + * @param ctr - pointer to the counter used in the cipher block. This will + * be NULL if a network application is sending a frame. Since + * these are not connection-based there is no counter sync + * issue but we still need a counter value. A random value + * is used. + * + * output parameters + * @param cntStart - counter is updated during encryption. + * + * @return void + */ + +void nwk_setSecureFrame(mrfiPacket_t *frame, uint8_t msglen, uint32_t *ctr) +{ + uint32_t locCnt; + + /* If an encrypted frame is to be sent to a non-connection based port use a + * random number as the lsb counter value. In this case only the lsb is used + * for a counter value during decryption. Not as secure but there are still + * the 32 bits in the IV. + */ + locCnt = ctr ? *ctr : MRFI_RandomByte(); + + /* place counter value into frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(frame), F_SEC_CTR_OS, (uint8_t)(locCnt & 0xFF)); + + /* Put MAC value in */ + nwk_putNumObjectIntoMsg((void *)&sMAC, (void *)(MRFI_P_PAYLOAD(frame) + F_SEC_MAC_OS), + sizeof(secMAC_t)); + + /* Put FCS value in */ + { + secFCS_t fcs = calcFCS(MRFI_P_PAYLOAD(frame) + F_SEC_MAC_OS, msglen + sizeof(secMAC_t)); + + nwk_putNumObjectIntoMsg((void *)&fcs, (void *)(MRFI_P_PAYLOAD( + frame) + F_SEC_ICHK_OS), sizeof(secFCS_t)); + } + + /* Encrypt frame */ + msg_encipher(MRFI_P_PAYLOAD( + frame) + F_SEC_ICHK_OS, msglen + sizeof(secMAC_t) + sizeof(secFCS_t), &locCnt); + + /* Set the Encryption bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(frame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + + /* Update the counter if it was a "real" counter. */ + if (ctr) + { + *ctr = locCnt; + } + + return; +} + +/****************************************************************************** + * @fn calcFCS + * + * @brief Calculate the frame check sequence. Currently it's just a + * cumulative XOR of each byte starting with the MAC byte. The + * FCS is placed in front of the MAC after the counter hint and is + * included in the encryption. + * + * input parameters + * @param msg - pointer to message + * @param len - length of message + * + * output parameters + * + * @return Returns the FCS using the typedef. + */ + +static secFCS_t calcFCS(uint8_t *msg, uint8_t len) +{ + uint8_t i; + secFCS_t result = 0; + + for (i = 0; i < len; ++i) + { + result ^= *(msg + i); + } + + return result; +} + +/****************************************************************************** + * @fn nwk_getSecureFrame + * + * @brief Called from NWK to get a secure a frame and decrypt. + * + * input parameters + * @param frame - pointer to frame containing encrypted message + * @param msglen - length of message + * @param ctr - pointer to the counter used in the cipher block. This will + * be NULL if a network applicaiton is getting a frame. Since + * these are not connection-nbased there is no counter sync + * issue but we still need a counter value. + * + * output parameters + * @param cntStart - counter is updated during decryption. If decryption fails + * this value is not changed. + * + * @return Returns non-zero if frame decryption is valid, otherwise returns 0. + */ + +uint8_t nwk_getSecureFrame(mrfiPacket_t *frame, uint8_t msglen, uint32_t *ctr) +{ + uint8_t rc = 1; + uint8_t done = 0; + uint8_t cntHint = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_SEC_CTR_OS); + uint32_t locCnt, frameCnt; + + /* Construct proposed CTR values */ + + /* Just like encryption, we may be talking to a non-connection based + * peer in which case the counter value is represented by the lsb byte + * conveyed in the frame. + */ + locCnt = ctr ? *ctr : cntHint; + + frameCnt = (locCnt & 0xFFFFFF00) + cntHint; + + do + { + /* See if counters match */ + if (locCnt == frameCnt) + { + /* When the counters appear to match is the only time we actually decipher + * the message. It is the only time we can do so since out-of-sync lsb counter + * values guarantees that something is wrong somewhere. Decryption is successful + * only if the MAC and FCS values match. The message is left as-is after the + * decipher attempt. Either it appears valid or is doesn't and is discarded. + * There is no recovery attempt if the counters match but the MAC or FCS do + * not. It is considered a rogue message. + */ + msg_decipher(MRFI_P_PAYLOAD(frame) + F_SEC_ICHK_OS, msglen - 1, &locCnt); + + /* Get MAC and make sure it matches. A failure can occur if a replayed frame happens + * to have the correct counter sync value but was encoded with the wrong complete + * counter value. Otherwise the MAC values must match when the counter values are equal. + */ + { + secMAC_t mac; + + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD( + frame) + F_SEC_MAC_OS), (void *)&mac, + sizeof(secMAC_t)); + if (mac != sMAC) + { + rc = 0; + } + } + + /* FCS check... */ + { + secFCS_t fcs; + + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD( + frame) + F_SEC_ICHK_OS), (void *)&fcs, + sizeof(secFCS_t)); + if (fcs != + calcFCS(MRFI_P_PAYLOAD(frame) + F_SEC_MAC_OS, msglen - 1 - sizeof(secMAC_t))) + { + rc = 0; + } + } + + /* we're done. */ + done = 1; + } + else + { + /* Uh oh. Counters don't match. Try and resync. We need to distinguish among + * missed frames, duplicates and rogues plus account for counter wrap. + */ + if (frameCnt > locCnt) + { + /* frameCnt is bigger. Second part of test below takes care of + * the unlikely case of a complete counter wrap (msb's all 0) in + * which case the test will incorrectly fail when the count is + * actually within the (wrapped) window. #ifdef'ed to avoid compiler + * warning in case user sets CNT_WINDOW to 0 (pointless comparison of + * unsigned value). + */ + if (((frameCnt - CTR_WINDOW) <= locCnt) +# if CTR_WINDOW > 0 + || (frameCnt < CTR_WINDOW) +# endif + ) + { + /* Value within window. We probably missed something. Adjust and decipher. + * If locCnt is less because it wrapped and frameCnt didn't it means that + * it's a duplicate or late frame. In that case the following will lead to + * a decryption that fails sanity checks which is OK because the frame will + * be correctly rejected. + */ + locCnt = frameCnt; + } + else + { + /* It's either a rogue or a really old duplicate packet. In either case + * we dismiss the frame. + */ + rc = 0; + done = 1; + } + } + else + { + /* locCnt is bigger. The only way the frame can be valid is if the + * counter wrapped causing frameCnt to appear to be smaller. Wrap the + * counter and decrypt. If the frame isn't valid, i.e., it's late, + * a duplicate, or a rogue, the decryption will fail sanity checks and + * the frame will be correctly rejected. The following arithmetic works + * correctly without a special test for the complete counter wrap case. + */ + frameCnt += 0x100; /* wrap the hint-based counter */ + if (((frameCnt - CTR_WINDOW) <= locCnt)) + { + /* An lsb wrap but still within window. We probably missed something. + * Adjust (with wrap) and decrypt. + */ + locCnt = frameCnt; + } + else + { + /* rogue frame */ + rc = 0; + done = 1; + } + } + } + } while (!done); + + if (ctr && rc) + { + /* Only update the counter if the count was a "real" one and the + * decryption succeeded. + */ + *ctr = locCnt; + } + + return rc; +} + +#endif /* SMPL_SECURE */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_security.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_security.h new file mode 100755 index 0000000..ad8b087 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/Components/nwk_applications/nwk_security.h @@ -0,0 +1,49 @@ +/************************************************************************************************** +* Filename: nwk_security.h +* Revised: $Date: 2009-01-09 15:02:17 -0800 (Fri, 09 Jan 2009) $ +* Revision: $Revision: 18728 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Security network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_SECURITY_H +#define NWK_SECURITY_H + +/* change the following as Security application is developed */ +#define MAX_SEC_APP_FRAME 0 + +/* prototypes */ +void nwk_securityInit(void); +fhStatus_t nwk_processSecurity(mrfiPacket_t *); + +void nwk_setSecureFrame(mrfiPacket_t *, uint8_t, uint32_t *); +uint8_t nwk_getSecureFrame(mrfiPacket_t *, uint8_t, uint32_t *); +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/simpliciti.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/simpliciti.h new file mode 100755 index 0000000..9881a61 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/simpliciti.h @@ -0,0 +1,163 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// +// SimpliciTI packet size (TX only mode) +// ------------------------------------- +// +// * packet rate (100/3) packets/second = 33.3 packets/second +// * packet length 28 bytes +// * packet structure 4 bytes preamble +// 4 bytes sync +// 1 bytes length +// 1 bytes address +// 16 bytes data +// 12 byte network data +// 4 byte user data +// 2 bytes crc +// +// SimpliciTI frequency overview +// ----------------------------- +// +// CC430_End_Device_433MHz.lib (433MHz ISM band) +// +// * base frequency 433.92 MHz +// * deviation 32 kHz +// * channel spacing 25 kHz +// * used channel number 0 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.4 dBm +// * duty 9,6% (TX only mode, 32 packets / second) +// +// CC430_End_Device_868MHz.lib (868MHz ISM band) +// +// * base frequency 869.525 MHz +// * deviation 32 kHz +// * channel spacing 25 kHz +// * used channel number 0 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.1 dBm +// * duty 9,6% (TX only mode, 32 packets / second) +// +// CC430_End_Device_915MHz.lib (915MHz ISM band) +// +// * base frequency 902.000 MHz +// * deviation 32 kHz +// * channel spacing 200 kHz +// * used channel number 20 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.3 dBm +// * duty 9.6% (TX only mode, 32 packets / second) +// +// ************************************************************************************************* + +// --------------------------------------------------------------- +// Generic defines and variables + +// Entry point into SimpliciTI library +extern unsigned char simpliciti_link(void); + +// 4 byte device address overrides device address set during compile time +extern unsigned char simpliciti_ed_address[4]; + +// Maximum data length +#define SIMPLICITI_MAX_PAYLOAD_LENGTH (32u) + +// Data to send / receive +extern unsigned char simpliciti_data[SIMPLICITI_MAX_PAYLOAD_LENGTH]; + +// Flag contains status information and triggers to send data or to exit SimpliciTI library +// Control is done from outside SimpliciTI library +extern unsigned char simpliciti_flag; +#define SIMPLICITI_STATUS_LINKING (BIT0) +#define SIMPLICITI_STATUS_LINKED (BIT1) +#define SIMPLICITI_STATUS_ERROR (BIT2) +#define SIMPLICITI_TRIGGER_SEND_DATA (BIT3) +#define SIMPLICITI_TRIGGER_RECEIVED_DATA (BIT4) +#define SIMPLICITI_TRIGGER_STOP (BIT5) + +// Radio frequency offset read from calibration memory +// Compensates crystal deviation from 26MHz nominal value +extern unsigned char rf_frequoffset; + +// Macros +#define getFlag(val, flag) ((val & flag) == flag) +#define setFlag(val, flag) (val |= flag) +#define clearFlag(val, flag) (val &= (~flag)) +#define toggleFlag(val, flag) (val ^= flag) + + +// --------------------------------------------------------------- +// SimpliciTI RX only + +// Entry point into SimpliciTI library +extern void simpliciti_main_tx_only(void); + +// Callback function to read data from acceleration sensor or buttons and trigger sending +extern void simpliciti_get_ed_data_callback(void); + + +// --------------------------------------------------------------- +// SimpliciTI Sync + +// Sync data length +#define BM_SYNC_DATA_LENGTH (19u) + +// Device data (0)TYPE (1) - (18) DATA +#define SYNC_ED_TYPE_R2R (1u) +#define SYNC_ED_TYPE_MEMORY (2u) +#define SYNC_ED_TYPE_STATUS (3u) + +// Host data (0)CMD (1) - (18) DATA +#define SYNC_AP_CMD_NOP (1u) +#define SYNC_AP_CMD_GET_STATUS (2u) +#define SYNC_AP_CMD_SET_WATCH (3u) +#define SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_1 (4u) +#define SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_2 (5u) +#define SYNC_AP_CMD_ERASE_MEMORY (6u) +#define SYNC_AP_CMD_EXIT (7u) + + +// Entry point into SimpliciTI library +extern void simpliciti_main_sync(void); + +// Callback function to decode access point command +extern void simpliciti_sync_decode_ap_cmd_callback(void); + +// Callback function to read data from application and trigger sending +extern void simpliciti_sync_get_data_callback(unsigned int index); + +// Send reply packets (>0), 0=no need to reply +extern unsigned char simpliciti_reply_count; + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/simpliciti_readme.txt b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/simpliciti_readme.txt new file mode 100755 index 0000000..d1ff81d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Data Logger/simpliciti/simpliciti_readme.txt @@ -0,0 +1,46 @@ +Some notes about the SimpliciTI configuration used in this project + +- The source code is based on the SimpliciTI 1.1.1 release. + +- A full SimpliciTI installation contains configurations for many targets and device types. To avoid confusion, + only the configuration (End Device) and target files (CC430EM) required for the eZ430-Chronos have been used. + +- All source code files have been copied into the project physically. Symbolic links have been replaced with + the real source code file. + +- Due to the indirect inclusion scheme of hardware-dependent source code, some source code files have been + excluded from build. However, they will be included through higher level source code. + +- Some modifications where required to the original source code. All these changes have been marked with [BM]. + + bsp_board.c/BSP_InitBoard(void) Changed from TA0 to TA1 for delay function, because TA0 is already occupied. + + bsp_msp430_defs.h/BSP_EarlyInit(void) Function removed, because SimpliciTI must run in watch context + + mrfi_radio_interface.c/mrfiRadioInterfaceCmdStrobe(uint8_t addr) + Added code to properly synchronize with radio interface. Otherwise + interface could get stuck. + + mrfi_radio.c Changed channel assignment (mrfiLogicalChanTable) for three ISM bands + Changed power output settings (mrfiRFPowerTable) for three ISM bands + + mrfi_radio.c/MRFI_Init(void) Added frequency offset correction to use calibrated frequency offset + when starting RF communication + + mrfi_radio.c/MRFI_RadioIsr(void) Changed radio ISR to normal function, since we have a shared radio ISR + + nwk_api.c Made variable sInit_done globally available to allow SimpliciTI to shutdown + and restart multiple times + + nwk.c/nwk_nwkInit Added workaround to allow allow SimpliciTI to shutdown + and restart multiple times + +- If you (for whatever reason) want to upgrade to a newer version of SimpliciTI, please bear in mind that + + a) the access point SimpliciTI version is 1.1.1 (and cannot be updated) + + b) the workarounds used here to enable SimpliciTI to shutdown and restart multiple times might not necessarily + work when used with later revisions + + + \ No newline at end of file diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.ccsproject b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.ccsproject new file mode 100755 index 0000000..fb1bc89 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.ccsproject @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.cdtbuild b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.cdtbuild new file mode 100755 index 0000000..bfea64b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.cdtbuild @@ -0,0 +1,870 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.cdtproject b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.cdtproject new file mode 100755 index 0000000..fa82503 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.cdtproject @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.project b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.project new file mode 100755 index 0000000..11546e0 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.project @@ -0,0 +1,20 @@ + + + ez430_chronos + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + com.ti.ccstudio.managedbuild.core.ccsNature + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.settings/org.eclipse.cdt.managedbuilder.core.prefs b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.settings/org.eclipse.cdt.managedbuilder.core.prefs new file mode 100755 index 0000000..9ede4df --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.settings/org.eclipse.cdt.managedbuilder.core.prefs @@ -0,0 +1,35 @@ +#Thu Oct 21 17:01:30 CEST 2010 +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1112165763/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1112165763/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1257141332/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1257141332/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1482413833/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1482413833/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1720680788/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1720680788/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1834157678/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.1834157678/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.2047404142/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.2047404142/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.2101481428/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.2101481428/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.518486332/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.518486332/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.572603594/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.572603594/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.577917970/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.577917970/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.767845949/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.767845949/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.82500526/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.82500526/internalBuilder/ignoreErr=true +com.ti.ccstudio.buildDefinitions.MSP430.Debug.855263628/internalBuilder/enabled=false +com.ti.ccstudio.buildDefinitions.MSP430.Debug.855263628/internalBuilder/ignoreErr=true +eclipse.preferences.version=1 +environment/project=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.1257141332=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.1834157678=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.2047404142=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.2101481428=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.518486332=\r\n\r\n +environment/project/com.ti.ccstudio.buildDefinitions.MSP430.Debug.82500526=\r\n\r\n diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.settings/org.eclipse.ltk.core.refactoring.prefs b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100755 index 0000000..4a2a626 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,3 @@ +#Tue Oct 12 16:47:51 CEST 2010 +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/CC430F6137.ccxml b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/CC430F6137.ccxml new file mode 100755 index 0000000..f2be62d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/CC430F6137.ccxml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_433MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_433MHz.lib new file mode 100755 index 0000000..5c81259 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_433MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_868MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_868MHz.lib new file mode 100755 index 0000000..d14e7de Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_868MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_915MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_915MHz.lib new file mode 100755 index 0000000..3057022 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_915MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_API.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_API.h new file mode 100755 index 0000000..049c99f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/BlueRobin_RX_API.h @@ -0,0 +1,157 @@ +// ************************************************************************************************* +// +// Copyright 2009 BM innovations GmbH (www.bm-innovations.com), all rights reserved. +// +// This trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC" may be used for non-profit non-commercial purposes only. If you want to use +// BlueRobin(TM) in a commercial project, please contact the copyright holder for a +// separate license agreement. +// +// By using this trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC", you implicitly agree that you will not modify, adapt, disassemble, decompile, +// reverse engineer, translate or otherwise attempt to discover the source code of the +// "BlueRobin(TM) receiver library for the Texas Instruments CC430 SoC". +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// +// Public header for eZ430-Chronos specific BlueRobin(TM) receiver library. +// +// The following BlueRobin(TM) profiles are supported by this build +// - heart rate (HR) transmitter +// +// The following number of channels is supported: 1 +// +// ************************************************************************************************* +// +// BlueRobin(TM) packet size +// ------------------------- +// +// * average packet rate 1 packet/875 msec = ~1.14 packets/second +// * payload per packet 5 bytes +// +// BlueRobin(TM) frequency overview +// (Please note: Settings apply for the transmitter side, i.e. the USB dongle) +// ---------------------------------------------------------------------- +// +// Bluerobin_RX_433MHz.lib (433MHz ISM band) +// +// * frequency 433.30 MHz - 434.00 MHz +// * deviation 95 kHz +// * channels 3 +// * data rate 250 kBaud +// +// Bluerobin_RX_868MHz.lib (868MHz ISM band) +// +// * frequency 868.25 MHz - 868.95 MHz +// * deviation 95 kHz +// * channels 3 +// * data rate 250 kBaud +// +// +// Bluerobin_RX_915MHz.lib (915MHz ISM band) +// +// * frequency 914.35 MHz - 917.75 MHz +// * deviation 95 kHz +// * channels 34 +// * data rate 250 kBaud +// +// ************************************************************************************************* + +#ifndef BRRX_API_H_ +#define BRRX_API_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Defines section + +// List of all possible channel states +typedef enum +{ + TX_OFF = 0, // Powerdown mode + TX_ACTIVE, // Active mode + TX_SEARCH // Search mode +} brtx_state_t; + +// Transmitter to channel assignment +#define HR_CHANNEL (0) + +// ************************************************************************************************* +// API section + +// ---------------------------------------------------------- +// Functions for initializing and controlling the library + +// Initialize several global variables. +void BRRX_Init_v(void); + +// Set delay after which a channel will be switched off if no new data can be received. +// Param1: Powerdown delay in packet intervals (875 ms) +void BRRX_SetPowerdownDelay_v(u8 Delay_u8); + +// Set timeout when searching for a transmitter +// Param1: Search timeout in seconds +void BRRX_SetSearchTimeout_v(u8 Timeout_u8); + +// Set reduction of valid signal level in learn mode. +// Param1: Reduction of signal level +void BRRX_SetSignalLevelReduction_v(u8 Reduction_u8); + +// Set ID for a channel. To search for an unknown transmitter the ID has to be set to 0. +// Can be only executed on channels currently in powerdown mode. +// Param1: Channel index +// Param2: New ID +void BRRX_SetID_v(u8 Index_u8, u32 ID_u32); + +// Get current ID of channel. +// Return: Current ID of channel +// Param1: Channel index +u32 BRRX_GetID_u32(u8 Index_u8); + +// Start reception on one or all channels. +// Param1: Channel index (use 0xFF to start all channels) +void BRRX_Start_v(u8 Index_u8); + +// Stop reception on one or all channels. +// Param1: Channel index (0xFF for all channels) +void BRRX_Stop_v(u8 Index_u8); + +// Get current state of a channel +// Param1: Channel index +brtx_state_t BRRX_GetState_t(u8 Index_u8); + +// ---------------------------------------------------------- +// eZ430-Chronos specific functions + +// Get current heart rate. +// Return: Heart rate in bpm +u8 BRRX_GetHeartRate_u8(void); + +// Get current distance. +// Return: Distance in 10m steps. +u16 BRRX_GetDistance_u16(void); + +// Get current speed. +// Return: Speed in 0.1km/h steps. Trial version is limited to 25.5km/h. +u8 BRRX_GetSpeed_u8(void); + +// ---------------------------------------------------------- +// Radio-related functions + +// RX packet end service function +// Must be called by CC1101_VECTOR ISR +void BlueRobin_RadioISR_v(void); + +#endif /*BRRX_API_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/bm.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/bm.h new file mode 100755 index 0000000..781b1e1 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/bluerobin/bm.h @@ -0,0 +1,480 @@ +// ************************************************************************************************* +// +// Copyright 2009 BM innovations GmbH (www.bm-innovations.com), all rights reserved. +// +// This trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC" may be used for non-profit non-commercial purposes only. If you want to use +// BlueRobin(TM) in a commercial project, please contact the copyright holder for a +// separate license agreement. +// +// By using this trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC", you implicitly agree that you will not modify, adapt, disassemble, decompile, +// reverse engineer, translate or otherwise attempt to discover the source code of the +// "BlueRobin(TM) receiver library for the Texas Instruments CC430 SoC". +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Standard definitions, have to be included in every source and header file. +// ************************************************************************************************* + +#ifndef __BM_H +#define __BM_H + +#if (defined __IAR_SYSTEMS_ASM) || (defined __IAR_SYSTEMS_ASM__) +# define _ASSEMBLER_USED_ +#endif + +#ifndef _ASSEMBLER_USED_ +# include +#endif + +#ifndef FALSE +// the classic false +# define FALSE (0 == 1) +#endif + +#ifndef TRUE +// the classic true +# define TRUE (1 == 1) +#endif + +#ifndef USE_RAW_ATTR +// per default this feature is disabled +# define USE_RAW_ATTR FALSE +#endif + +// ************************************************************************************************* +// First Section: Basic Data Types +// ************************************************************************************************* + +// Fundamental #definitions +// CPU target idents are used for target dependent compilations + +// Texas Instruments MSP430 +#define _TI_MSP430_ (16) + +// Find the currently running compiler +// and make the related #define's + +// _IAR_TID_ target ID from IAR compilers +// _CPU_TID_ remap to enum of processor target numbers +// _CPU_8BIT_INT_ type for 8 bit int +// _CPU_16BIT_INT_ type for 16 bit int +// _CPU_32BIT_INT_ type for 32 bit int +// _CPU_32BIT_FLOAT_ type for 32 bit float +// _CPU_64BIT_FLOAT_ type for 64 bit float +// INTERRUPT declares an interrupt service routine without an entry in the vector +// table +// ISR(vector) declares an interrupt service routine which is added in vector table at +// offset vector +// MONITOR declares a function atomic +// INTERRUPTS_ENABLE remap to the intrinsic for enable interrupts +// INTERRUPTS_DISABLE remap to the intrinsic for disable interrupts +// NO_OPERATION remap to the intrinsic for no operation +// _CPU_DIRECTION_OUT_1_ if TRUE the direction register indicates with an 1: direction is output +// _CPU_EDGE_HIGH_LOW_1_ if TRUE the edge select register indicates with an 1: trigger on high +// low +// NO_INIT declare a variable as not initialized +// INLINE_FUNC declare a function as inline for release builds + +#if ((defined __IAR_SYSTEMS_ICC) || (defined __IAR_SYSTEMS_ASM)) && (__IAR_SYSTEMS_ICC__ < 2) +// Found IAR Compiler with classic IAR frontend +# ifndef _IAR_TID_ +# define _IAR_TID_ ((__TID__ >> 8) & 0x7f) +# endif + +# define INTERRUPT interrupt +# define ISR(vector) interrupt[(vector)] +# define MONITOR monitor + +# if ((_IAR_TID_) == 43) +// Found Texas Instruments MSP430 CPU +# define _CPU_TID_ _TI_MSP430_ +# define _CPU_DIRECTION_OUT_1_ TRUE +# define _CPU_EDGE_HIGH_LOW_1_ TRUE +# define INTERRUPTS_ENABLE() _EINT() +// WA for HW bug, add a NOP +# define INTERRUPTS_DISABLE() { _DINT(); _NOP(); } +# define NO_OPERATION() _NOP() + +# else +# error "Unknown IAR Compiler, the file bm.h has to be expanded !" +# endif + +#elif defined __IAR_SYSTEMS_ICC__ +// Found IAR Compiler with EDG frontend +# define _IAR_TID_ ((__TID__ >> 8) & 0x7f) + +# if USE_RAW_ATTR == TRUE +// Use the raw attribute in ISR's +# define _RAW __raw +# else +// Empty define RAW as it is not used +# define _RAW +# endif +# define INTERRUPT _RAW __interrupt +# define MONITOR __monitor +# define NO_INIT __no_init +# define INTERRUPTS_ENABLE() __enable_interrupt() +# define INTERRUPTS_DISABLE() __disable_interrupt() +# define NO_OPERATION() __no_operation() + +# ifndef DEBUG +// Force inlining of function in release builds +# define INLINE_FUNC PRAGMA(inline = forced) +# else +// Do not force inlining of function in debug builds +# define INLINE_FUNC +# endif + +# if (!defined CODECHECK) && (!defined __DA_C__) +// Define to a new way of using #pragmas in preprocessor +# define PRAGMA(x) _Pragma(# x) +# define ISR(x) PRAGMA(vector = (x)) INTERRUPT +# endif + +# if ((_IAR_TID_) == 43) +// Found Texas Instruments MSP430 CPU (V2) +# define _CPU_TID_ _TI_MSP430_ +# define _CPU_DIRECTION_OUT_1_ TRUE +# define _CPU_EDGE_HIGH_LOW_1_ TRUE +# define _CPU_64BIT_INT_ long long +# if __VER__ < 220 +// WA for HW bug, add a nop after DINT, Compiler has a bugfix since version 2.20 +# undef INTERRUPTS_DISABLE +# define INTERRUPTS_DISABLE() { __disable_interrupt(); __no_operation(); } +# endif + +# else +# error "Unknown new IAR Compiler, the file bm.h has to be expanded !" +# endif + +#elif defined __CCE__ +// Found CCE Compiler +# define INTERRUPT __interrupt +# define MONITOR // __monitor +# define NO_INIT __no_init +# define INTERRUPTS_ENABLE() __enable_interrupt() +# define INTERRUPTS_DISABLE() __disable_interrupt() +# define NO_OPERATION() __no_operation() + +# ifndef DEBUG +// Force inlining of function in release builds +# define INLINE_FUNC PRAGMA(inline = forced) +# else +// Do not force inlining of function in debug builds +# define INLINE_FUNC +# endif + +// Found Texas Instruments MSP430 CPU (V2) +# define _CPU_TID_ _TI_MSP430_ +# define _CPU_DIRECTION_OUT_1_ TRUE +# define _CPU_EDGE_HIGH_LOW_1_ TRUE +//#define _CPU_64BIT_INT_ long long + +// #endif + +#else +# error "Unknown Compiler, the file bm.h has to be expanded !" +#endif + +#ifndef _ASSEMBLER_USED_ +// Get the limits to autodetect the size of integral types +# include +// Get floats to autodetect the size of float types +# include + +// *********************************************************************************************** +// +// Common basic data types +// +// *********************************************************************************************** +# if UCHAR_MAX == 0xFFu +# define _CPU_8BIT_INT_ char +# else +# error "unable to get size of u8 automatically" +# endif + +# if USHRT_MAX == 0xFFFFu +# define _CPU_16BIT_INT_ short +# elif UINT_MAX == 0xFFFFu +# define _CPU_16BIT_INT_ int +# else +# error "unable to get size of u16 automatically" +# endif + +# if USHRT_MAX == 0xFFFFFFFFu +# define _CPU_32BIT_INT_ short +# elif UINT_MAX == 0xFFFFFFFFu +# define _CPU_32BIT_INT_ int +# elif ULONG_MAX == 0xFFFFFFFFu +# define _CPU_32BIT_INT_ long +# else +# error "unable to get size of u32 automatically" +# endif + +# ifdef __IAR_SYSTEMS_ICC__ +# if __IAR_SYSTEMS_ICC__ > 1 +# define _CPU_32BIT_FLOAT_ float +# if __DOUBLE_SIZE__ == 8 +# define _CPU_64BIT_FLOAT_ double +# endif +# endif +# endif + +# ifndef _CPU_32BIT_FLOAT_ +# if FLT_MANT_DIG == 24 +# define _CPU_32BIT_FLOAT_ float +# elif DBL_MANT_DIG == 24 +# define _CPU_32BIT_FLOAT_ double +# else +# error "unable to get size of f32 automatically" +# endif + +# if DBL_MANT_DIG == 53 +# define _CPU_64BIT_FLOAT_ double +# endif +# endif + +// *********************************************************************************************** +// +// Following lines #typedef the basic data types in a compiler independent way. +// +// *********************************************************************************************** + +# ifdef _CPU_8BIT_INT_ +// unsigned 8 bit +typedef unsigned _CPU_8BIT_INT_ u8; +// unsigned 8 bit max value +# define U8_MAX (0xFFU) +// signed 8 bit max value +typedef signed _CPU_8BIT_INT_ s8; +// signed 8 bit min value +# define S8_MIN (-127 - 1) +// signed 8 bit max value +# define S8_MAX (127) +# endif + +# ifdef _CPU_16BIT_INT_ +// unsigned 16 bit +typedef unsigned _CPU_16BIT_INT_ u16; +// unsigned 16 bit max value +# define U16_MAX (0xFFFFU) +// signed 16 bit +typedef signed _CPU_16BIT_INT_ s16; +// signed 16 bit min value +# define S16_MIN (-32767 - 1) +// signed 16 bit max value +# define S16_MAX (32767) +# endif + +# ifdef _CPU_32BIT_INT_ +// unsigned 32 bit +typedef unsigned _CPU_32BIT_INT_ u32; +// unsigned 32 bit max value +# define U32_MAX (0xFFFFFFFFUL) +// signed 32 bit +typedef signed _CPU_32BIT_INT_ s32; +// signed 32 bit min value +# define S32_MIN (-2147483647L - 1L) +// signed 32 bit max value +# define S32_MAX (2147483647L) +# endif + +# ifdef _CPU_64BIT_INT_ +// unsigned 64 bit +typedef unsigned _CPU_64BIT_INT_ u64; +// signed 64 bit +typedef signed _CPU_64BIT_INT_ s64; +# endif + +# ifdef _CPU_32BIT_FLOAT_ +// float 32 bit +typedef _CPU_32BIT_FLOAT_ f32; +// number of digits in mantissa of f32 +# define F32_MANT_DIG (24) +// epsilon for f32 +# define F32_EPSILON (1.192092896e-07) +// number of digits of precision of f32 +# define F32_DIG (6) +// exponent min of f32 +# define F32_MIN_EXP (-125) +// min positive value of f32 +# define F32_MIN (1.175494351e-38) +// decimal exponent min of f32 +# define F32_MIN_10_EXP (-37) +// exponent max of f32 +# define F32_MAX_EXP (128) +// max value of f32 +# define F32_MAX (3.402823466e+38) +// decimal exponent max of f32 +# define F32_MAX_10_EXP (38) +# endif + +# ifdef _CPU_64BIT_FLOAT_ +// float 64 bit +typedef _CPU_64BIT_FLOAT_ f64; +// number of digits in mantissa of f64 +# define F64_MANT_DIG (53) +// epsilon for f64 +# define F64_EPSILON (2.2204460492503131e-016) +// number of digits of precision of f64 +# define F64_DIG (15) +// exponent min of f64 +# define F64_MIN_EXP (-1021) +// min positive value of f64 +# define F64_MIN (2.2250738585072014e-308) +// decimal exponent min of f64 +# define F64_MIN_10_EXP (-307) +// exponent max of f64 +# define F64_MAX_EXP (1024) +// max value of f64 +# define F64_MAX (1.7976931348623158e+308) +// decimal exponent max of f64 +# define F64_MAX_10_EXP (308) +# endif + +typedef unsigned char BYTE; +typedef unsigned int WORD; +typedef unsigned long DWORD; + +#endif // _ASSMEBLER_USED_ + +// A macro that calculates the number of bits of a given type +#ifndef BITSIZEOF +# define BITSIZEOF(type) (sizeof(type) * CHAR_BIT) +#endif + +/* A macro that generates a bit mask according to a given bit number. + * Example: + * - BIT(0) expands to 1 (== 0x01) + * - BIT(3) expands to 8 (== 0x08) + */ +#define BIT(x) (1uL << (x)) + +/* A macro that generates a bit mask according to a given bit number with a cast to type. + * The difference to BIT(X) is the additional type argument T that is used to cast the type of the + * constant 1 and the type of the result as well. + * Example: + * - BIT_T(u8,0) expands to (u8)1 (== 0x01) + * - BIT_T(u32,3) expands to (u32)8 (== 0x08L) + */ +#define BIT_T(t, x) ((t)((t)1 << (x))) + +/* A macro to calculate the position of the highest bit. + * The result is same as LOG2 in case only one bit is set. Use with constant values only because + * of code size. + */ +#define BIT_HIGHEST(Input_u32) ( \ + ((Input_u32) & BIT(31)) ? 31 : ( \ + ((Input_u32) & BIT(30)) ? 30 : ( \ + ((Input_u32) & BIT(29)) ? 29 : ( \ + ((Input_u32) & BIT(28)) ? 28 : ( \ + ((Input_u32) & BIT(27)) ? 27 : ( \ + ((Input_u32) & BIT(26)) ? 26 : ( \ + ((Input_u32) & BIT(25)) ? 25 : ( \ + ((Input_u32) & BIT(24)) ? 24 : ( \ + ((Input_u32) & BIT(23)) ? 23 : ( \ + ((Input_u32) & BIT(22)) ? 22 : ( \ + ((Input_u32) & BIT(21)) ? 21 : ( \ + ((Input_u32) & BIT(20)) ? 20 : ( \ + ((Input_u32) & BIT(19)) ? 19 : ( \ + ((Input_u32) & BIT(18)) ? 18 : ( \ + ((Input_u32) & BIT(17)) ? 17 : ( \ + ((Input_u32) & BIT(16)) ? 16 : ( \ + ((Input_u32) & \ + BIT(15)) ? 15 : ( \ + ((Input_u32) & \ + BIT(14)) ? 14 : ( \ + ((Input_u32) & \ + BIT(13)) ? 13 : ( \ + ((Input_u32) & \ + BIT(12)) ? 12 \ + : ( \ + ((Input_u32) \ + & BIT(11)) \ + ? 11 : ( \ + (( \ + Input_u32) \ + & BIT( \ + 10)) ? 10 : ( \ + (( \ + Input_u32) \ + & \ + BIT(9)) ? 9 : ( \ + (( \ + Input_u32) \ + & \ + BIT(8)) ? 8 : ( \ + (( \ + Input_u32) \ + & \ + BIT(7)) ? 7 : ( \ + (( \ + Input_u32) \ + & \ + BIT(6)) ? 6 : ( \ + (( \ + Input_u32) \ + & \ + BIT(5)) ? 5 : ( \ + (( \ + Input_u32) \ + & \ + BIT(4)) ? 4 : ( \ + (( \ + Input_u32) \ + & \ + BIT(3)) ? 3 : ( \ + (( \ + Input_u32) \ + & \ + BIT(2)) ? 2 : ( \ + (( \ + Input_u32) \ + & \ + BIT(1)) ? 1 : ( \ + (( \ + Input_u32) \ + & \ + BIT(0)) ? 0 : -1uL)))))))))))))))))))))))))))))))) + +#ifndef MONITOR +# define MONITOR +#endif + +#ifndef NO_INIT +# define NO_INIT +#endif + +#ifndef INTERRUPT +# define INTERRUPT +#endif + +#ifndef ISR +# define ISR(ignore) +#endif + +#ifndef INLINE_FUNC +# define INLINE_FUNC +#endif + +#ifndef INTERRUPTS_ENABLE +# define INTERRUPTS_ENABLE() +#endif + +#ifndef INTERRUPTS_DISABLE +# define INTERRUPTS_DISABLE() +#endif + +#endif // __BM_H diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/change_record.txt b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/change_record.txt new file mode 100755 index 0000000..e16bfa5 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/change_record.txt @@ -0,0 +1,38 @@ +V1.6 (21.11.2010) +Fixed following bugs +- rfsimpliciti.c/simpliciti_sync_decode_ap_cmd_callback(), +- timer.c/TIMER0_A0_ISR(), LCD shows "done" after successfully received data +- main.c/wakeup_event(), +- rfbsl.c/sx_rfbsl() rfBSL requires two button presses in order to update watch +- timer.c/Timer0_A3_Start() Fixed register read (Asynchronous) +- timer.c/Timer0_A4_Delay() Fixed register read (Asynchronous) + Avoid unwanted flag changes caused by interrupt methods + After timeout the accelerometer menu shows "----" +- port.c/PORT2_ISR() and timer.c/TIMER0_A0_ISR() Changes the menu if the pressed time from STAR or NUM button are between "short(50ms)" and "long(3s)" + The backlight stays 3 seconds on +- display.c Removed file display1.c. The content is now in display.c +- display.h Fixed LCD_UNIT_L1_PER_S_MASK bit + +Other changes: +- adc12.c and adc12.h Removed commented function and #defines +- battery.c Removed commented function +- DCO settling time Set to 375000 cycles +__________________________________________________________________________________________________________________________________________________ +V1.5 (16.03.2010) +Fixed following bugs +- main.c/init_application() Changed XT1 drive level to highest to avoid ACLK noise when turning on backlight. +- main.c/wakeup_event(), timer.c/TIMER0_A0_ISR() Modified key lock procedure. +- vti_ps.c/ps_get_temp() Negative °C are now converted correctly to Kelvin +- altitude.c/mx_altitude() Enabled fast mode when changing altitude offset +- ports.c/PORT2_ISR() Disabled stopwatch stop when watch buttons are locked + +Other changes +- main.c/read_calibration_values() Added range check for rf_frequoffset variable + Added bytes for altitude offset correction and s/w version +- altitude.h, altitude.c Added initial altitude offset correction +- SimpliciTI Added SimpliciTI sources to project. Upgraded to Version 1.1.1. +- RFBSL Added wireless update support +- Button names Changed button names from M1/M2/S1/S2/BL to STAR/NUM/UP/DOWN/BACKLIGHT +__________________________________________________________________________________________________________________________________________________ +V1.4 (22.11.2009) +First version released to manufacturing. \ No newline at end of file diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/adc12.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/adc12.c new file mode 100755 index 0000000..07f13cc --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/adc12.c @@ -0,0 +1,164 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// ADC12 functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include + +// driver +#include "adc12.h" +#include "timer.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +u16 adc12_result; +u8 adc12_data_ready; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn adc12_single_conversion +// @brief Init ADC12. Do single conversion. Turn off ADC12. +// @param u16 ref Select reference +// u16 sht Sample-and-hold time +// u16 channel Channel of the conversion +// @return u16 adc12_result Return ADC result +// ************************************************************************************************* +u16 adc12_single_conversion(u16 ref, u16 sht, u16 channel) +{ + // Initialize the shared reference module + REFCTL0 |= REFMSTR + ref + REFON; // Enable internal reference (1.5V or 2.5V) + + // Initialize ADC12_A + ADC12CTL0 = sht + ADC12ON; // Set sample time + ADC12CTL1 = ADC12SHP; // Enable sample timer + ADC12MCTL0 = ADC12SREF_1 + channel; // ADC input channel + ADC12IE = 0x001; // ADC_IFG upon conv result-ADCMEMO + + // Wait 2 ticks (66us) to allow internal reference to settle + Timer0_A4_Delay(2); + + // Start ADC12 + ADC12CTL0 |= ADC12ENC; + + // Clear data ready flag + adc12_data_ready = 0; + + // Sampling and conversion start + ADC12CTL0 |= ADC12SC; + + // Delay to get next ADC value + Timer0_A4_Delay(5); + while (!adc12_data_ready) ; + + // Shut down ADC12 + ADC12CTL0 &= ~(ADC12ENC | ADC12SC | sht); + ADC12CTL0 &= ~ADC12ON; + + // Shut down reference voltage + REFCTL0 &= ~(REFMSTR + ref + REFON); + + ADC12IE = 0; + + // Return ADC result + return (adc12_result); +} + +// ************************************************************************************************* +// @fn ADC12ISR +// @brief Store ADC12 conversion result. Set flag to indicate data ready. +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=ADC12_VECTOR +__interrupt void ADC12ISR(void) +{ + switch (__even_in_range(ADC12IV, 34)) + { + case 0: + break; // Vector 0: No interrupt + case 2: + break; // Vector 2: ADC overflow + case 4: + break; // Vector 4: ADC timing overflow + case 6: // Vector 6: ADC12IFG0 + adc12_result = ADC12MEM0; // Move results, IFG is cleared + adc12_data_ready = 1; + _BIC_SR_IRQ(LPM3_bits); // Exit active CPU + break; + case 8: + break; // Vector 8: ADC12IFG1 + case 10: + break; // Vector 10: ADC12IFG2 + case 12: + break; // Vector 12: ADC12IFG3 + case 14: + break; // Vector 14: ADC12IFG4 + case 16: + break; // Vector 16: ADC12IFG5 + case 18: + break; // Vector 18: ADC12IFG6 + case 20: + break; // Vector 20: ADC12IFG7 + case 22: + break; // Vector 22: ADC12IFG8 + case 24: + break; // Vector 24: ADC12IFG9 + case 26: + break; // Vector 26: ADC12IFG10 + case 28: + break; // Vector 28: ADC12IFG11 + case 30: + break; // Vector 30: ADC12IFG12 + case 32: + break; // Vector 32: ADC12IFG13 + case 34: + break; // Vector 34: ADC12IFG14 + default: + break; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/adc12.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/adc12.h new file mode 100755 index 0000000..90fc327 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/adc12.h @@ -0,0 +1,57 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ADC12_H_ +#define ADC12_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern u16 adc12_single_conversion(u16 ref, u16 sht, u16 channel); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +extern u16 adc12_result; +extern u8 adc12_data_ready; + +// ************************************************************************************************* +// Extern section + +#endif /*ADC12_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/buzzer.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/buzzer.c new file mode 100755 index 0000000..9ac581a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/buzzer.c @@ -0,0 +1,220 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Buzzer functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "buzzer.h" +#include "timer.h" +#include "display.h" + +// logic +#include "alarm.h" + +// ************************************************************************************************* +// Prototypes section +void toggle_buzzer(void); +void countdown_buzzer(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct buzzer sBuzzer; + +// ************************************************************************************************* +// Extern section +//extern u16 timer0_A3_ticks_g; + +// ************************************************************************************************* +// @fn reset_buzzer +// @brief Init buzzer variables +// @param none +// @return none +// ************************************************************************************************* +void reset_buzzer(void) +{ + sBuzzer.time = 0; + sBuzzer.state = BUZZER_OFF; +} + +// ************************************************************************************************* +// @fn start_buzzer +// @brief Start buzzer output for a number of cylces +// @param u8 cycles Keep buzzer output for number of cycles +// u16 on_time Output buzzer for "on_time" ACLK ticks +// u16 off_time Do not output buzzer for "off_time" ACLK ticks +// @return none +// ************************************************************************************************* +void start_buzzer(u8 cycles, u16 on_time, u16 off_time) +{ + // Store new buzzer duration while buzzer is off + if (sBuzzer.time == 0) + { + sBuzzer.time = cycles; + sBuzzer.on_time = on_time; + sBuzzer.off_time = off_time; + + // Need to init every time, because SimpliciTI claims same timer + // Reset TA1R, set up mode, TA1 runs from 32768Hz ACLK + TA1CTL = TACLR | MC_1 | TASSEL__ACLK; + + // Set PWM frequency + TA1CCR0 = BUZZER_TIMER_STEPS; + + // Enable IRQ, set output mode "toggle" + TA1CCTL0 = OUTMOD_4; + + // Allow buzzer PWM output on P2.7 + P2SEL |= BIT7; + + // Activate Timer0_A3 periodic interrupts + fptr_Timer0_A3_function = toggle_buzzer; + Timer0_A3_Start(sBuzzer.on_time); + + // Preload timer advance variable + sTimer.timer0_A3_ticks = sBuzzer.off_time; + + // Start with buzzer output on + sBuzzer.state = BUZZER_ON_OUTPUT_ENABLED; + } +} + +// ************************************************************************************************* +// @fn toggle_buzzer +// @brief Keeps track of buzzer on/off duty cycle +// @param none +// @return none +// ************************************************************************************************* +void toggle_buzzer(void) +{ + // Turn off buzzer + if (sBuzzer.state == BUZZER_ON_OUTPUT_ENABLED) + { + // Stop PWM timer + TA1CTL &= ~(BIT4 | BIT5); + + // Reset and disable buzzer PWM output + P2OUT &= ~BIT7; + P2SEL &= ~BIT7; + + // Update buzzer state + sBuzzer.state = BUZZER_ON_OUTPUT_DISABLED; + + // Reload Timer0_A4 IRQ to restart output + sTimer.timer0_A3_ticks = sBuzzer.on_time; + } + else // Turn on buzzer + { + // Decrement buzzer total cycles + countdown_buzzer(); + + // Reload Timer0_A4 to stop output if sBuzzer.time > 0 + if (sBuzzer.state != BUZZER_OFF) + { + // Reset timer TA1 + TA1R = 0; + TA1CTL |= MC_1; + + // Enable buzzer PWM output + P2SEL |= BIT7; + + // Update buzzer state + sBuzzer.state = BUZZER_ON_OUTPUT_ENABLED; + + // Reload Timer0_A4 IRQ to turn off output + sTimer.timer0_A3_ticks = sBuzzer.off_time; + } + } +} + +// ************************************************************************************************* +// @fn stop_buzzer +// @brief Stop buzzer output +// @param none +// @return none +// ************************************************************************************************* +void stop_buzzer(void) +{ + // Stop PWM timer + TA1CTL &= ~(BIT4 | BIT5); + + // Disable buzzer PWM output + P2OUT &= ~BIT7; + P2SEL &= ~BIT7; + + // Clear PWM timer interrupt + TA1CCTL0 &= ~CCIE; + + // Disable periodic start/stop interrupts + Timer0_A3_Stop(); + + // Clear variables + reset_buzzer(); +} + +// ************************************************************************************************* +// @fn is_buzzer +// @brief Check if buzzer is operating +// @param none +// @return u8 1 = Buzzer is operating, 0 = Buzzer is off +// ************************************************************************************************* +u8 is_buzzer(void) +{ + return (sBuzzer.state != BUZZER_OFF); +} + +// ************************************************************************************************* +// @fn countdown_buzzer +// @brief Decrement active buzzer time. Turn off buzzer if cycle end reached. +// @param none +// @return none +// ************************************************************************************************* +void countdown_buzzer(void) +{ + // Stop buzzer when reaching 0 cycles + if (--sBuzzer.time == 0) + { + stop_buzzer(); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/buzzer.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/buzzer.h new file mode 100755 index 0000000..59fbba9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/buzzer.h @@ -0,0 +1,87 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BUZZER_H_ +#define BUZZER_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_buzzer(void); +extern void start_buzzer(u8 cycles, u16 on_time, u16 off_time); +extern void stop_buzzer(void); +extern void toggle_buzzer(void); +extern u8 is_buzzer(void); +extern void countdown_buzzer(void); + +// ************************************************************************************************* +// Defines section + +// Buzzer states +#define BUZZER_OFF (0u) +#define BUZZER_ON_OUTPUT_DISABLED (1u) +#define BUZZER_ON_OUTPUT_ENABLED (2u) + +// Buzzer output signal frequency = 32,768kHz/(BUZZER_TIMER_STEPS+1)/2 = 2.7kHz +#define BUZZER_TIMER_STEPS (5u) + +// Buzzer on time +#define BUZZER_ON_TICKS (CONV_MS_TO_TICKS(20)) + +// Buzzer off time +#define BUZZER_OFF_TICKS (CONV_MS_TO_TICKS(200)) + +// ************************************************************************************************* +// Global Variable section +struct buzzer +{ + // Keep output for "time" seconds + u8 time; + + // On/off duty + u16 on_time; + u16 off_time; + + // Current buzzer output state + u8 state; +}; +extern struct buzzer sBuzzer; + +// ************************************************************************************************* +// Extern section + +#endif /*BUZZER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/display.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/display.c new file mode 100755 index 0000000..46a5d70 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/display.c @@ -0,0 +1,759 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Display functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include +#include + +// driver +#include "display.h" + +// logic +#include "clock.h" +#include "user.h" +#include "date.h" +#include "stopwatch.h" +#include "temperature.h" + +// ************************************************************************************************* +// Prototypes section +void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state); +void clear_line(u8 line); +void display_symbol(u8 symbol, u8 mode); +void display_char(u8 segment, u8 chr, u8 mode); +void display_chars(u8 segments, u8 * str, u8 mode); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// Table with memory bit assignment for digits "0" to "9" and characters "A" to "Z" +const u8 lcd_font[] = { + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F, // Displays "0" + SEG_B + SEG_C, // Displays "1" + SEG_A + SEG_B + SEG_D + SEG_E + SEG_G, // Displays "2" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_G, // Displays "3" + SEG_B + SEG_C + SEG_F + SEG_G, // Displays "4" + SEG_A + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "5" + SEG_A + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "6" + SEG_A + SEG_B + SEG_C, // Displays "7" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "8" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "9" + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + SEG_D + SEG_E + SEG_G, // Displays "c" + 0, // Displays " " + SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G, // Displays "A" + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "b" + SEG_A + SEG_D + SEG_E + SEG_F, // Displays "C" + SEG_B + SEG_C + SEG_D + SEG_E + SEG_G, // Displays "d" + SEG_A + +SEG_D + SEG_E + SEG_F + SEG_G, // Displays "E" + SEG_A + SEG_E + SEG_F + SEG_G, // Displays "F" + // SEG_A+ SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "G" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "g" + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G, // Displays "H" + SEG_E + SEG_F, // Displays "I" + SEG_A + SEG_B + SEG_C + SEG_D, // Displays "J" + // SEG_B+SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "k" + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "k" + SEG_D + SEG_E + SEG_F, // Displays "L" + SEG_A + SEG_B + SEG_C + SEG_E + SEG_F, // Displays "M" + SEG_C + SEG_E + SEG_G, // Displays "n" + SEG_C + SEG_D + SEG_E + SEG_G, // Displays "o" + SEG_A + SEG_B + SEG_E + SEG_F + SEG_G, // Displays "P" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F, // Displays "Q" + SEG_E + SEG_G, // Displays "r" + SEG_A + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "S" + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "t" + SEG_C + SEG_D + SEG_E, // Displays "u" + SEG_C + SEG_D + SEG_E, // Displays "u" + SEG_G, // Displays "-" + SEG_B + SEG_C + +SEG_E + SEG_F + SEG_G, // Displays "X" + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "Y" + SEG_A + SEG_B + SEG_D + SEG_E + SEG_G, // Displays "Z" +}; + +// Table with memory address for each display element +const u8 *segments_lcdmem[] = { + LCD_SYMB_AM_MEM, + LCD_SYMB_PM_MEM, + LCD_SYMB_ARROW_UP_MEM, + LCD_SYMB_ARROW_DOWN_MEM, + LCD_SYMB_PERCENT_MEM, + LCD_SYMB_TOTAL_MEM, + LCD_SYMB_AVERAGE_MEM, + LCD_SYMB_MAX_MEM, + LCD_SYMB_BATTERY_MEM, + LCD_UNIT_L1_FT_MEM, + LCD_UNIT_L1_K_MEM, + LCD_UNIT_L1_M_MEM, + LCD_UNIT_L1_I_MEM, + LCD_UNIT_L1_PER_S_MEM, + LCD_UNIT_L1_PER_H_MEM, + LCD_UNIT_L1_DEGREE_MEM, + LCD_UNIT_L2_KCAL_MEM, + LCD_UNIT_L2_KM_MEM, + LCD_UNIT_L2_MI_MEM, + LCD_ICON_HEART_MEM, + LCD_ICON_STOPWATCH_MEM, + LCD_ICON_RECORD_MEM, + LCD_ICON_ALARM_MEM, + LCD_ICON_BEEPER1_MEM, + LCD_ICON_BEEPER2_MEM, + LCD_ICON_BEEPER3_MEM, + LCD_SEG_L1_3_MEM, + LCD_SEG_L1_2_MEM, + LCD_SEG_L1_1_MEM, + LCD_SEG_L1_0_MEM, + LCD_SEG_L1_COL_MEM, + LCD_SEG_L1_DP1_MEM, + LCD_SEG_L1_DP0_MEM, + LCD_SEG_L2_5_MEM, + LCD_SEG_L2_4_MEM, + LCD_SEG_L2_3_MEM, + LCD_SEG_L2_2_MEM, + LCD_SEG_L2_1_MEM, + LCD_SEG_L2_0_MEM, + LCD_SEG_L2_COL1_MEM, + LCD_SEG_L2_COL0_MEM, + LCD_SEG_L2_DP_MEM, +}; + +// Table with bit mask for each display element +const u8 segments_bitmask[] = { + LCD_SYMB_AM_MASK, + LCD_SYMB_PM_MASK, + LCD_SYMB_ARROW_UP_MASK, + LCD_SYMB_ARROW_DOWN_MASK, + LCD_SYMB_PERCENT_MASK, + LCD_SYMB_TOTAL_MASK, + LCD_SYMB_AVERAGE_MASK, + LCD_SYMB_MAX_MASK, + LCD_SYMB_BATTERY_MASK, + LCD_UNIT_L1_FT_MASK, + LCD_UNIT_L1_K_MASK, + LCD_UNIT_L1_M_MASK, + LCD_UNIT_L1_I_MASK, + LCD_UNIT_L1_PER_S_MASK, + LCD_UNIT_L1_PER_H_MASK, + LCD_UNIT_L1_DEGREE_MASK, + LCD_UNIT_L2_KCAL_MASK, + LCD_UNIT_L2_KM_MASK, + LCD_UNIT_L2_MI_MASK, + LCD_ICON_HEART_MASK, + LCD_ICON_STOPWATCH_MASK, + LCD_ICON_RECORD_MASK, + LCD_ICON_ALARM_MASK, + LCD_ICON_BEEPER1_MASK, + LCD_ICON_BEEPER2_MASK, + LCD_ICON_BEEPER3_MASK, + LCD_SEG_L1_3_MASK, + LCD_SEG_L1_2_MASK, + LCD_SEG_L1_1_MASK, + LCD_SEG_L1_0_MASK, + LCD_SEG_L1_COL_MASK, + LCD_SEG_L1_DP1_MASK, + LCD_SEG_L1_DP0_MASK, + LCD_SEG_L2_5_MASK, + LCD_SEG_L2_4_MASK, + LCD_SEG_L2_3_MASK, + LCD_SEG_L2_2_MASK, + LCD_SEG_L2_1_MASK, + LCD_SEG_L2_0_MASK, + LCD_SEG_L2_COL1_MASK, + LCD_SEG_L2_COL0_MASK, + LCD_SEG_L2_DP_MASK, +}; + +// Quick integer to array conversion table for most common integer values +const u8 int_to_array_conversion_table[][3] = { + "000", "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", + "013", "014", "015", + "016", "017", "018", "019", "020", "021", "022", "023", "024", "025", "026", "027", "028", + "029", "030", "031", + "032", "033", "034", "035", "036", "037", "038", "039", "040", "041", "042", "043", "044", + "045", "046", "047", + "048", "049", "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", "060", + "061", "062", "063", + "064", "065", "066", "067", "068", "069", "070", "071", "072", "073", "074", "075", "076", + "077", "078", "079", + "080", "081", "082", "083", "084", "085", "086", "087", "088", "089", "090", "091", "092", + "093", "094", "095", + "096", "097", "098", "099", "100", "101", "102", "103", "104", "105", "106", "107", "108", + "109", "110", "111", + "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", + "125", "126", "127", + "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", + "141", "142", "143", + "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", + "157", "158", "159", + "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", + "173", "174", "175", + "176", "177", "178", "179", "180", +}; + +// Display flags +volatile s_display_flags display; + +// Global return string for int_to_array function +u8 int_to_array_str[8]; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); +extern void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn lcd_init +// @brief Erase LCD memory. Init LCD peripheral. +// @param none +// @return none +// ************************************************************************************************* +void lcd_init(void) +{ + // Clear entire display memory + LCDBMEMCTL |= LCDCLRBM + LCDCLRM; + + // LCD_FREQ = ACLK/16/8 = 256Hz + // Frame frequency = 256Hz/4 = 64Hz, LCD mux 4, LCD on + LCDBCTL0 = (LCDDIV0 + LCDDIV1 + LCDDIV2 + LCDDIV3) | (LCDPRE0 + LCDPRE1) | LCD4MUX | LCDON; + + // LCB_BLK_FREQ = ACLK/8/4096 = 1Hz + LCDBBLKCTL = LCDBLKPRE0 | LCDBLKPRE1 | LCDBLKDIV0 | LCDBLKDIV1 | LCDBLKDIV2 | LCDBLKMOD0; + + // I/O to COM outputs + P5SEL |= (BIT5 | BIT6 | BIT7); + P5DIR |= (BIT5 | BIT6 | BIT7); + + // Activate LCD output + LCDBPCTL0 = 0xFFFF; // Select LCD segments S0-S15 + LCDBPCTL1 = 0x00FF; // Select LCD segments S16-S22 + +#ifdef USE_LCD_CHARGE_PUMP + // Charge pump voltage generated internally, internal bias (V2-V4) generation + LCDBVCTL = LCDCPEN | VLCD_2_72; +#endif +} + +// ************************************************************************************************* +// @fn clear_display_all +// @brief Erase LINE1 and LINE2 segments. Clear also function-specific content. +// @param none +// @return none +// ************************************************************************************************* +void clear_display_all(void) +{ + // Clear generic content + clear_line(LINE1); + clear_line(LINE2); + + // Clean up function-specific content + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_CLEAR); +} + +// ************************************************************************************************* +// @fn clear_display +// @brief Erase LINE1 and LINE2 segments. Keep icons. +// @param none +// @return none +// ************************************************************************************************* +void clear_display(void) +{ + clear_line(LINE1); + clear_line(LINE2); +} + +// ************************************************************************************************* +// @fn clear_line +// @brief Erase segments of a given line. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void clear_line(u8 line) +{ + display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_5_0), NULL, SEG_OFF); + if (line == LINE1) + { + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + display_symbol(LCD_SEG_L1_DP0, SEG_OFF); + display_symbol(LCD_SEG_L1_COL, SEG_OFF); + } + else // line == LINE2 + { + display_symbol(LCD_SEG_L2_DP, SEG_OFF); + display_symbol(LCD_SEG_L2_COL1, SEG_OFF); + display_symbol(LCD_SEG_L2_COL0, SEG_OFF); + } +} + +// ************************************************************************************************* +// @fn write_segment +// @brief Write to one or multiple LCD segments +// @param lcdmem Pointer to LCD byte memory +// bits Segments to address +// bitmask Bitmask for particular display item +// mode On, off or blink segments +// @return +// ************************************************************************************************* +void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state) +{ + if (state == SEG_ON) + { + // Clear segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (u8) (*lcdmem | bits); + } + else if (state == SEG_OFF) + { + // Clear segments + *lcdmem = (u8) (*lcdmem & ~bitmask); + } + else if (state == SEG_ON_BLINK_ON) + { + // Clear visible / blink segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + + // Set visible / blink segments + *lcdmem = (u8) (*lcdmem | bits); + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) | bits); + } + else if (state == SEG_ON_BLINK_OFF) + { + // Clear visible segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (u8) (*lcdmem | bits); + + // Clear blink segments + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + } + else if (state == SEG_OFF_BLINK_OFF) + { + // Clear segments + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Clear blink segments + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + } +} + +// ************************************************************************************************* +// @fn int_to_array +// @brief Generic integer to array routine. Converts integer n to string. +// Default conversion result has leading zeros, e.g. "00123" +// Option to convert leading '0' into whitespace (blanks) +// @param u32 n integer to convert +// u8 digits number of digits +// u8 blanks fill up result string with number of +// whitespaces instead of leading zeros +// @return u8 string +// ************************************************************************************************* +u8 *int_to_array(u32 n, u8 digits, u8 blanks) +{ + u8 i; + u8 digits1 = digits; + + // Preset result string + memcpy(int_to_array_str, "0000000", 7); + + // Return empty string if number of digits is invalid (valid range for digits: 1-7) + if ((digits == 0) || (digits > 7)) + return (int_to_array_str); + + // Numbers 0 .. 180 can be copied from int_to_array_conversion_table without conversion + if (n <= 180) + { + if (digits >= 3) + { + memcpy(int_to_array_str + (digits - 3), int_to_array_conversion_table[n], 3); + } + else // digits == 1 || 2 + { + memcpy(int_to_array_str, int_to_array_conversion_table[n] + (3 - digits), digits); + } + } + else // For n > 180 need to calculate string content + { + // Calculate digits from least to most significant number + do + { + int_to_array_str[digits - 1] = n % 10 + '0'; + n /= 10; + } + while (--digits > 0); + } + + // Remove specified number of leading '0', always keep last one + i = 0; + while ((int_to_array_str[i] == '0') && (i < digits1 - 1)) + { + if (blanks > 0) + { + // Convert only specified number of leading '0' + int_to_array_str[i] = ' '; + blanks--; + } + i++; + } + + return (int_to_array_str); +} + +// ************************************************************************************************* +// @fn display_value +// @brief Generic decimal display routine. Used exclusively by set_value function. +// @param u8 segments LCD segments where value is displayed +// u32 value Integer value to be displayed +// u8 digits Number of digits to convert +// u8 blanks Number of leadings blanks in +// int_to_array result string +// @return none +// ************************************************************************************************* +void display_value(u8 segments, u32 value, u8 digits, u8 blanks) +{ + u8 *str; + + str = int_to_array(value, digits, blanks); + + // Display string in blink mode + display_chars(segments, str, SEG_ON_BLINK_ON); +} + +// ************************************************************************************************* +// @fn display_hours +// @brief Display hours in 24H / 12H time format. +// @param u8 segments Segments where to display hour data +// u32 value Hour data +// u8 digits Must be "2" +// u8 blanks Must be "0" +// @return none +// ************************************************************************************************* +void display_hours(u8 segments, u32 value, u8 digits, u8 blanks) +{ + u8 hours; + + if (sys.flag.use_metric_units) + { + // Display hours in 24H time format + display_value(segments, (u16) value, digits, blanks); + } + else + { + // convert internal 24H time format to 12H time format + hours = convert_hour_to_12H_format(value); + + // display hours in 12H time format + display_value(segments, hours, digits, blanks); + display_am_pm_symbol(value); + } +} + +// ************************************************************************************************* +// @fn display_am_pm_symbol +// @brief Display AM or PM symbol. +// @param u8 hour 24H internal time format +// @return none +// ************************************************************************************************* +void display_am_pm_symbol(u8 hour) +{ + // Display AM/PM symbol + if (is_hour_am(hour)) + { + display_symbol(LCD_SYMB_AM, SEG_ON); + } + else + { + // Clear AM segments first - required when changing from AM to PM + display_symbol(LCD_SYMB_AM, SEG_OFF); + display_symbol(LCD_SYMB_PM, SEG_ON); + } +} + +// ************************************************************************************************* +// @fn display_symbol +// @brief Switch symbol on or off on LCD. +// @param u8 symbol A valid LCD symbol (index 0..42) +// u8 state SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_symbol(u8 symbol, u8 mode) +{ + u8 *lcdmem; + u8 bits; + u8 bitmask; + + if (symbol <= LCD_SEG_L2_DP) + { + // Get LCD memory address for symbol from table + lcdmem = (u8 *) segments_lcdmem[symbol]; + + // Get bits for symbol from table + bits = segments_bitmask[symbol]; + + // Bitmask for symbols equals bits + bitmask = bits; + + // Write LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + +// ************************************************************************************************* +// @fn display_char +// @brief Write to 7-segment characters. +// @param u8 segment A valid LCD segment +// u8 chr Character to display +// u8 mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_char(u8 segment, u8 chr, u8 mode) +{ + u8 *lcdmem; // Pointer to LCD memory + u8 bitmask; // Bitmask for character + u8 bits, bits1; // Bits to write + + // Write to single 7-segment character + if ((segment >= LCD_SEG_L1_3) && (segment <= LCD_SEG_L2_DP)) + { + // Get LCD memory address for segment from table + lcdmem = (u8 *) segments_lcdmem[segment]; + + // Get bitmask for character from table + bitmask = segments_bitmask[segment]; + + // Get bits from font set + if ((chr >= 0x30) && (chr <= 0x5A)) + { + // Use font set + bits = lcd_font[chr - 0x30]; + } + else if (chr == 0x2D) + { + // '-' not in font set + bits = BIT1; + } + else + { + // Other characters map to ' ' (blank) + bits = 0; + } + + // When addressing LINE2 7-segment characters need to swap high- and low-nibble, + // because LCD COM/SEG assignment is mirrored against LINE1 + if (segment >= LCD_SEG_L2_5) + { + bits1 = ((bits << 4) & 0xF0) | ((bits >> 4) & 0x0F); + bits = bits1; + + // When addressing LCD_SEG_L2_5, need to convert ASCII '1' and 'L' to 1 bit, + // because LCD COM/SEG assignment is special for this incomplete character + if (segment == LCD_SEG_L2_5) + { + if ((chr == '1') || (chr == 'L')) + bits = BIT7; + } + } + + // Physically write to LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + +// ************************************************************************************************* +// @fn display_chars +// @brief Write to consecutive 7-segment characters. +// @param u8 segments LCD segment array +// u8 * str Pointer to a string +// u8 mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_chars(u8 segments, u8 * str, u8 mode) +{ + u8 i; + u8 length = 0; // Write length + u8 char_start; // Starting point for consecutive write + + switch (segments) + { + // LINE1 + case LCD_SEG_L1_3_0: + length = 4; + char_start = LCD_SEG_L1_3; + break; + case LCD_SEG_L1_2_0: + length = 3; + char_start = LCD_SEG_L1_2; + break; + case LCD_SEG_L1_1_0: + length = 2; + char_start = LCD_SEG_L1_1; + break; + case LCD_SEG_L1_3_1: + length = 3; + char_start = LCD_SEG_L1_3; + break; + case LCD_SEG_L1_3_2: + length = 2; + char_start = LCD_SEG_L1_3; + break; + + // LINE2 + case LCD_SEG_L2_5_0: + length = 6; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_4_0: + length = 5; + char_start = LCD_SEG_L2_4; + break; + case LCD_SEG_L2_3_0: + length = 4; + char_start = LCD_SEG_L2_3; + break; + case LCD_SEG_L2_2_0: + length = 3; + char_start = LCD_SEG_L2_2; + break; + case LCD_SEG_L2_1_0: + length = 2; + char_start = LCD_SEG_L2_1; + break; + case LCD_SEG_L2_5_4: + length = 2; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_5_2: + length = 4; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_3_2: + length = 2; + char_start = LCD_SEG_L2_3; + break; + case LCD_SEG_L2_4_2: + length = 3; + char_start = LCD_SEG_L2_4; + break; + } + + // Write to consecutive digits + for (i = 0; i < length; i++) + { + // Use single character routine to write display memory + display_char(char_start + i, *(str + i), mode); + } +} + +// ************************************************************************************************* +// @fn switch_seg +// @brief Returns index of 7-segment character. Required for display routines that can draw +// information on both lines. +// @param u8 line LINE1 or LINE2 +// u8 index1 Index of LINE1 +// u8 index2 Index of LINE2 +// @return uint8 +// ************************************************************************************************* +u8 switch_seg(u8 line, u8 index1, u8 index2) +{ + if (line == LINE1) + { + return index1; + } + else // line == LINE2 + { + return index2; + } +} + +// ************************************************************************************************* +// @fn start_blink +// @brief Start blinking. +// @param none +// @return none +// ************************************************************************************************* +void start_blink(void) +{ + LCDBBLKCTL |= LCDBLKMOD0; +} + +// ************************************************************************************************* +// @fn stop_blink +// @brief Stop blinking. +// @param none +// @return none +// ************************************************************************************************* +void stop_blink(void) +{ + LCDBBLKCTL &= ~LCDBLKMOD0; +} + +// ************************************************************************************************* +// @fn stop_blink +// @brief Clear blinking memory. +// @param none +// @return none +// ************************************************************************************************* +void clear_blink_mem(void) +{ + LCDBMEMCTL |= LCDCLRBM; +} + +// ************************************************************************************************* +// @fn set_blink_rate +// @brief Set blink rate register bits. +// @param none +// @return none +// ************************************************************************************************* +void set_blink_rate(u8 bits) +{ + LCDBBLKCTL &= ~(BIT7 | BIT6 | BIT5); + LCDBBLKCTL |= bits; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/display.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/display.h new file mode 100755 index 0000000..3674a4e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/display.h @@ -0,0 +1,338 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef __DISPLAY_H +#define __DISPLAY_H + +// ************************************************************************************************* +// Include section + +#include + +// ************************************************************************************************* +// Extern section + +// Constants defined in library +extern const u8 lcd_font[]; +extern const u8 *segments_lcdmem[]; +extern const u8 segments_bitmask[]; +extern const u8 int_to_array_conversion_table[][3]; + +// ************************************************************************************************* +// Global Variable section + +// Set of display flags +typedef union +{ + struct + { + // Line1 + Line2 + Icons + u16 full_update : 1; // 1 = Redraw all content + u16 partial_update : 1; // 1 = Update changes + + // Line only + u16 line1_full_update : 1; // 1 = Redraw Line1 content + u16 line2_full_update : 1; // 1 = Redraw Line2 content + + // Logic module data update flags + u16 update_time : 1; // 1 = Time was updated + u16 update_stopwatch : 1; // 1 = Stopwatch was updated + u16 update_temperature : 1; // 1 = Temperature was updated + u16 update_battery_voltage : 1; // 1 = Battery voltage was updated + u16 update_date : 1; // 1 = Date was updated + u16 update_alarm : 1; // 1 = Alarm time was updated + u16 update_acceleration : 1; // 1 = Acceleration data was updated + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_display_flags; + +extern volatile s_display_flags display; + +// ************************************************************************************************* +// Defines section + +// Display function modes +#define DISPLAY_LINE_UPDATE_FULL (BIT0) +#define DISPLAY_LINE_UPDATE_PARTIAL (BIT1) +#define DISPLAY_LINE_CLEAR (BIT2) + +// Definitions for line view style +#define DISPLAY_DEFAULT_VIEW (0u) +#define DISPLAY_ALTERNATIVE_VIEW (1u) + +// Definitions for line access +#define LINE1 (1u) +#define LINE2 (2u) + +// LCD display modes +#define SEG_OFF (0u) +#define SEG_ON (1u) +#define SEG_ON_BLINK_ON (2u) +#define SEG_ON_BLINK_OFF (3u) +#define SEG_OFF_BLINK_OFF (4u) + +// 7-segment character bit assignments +#define SEG_A (BIT4) +#define SEG_B (BIT5) +#define SEG_C (BIT6) +#define SEG_D (BIT7) +#define SEG_E (BIT2) +#define SEG_F (BIT0) +#define SEG_G (BIT1) + +// ------------------------------------------ +// LCD symbols for easier access +// +// xxx_SEG_xxx = Seven-segment character (sequence 5-4-3-2-1-0) +// xxx_SYMB_xxx = Display symbol, e.g. "AM" for ante meridiem +// xxx_UNIT_xxx = Display unit, e.g. "km/h" for kilometers per hour +// xxx_ICON_xxx = Display icon, e.g. heart to indicate reception of heart rate data +// xxx_L1_xxx = Item is part of Line1 information +// xxx_L2_xxx = Item is part of Line2 information + +// Symbols for Line1 +#define LCD_SYMB_AM 0 +#define LCD_SYMB_PM 1 +#define LCD_SYMB_ARROW_UP 2 +#define LCD_SYMB_ARROW_DOWN 3 +#define LCD_SYMB_PERCENT 4 + +// Symbols for Line2 +#define LCD_SYMB_TOTAL 5 +#define LCD_SYMB_AVERAGE 6 +#define LCD_SYMB_MAX 7 +#define LCD_SYMB_BATTERY 8 + +// Units for Line1 +#define LCD_UNIT_L1_FT 9 +#define LCD_UNIT_L1_K 10 +#define LCD_UNIT_L1_M 11 +#define LCD_UNIT_L1_I 12 +#define LCD_UNIT_L1_PER_S 13 +#define LCD_UNIT_L1_PER_H 14 +#define LCD_UNIT_L1_DEGREE 15 + +// Units for Line2 +#define LCD_UNIT_L2_KCAL 16 +#define LCD_UNIT_L2_KM 17 +#define LCD_UNIT_L2_MI 18 + +// Icons +#define LCD_ICON_HEART 19 +#define LCD_ICON_STOPWATCH 20 +#define LCD_ICON_RECORD 21 +#define LCD_ICON_ALARM 22 +#define LCD_ICON_BEEPER1 23 +#define LCD_ICON_BEEPER2 24 +#define LCD_ICON_BEEPER3 25 + +// Line1 7-segments +#define LCD_SEG_L1_3 26 +#define LCD_SEG_L1_2 27 +#define LCD_SEG_L1_1 28 +#define LCD_SEG_L1_0 29 +#define LCD_SEG_L1_COL 30 +#define LCD_SEG_L1_DP1 31 +#define LCD_SEG_L1_DP0 32 + +// Line2 7-segments +#define LCD_SEG_L2_5 33 +#define LCD_SEG_L2_4 34 +#define LCD_SEG_L2_3 35 +#define LCD_SEG_L2_2 36 +#define LCD_SEG_L2_1 37 +#define LCD_SEG_L2_0 38 +#define LCD_SEG_L2_COL1 39 +#define LCD_SEG_L2_COL0 40 +#define LCD_SEG_L2_DP 41 + +// Line1 7-segment arrays +#define LCD_SEG_L1_3_0 70 +#define LCD_SEG_L1_2_0 71 +#define LCD_SEG_L1_1_0 72 +#define LCD_SEG_L1_3_1 73 +#define LCD_SEG_L1_3_2 74 + +// Line2 7-segment arrays +#define LCD_SEG_L2_5_0 90 +#define LCD_SEG_L2_4_0 91 +#define LCD_SEG_L2_3_0 92 +#define LCD_SEG_L2_2_0 93 +#define LCD_SEG_L2_1_0 94 +#define LCD_SEG_L2_5_2 95 +#define LCD_SEG_L2_3_2 96 +#define LCD_SEG_L2_5_4 97 +#define LCD_SEG_L2_4_2 98 + +// LCD controller memory map +#define LCD_MEM_1 ((u8*)0x0A20) +#define LCD_MEM_2 ((u8*)0x0A21) +#define LCD_MEM_3 ((u8*)0x0A22) +#define LCD_MEM_4 ((u8*)0x0A23) +#define LCD_MEM_5 ((u8*)0x0A24) +#define LCD_MEM_6 ((u8*)0x0A25) +#define LCD_MEM_7 ((u8*)0x0A26) +#define LCD_MEM_8 ((u8*)0x0A27) +#define LCD_MEM_9 ((u8*)0x0A28) +#define LCD_MEM_10 ((u8*)0x0A29) +#define LCD_MEM_11 ((u8*)0x0A2A) +#define LCD_MEM_12 ((u8*)0x0A2B) + +// Memory assignment +#define LCD_SEG_L1_0_MEM (LCD_MEM_6) +#define LCD_SEG_L1_1_MEM (LCD_MEM_4) +#define LCD_SEG_L1_2_MEM (LCD_MEM_3) +#define LCD_SEG_L1_3_MEM (LCD_MEM_2) +#define LCD_SEG_L1_COL_MEM (LCD_MEM_1) +#define LCD_SEG_L1_DP1_MEM (LCD_MEM_1) +#define LCD_SEG_L1_DP0_MEM (LCD_MEM_5) +#define LCD_SEG_L2_0_MEM (LCD_MEM_8) +#define LCD_SEG_L2_1_MEM (LCD_MEM_9) +#define LCD_SEG_L2_2_MEM (LCD_MEM_10) +#define LCD_SEG_L2_3_MEM (LCD_MEM_11) +#define LCD_SEG_L2_4_MEM (LCD_MEM_12) +#define LCD_SEG_L2_5_MEM (LCD_MEM_12) +#define LCD_SEG_L2_COL1_MEM (LCD_MEM_1) +#define LCD_SEG_L2_COL0_MEM (LCD_MEM_5) +#define LCD_SEG_L2_DP_MEM (LCD_MEM_9) +#define LCD_SYMB_AM_MEM (LCD_MEM_1) +#define LCD_SYMB_PM_MEM (LCD_MEM_1) +#define LCD_SYMB_ARROW_UP_MEM (LCD_MEM_1) +#define LCD_SYMB_ARROW_DOWN_MEM (LCD_MEM_1) +#define LCD_SYMB_PERCENT_MEM (LCD_MEM_5) +#define LCD_SYMB_TOTAL_MEM (LCD_MEM_11) +#define LCD_SYMB_AVERAGE_MEM (LCD_MEM_10) +#define LCD_SYMB_MAX_MEM (LCD_MEM_8) +#define LCD_SYMB_BATTERY_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_FT_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_K_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_M_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_I_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_PER_S_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_PER_H_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_DEGREE_MEM (LCD_MEM_5) +#define LCD_UNIT_L2_KCAL_MEM (LCD_MEM_7) +#define LCD_UNIT_L2_KM_MEM (LCD_MEM_7) +#define LCD_UNIT_L2_MI_MEM (LCD_MEM_7) +#define LCD_ICON_HEART_MEM (LCD_MEM_2) +#define LCD_ICON_STOPWATCH_MEM (LCD_MEM_3) +#define LCD_ICON_RECORD_MEM (LCD_MEM_1) +#define LCD_ICON_ALARM_MEM (LCD_MEM_4) +#define LCD_ICON_BEEPER1_MEM (LCD_MEM_5) +#define LCD_ICON_BEEPER2_MEM (LCD_MEM_6) +#define LCD_ICON_BEEPER3_MEM (LCD_MEM_7) + +// Bit masks for write access +#define LCD_SEG_L1_0_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_1_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_2_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_3_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_COL_MASK (BIT5) +#define LCD_SEG_L1_DP1_MASK (BIT6) +#define LCD_SEG_L1_DP0_MASK (BIT2) +#define LCD_SEG_L2_0_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_1_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_2_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_3_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_4_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_5_MASK (BIT7) +#define LCD_SEG_L2_COL1_MASK (BIT4) +#define LCD_SEG_L2_COL0_MASK (BIT0) +#define LCD_SEG_L2_DP_MASK (BIT7) +#define LCD_SYMB_AM_MASK (BIT1 + BIT0) +#define LCD_SYMB_PM_MASK (BIT0) +#define LCD_SYMB_ARROW_UP_MASK (BIT2) +#define LCD_SYMB_ARROW_DOWN_MASK (BIT3) +#define LCD_SYMB_PERCENT_MASK (BIT4) +#define LCD_SYMB_TOTAL_MASK (BIT7) +#define LCD_SYMB_AVERAGE_MASK (BIT7) +#define LCD_SYMB_MAX_MASK (BIT7) +#define LCD_SYMB_BATTERY_MASK (BIT7) +#define LCD_UNIT_L1_FT_MASK (BIT5) +#define LCD_UNIT_L1_K_MASK (BIT6) +#define LCD_UNIT_L1_M_MASK (BIT1) +#define LCD_UNIT_L1_I_MASK (BIT0) +#define LCD_UNIT_L1_PER_S_MASK (BIT7) +#define LCD_UNIT_L1_PER_H_MASK (BIT2) +#define LCD_UNIT_L1_DEGREE_MASK (BIT1) +#define LCD_UNIT_L2_KCAL_MASK (BIT4) +#define LCD_UNIT_L2_KM_MASK (BIT5) +#define LCD_UNIT_L2_MI_MASK (BIT6) +#define LCD_ICON_HEART_MASK (BIT3) +#define LCD_ICON_STOPWATCH_MASK (BIT3) +#define LCD_ICON_RECORD_MASK (BIT7) +#define LCD_ICON_ALARM_MASK (BIT3) +#define LCD_ICON_BEEPER1_MASK (BIT3) +#define LCD_ICON_BEEPER2_MASK (BIT3) +#define LCD_ICON_BEEPER3_MASK (BIT3) + +// ************************************************************************************************* +// API section + +// Physical LCD memory write +extern void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state); + +// Display init / clear +extern void lcd_init(void); +extern void clear_display(void); +extern void clear_display_all(void); +extern void clear_line(u8 line); + +// Blinking function +extern void start_blink(void); +extern void stop_blink(void); +extern void clear_blink_mem(void); +extern void set_blink_rate(u8 bits); + +// Character / symbol draw functions +extern void display_char(u8 segment, u8 chr, u8 mode); +extern void display_chars(u8 segments, u8 * str, u8 mode); +extern void display_symbol(u8 symbol, u8 mode); + +// Time display function +extern void DisplayTime(u8 updateMode); +extern void display_am_pm_symbol(u8 timeAM); + +// Set_value display functions +extern void display_value(u8 segments, u32 value, u8 digits, u8 blanks); +extern void display_hours(u8 segments, u32 value, u8 digits, u8 blanks); + +// Integer to string conversion +extern u8 *int_to_array(u32 n, u8 digits, u8 blanks); + +// Segment index helper function +extern u8 switch_seg(u8 line, u8 index1, u8 index2); + +#endif /*DISPLAY_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/ez430_chronos_drivers.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/ez430_chronos_drivers.lib new file mode 100755 index 0000000..2601d5b Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/ez430_chronos_drivers.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/pmm.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/pmm.c new file mode 100755 index 0000000..6d53a7c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/pmm.c @@ -0,0 +1,78 @@ +//****************************************************************************// +// Function Library for setting the PMM +// +// This file is used in conjunction with PMM.c to set the core +// voltage level of a device. To set a core voltage level, call +// SetVCore(level). See RF project(s) for example usage. +// +// Original programm Stefan Schauer +// Rev 1.1: changed VCoreUp to fit with recommended flow (09/04/2008) +// +//****************************************************************************// +#include "cc430x613x.h" +#include "pmm.h" + +//****************************************************************************// +// Set VCore level +// SetVCore level is called from the user API +//****************************************************************************// +void SetVCore(unsigned char level) // Note: change level by one + // step only +{ + unsigned char actLevel; + + do + { + actLevel = PMMCTL0_L & PMMCOREV_3; + if (actLevel < level) + SetVCoreUp(++actLevel); // Set VCore (step by step) + if (actLevel > level) + SetVCoreDown(--actLevel); // Set VCore (step by step) + } + while (actLevel != level); +} + +//****************************************************************************// +// Set VCore up +//****************************************************************************// +void SetVCoreUp(unsigned char level) // Note: change level by one + // step only +{ + // Open PMM module registers for write access + PMMCTL0_H = 0xA5; + + // Set SVS/M high side to new level + SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; + + SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; // Set SVM new Level + while ((PMMIFG & SVSMLDLYIFG) == 0) ; // Wait till SVM is settled + // (Delay) + PMMCTL0_L = PMMCOREV0 * level; // Set VCore to x + PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); // Clear already set flags + if ((PMMIFG & SVMLIFG)) + while ((PMMIFG & SVMLVLRIFG) == 0) ; // Wait till level is reached + + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Set SVS/M Low side to new + // level + PMMCTL0_H = 0x00; // Lock PMM module registers + // for write access +} + +//****************************************************************************// +// Set VCore down +//****************************************************************************// +void SetVCoreDown(unsigned char level) +{ + PMMCTL0_H = 0xA5; // Open PMM module registers + // for write access + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Set SVS/M Low side to new + // level + while ((PMMIFG & SVSMLDLYIFG) == 0) ; // Wait till SVM is settled + // (Delay) + PMMCTL0_L = (level * PMMCOREV0); // Set VCore to 1.85 V for Max + // Speed. + PMMCTL0_H = 0x00; // Lock PMM module registers + // for write access +} + +//****************************************************************************// diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/pmm.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/pmm.h new file mode 100755 index 0000000..170008f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/pmm.h @@ -0,0 +1,43 @@ +//==================================================================== +// File: PMM.h +// +// This file is used in conjunction with PMM.c to set the core +// voltage level of a device. To set a core voltage level, call +// SetVCore(level). See RF project(s) for example usage. +// +// Version 1.0 first +// 07/14/07 +// +//==================================================================== + +#ifndef __PMM +#define __PMM + +//==================================================================== + +/** + * Set the VCore to a new level + * + * \param level PMM level ID + */ +void SetVCore(unsigned char level); + +//==================================================================== + +/** + * Set the VCore to a new higher level + * + * \param level PMM level ID + */ +void SetVCoreUp(unsigned char level); + +//==================================================================== + +/** + * Set the VCore to a new Lower level + * + * \param level PMM level ID + */ +void SetVCoreDown(unsigned char level); + +#endif /* __PMM */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/ports.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/ports.c new file mode 100755 index 0000000..cd086c3 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/ports.c @@ -0,0 +1,455 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Button entry functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "ports.h" +#include "buzzer.h" +#include "vti_as.h" +#include "vti_ps.h" +#include "timer.h" +#include "display.h" + +// logic +#include "clock.h" +#include "alarm.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "altitude.h" +#include "stopwatch.h" + +// ************************************************************************************************* +// Prototypes section +void button_repeat_on(u16 msec); +void button_repeat_off(void); +void button_repeat_function(void); + +// ************************************************************************************************* +// Defines section + +// Macro for button IRQ +#define IRQ_TRIGGERED(flags, bit) ((flags & bit) == bit) + +// ************************************************************************************************* +// Global Variable section +volatile s_button_flags button; +volatile struct struct_button sButton; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// @fn init_buttons +// @brief Init and enable button interrupts. +// @param none +// @return none +// ************************************************************************************************* +void init_buttons(void) +{ + // Set button ports to input + BUTTONS_DIR &= ~ALL_BUTTONS; + + // Enable internal pull-downs + BUTTONS_OUT &= ~ALL_BUTTONS; + BUTTONS_REN |= ALL_BUTTONS; + + // IRQ triggers on rising edge + BUTTONS_IES &= ~ALL_BUTTONS; + + // Reset IRQ flags + BUTTONS_IFG &= ~ALL_BUTTONS; + + // Enable button interrupts + BUTTONS_IE |= ALL_BUTTONS; +} + +// ************************************************************************************************* +// @fn PORT2_ISR +// @brief Interrupt service routine for +// - buttons +// - acceleration sensor CMA_INT +// - pressure sensor DRDY +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=PORT2_VECTOR +__interrupt void PORT2_ISR(void) +{ + // Clear flags + u8 int_flag, int_enable; + u8 buzzer = 0; + u8 simpliciti_button_event = 0; + static u8 simpliciti_button_repeat = 0; + + // Remember interrupt enable bits + int_enable = BUTTONS_IE; + + if ((!button.flag.star_long) && (!button.flag.num_long)) + { + // Clear button flags + button.all_flags = 0; + + // Store valid button interrupt flag + int_flag = BUTTONS_IFG & int_enable; + + // --------------------------------------------------- + // While SimpliciTI stack is active, buttons behave differently: + // - Store button events in SimpliciTI packet data + // - Exit SimpliciTI when button DOWN was pressed + if (is_rf()) + { + // Erase previous button press after a number of resends (increase number if link + // quality is low) + // This will create a series of packets containing the same button press + // Necessary because we have no acknowledge + // Filtering (edge detection) will be done by receiver software + if (simpliciti_button_repeat++ > 6) + { + simpliciti_data[0] &= ~0xF0; + simpliciti_button_repeat = 0; + } + + if ((int_flag & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_STAR; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_NUM; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_UP_PIN) == BUTTON_UP_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_UP; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN) + { + simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; + } + + // Trigger packet sending inside SimpliciTI stack + if (simpliciti_button_event) + simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; + } + else // Normal operation + { + // Debounce buttons + if ((int_flag & ALL_BUTTONS) != 0) + { + // Disable PORT2 IRQ + __disable_interrupt(); + BUTTONS_IE = 0x00; + __enable_interrupt(); + + // Debounce delay 1 + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN)); + + // Reset inactivity detection + sTime.last_activity = sTime.system_time; + } + + // --------------------------------------------------- + // STAR button IRQ + if (IRQ_TRIGGERED(int_flag, BUTTON_STAR_PIN)) + { + // Filter bouncing noise + if (BUTTON_STAR_IS_PRESSED) + { + button.flag.star = 1; + button.flag.star_not_long = 0; + // Generate button click + buzzer = 1; + } + else if ((BUTTONS_IES & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) + { + button.flag.star = 1; + button.flag.star_not_long = 0; + BUTTONS_IES &= ~BUTTON_STAR_PIN; + } + } + // --------------------------------------------------- + // NUM button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN)) + { + // Filter bouncing noise + if (BUTTON_NUM_IS_PRESSED) + { + button.flag.num = 1; + button.flag.num_not_long = 0; + // Generate button click + buzzer = 1; + } + else if ((BUTTONS_IES & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) + { + button.flag.num = 1; + button.flag.num_not_long = 0; + BUTTONS_IES &= ~BUTTON_NUM_PIN; + } + } + // --------------------------------------------------- + // UP button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_UP_PIN)) + { + // Filter bouncing noise + if (BUTTON_UP_IS_PRESSED) + { + button.flag.up = 1; + + // Generate button click + buzzer = 1; + } + } + // --------------------------------------------------- + // DOWN button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_DOWN_PIN)) + { + // Filter bouncing noise + if (BUTTON_DOWN_IS_PRESSED) + { + button.flag.down = 1; + + // Generate button click + buzzer = 1; + + // Faster reaction for stopwatch stop button press + if (is_stopwatch() && !sys.flag.lock_buttons) + { + stop_stopwatch(); + button.flag.down = 0; + } + } + } + // --------------------------------------------------- + // B/L button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_BACKLIGHT_PIN)) + { + // Filter bouncing noise + if (BUTTON_BACKLIGHT_IS_PRESSED) + { + sButton.backlight_status = 1; + sButton.backlight_timeout = 0; + P2OUT |= BUTTON_BACKLIGHT_PIN; + P2DIR |= BUTTON_BACKLIGHT_PIN; + } + } + } + + // Trying to lock/unlock buttons? + if (button.flag.num && button.flag.down) + { + // No buzzer output + buzzer = 0; + button.all_flags = 0; + } + + // Generate button click when button was activated + if (buzzer) + { + // Any button event stops active alarm + if (sAlarm.state == ALARM_ON) + { + stop_alarm(); + button.all_flags = 0; + } + else if (!sys.flag.up_down_repeat_enabled) + { + start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150)); + } + + // Debounce delay 2 + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + } + + // --------------------------------------------------- + // Acceleration sensor IRQ + if (IRQ_TRIGGERED(int_flag, AS_INT_PIN)) + { + // Get data from sensor + request.flag.acceleration_measurement = 1; + } + + // --------------------------------------------------- + // Pressure sensor IRQ + if (IRQ_TRIGGERED(int_flag, PS_INT_PIN)) + { + // Get data from sensor + request.flag.altitude_measurement = 1; + } + + // --------------------------------------------------- + // Safe long button event detection + if (button.flag.star || button.flag.num) + { + // Additional debounce delay to enable safe high detection - 50ms + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT)); + + // Check if this button event is short enough + if (BUTTON_STAR_IS_PRESSED) + { + // Change interrupt edge to detect button release + BUTTONS_IES |= BUTTON_STAR_PIN; + button.flag.star = 0; + // This flag is used to detect if the user released the button before the + // time for a long button press (3s) + button.flag.star_not_long = 1; + } + if (BUTTON_NUM_IS_PRESSED) + { + // Change interrupt edge to detect button release + BUTTONS_IES |= BUTTON_NUM_PIN; + button.flag.num = 0; + // This flag is used to detect if the user released the button before the + // time for a long button press (3s) + button.flag.num_not_long = 1; + } + } + + } + // Reenable PORT2 IRQ + __disable_interrupt(); + BUTTONS_IFG = 0x00; + BUTTONS_IE = int_enable; + __enable_interrupt(); + + // Exit from LPM3/LPM4 on RETI + __bic_SR_register_on_exit(LPM4_bits); +} + +// ************************************************************************************************* +// @fn button_repeat_on +// @brief Start button auto repeat timer. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_on(u16 msec) +{ + // Set button repeat flag + sys.flag.up_down_repeat_enabled = 1; + + // Set Timer0_A3 function pointer to button repeat function + fptr_Timer0_A3_function = button_repeat_function; + + // Timer0_A3 IRQ triggers every 200ms + Timer0_A3_Start(CONV_MS_TO_TICKS(msec)); +} + +// ************************************************************************************************* +// @fn button_repeat_off +// @brief Stop button auto repeat timer. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_off(void) +{ + // Clear button repeat flag + sys.flag.up_down_repeat_enabled = 0; + + // Timer0_A3 IRQ repeats with 4Hz + Timer0_A3_Stop(); +} + +// ************************************************************************************************* +// @fn button_repeat_function +// @brief Check at regular intervals if button is pushed continuously +// and trigger virtual button event. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_function(void) +{ + static u8 start_delay = 10; // Wait for 2 seconds before starting auto up/down + u8 repeat = 0; + + // If buttons UP or DOWN are continuously high, repeatedly set button flag + if (BUTTON_UP_IS_PRESSED) + { + if (start_delay == 0) + { + // Generate a virtual button event + button.flag.up = 1; + repeat = 1; + } + else + { + start_delay--; + } + } + else if (BUTTON_DOWN_IS_PRESSED) + { + if (start_delay == 0) + { + // Generate a virtual button event + button.flag.down = 1; + repeat = 1; + } + else + { + start_delay--; + } + } + else + { + // Reset repeat counter + sButton.repeats = 0; + start_delay = 10; + + // Enable blinking + start_blink(); + } + + // If virtual button event is generated, stop blinking and reset timeout counter + if (repeat) + { + // Increase repeat counter + sButton.repeats++; + + // Reset inactivity detection counter + sTime.last_activity = sTime.system_time; + + // Disable blinking + stop_blink(); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/ports.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/ports.h new file mode 100755 index 0000000..fcb731f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/ports.h @@ -0,0 +1,130 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef PORTS_H_ +#define PORTS_H_ + +// ************************************************************************************************* +// Defines section + +// Port, pins and interrupt resources for buttons +#define BUTTONS_IN (P2IN) +#define BUTTONS_OUT (P2OUT) +#define BUTTONS_DIR (P2DIR) +#define BUTTONS_REN (P2REN) +#define BUTTONS_IE (P2IE) +#define BUTTONS_IES (P2IES) +#define BUTTONS_IFG (P2IFG) +#define BUTTONS_IRQ_VECT2 (PORT2_VECTOR) + +// Button ports +#define BUTTON_STAR_PIN (BIT2) +#define BUTTON_NUM_PIN (BIT1) +#define BUTTON_UP_PIN (BIT4) +#define BUTTON_DOWN_PIN (BIT0) +#define BUTTON_BACKLIGHT_PIN (BIT3) +#define ALL_BUTTONS (BUTTON_STAR_PIN + BUTTON_NUM_PIN + BUTTON_UP_PIN + \ + BUTTON_DOWN_PIN + BUTTON_BACKLIGHT_PIN) + +// Macros for button press detection +#define BUTTON_STAR_IS_PRESSED ((BUTTONS_IN & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) +#define BUTTON_NUM_IS_PRESSED ((BUTTONS_IN & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) +#define BUTTON_UP_IS_PRESSED ((BUTTONS_IN & BUTTON_UP_PIN) == BUTTON_UP_PIN) +#define BUTTON_DOWN_IS_PRESSED ((BUTTONS_IN & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN) +#define BUTTON_BACKLIGHT_IS_PRESSED ((BUTTONS_IN & BUTTON_BACKLIGHT_PIN) == \ + BUTTON_BACKLIGHT_PIN) +#define NO_BUTTON_IS_PRESSED ((BUTTONS_IN & ALL_BUTTONS) == 0) + +// Macros for button release detection +#define BUTTON_STAR_IS_RELEASED ((BUTTONS_IN & BUTTON_STAR_PIN) == 0) +#define BUTTON_NUM_IS_RELEASED ((BUTTONS_IN & BUTTON_NUM_PIN) == 0) +#define BUTTON_UP_IS_RELEASED (BUTTONS_IN & BUTTON_UP_PIN) == 0) +#define BUTTON_DOWN_IS_RELEASED ((BUTTONS_IN & BUTTON_DOWN_PIN) == 0) +#define BUTTON_BACKLIGHT_IS_RELEASED ((BUTTONS_IN & BUTTON_BACKLIGHT_PIN) == 0) + +// Button debounce time (msec) +#define BUTTONS_DEBOUNCE_TIME_IN (5u) +#define BUTTONS_DEBOUNCE_TIME_OUT (250u) +#define BUTTONS_DEBOUNCE_TIME_LEFT (50u) + +// Detect if STAR / NUM button is held low continuously +#define LEFT_BUTTON_LONG_TIME (2u) + +// Backlight time (sec) +#define BACKLIGHT_TIME_ON (3u) + +// Leave set_value() function after some seconds of user inactivity +#define INACTIVITY_TIME (30u) + +// Set of button flags +typedef union +{ + struct + { + // Manual button events + u16 star : 1; // Short STAR button press + u16 num : 1; // Short NUM button press + u16 up : 1; // Short UP button press + u16 down : 1; // Short DOWN button press + u16 backlight : 1; // Short BACKLIGHT button press + u16 star_long : 1; // Long STAR button press + u16 num_long : 1; // Long NUM button press + u16 star_not_long : 1; // Between short and long STAR button press + u16 num_not_long : 1; // Between short and long NUM button press + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_button_flags; +extern volatile s_button_flags button; + +struct struct_button +{ + u8 star_timeout; // this variable is incremented each second if STAR button is still + // pressed + u8 num_timeout; // this variable is incremented each second if NUM button is still + // pressed + u8 backlight_timeout; // controls the timeout for the backlight + u8 backlight_status; // 1 case backlight is on + s16 repeats; +}; +extern volatile struct struct_button sButton; + +// ************************************************************************************************* +// Extern section +extern void button_repeat_on(u16 msec); +extern void button_repeat_off(void); +extern void button_repeat_function(void); +extern void init_buttons(void); + +#endif /*PORTS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/radio.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/radio.c new file mode 100755 index 0000000..276d929 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/radio.c @@ -0,0 +1,187 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// system +#include "project.h" + +// driver +#include "rf1a.h" +#include "timer.h" + +// logic +#include "rfsimpliciti.h" +#include "bluerobin.h" + +// ************************************************************************************************* +// Extern section + +// SimpliciTI CC430 radio ISR - located in SimpliciTi library +extern void MRFI_RadioIsr(void); + +// BlueRobin CC430 radio ISR - located in BlueRobin library +extern void BlueRobin_RadioISR_v(void); + +// ************************************************************************************************* +// @fn radio_reset +// @brief Reset radio core. +// @param none +// @return none +// ************************************************************************************************* +void radio_reset(void) +{ + volatile u16 i; + u8 x; + + // Reset radio core + Strobe(RF_SRES); + // Wait before checking IDLE + for (i = 0; i < 100; i++) ; + do + { + x = Strobe(RF_SIDLE); + } + while ((x & 0x70) != 0x00); + + // Clear radio error register + RF1AIFERR = 0; +} + +// ************************************************************************************************* +// @fn radio_powerdown +// @brief Put radio to SLEEP mode. +// @param none +// @return none +// ************************************************************************************************* +void radio_powerdown(void) +{ + // Chip bug: Radio does not come out of this SLEEP when put to sleep + // using the SPWD cmd. However, it does wakes up if SXOFF was used to + // put it to sleep. + + // Powerdown radio + Strobe(RF_SIDLE); + Strobe(RF_SPWD); +} + +// ************************************************************************************************* +// @fn radio_sxoff +// @brief Put radio to SLEEP mode (XTAL off only). +// @param none +// @return none +// ************************************************************************************************* +void radio_sxoff(void) +{ + // Chip bug: Radio does not come out of this SLEEP when put to sleep + // using the SPWD cmd. However, it does wakes up if SXOFF was used to + // put it to sleep. + + // Powerdown radio + Strobe(RF_SIDLE); + Strobe(RF_SXOFF); +} + +// ************************************************************************************************* +// @fn open_radio +// @brief Prepare radio for RF communication. +// @param none +// @return none +// ************************************************************************************************* +void open_radio(void) +{ + // Reset radio core + radio_reset(); + + // Enable radio IRQ + RF1AIFG &= ~BIT4; // Clear a pending interrupt + RF1AIE |= BIT4; // Enable the interrupt +} + +// ************************************************************************************************* +// @fn close_radio +// @brief Shutdown radio for RF communication. +// @param none +// @return none +// ************************************************************************************************* +void close_radio(void) +{ + // Disable radio IRQ + RF1AIFG = 0; + RF1AIE = 0; + + // Reset radio core + radio_reset(); + + // Put radio to sleep + radio_powerdown(); +} + +// ************************************************************************************************* +// @fn GDOx_ISR +// @brief GDO0/2 ISR to detect received packet. +// In BlueRobin mode: capture packet end time and decode received +// packet +// In SimpliciTI mode: go to SimpliciTI handler +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=CC1101_VECTOR +__interrupt void radio_ISR(void) +{ + u8 rf1aivec = RF1AIV; + + // Forward to SimpliciTI interrupt service routine + if (is_rf()) + { + MRFI_RadioIsr(); + } + else // BlueRobin packet end interrupt service routine + { + if (rf1aivec == RF1AIV_RFIFG9) + { + if ((sBlueRobin.state == BLUEROBIN_SEARCHING) || + (sBlueRobin.state == BLUEROBIN_CONNECTED)) + { + BlueRobin_RadioISR_v(); + } + } + else if (rf1aivec == RF1AIV_NONE) // RF1A interface interrupt (error etc.) + { + asm (" nop"); // break here + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/radio.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/radio.h new file mode 100755 index 0000000..f4c1bb9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/radio.h @@ -0,0 +1,48 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RADIO_H_ +#define RADIO_H_ + +extern void radio_reset(void); +extern void radio_powerdown(void); +extern void radio_sxoff(void); +extern void radio_idle(void); +extern void open_radio(void); +extern void close_radio(void); +extern void pmm_set_high_current_mode(void); +extern void pmm_set_low_current_mode(void); + +#endif /*RADIO_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/rf1a.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/rf1a.c new file mode 100755 index 0000000..9f3b5be --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/rf1a.c @@ -0,0 +1,233 @@ +// ************************************************************************************************* +// +// Actual revision: $Revision: $ +// Revision label: $Name: $ +// Revision state: $State: $ +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include + +// driver +#include "rf1a.h" + +// ************************************************************************************************* +// Global section + +// ************************************************************************************************* +// Define section +#define st(x) do { x } while (__LINE__ == -1) +#define ENTER_CRITICAL_SECTION(x) st(x = __get_interrupt_state(); __disable_interrupt(); ) +#define EXIT_CRITICAL_SECTION(x) __set_interrupt_state(x) + +// ************************************************************************************************* +// @fn Strobe +// @brief Send command to radio. +// @param unsigned char strobe Command to radio +// @return statusByte Radio core status +// ************************************************************************************************* +unsigned char Strobe(unsigned char strobe) +{ + u8 statusByte = 0; + u16 int_state, gdo_state; + + // Check for valid strobe command + if ((strobe == 0xBD) || ((strobe > RF_SRES) && (strobe < RF_SNOP))) + { + ENTER_CRITICAL_SECTION(int_state); + + // Clear the Status read flag + RF1AIFCTL1 &= ~(RFSTATIFG); + + // Wait for radio to be ready for next instruction + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + + // Write the strobe instruction + if ((strobe > RF_SRES) && (strobe < RF_SNOP)) + { + + gdo_state = ReadSingleReg(IOCFG2); // buffer IOCFG2 state + WriteSingleReg(IOCFG2, 0x29); // c-ready to GDO2 + + RF1AINSTRB = strobe; + if ((RF1AIN & 0x04) == 0x04) // chip at sleep mode + { + if ((strobe == RF_SXOFF) || (strobe == RF_SPWD) || (strobe == RF_SWOR)) + { + } + else + { + while ((RF1AIN & 0x04) == 0x04) ; // c-ready ? + __delay_cycles(9800); // Delay for ~810usec at 12MHz CPU clock + } + } + WriteSingleReg(IOCFG2, gdo_state); // restore IOCFG2 setting + } + else // chip active mode + { + RF1AINSTRB = strobe; + } + statusByte = RF1ASTATB; + while (!(RF1AIFCTL1 & RFSTATIFG)) ; + EXIT_CRITICAL_SECTION(int_state); + } + return statusByte; +} + +// ************************************************************************************************* +// @fn ResetRadioCore +// @brief Software reset radio core. +// @param none +// @return none +// ************************************************************************************************* +void ResetRadioCore(void) +{ + Strobe(RF_SRES); // Reset the Radio Core + Strobe(RF_SNOP); // Reset Radio Pointer +} + +// ************************************************************************************************* +// @fn ReadSingleReg +// @brief Read byte from register. +// @param none +// @return none +// ************************************************************************************************* +unsigned char ReadSingleReg(unsigned char addr) +{ + unsigned char x; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + RF1AINSTR1B = (addr | RF_REGRD); + x = RF1ADOUT1B; + + EXIT_CRITICAL_SECTION(int_state); + + return x; +} + +// ************************************************************************************************* +// @fn WriteSingleReg +// @brief Write byte to register. +// @param none +// @return none +// ************************************************************************************************* +void WriteSingleReg(unsigned char addr, unsigned char value) +{ + volatile unsigned int i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for the next + // instruction + + RF1AINSTRW = ((addr | RF_REGWR) << 8) + value; // Send address + Instruction + while (!(RFDINIFG & RF1AIFCTL1)) ; + + i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status + // byte + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn ReadBurstReg +// @brief Read sequence of bytes from register. +// @param none +// @return none +// ************************************************************************************************* +void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) +{ + unsigned int i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for next instruction + RF1AINSTR1B = (addr | RF_REGRD); // Send address + Instruction + + for (i = 0; i < (count - 1); i++) + { + while (!(RFDOUTIFG & RF1AIFCTL1)) ; // Wait for the Radio Core to update the RF1ADOUTB reg + buffer[i] = RF1ADOUT1B; // Read DOUT from Radio Core + clears RFDOUTIFG + // Also initiates auo-read for next DOUT byte + } + buffer[count - 1] = RF1ADOUT0B; // Store the last DOUT from Radio Core + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn WriteBurstReg +// @brief Write sequence of bytes to register. +// @param none +// @return none +// ************************************************************************************************* +void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) +{ + // Write Burst works wordwise not bytewise - bug known already + unsigned char i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for next + // instruction + RF1AINSTRW = ((addr | RF_REGWR) << 8) + buffer[0]; // Send address + Instruction + + for (i = 1; i < count; i++) + { + RF1ADINB = buffer[i]; // Send data + while (!(RFDINIFG & RF1AIFCTL1)) ; // Wait for TX to finish + } + i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status + // byte + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn WritePATable +// @brief Write data to power table +// @param unsigned char value Value to write +// @return none +// ************************************************************************************************* +void WritePATable(unsigned char value) +{ + unsigned char readbackPATableValue = 0; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (readbackPATableValue != value) + { + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRW = 0x7E00 + value; // PA Table write (burst) + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; // reset pointer + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = 0xFE; // PA Table read (burst) + + while (!(RF1AIFCTL1 & RFDINIFG)) ; + RF1ADINB = 0x00; //dummy write + + while (!(RF1AIFCTL1 & RFDOUTIFG)) ; + readbackPATableValue = RF1ADOUT0B; + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; + } + + EXIT_CRITICAL_SECTION(int_state); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/rf1a.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/rf1a.h new file mode 100755 index 0000000..f1acd1c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/rf1a.h @@ -0,0 +1,20 @@ +// ************************************************************************************************* +// +// Actual revision: $Revision: $ +// Revision label: $Name: $ +// Revision state: $State: $ +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// ************************************************************************************************* +// Prototype section +unsigned char Strobe(unsigned char strobe); +unsigned char ReadSingleReg(unsigned char addr); +void WriteSingleReg(unsigned char addr, unsigned char value); +void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count); +void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count); +void ResetRadioCore(void); +void WritePATable(unsigned char value); +void WaitForXT2(void); diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/timer.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/timer.c new file mode 100755 index 0000000..8cd2811 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/timer.c @@ -0,0 +1,576 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Timer service routines. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "timer.h" +#include "ports.h" +#include "buzzer.h" +#include "vti_ps.h" +#include "vti_as.h" +#include "display.h" + +// logic +#include "clock.h" +#include "battery.h" +#include "stopwatch.h" +#include "alarm.h" +#include "altitude.h" +#include "display.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "acceleration.h" +#include "bluerobin.h" +#include "temperature.h" + +// ************************************************************************************************* +// Prototypes section +void Timer0_Init(void); +void Timer0_Stop(void); +void Timer0_A1_Start(void); +void Timer0_A1_Stop(void); +void Timer0_A3_Start(u16 ticks); +void Timer0_A3_Stop(void); +void Timer0_A4_Delay(u16 ticks); + +void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct timer sTimer; + +// ************************************************************************************************* +// Extern section +extern void BRRX_TimerTask_v(void); +extern void to_lpm(void); + +// ************************************************************************************************* +// @fn Timer0_Init +// @brief Set Timer0 to a period of 1 or 2 sec. IRQ TACCR0 is asserted when timer overflows. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Init(void) +{ + // Set interrupt frequency to 1Hz + TA0CCR0 = 32768 - 1; + + // Enable timer interrupt + TA0CCTL0 |= CCIE; + + // Clear and start timer now + // Continuous mode: Count to 0xFFFF and restart from 0 again - 1sec timing will be generated by + // ISR + TA0CTL |= TASSEL0 + MC1 + TACLR; +} + +// ************************************************************************************************* +// @fn Timer0_Start +// @brief Start Timer0. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Start(void) +{ + // Start Timer0 in continuous mode + TA0CTL |= MC_2; +} + +// ************************************************************************************************* +// @fn Timer0_Stop +// @brief Stop and reset Timer0. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Stop(void) +{ + // Stop Timer0 + TA0CTL &= ~MC_2; + + // Set Timer0 count register to 0x0000 + TA0R = 0; +} + +// ************************************************************************************************* +// @fn Timer0_A3_Start +// @brief Trigger IRQ every "ticks" microseconds +// @param ticks (1 tick = 1/32768 sec) +// @return none +// ************************************************************************************************* +void Timer0_A3_Start(u16 ticks) +{ + u16 value = 0; + + // Store timer ticks in global variable + sTimer.timer0_A3_ticks = ticks; + + // Delay based on current counter value + // To make sure this value is correctly read + while (value != TA0R) + value = TA0R; + value += ticks; + + // Update CCR + TA0CCR3 = value; + + // Reset IRQ flag + TA0CCTL3 &= ~CCIFG; + + // Enable timer interrupt + TA0CCTL3 |= CCIE; +} + +// ************************************************************************************************* +// @fn Timer0_A3_Stop +// @brief Stop Timer0_A3. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_A3_Stop(void) +{ + // Clear timer interrupt + TA0CCTL3 &= ~CCIE; +} + +// ************************************************************************************************* +// @fn Timer0_A4_Delay +// @brief Wait for some microseconds +// @param ticks (1 tick = 1/32768 sec) +// @return none +// ************************************************************************************************* +void Timer0_A4_Delay(u16 ticks) +{ + u16 value = 0; + + // Exit immediately if Timer0 not running - otherwise we'll get stuck here + if ((TA0CTL & (BIT4 | BIT5)) == 0) + return; + + // Disable timer interrupt + TA0CCTL4 &= ~CCIE; + + // Clear delay_over flag + sys.flag.delay_over = 0; + + // Add delay to current timer value + // To make sure this value is correctly read + while (value != TA0R) + value = TA0R; + value += ticks; + + // Update CCR + TA0CCR4 = value; + + // Reset IRQ flag + TA0CCTL4 &= ~CCIFG; + + // Enable timer interrupt + TA0CCTL4 |= CCIE; + + // Wait for timer IRQ + while (1) + { + // Delay in LPM + to_lpm(); // will also set GIE again + +#ifdef USE_WATCHDOG + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; +#endif + // Redraw stopwatch display + if (is_stopwatch()) + display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_PARTIAL); + + // Check stop condition + // disable interrupt to prevent flag's change caused by interrupt methods + __disable_interrupt(); + if (sys.flag.delay_over) + break; + } + __enable_interrupt(); +} + +// ************************************************************************************************* +// @fn TIMER0_A0_ISR +// @brief IRQ handler for TIMER0_A0 IRQ +// Timer0_A0 1/1sec clock tick (serviced by +// function TIMER0_A0_ISR) +// Timer0_A1 +// (serviced by function +// TIMER0_A1_5_ISR) +// Timer0_A2 1/100 sec Stopwatch (serviced by +// function TIMER0_A1_5_ISR) +// Timer0_A3 Configurable periodic IRQ (serviced by +// function TIMER0_A1_5_ISR) +// Timer0_A4 One-time delay (serviced by +// function TIMER0_A1_5_ISR) +// @param none +// @return none +// ************************************************************************************************* +#pragma vector = TIMER0_A0_VECTOR +__interrupt void TIMER0_A0_ISR(void) +{ + static u8 button_lock_counter = 0; + + // Disable IE + TA0CCTL0 &= ~CCIE; + // Reset IRQ flag + TA0CCTL0 &= ~CCIFG; + // Add 1 sec to TACCR0 register (IRQ will be asserted at 0x7FFF and 0xFFFF = 1 sec intervals) + TA0CCR0 += 32768; + // Enable IE + TA0CCTL0 |= CCIE; + + // Add 1 second to global time + clock_tick(); + + // Set clock update flag + display.flag.update_time = 1; + + // While SimpliciTI stack operates or BlueRobin searches, freeze system state + if (is_rf() || is_bluerobin_searching()) + { + // SimpliciTI automatic timeout + if (sRFsmpl.timeout == 0) + { + simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; + } + else + { + sRFsmpl.timeout--; + } + + // switch message after received packet + if (sRFsmpl.mode == SIMPLICITI_SYNC) + { + if (sRFsmpl.display_sync_done == 0) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " SYNC", SEG_ON); + } + else + { + sRFsmpl.display_sync_done--; + } + } + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); + return; + } + + // ------------------------------------------------------------------- + // Service modules that require 1/min processing + if (sTime.drawFlag >= 2) + { + // Measure battery voltage to keep track of remaining battery life + request.flag.voltage_measurement = 1; + + // Check if alarm needs to be turned on + check_alarm(); + } + + // ------------------------------------------------------------------- + // Service active modules that require 1/s processing + + // Generate alarm signal + if (sAlarm.state == ALARM_ON) + { + // Decrement alarm duration counter + if (sAlarm.duration-- > 0) + { + request.flag.buzzer = 1; + } + else + { + sAlarm.duration = ALARM_ON_DURATION; + stop_alarm(); + } + } + + // Do a temperature measurement each second while menu item is active + if (is_temp_measurement()) + request.flag.temperature_measurement = 1; + + // Do a pressure measurement each second while menu item is active + if (is_altitude_measurement()) + { + // Countdown altitude measurement timeout while menu item is active + sAlt.timeout--; + + // Stop measurement when timeout has elapsed + if (sAlt.timeout == 0) + { + stop_altitude_measurement(); + // Show ---- m/ft + display_chars(LCD_SEG_L1_3_0, (u8 *) "----", SEG_ON); + // Clear up/down arrow + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + + // In case we missed the IRQ due to debouncing, get data now + if ((PS_INT_IN & PS_INT_PIN) == PS_INT_PIN) + request.flag.altitude_measurement = 1; + } + + // Count down timeout + if (is_acceleration_measurement()) + { + // Countdown acceleration measurement timeout + sAccel.timeout--; + + // Stop measurement when timeout has elapsed + if (sAccel.timeout == 0) + { + as_stop(); + // Show ---- + display_chars(LCD_SEG_L1_3_0, (u8 *) "----", SEG_ON); + // Clear up/down arrow + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + } + + // If DRDY is (still) high, request data again + if ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN) + request.flag.acceleration_measurement = 1; + } + + // If BlueRobin transmitter is connected, get data from API + if (is_bluerobin()) + get_bluerobin_data(); + + // If battery is low, decrement display counter + if (sys.flag.low_battery) + { + if (sBatt.lobatt_display-- == 0) + { + message.flag.prepare = 1; + message.flag.type_lobatt = 1; + sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE; + } + } + + // If a message has to be displayed, set display flag + if (message.all_flags) + { + if (message.flag.prepare) + { + message.flag.prepare = 0; + message.flag.show = 1; + } + else if (message.flag.erase) // message cycle is over, so erase it + { + message.flag.erase = 0; + display.flag.full_update = 1; + } + } + + // ------------------------------------------------------------------- + // Check idle timeout, set timeout flag + if (sys.flag.idle_timeout_enabled) + { + if (sTime.system_time - sTime.last_activity > INACTIVITY_TIME) + sys.flag.idle_timeout = 1; //setFlag(sysFlag_g, SYS_TIMEOUT_IDLE); + } + + // ------------------------------------------------------------------- + // Turn the Backlight off after timeout + if (sButton.backlight_status == 1) + { + if (sButton.backlight_timeout > BACKLIGHT_TIME_ON) + { + //turn off Backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + sButton.backlight_timeout = 0; + sButton.backlight_status = 0; + } + else + { + sButton.backlight_timeout++; + } + } + + // ------------------------------------------------------------------- + // Detect continuous button high states + + // Trying to lock/unlock buttons? + if (BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED) + { + if (button_lock_counter++ > LEFT_BUTTON_LONG_TIME) + { + // Toggle lock / unlock buttons flag + sys.flag.lock_buttons = ~sys.flag.lock_buttons; + + // Show "buttons are locked/unlocked" message synchronously with next second tick + message.flag.prepare = 1; + if (sys.flag.lock_buttons) + message.flag.type_locked = 1; + else + message.flag.type_unlocked = 1; + + // Reset button lock counter + button_lock_counter = 0; + } + } + else // Trying to create a long button press? + { + // Reset button lock counter + button_lock_counter = 0; + + if (BUTTON_STAR_IS_PRESSED) + { + sButton.star_timeout++; + + // Check if button was held low for some seconds + if (sButton.star_timeout > LEFT_BUTTON_LONG_TIME) + { + button.flag.star_long = 1; + button.flag.star_not_long = 0; + sButton.star_timeout = 0; + // Return interrupt edge to normal value + BUTTONS_IES &= ~BUTTON_STAR_PIN; + } + } + else // there was a button press not long enough + { + sButton.star_timeout = 0; + } + + if (BUTTON_NUM_IS_PRESSED) + { + sButton.num_timeout++; + + // Check if button was held low for some seconds + if (sButton.num_timeout > LEFT_BUTTON_LONG_TIME) + { + button.flag.num_long = 1; + button.flag.num_not_long = 0; + sButton.num_timeout = 0; + // Return interrupt edge to normal value + BUTTONS_IES &= ~BUTTON_NUM_PIN; + } + } + else // there was a button press not long enough + { + sButton.num_timeout = 0; + } + } + + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); +} + +// ************************************************************************************************* +// @fn Timer0_A1_5_ISR +// @brief IRQ handler for timer IRQ. +// Timer0_A0 1/1sec clock tick (serviced by function +// TIMER0_A0_ISR) +// Timer0_A1 BlueRobin timer +// Timer0_A2 1/100 sec Stopwatch +// Timer0_A3 Configurable periodic IRQ (used by button_repeat and +// buzzer) +// Timer0_A4 One-time delay +// @param none +// @return none +// ************************************************************************************************* +#pragma vector = TIMER0_A1_VECTOR +__interrupt void TIMER0_A1_5_ISR(void) +{ + u16 value = 0; + + switch (TA0IV) + { + // Timer0_A1 BlueRobin timer + case 0x02: // Timer0_A1 handler + BRRX_TimerTask_v(); + break; + + // Timer0_A2 1/1 or 1/100 sec Stopwatch + case 0x04: // Timer0_A2 handler + // Disable IE + TA0CCTL2 &= ~CCIE; + // Reset IRQ flag + TA0CCTL2 &= ~CCIFG; + // Load CCR register with next capture point + update_stopwatch_timer(); + // Enable timer interrupt + TA0CCTL2 |= CCIE; + // Increase stopwatch counter + stopwatch_tick(); + break; + + // Timer0_A3 Configurable periodic IRQ (used by button_repeat and buzzer) + case 0x06: // Disable IE + TA0CCTL3 &= ~CCIE; + // Reset IRQ flag + TA0CCTL3 &= ~CCIFG; + // Store new value in CCR + // To make sure this value is correctly read + while (value != TA0R) + value = TA0R; + value += sTimer.timer0_A3_ticks; + // Load CCR register with next capture point + TA0CCR3 = value; + // Enable timer interrupt + TA0CCTL3 |= CCIE; + // Call function handler + fptr_Timer0_A3_function(); + break; + + // Timer0_A4 One-time delay + case 0x08: // Disable IE + TA0CCTL4 &= ~CCIE; + // Reset IRQ flag + TA0CCTL4 &= ~CCIFG; + // Set delay over flag + sys.flag.delay_over = 1; + break; + } + + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/timer.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/timer.h new file mode 100755 index 0000000..89e0e53 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/timer.h @@ -0,0 +1,71 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef TIMER_H_ +#define TIMER_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void Timer0_Init(void); +extern void Timer0_Start(void); +extern void Timer0_Stop(void); +extern void Timer0_A3_Start(u16 ticks); +extern void Timer0_A3_Stop(void); +extern void Timer0_A4_Delay(u16 ticks); + +extern void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// Defines section +struct timer +{ + // Timer0_A3 periodic delay + u16 timer0_A3_ticks; +}; +extern struct timer sTimer; + +// Trigger reset when all buttons are pressed +#define BUTTON_RESET_SEC (3u) + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*TIMER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_as.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_as.c new file mode 100755 index 0000000..bede10d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_as.c @@ -0,0 +1,360 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// VTI CMA3000-D0x acceleration sensor driver functions +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// logic +#include "simpliciti.h" + +// driver +#include "vti_as.h" +#include "timer.h" +#include "display.h" + +// ************************************************************************************************* +// Prototypes section +void as_start(void); +void as_stop(void); +u8 as_read_register(u8 bAddress); +u8 as_write_register(u8 bAddress, u8 bData); + +// ************************************************************************************************* +// Defines section + +// ================================================================================================= +// CMA3000-D0x acceleration sensor configuration +// ================================================================================================= +// DCO frequency division factor determining speed of the acceleration sensor SPI interface +// Speed in Hz = 12MHz / AS_BR_DIVIDER (max. 500kHz) +#define AS_BR_DIVIDER (30u) + +// Acceleration measurement range in g +// Valid ranges are: 2 and 8 +#define AS_RANGE (2u) + +// Sample rate for acceleration values in Hz +// Valid sample rates for 2g range are: 100, 400 +// Valid sample rates for 8g range are: 40, 100, 400 +#define AS_SAMPLE_RATE (100u) + +// ************************************************************************************************* +// Global Variable section + +// Global flag for proper acceleration sensor operation +u8 as_ok; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn as_init +// @brief Setup acceleration sensor connection, do not power up yet +// @param none +// @return none +// ************************************************************************************************* +void as_init(void) +{ +#ifdef AS_DISCONNECT + // Deactivate connection to acceleration sensor + AS_PWR_OUT &= ~AS_PWR_PIN; // Power off + AS_INT_OUT &= ~AS_INT_PIN; // Pin to low to avoid floating pins + AS_SPI_OUT &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Pin to low to avoid floating pins + AS_CSN_OUT &= ~AS_CSN_PIN; // Pin to low to avoid floating pins + AS_INT_DIR |= AS_INT_PIN; // Pin to output to avoid floating pins + AS_SPI_DIR |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Pin to output to avoid floating pins + AS_CSN_DIR |= AS_CSN_PIN; // Pin to output to avoid floating pins + AS_PWR_DIR |= AS_PWR_PIN; // Power pin to output direction +#else + AS_INT_DIR &= ~AS_INT_PIN; // Input + AS_SPI_DIR &= ~AS_SDI_PIN; // Input + AS_SPI_DIR |= AS_SDO_PIN + AS_SCK_PIN; // Output + AS_SPI_SEL |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Port pins to SDO, SDI and SCK function + AS_CSN_OUT |= AS_CSN_PIN; // CSN=1 + AS_CSN_DIR |= AS_CSN_PIN; // + AS_PWR_OUT |= AS_PWR_PIN; // VDD=1 + AS_PWR_DIR |= AS_PWR_PIN; // +#endif + + // Reset global sensor flag + as_ok = 1; +} + +// ************************************************************************************************* +// @fn as_start +// @brief Power-up and initialize acceleration sensor +// @param none +// @return none +// ************************************************************************************************* +void as_start(void) +{ + volatile u16 Counter_u16; + u8 bConfig; //, bStatus; + + // Initialize SPI interface to acceleration sensor + AS_SPI_CTL0 |= UCSYNC | UCMST | UCMSB // SPI master, 8 data bits, MSB first, + | UCCKPH; // clock idle low, data output on falling + // edge + AS_SPI_CTL1 |= UCSSEL1; // SMCLK as clock source + AS_SPI_BR0 = AS_BR_DIVIDER; // Low byte of division factor for baud rate + AS_SPI_BR1 = 0x00; // High byte of division factor for baud + // rate + AS_SPI_CTL1 &= ~UCSWRST; // Start SPI hardware + + // Initialize interrupt pin for data read out from acceleration sensor + AS_INT_IES &= ~AS_INT_PIN; // Interrupt on rising edge + +#ifdef AS_DISCONNECT + // Enable interrupt + AS_INT_DIR &= ~AS_INT_PIN; // Switch INT pin to input + AS_SPI_DIR &= ~AS_SDI_PIN; // Switch SDI pin to input + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin + AS_SPI_SEL |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Port pins to SDO, SDI and SCK function + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_PWR_OUT |= AS_PWR_PIN; // Power on active high +#endif + + // Delay of >5ms required between switching on power and configuring sensor + Timer0_A4_Delay(CONV_MS_TO_TICKS(10)); + + // Initialize interrupt pin for data read out from acceleration sensor + AS_INT_IFG &= ~AS_INT_PIN; // Reset flag + AS_INT_IE |= AS_INT_PIN; // Enable interrupt + + // Configure sensor and start to sample data +#if (AS_RANGE == 2) + bConfig = 0x80; +# if (AS_SAMPLE_RATE == 100) + bConfig |= 0x02; +# elif (AS_SAMPLE_RATE == 400) + bConfig |= 0x04; +# else +# error "Sample rate not supported" +# endif +#elif (AS_RANGE == 8) + bConfig = 0x00; +# if (AS_SAMPLE_RATE == 40) + bConfig |= 0x06; +# elif (AS_SAMPLE_RATE == 100) + bConfig |= 0x02; +# elif (AS_SAMPLE_RATE == 400) + bConfig |= 0x04; +# else +# error "Sample rate not supported" +# endif +#else +# error "Measurement range not supported" +#endif + + // Reset sensor + as_write_register(0x04, 0x02); + as_write_register(0x04, 0x0A); + as_write_register(0x04, 0x04); + + // Wait 5 ms before starting sensor output + Timer0_A4_Delay(CONV_MS_TO_TICKS(5)); + + // Set 2g measurement range, start to output data with 100Hz rate + as_write_register(0x02, bConfig); +} + +// ************************************************************************************************* +// @fn as_stop +// @brief Power down acceleration sensor +// @param none +// @return none +// ************************************************************************************************* +void as_stop(void) +{ + // Disable interrupt + AS_INT_IE &= ~AS_INT_PIN; // Disable interrupt + +#ifdef AS_DISCONNECT + // Power-down sensor + AS_PWR_OUT &= ~AS_PWR_PIN; // Power off + AS_INT_OUT &= ~AS_INT_PIN; // Pin to low to avoid floating pins + AS_SPI_OUT &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Pins to low to avoid floating pins + AS_SPI_SEL &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Port pins to I/O function + AS_CSN_OUT &= ~AS_CSN_PIN; // Pin to low to avoid floating pins + AS_INT_DIR |= AS_INT_PIN; // Pin to output to avoid floating pins + AS_SPI_DIR |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Pins to output to avoid floating pins + AS_CSN_DIR |= AS_CSN_PIN; // Pin to output to avoid floating pins +#else + // Reset sensor -> sensor to powerdown + as_write_register(0x04, 0x02); + as_write_register(0x04, 0x0A); + as_write_register(0x04, 0x04); +#endif +} + +// ************************************************************************************************* +// @fn as_read_register +// @brief Read a byte from the acceleration sensor +// @param u8 bAddress Register address +// @return u8 bResult Register content +// If the returned value is 0, +// there was an error. +// ************************************************************************************************* +u8 as_read_register(u8 bAddress) +{ + u8 bResult; + u16 timeout; + + // Exit function if an error was detected previously + if (!as_ok) + return (0); + + bAddress <<= 2; // Address to be shifted left by 2 and + // RW bit to be reset + + AS_SPI_REN &= ~AS_SDI_PIN; // Pulldown on SDI pin not required + AS_CSN_OUT &= ~AS_CSN_PIN; // Select acceleration sensor + + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bAddress; // Write address to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = 0; // Write dummy data to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer + + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin required again + + // Return new data from RX buffer + return bResult; +} + +// ************************************************************************************************* +// @fn as_write_register +// @brief Write a byte to the acceleration sensor +// @param u8 bAddress Register address +// u8 bData Data to write +// @return u8 0 or bResult Register content. +// If the returned value is 0, +// there was an error. +// ************************************************************************************************* +u8 as_write_register(u8 bAddress, u8 bData) +{ + u8 bResult; + u16 timeout; + + // Exit function if an error was detected previously + if (!as_ok) + return (0); + + bAddress <<= 2; // Address to be shifted left by 1 + bAddress |= BIT1; // RW bit to be set + + AS_SPI_REN &= ~AS_SDI_PIN; // Pulldown on SDI pin not required + AS_CSN_OUT &= ~AS_CSN_PIN; // Select acceleration sensor + + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bAddress; // Write address to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bData; // Write data to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer + + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin required again + + return bResult; +} + +// ************************************************************************************************* +// @fn as_get_data +// @brief Service routine to read acceleration values. +// @param none +// @return none +// ************************************************************************************************* +void as_get_data(u8 * data) +{ + // Exit if sensor is not powered up + if ((AS_PWR_OUT & AS_PWR_PIN) != AS_PWR_PIN) + return; + + // Store X/Y/Z acceleration data in buffer + *(data + 0) = as_read_register(0x06); + *(data + 1) = as_read_register(0x07); + *(data + 2) = as_read_register(0x08); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_as.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_as.h new file mode 100755 index 0000000..358a948 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_as.h @@ -0,0 +1,106 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef VTI_AS_H_ +#define VTI_AS_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void as_init(void); +extern void as_start(void); +extern void as_stop(void); +extern u8 as_read_register(u8 bAddress); +extern u8 as_write_register(u8 bAddress, u8 bData); +extern void as_get_data(u8 * data); + +// ************************************************************************************************* +// Defines section + +// Disconnect power supply for acceleration sensor when not used +#define AS_DISCONNECT + +// Port and pin resource for SPI interface to acceleration sensor +// SDO=MOSI=P1.6, SDI=MISO=P1.5, SCK=P1.7 +#define AS_SPI_IN (P1IN) +#define AS_SPI_OUT (P1OUT) +#define AS_SPI_DIR (P1DIR) +#define AS_SPI_SEL (P1SEL) +#define AS_SPI_REN (P1REN) +#define AS_SDO_PIN (BIT6) +#define AS_SDI_PIN (BIT5) +#define AS_SCK_PIN (BIT7) + +// CSN=PJ.1 +#define AS_CSN_OUT (PJOUT) +#define AS_CSN_DIR (PJDIR) +#define AS_CSN_PIN (BIT1) + +#define AS_TX_BUFFER (UCA0TXBUF) +#define AS_RX_BUFFER (UCA0RXBUF) +#define AS_TX_IFG (UCTXIFG) +#define AS_RX_IFG (UCRXIFG) +#define AS_IRQ_REG (UCA0IFG) +#define AS_SPI_CTL0 (UCA0CTL0) +#define AS_SPI_CTL1 (UCA0CTL1) +#define AS_SPI_BR0 (UCA0BR0) +#define AS_SPI_BR1 (UCA0BR1) + +// Port and pin resource for power-up of acceleration sensor, VDD=PJ.0 +#define AS_PWR_OUT (PJOUT) +#define AS_PWR_DIR (PJDIR) +#define AS_PWR_PIN (BIT0) + +// Port, pin and interrupt resource for interrupt from acceleration sensor, CMA_INT=P2.5 +#define AS_INT_IN (P2IN) +#define AS_INT_OUT (P2OUT) +#define AS_INT_DIR (P2DIR) +#define AS_INT_IE (P2IE) +#define AS_INT_IES (P2IES) +#define AS_INT_IFG (P2IFG) +#define AS_INT_PIN (BIT5) + +// SPI timeout to detect sensor failure +#define SPI_TIMEOUT (1000u) + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*VTI_AS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_ps.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_ps.c new file mode 100755 index 0000000..645f17e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_ps.c @@ -0,0 +1,559 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// VTI SCP1000-D0x pressure sensor driver functions +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "vti_ps.h" +#include "timer.h" + +// ************************************************************************************************* +// Prototypes section +u16 ps_read_register(u8 address, u8 mode); +u8 ps_write_register(u8 address, u8 data); +u8 ps_twi_read(u8 ack); +void twi_delay(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// VTI pressure (hPa) to altitude (m) conversion tables +const s16 h0[17] = +{ -153, 0, 111, 540, 989, 1457, 1949, 2466, 3012, 3591, 4206, 4865, 5574, 6344, 7185, 8117, 9164 }; +const u16 p0[17] = +{ 1031, 1013, 1000, 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300 }; + +float p[17]; + +// Global flag for proper pressure sensor operation +u8 ps_ok; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn ps_init +// @brief Init pressure sensor I/O +// @param none +// @return none +// ************************************************************************************************* +void ps_init(void) +{ + volatile u8 success, status, eeprom, timeout; + + PS_INT_DIR &= ~PS_INT_PIN; // DRDY is input + PS_INT_IES &= ~PS_INT_PIN; // Interrupt on DRDY rising edge + PS_TWI_OUT |= PS_SCL_PIN + PS_SDA_PIN; // SCL and SDA are outputs by default + PS_TWI_DIR |= PS_SCL_PIN + PS_SDA_PIN; // SCL and SDA are outputs by default + + // Reset global ps_ok flag + ps_ok = 0; + + // 100msec delay to allow VDD stabilisation + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + + // Reset pressure sensor -> powerdown sensor + success = ps_write_register(0x06, 0x01); + + // 100msec delay + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + + // Check if STATUS register BIT0 is cleared + status = ps_read_register(0x07, PS_TWI_8BIT_ACCESS); + if (((status & BIT0) == 0) && (status != 0)) + { + // Check EEPROM checksum in DATARD8 register + eeprom = ps_read_register(0x7F, PS_TWI_8BIT_ACCESS); + if (eeprom == 0x01) + ps_ok = 1; + else + ps_ok = 0; + } +} + +// ************************************************************************************************* +// @fn ps_start +// @brief Init pressure sensor registers and start sampling +// @param none +// @return u8 1=Sensor started, 0=Sensor did not start +// ************************************************************************************************* +void ps_start(void) +{ + // Start sampling data in ultra low power mode + ps_write_register(0x03, 0x0B); +} + +// ************************************************************************************************* +// @fn ps_stop +// @brief Power down pressure sensor +// @param none +// @return none +// ************************************************************************************************* +void ps_stop(void) +{ + // Put sensor to standby + ps_write_register(0x03, 0x00); +} + +// ************************************************************************************************* +// @fn ps_twi_sda +// @brief Control SDA line +// @param u8 condition PS_TWI_SEND_START, PS_TWI_SEND_RESTART, PS_TWI_SEND_STOP +// PS_TWI_CHECK_ACK +// @return u8 1=ACK, 0=NACK +// ************************************************************************************************* +u8 ps_twi_sda(u8 condition) +{ + u8 sda = 0; + + if (condition == PS_TWI_SEND_START) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; // SCL 1-0 transition while SDA=0 + twi_delay(); + } + else if (condition == PS_TWI_SEND_RESTART) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SCL_LO; + PS_TWI_SDA_HI; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; + twi_delay(); + } + else if (condition == PS_TWI_SEND_STOP) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_HI; // SDA 0-1 transition while SCL=1 + twi_delay(); + } + else if (condition == PS_TWI_CHECK_ACK) + { + PS_TWI_SDA_IN; // SDA is input + PS_TWI_SCL_LO; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + sda = PS_TWI_IN & PS_SDA_PIN; + PS_TWI_SCL_LO; + } + + // Return value will only be evaluated when checking device ACK + return (sda == 0); +} + +// ************************************************************************************************* +// @fn twi_delay +// @brief Delay between TWI signal edges. +// @param none +// @return none +// ************************************************************************************************* +void twi_delay(void) +{ + asm (" nop"); +} + +// ************************************************************************************************* +// @fn ps_twi_write +// @brief Clock out bits through SDA. +// @param u8 data Byte to send +// @return none +// ************************************************************************************************* +void ps_twi_write(u8 data) +{ + u8 i, mask; + + // Set mask byte to 10000000b + mask = BIT0 << 7; + + PS_TWI_SDA_OUT; // SDA is output + + for (i = 8; i > 0; i--) + { + PS_TWI_SCL_LO; // SCL=0 + if ((data & mask) == mask) + { + PS_TWI_SDA_HI; // SDA=1 + } + else + { + PS_TWI_SDA_LO; // SDA=0 + } + mask = mask >> 1; + twi_delay(); + PS_TWI_SCL_HI; // SCL=1 + twi_delay(); + } + + PS_TWI_SCL_LO; // SCL=0 + PS_TWI_SDA_IN; // SDA is input +} + +// ************************************************************************************************* +// @fn ps_twi_read +// @brief Read bits from SDA +// @param u8 ack 1=Send ACK after read, 0=Send NACK after read +// @return u8 Bits read +// ************************************************************************************************* +u8 ps_twi_read(u8 ack) +{ + u8 i; + u8 data = 0; + + PS_TWI_SDA_IN; // SDA is input + + for (i = 0; i < 8; i++) + { + PS_TWI_SCL_LO; // SCL=0 + twi_delay(); + PS_TWI_SCL_HI; // SCL=0 + twi_delay(); + + // Shift captured bits to left + data = data << 1; + + // Capture new bit + if ((PS_TWI_IN & PS_SDA_PIN) == PS_SDA_PIN) + data |= BIT0; + } + + PS_TWI_SDA_OUT; // SDA is output + + // 1 aditional clock phase to generate master ACK + PS_TWI_SCL_LO; // SCL=0 + if (ack == 1) + PS_TWI_SDA_LO // Send ack -> continue read + else + PS_TWI_SDA_HI // Send nack -> stop read + twi_delay(); + PS_TWI_SCL_HI; // SCL=0 + twi_delay(); + PS_TWI_SCL_LO; + + return (data); +} + +// ************************************************************************************************* +// @fn as_write_register +// @brief Write a byte to the pressure sensor +// @param u8 address Register address +// u8 data Data to write +// @return u8 +// ************************************************************************************************* +u8 ps_write_register(u8 address, u8 data) +{ + volatile u8 success; + + ps_twi_sda(PS_TWI_SEND_START); // Generate start condition + + ps_twi_write((0x11 << 1) | PS_TWI_WRITE); // Send 7bit device address 0x11 + write bit '0' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(address); // Send 8bit register address + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(data); // Send 8bit data to register + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + // Slave does not send this ACK + // if (!success) return (0); + + ps_twi_sda(PS_TWI_SEND_STOP); // Generate stop condition + + return (1); +} + +// ************************************************************************************************* +// @fn ps_read_register +// @brief Read a byte from the pressure sensor +// @param u8 address Register address +// u8 mode PS_TWI_8BIT_ACCESS, PS_TWI_16BIT_ACCESS +// @return u16 Register content +// ************************************************************************************************* +u16 ps_read_register(u8 address, u8 mode) +{ + u8 success; + u16 data = 0; + + ps_twi_sda(PS_TWI_SEND_START); // Generate start condition + + ps_twi_write((0x11 << 1) | PS_TWI_WRITE); // Send 7bit device address 0x11 + write bit '0' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(address); // Send 8bit register address + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_sda(PS_TWI_SEND_RESTART); // Generate restart condition + + ps_twi_write((0x11 << 1) | PS_TWI_READ); // Send 7bit device address 0x11 + read bit '1' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + if (mode == PS_TWI_16BIT_ACCESS) + { + data = ps_twi_read(1) << 8; // Read MSB 8bit data from register + data |= ps_twi_read(0); // Read LSB 8bit data from register + } + else + { + data = ps_twi_read(0); // Read 8bit data from register + } + + ps_twi_sda(PS_TWI_SEND_STOP); // Generate stop condition + + return (data); +} + +// ************************************************************************************************* +// @fn ps_get_pa +// @brief Read out pressure. Format is Pa. Range is 30000 .. 120000 Pa. +// @param none +// @return u32 15-bit pressure sensor value (Pa) +// ************************************************************************************************* +u32 ps_get_pa(void) +{ + volatile u32 data = 0; + + // Get 3 MSB from DATARD8 register + data = ps_read_register(0x7F, PS_TWI_8BIT_ACCESS); + data = ((data & 0x07) << 8) << 8; + + // Get 16 LSB from DATARD16 register + data |= ps_read_register(0x80, PS_TWI_16BIT_ACCESS); + + // Convert decimal value to Pa + data = (data >> 2); + + return (data); +} + +// ************************************************************************************************* +// @fn ps_get_temp +// @brief Read out temperature. +// @param none +// @return u16 13-bit temperature value in xx.x K format +// ************************************************************************************************* +u16 ps_get_temp(void) +{ + volatile u16 data = 0; + u16 temp = 0; + u8 is_negative = 0; + u16 kelvin; + + // Get 13 bit from TEMPOUT register + data = ps_read_register(0x81, PS_TWI_16BIT_ACCESS); + + // Convert negative temperatures + if ((data & BIT(13)) == BIT(13)) + { + // Sign extend temperature + data |= 0xC000; + // Convert two's complement + data = ~data; + data += 1; + is_negative = 1; + } + + temp = data / 2; + + // Convert from °C to K + if (is_negative) + kelvin = 2732 - temp; + else + kelvin = temp + 2732; + + return (kelvin); +} + +// ************************************************************************************************* +// @fn init_pressure_table +// @brief Init pressure table with constants +// @param u32 p Pressure (Pa) +// @return u16 Altitude (m) +// ************************************************************************************************* +void init_pressure_table(void) +{ + u8 i; + + for (i = 0; i < 17; i++) + p[i] = p0[i]; +} + +// ************************************************************************************************* +// @fn update_pressure_table +// @brief Calculate pressure table for reference altitude. +// Implemented straight from VTI reference code. +// @param s16 href Reference height +// u32 p_meas Pressure (Pa) +// u16 t_meas Temperature (10*K) +// @return none +// ************************************************************************************************* +void update_pressure_table(s16 href, u32 p_meas, u16 t_meas) +{ + const float Invt00 = 0.003470415; + const float coefp = 0.00006; + volatile float p_fact; + volatile float p_noll; + volatile float hnoll; + volatile float h_low = 0; + volatile float t0; + u8 i; + + // Typecast arguments + volatile float fl_href = href; + volatile float fl_p_meas = (float)p_meas / 100; // Convert from Pa to hPa + volatile float fl_t_meas = (float)t_meas / 10; // Convert from 10 K to 1 K + + t0 = fl_t_meas + (0.0065 * fl_href); + + hnoll = fl_href / (t0 * Invt00); + + for (i = 0; i <= 15; i++) + { + if (h0[i] > hnoll) + break; + h_low = h0[i]; + } + + p_noll = + (float)(hnoll - + h_low) * + (1 - + (hnoll - + (float)h0[i]) * + coefp) * ((float)p0[i] - (float)p0[i - 1]) / ((float)h0[i] - h_low) + (float)p0[i - 1]; + + // Calculate multiplicator + p_fact = fl_p_meas / p_noll; + + // Apply correction factor to pressure table + for (i = 0; i <= 16; i++) + { + p[i] = p0[i] * p_fact; + } +} + +// ************************************************************************************************* +// @fn conv_pa_to_meter +// @brief Convert pressure (Pa) to altitude (m) using a conversion table +// Implemented straight from VTI reference code. +// @param u32 p_meas Pressure (Pa) +// u16 t_meas Temperature (10*K) +// @return s16 Altitude (m) +// ************************************************************************************************* +s16 conv_pa_to_meter(u32 p_meas, u16 t_meas) +{ + const float coef2 = 0.0007; + const float Invt00 = 0.003470415; + volatile float hnoll; + volatile float t0; + volatile float p_low; + volatile float fl_h; + volatile s16 h; + u8 i; + + // Typecast arguments + volatile float fl_p_meas = (float)p_meas / 100; // Convert from Pa to hPa + volatile float fl_t_meas = (float)t_meas / 10; // Convert from 10 K to 1 K + + for (i = 0; i <= 16; i++) + { + if (p[i] < fl_p_meas) + break; + p_low = p[i]; + } + + if (i == 0) + { + hnoll = (float)(fl_p_meas - p[0]) / (p[1] - p[0]) * ((float)(h0[1] - h0[0])); + } + else if (i < 15) + { + hnoll = + (float)(fl_p_meas - + p_low) * + (1 - + (fl_p_meas - + p[i]) * coef2) / (p[i] - p_low) * ((float)(h0[i] - h0[i - 1])) + h0[i - 1]; + } + else if (i == 15) + { + hnoll = + (float)(fl_p_meas - p_low) / (p[i] - p_low) * ((float)(h0[i] - h0[i - 1])) + h0[i - 1]; + } + else // i==16 + { + hnoll = (float)(fl_p_meas - p[16]) / (p[16] - p[15]) * ((float)(h0[16] - h0[15])) + h0[16]; + } + + // Compensate temperature error + t0 = fl_t_meas / (1 - hnoll * Invt00 * 0.0065); + fl_h = Invt00 * t0 * hnoll; + h = (u16) fl_h; + + return (h); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_ps.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_ps.h new file mode 100755 index 0000000..e044695 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/driver/vti_ps.h @@ -0,0 +1,99 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef VTI_PS_H_ +#define VTI_PS_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void ps_init(void); +extern void ps_start(void); +extern void ps_stop(void); +extern u32 ps_get_pa(void); +extern u16 ps_get_temp(void); +extern void init_pressure_table(void); +extern void update_pressure_table(s16 href, u32 p_meas, u16 t_meas); +extern s16 conv_pa_to_meter(u32 p_meas, u16 t_meas); + +// ************************************************************************************************* +// Defines section + +// Port and pin resource for TWI interface to pressure sensor +// SCL=PJ.3, SDA=PJ.2, DRDY=P2.6 +#define PS_TWI_IN (PJIN) +#define PS_TWI_OUT (PJOUT) +#define PS_TWI_DIR (PJDIR) +#define PS_TWI_REN (PJREN) +#define PS_SCL_PIN (BIT3) +#define PS_SDA_PIN (BIT2) + +// Port, pin and interrupt resource for interrupt from acceleration sensor, DRDY=P2.6 +#define PS_INT_IN (P2IN) +#define PS_INT_OUT (P2OUT) +#define PS_INT_DIR (P2DIR) +#define PS_INT_IE (P2IE) +#define PS_INT_IES (P2IES) +#define PS_INT_IFG (P2IFG) +#define PS_INT_PIN (BIT6) + +// TWI defines +#define PS_TWI_WRITE (0u) +#define PS_TWI_READ (1u) + +#define PS_TWI_SEND_START (0u) +#define PS_TWI_SEND_RESTART (1u) +#define PS_TWI_SEND_STOP (2u) +#define PS_TWI_CHECK_ACK (3u) + +#define PS_TWI_8BIT_ACCESS (0u) +#define PS_TWI_16BIT_ACCESS (1u) + +#define PS_TWI_SCL_HI { PS_TWI_OUT |= PS_SCL_PIN; } +#define PS_TWI_SCL_LO { PS_TWI_OUT &= ~PS_SCL_PIN; } +#define PS_TWI_SDA_HI { PS_TWI_OUT |= PS_SDA_PIN; } +#define PS_TWI_SDA_LO { PS_TWI_OUT &= ~PS_SDA_PIN; } +#define PS_TWI_SDA_IN { PS_TWI_OUT |= PS_SDA_PIN; PS_TWI_DIR &= ~PS_SDA_PIN; } +#define PS_TWI_SDA_OUT { PS_TWI_DIR |= PS_SDA_PIN; } + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*VTI_PS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/include/project.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/include/project.h new file mode 100755 index 0000000..082ff44 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/include/project.h @@ -0,0 +1,131 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef PROJECT_H_ +#define PROJECT_H_ + +// ************************************************************************************************* +// Include section +#include +#include + +// ************************************************************************************************* +// Defines section + +// Comment this to not use the LCD charge pump +//#define USE_LCD_CHARGE_PUMP + +// Comment this define to build the application without watchdog support +#define USE_WATCHDOG + +// Use/not use filter when measuring physical values +#define FILTER_OFF (0u) +#define FILTER_ON (1u) + +// ************************************************************************************************* +// Macro section + +// Conversion from usec to ACLK timer ticks +#define CONV_US_TO_TICKS(usec) (((usec) * 32768) / 1000000) + +// Conversion from msec to ACLK timer ticks +#define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000) + +// ************************************************************************************************* +// Typedef section + +typedef enum +{ + MENU_ITEM_NOT_VISIBLE = 0, // Menu item is not visible + MENU_ITEM_VISIBLE // Menu item is visible +} menu_t; + +// Set of system flags +typedef union +{ + struct + { + u16 idle_timeout : 1; // Timeout after inactivity + u16 idle_timeout_enabled : 1; // When in set mode, timeout after a given period + u16 lock_buttons : 1; // Lock buttons + u16 mask_buzzer : 1; // Do not output buzz for next button event + u16 up_down_repeat_enabled : 1; // While in set_value(), create virtual UP/DOWN button + // events + u16 low_battery : 1; // 1 = Battery is low + u16 use_metric_units : 1; // 1 = Use metric units, 0 = use English units + u16 delay_over : 1; // 1 = Timer delay over + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_system_flags; +extern volatile s_system_flags sys; + +// Set of request flags +typedef union +{ + struct + { + u16 temperature_measurement : 1; // 1 = Measure temperature + u16 voltage_measurement : 1; // 1 = Measure voltage + u16 altitude_measurement : 1; // 1 = Measure air pressure + u16 acceleration_measurement : 1; // 1 = Measure acceleration + u16 buzzer : 1; // 1 = Output buzzer + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_request_flags; +extern volatile s_request_flags request; + +// Set of message flags +typedef union +{ + struct + { + u16 prepare : 1; // 1 = Wait for clock tick, then set + // display.flag.show_message flag + u16 show : 1; // 1 = Display message now + u16 erase : 1; // 1 = Erase message + u16 type_locked : 1; // 1 = Show "buttons are locked" in Line2 + u16 type_unlocked : 1; // 1 = Show "buttons are unlocked" in Line2 + u16 type_lobatt : 1; // 1 = Show "lobatt" text in Line2 + u16 type_alarm_on : 1; // 1 = Show " on" text in Line1 + u16 type_alarm_off : 1; // 1 = Show " off" text in Line1 + } flag; + u16 all_flags; // Shortcut to all message flags (for reset) +} s_message_flags; +extern volatile s_message_flags message; + +// ************************************************************************************************* +// Global Variable section + +#endif /*PROJECT_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/lnk_cc430f6137.cmd b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/lnk_cc430f6137.cmd new file mode 100755 index 0000000..a5bdb4a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/lnk_cc430f6137.cmd @@ -0,0 +1,200 @@ +/******************************************************************************/ +/* lnk_cc430f6137.cmd - LINKER COMMAND FILE FOR LINKING CC430F6137 PROGRAMS */ +/* */ +/* Ver | dd mmm yyyy | Who | Description of changes */ +/* =====|=============|======|============================================= */ +/* 0.01| 08 Mar 2004 | A.D. | First prototype */ +/* 0.02| 26 Mai 2004 | A.D. | Leading symbol underscores removed, */ +/* | | | Interrupt vector definition changed */ +/* 0.03| 22 Jun 2004 | A.D. | File reformatted */ +/* */ +/* Usage: lnk430 -o -m lnk.cmd */ +/* cl430 -z -o -m lnk.cmd */ +/* */ +/*----------------------------------------------------------------------------*/ + +/* These linker options are for command line linking only. For IDE linking, */ +/* you should set your linker options in Project Properties */ +/* -c LINK USING C CONVENTIONS */ +/* -stack 0x0100 SOFTWARE STACK SIZE */ +/* -heap 0x0100 HEAP AREA SIZE */ + +/*----------------------------------------------------------------------------*/ +/* 'Allocate' peripheral registers at given addresses */ +/*----------------------------------------------------------------------------*/ + +/****************************************************************************/ +/* SPECIFY THE SYSTEM MEMORY MAP */ +/****************************************************************************/ + +MEMORY +{ + SFR : origin = 0x0000, length = 0x0010 + PERIPHERALS_8BIT : origin = 0x0010, length = 0x00F0 + PERIPHERALS_16BIT : origin = 0x0100, length = 0x0100 + RAM : origin = 0x1C00, length = 0x0FFE + INFOA : origin = 0x1980, length = 0x0080 + INFOB : origin = 0x1900, length = 0x0080 + INFOC : origin = 0x1880, length = 0x0080 + INFOD : origin = 0x1800, length = 0x0080 + FLASH : origin = 0x8000, length = 0x7F80 + INT00 : origin = 0xFF80, length = 0x0002 + INT01 : origin = 0xFF82, length = 0x0002 + INT02 : origin = 0xFF84, length = 0x0002 + INT03 : origin = 0xFF86, length = 0x0002 + INT04 : origin = 0xFF88, length = 0x0002 + INT05 : origin = 0xFF8A, length = 0x0002 + INT06 : origin = 0xFF8C, length = 0x0002 + INT07 : origin = 0xFF8E, length = 0x0002 + INT08 : origin = 0xFF90, length = 0x0002 + INT09 : origin = 0xFF92, length = 0x0002 + INT10 : origin = 0xFF94, length = 0x0002 + INT11 : origin = 0xFF96, length = 0x0002 + INT12 : origin = 0xFF98, length = 0x0002 + INT13 : origin = 0xFF9A, length = 0x0002 + INT14 : origin = 0xFF9C, length = 0x0002 + INT15 : origin = 0xFF9E, length = 0x0002 + INT16 : origin = 0xFFA0, length = 0x0002 + INT17 : origin = 0xFFA2, length = 0x0002 + INT18 : origin = 0xFFA4, length = 0x0002 + INT19 : origin = 0xFFA6, length = 0x0002 + INT20 : origin = 0xFFA8, length = 0x0002 + INT21 : origin = 0xFFAA, length = 0x0002 + INT22 : origin = 0xFFAC, length = 0x0002 + INT23 : origin = 0xFFAE, length = 0x0002 + INT24 : origin = 0xFFB0, length = 0x0002 + INT25 : origin = 0xFFB2, length = 0x0002 + INT26 : origin = 0xFFB4, length = 0x0002 + INT27 : origin = 0xFFB6, length = 0x0002 + INT28 : origin = 0xFFB8, length = 0x0002 + INT29 : origin = 0xFFBA, length = 0x0002 + INT30 : origin = 0xFFBC, length = 0x0002 + INT31 : origin = 0xFFBE, length = 0x0002 + INT32 : origin = 0xFFC0, length = 0x0002 + INT33 : origin = 0xFFC2, length = 0x0002 + INT34 : origin = 0xFFC4, length = 0x0002 + INT35 : origin = 0xFFC6, length = 0x0002 + INT36 : origin = 0xFFC8, length = 0x0002 + INT37 : origin = 0xFFCA, length = 0x0002 + INT38 : origin = 0xFFCC, length = 0x0002 + INT39 : origin = 0xFFCE, length = 0x0002 + INT40 : origin = 0xFFD0, length = 0x0002 + INT41 : origin = 0xFFD2, length = 0x0002 + INT42 : origin = 0xFFD4, length = 0x0002 + INT43 : origin = 0xFFD6, length = 0x0002 + INT44 : origin = 0xFFD8, length = 0x0002 + INT45 : origin = 0xFFDA, length = 0x0002 + INT46 : origin = 0xFFDC, length = 0x0002 + INT47 : origin = 0xFFDE, length = 0x0002 + INT48 : origin = 0xFFE0, length = 0x0002 + INT49 : origin = 0xFFE2, length = 0x0002 + INT50 : origin = 0xFFE4, length = 0x0002 + INT51 : origin = 0xFFE6, length = 0x0002 + INT52 : origin = 0xFFE8, length = 0x0002 + INT53 : origin = 0xFFEA, length = 0x0002 + INT54 : origin = 0xFFEC, length = 0x0002 + INT55 : origin = 0xFFEE, length = 0x0002 + INT56 : origin = 0xFFF0, length = 0x0002 + INT57 : origin = 0xFFF2, length = 0x0002 + INT58 : origin = 0xFFF4, length = 0x0002 + INT59 : origin = 0xFFF6, length = 0x0002 + INT60 : origin = 0xFFF8, length = 0x0002 + INT61 : origin = 0xFFFA, length = 0x0002 + INT62 : origin = 0xFFFC, length = 0x0002 + RESET : origin = 0xFFFE, length = 0x0002 +} + +/****************************************************************************/ +/* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */ +/****************************************************************************/ + +SECTIONS +{ + .bss : {} > RAM /* GLOBAL & STATIC VARS */ + .sysmem : {} > RAM /* DYNAMIC MEMORY ALLOCATION AREA */ + .stack : {} > RAM (HIGH) /* SOFTWARE SYSTEM STACK */ + + .text : {} > FLASH /* CODE */ + .cinit : {} > FLASH /* INITIALIZATION TABLES */ + .const : {} > FLASH /* CONSTANT DATA */ + .cio : {} > RAM /* C I/O BUFFER */ + + .pinit : {} > FLASH /* C++ CONSTRUCTOR TABLES */ + + .infoA : {} > INFOA /* MSP430 INFO FLASH MEMORY SEGMENTS */ + .infoB : {} > INFOB + .infoC : {} > INFOC + .infoD : {} > INFOD + + .int00 : {} > INT00 /* MSP430 INTERRUPT VECTORS */ + .int01 : {} > INT01 + .int02 : {} > INT02 + .int03 : {} > INT03 + .int04 : {} > INT04 + .int05 : {} > INT05 + .int06 : {} > INT06 + .int07 : {} > INT07 + .int08 : {} > INT08 + .int09 : {} > INT09 + .int10 : {} > INT10 + .int11 : {} > INT11 + .int12 : {} > INT12 + .int13 : {} > INT13 + .int14 : {} > INT14 + .int15 : {} > INT15 + .int16 : {} > INT16 + .int17 : {} > INT17 + .int18 : {} > INT18 + .int19 : {} > INT19 + .int20 : {} > INT20 + .int21 : {} > INT21 + .int22 : {} > INT22 + .int23 : {} > INT23 + .int24 : {} > INT24 + .int25 : {} > INT25 + .int26 : {} > INT26 + .int27 : {} > INT27 + .int28 : {} > INT28 + .int29 : {} > INT29 + .int30 : {} > INT30 + .int31 : {} > INT31 + .int32 : {} > INT32 + .int33 : {} > INT33 + .int34 : {} > INT34 + .int35 : {} > INT35 + .int36 : {} > INT36 + .int37 : {} > INT37 + .int38 : {} > INT38 + .int39 : {} > INT39 + .int40 : {} > INT40 + .int41 : {} > INT41 + .int42 : {} > INT42 + .int43 : {} > INT43 + .int44 : {} > INT44 + .int45 : {} > INT45 + .int46 : {} > INT46 + .int47 : {} > INT47 + .int48 : {} > INT48 + .int49 : {} > INT49 + .int50 : {} > INT50 + .int51 : {} > INT51 + .int52 : {} > INT52 + .int53 : {} > INT53 + .int54 : {} > INT54 + .int55 : {} > INT55 + .int56 : {} > INT56 + .int57 : {} > INT57 + .int58 : {} > INT58 + .int59 : {} > INT59 + .int60 : {} > INT60 + .int61 : {} > INT61 + .int62 : {} > INT62 + .reset : {} > RESET /* MSP430 RESET VECTOR */ +} + +/****************************************************************************/ +/* INCLUDE PERIPHERALS MEMORY MAP */ +/****************************************************************************/ + +-l cc430x613x.cmd + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/acceleration.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/acceleration.c new file mode 100755 index 0000000..41db976 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/acceleration.c @@ -0,0 +1,270 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Temperature measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "vti_as.h" + +// logic +#include "acceleration.h" +#include "simpliciti.h" +#include "user.h" + +// ************************************************************************************************* +// Global Variable section +struct accel sAccel; + +// Conversion values from data to mgrav taken from CMA3000-D0x datasheet (rev 0.4, table 4) +const u16 mgrav_per_bit[7] = { 18, 36, 71, 143, 286, 571, 1142 }; + +// ************************************************************************************************* +// Extern section + +// Global flag for proper acceleration sensor operation +extern u8 as_ok; + +// ************************************************************************************************* +// @fn reset_acceleration +// @brief Reset acceleration variables. +// @param none +// @return none +// ************************************************************************************************* +void reset_acceleration(void) +{ + // Start with Y-axis display + sAccel.view_style = DISPLAY_ACCEL_Y; + + // Clear timeout counter + sAccel.timeout = 0; + + // Default mode is off + sAccel.mode = ACCEL_MODE_OFF; +} + +// ************************************************************************************************* +// @fn sx_acceleration +// @brief Acceleration direct function. Button UP switches between X/Y/Z values. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_acceleration(u8 line) +{ + if (++sAccel.view_style > 2) + sAccel.view_style = 0; + + // Reset current acceleration value + sAccel.data = 0; + + // Get data from sensor + as_get_data(sAccel.xyz); +} + +// ************************************************************************************************* +// @fn acceleration_value_is_positive +// @brief Returns 1 if 2's complement number is positive +// @param u8 value 2's complement number +// @return u8 1 = number is positive, 0 = number is negavtive +// ************************************************************************************************* +u8 acceleration_value_is_positive(u8 value) +{ + return ((value & BIT7) == 0); +} + +// ************************************************************************************************* +// @fn convert_acceleration_value_to_mgrav +// @brief Converts measured value to mgrav units +// @param u8 value g data from sensor +// @return u16 Acceleration (mgrav) +// ************************************************************************************************* +u16 convert_acceleration_value_to_mgrav(u8 value) +{ + u16 result; + u8 i; + + if (!acceleration_value_is_positive(value)) + { + // Convert 2's complement negative number to positive number + value = ~value; + value += 1; + } + + result = 0; + for (i = 0; i < 7; i++) + { + result += ((value & (BIT(i))) >> i) * mgrav_per_bit[i]; + } + + return (result); +} + +// ************************************************************************************************* +// @fn is_acceleration_measurement +// @brief Returns 1 if acceleration is currently measured. +// @param none +// @return u8 1 = acceleration measurement ongoing +// ************************************************************************************************* +u8 is_acceleration_measurement(void) +{ + return ((sAccel.mode == ACCEL_MODE_ON) && (sAccel.timeout > 0)); +} + +// ************************************************************************************************* +// @fn do_acceleration_measurement +// @brief Get sensor data and store in sAccel struct +// @param none +// @return none +// ************************************************************************************************* +void do_acceleration_measurement(void) +{ + // Get data from sensor + as_get_data(sAccel.xyz); + + // Set display update flag + display.flag.update_acceleration = 1; +} + +// ************************************************************************************************* +// @fn display_acceleration +// @brief Display routine. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_acceleration(u8 line, u8 update) +{ + u8 *str; + u8 raw_data; + u16 accel_data; + + // Show warning if acceleration sensor was not initialised properly + if (!as_ok) + { + display_chars(LCD_SEG_L1_2_0, (u8 *) "ERR", SEG_ON); + } + else + { + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + { + // Start acceleration sensor + if (!is_acceleration_measurement()) + { + // Clear previous acceleration value + sAccel.data = 0; + + // Start sensor + as_start(); + + // Set timeout counter + sAccel.timeout = ACCEL_MEASUREMENT_TIMEOUT; + + // Set mode + sAccel.mode = ACCEL_MODE_ON; + + // Start with Y-axis values + sAccel.view_style = DISPLAY_ACCEL_Y; + } + + // Display decimal point + display_symbol(LCD_SEG_L1_DP1, SEG_ON); + } + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + // Convert X/Y/Z values to mg + switch (sAccel.view_style) + { + case DISPLAY_ACCEL_X: + raw_data = sAccel.xyz[0]; + display_char(LCD_SEG_L1_3, 'X', SEG_ON); + break; + case DISPLAY_ACCEL_Y: + raw_data = sAccel.xyz[1]; + display_char(LCD_SEG_L1_3, 'Y', SEG_ON); + break; + default: + raw_data = sAccel.xyz[2]; + display_char(LCD_SEG_L1_3, 'Z', SEG_ON); + break; + } + accel_data = convert_acceleration_value_to_mgrav(raw_data) / 10; + + // Filter acceleration + accel_data = (u16) ((accel_data * 0.2) + (sAccel.data * 0.8)); + + // Store average acceleration + sAccel.data = accel_data; + + // Display acceleration in x.xx format + str = int_to_array(accel_data, 3, 0); + display_chars(LCD_SEG_L1_2_0, str, SEG_ON); + + // Display sign + if (acceleration_value_is_positive(raw_data)) + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + else + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Stop acceleration sensor + as_stop(); + + // Clear mode + sAccel.mode = ACCEL_MODE_OFF; + + // Clean up display + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/acceleration.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/acceleration.h new file mode 100755 index 0000000..14f3d43 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/acceleration.h @@ -0,0 +1,77 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ACCELERATION_H_ +#define ACCELERATION_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section +#define DISPLAY_ACCEL_X (0u) +#define DISPLAY_ACCEL_Y (1u) +#define DISPLAY_ACCEL_Z (2u) + +#define ACCEL_MODE_OFF (0u) +#define ACCEL_MODE_ON (1u) + +// Stop acceleration measurement after 60 minutes to save battery +#define ACCEL_MEASUREMENT_TIMEOUT (60 * 60u) + +// ************************************************************************************************* +// Global Variable section +struct accel +{ + u8 mode; // ACC_MODE_OFF, ACC_MODE_ON + u8 xyz[3]; // Sensor raw data + u16 data; // Acceleration data in 10 * mgrav + u8 view_style; // Display X/Y/Z values + u16 timeout; // Timeout +}; +extern struct accel sAccel; + +// ************************************************************************************************* +// Extern section +extern void reset_acceleration(void); +extern void sx_acceleration(u8 line); +extern void display_acceleration(u8 line, u8 update); +extern u8 is_acceleration_measurement(void); +extern void do_acceleration_measurement(void); + +#endif /*ACCELERATION_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/alarm.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/alarm.c new file mode 100755 index 0000000..0bfdc94 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/alarm.c @@ -0,0 +1,280 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Alarm routines. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "buzzer.h" +#include "ports.h" + +// logic +#include "alarm.h" +#include "clock.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct alarm sAlarm; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_alarm +// @brief Resets alarmData to 06:30 +// @param none +// @return none +// ************************************************************************************************* +void reset_alarm(void) +{ + // Default alarm time 06:30 + sAlarm.hour = 06; + sAlarm.minute = 30; + + // Alarm is initially off + sAlarm.duration = ALARM_ON_DURATION; + sAlarm.state = ALARM_DISABLED; +} + +// ************************************************************************************************* +// @fn check_alarm +// @brief Check if current time matches alarm time +// @param none +// @return none +// ************************************************************************************************* +void check_alarm(void) +{ + // Return if alarm is not enabled + if (sAlarm.state != ALARM_ENABLED) + return; + + // Compare current time and alarm time + // Start with minutes - only 1/60 probability to match + if (sTime.minute == sAlarm.minute) + { + if (sTime.hour == sAlarm.hour) + { + // Indicate that alarm is on + sAlarm.state = ALARM_ON; + } + } +} + +// ************************************************************************************************* +// @fn stop_alarm +// @brief Stop active alarm +// @param none +// @return none +// ************************************************************************************************* +void stop_alarm(void) +{ + // Indicate that alarm is enabled, but not active + sAlarm.state = ALARM_ENABLED; + + // Stop buzzer + stop_buzzer(); +} + +// ************************************************************************************************* +// @fn sx_alarm +// @brief Sx button turns alarm on/off. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void sx_alarm(u8 line) +{ + // UP: Alarm on, off + if (button.flag.up) + { + // Toggle alarm state + if (sAlarm.state == ALARM_DISABLED) + { + sAlarm.state = ALARM_ENABLED; + + // Show " on" message + message.flag.prepare = 1; + message.flag.type_alarm_on = 1; + } + else if (sAlarm.state == ALARM_ENABLED) + { + sAlarm.state = ALARM_DISABLED; + + // Show " off" message + message.flag.prepare = 1; + message.flag.type_alarm_off = 1; + } + } +} + +// ************************************************************************************************* +// @fn mx_alarm +// @brief Set alarm time. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void mx_alarm(u8 line) +{ + u8 select; + s32 hours; + s32 minutes; + u8 *str; + + // Clear display + clear_display_all(); + + // Keep global values in case new values are discarded + hours = sAlarm.hour; + minutes = sAlarm.minute; + + // Display HH:MM (LINE1) + str = int_to_array(hours, 2, 0); + display_chars(LCD_SEG_L1_3_2, str, SEG_ON); + display_symbol(LCD_SEG_L1_COL, SEG_ON); + + str = int_to_array(minutes, 2, 0); + display_chars(LCD_SEG_L1_1_0, str, SEG_ON); + + // Init value index + select = 0; + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout: exit without saving + if (sys.flag.idle_timeout) + break; + + // STAR (short): save, then exit + if (button.flag.star) + { + // Store local variables in global alarm time + sAlarm.hour = hours; + sAlarm.minute = minutes; + // Set display update flag + display.flag.line1_full_update = 1; + break; + } + + switch (select) + { + case 0: // Set hour + set_value(&hours, 2, 0, 0, 23, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, + display_hours); + select = 1; + break; + + case 1: // Set minutes + set_value(&minutes, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, + display_value); + select = 0; + break; + } + } + + // Clear button flag + button.all_flags = 0; + + // Indicate to display function that new value is available + display.flag.update_alarm = 1; +} + +// ************************************************************************************************* +// @fn display_alarm +// @brief Display alarm time. 24H / 12H time format. +// @param u8 line LINE1, LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_alarm(u8 line, u8 update) +{ + u8 hour12; + + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sys.flag.use_metric_units) + { + // Display 24H alarm time "HH:MM" + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(sAlarm.hour, 2, 0), SEG_ON); + } + else + { + // Display 12H alarm time "HH:MM" + AM/PM + hour12 = convert_hour_to_12H_format(sAlarm.hour); + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(hour12, 2, 0), SEG_ON); + + // Display AM/PM symbol + display_am_pm_symbol(sAlarm.hour); + } + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sAlarm.minute, 2, 0), SEG_ON); + display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_ON); + + // Show blinking alarm icon + display_symbol(LCD_ICON_ALARM, SEG_ON_BLINK_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Clean up function-specific segments before leaving function + display_symbol(LCD_SYMB_AM, SEG_OFF); + + // Clear / set alarm icon + if (sAlarm.state == ALARM_DISABLED) + { + display_symbol(LCD_ICON_ALARM, SEG_OFF_BLINK_OFF); + } + else + { + display_symbol(LCD_ICON_ALARM, SEG_ON_BLINK_OFF); + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/alarm.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/alarm.h new file mode 100755 index 0000000..87b036b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/alarm.h @@ -0,0 +1,75 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// internal functions +extern void reset_alarm(void); +extern void check_alarm(void); +extern void stop_alarm(void); + +// menu functions +extern void sx_alarm(u8 line); +extern void mx_alarm(u8 line); +extern void display_alarm(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// Alarm states +#define ALARM_DISABLED (0u) +#define ALARM_ENABLED (1u) +#define ALARM_ON (2u) + +// Keep alarm for 10 on-off cycles +#define ALARM_ON_DURATION (10u) + +// ************************************************************************************************* +// Global Variable section +struct alarm +{ + u8 state; // ALARM_DISABLED, ALARM_ENABLED, ALARM_ON + u8 duration; // Alarm duration + u8 hour; // Alarm hour + u8 minute; // Alarm minute +}; +extern struct alarm sAlarm; + +// ************************************************************************************************* +// Extern section diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/altitude.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/altitude.c new file mode 100755 index 0000000..8837ea5 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/altitude.c @@ -0,0 +1,420 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Altitude measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "altitude.h" +#include "display.h" +#include "vti_ps.h" +#include "ports.h" +#include "timer.h" + +// logic +#include "user.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct alt sAlt; + +// ************************************************************************************************* +// Extern section + +// Global flag for pressure sensor initialisation status +extern u8 ps_ok; + +// ************************************************************************************************* +// @fn reset_altitude_measurement +// @brief Reset altitude measurement. +// @param none +// @return none +// ************************************************************************************************* +void reset_altitude_measurement(void) +{ + // Menu item is not visible + sAlt.state = MENU_ITEM_NOT_VISIBLE; + + // Clear timeout counter + sAlt.timeout = 0; + + // Set default altitude value + sAlt.altitude = 0; + + // Pressure sensor ok? + if (ps_ok) + { + // Initialise pressure table + init_pressure_table(); + + // Do single conversion + start_altitude_measurement(); + stop_altitude_measurement(); + + // Apply calibration offset and recalculate pressure table + if (sAlt.altitude_offset != 0) + { + sAlt.altitude += sAlt.altitude_offset; + update_pressure_table(sAlt.altitude, sAlt.pressure, sAlt.temperature); + } + } +} + +// ************************************************************************************************* +// @fn conv_m_to_ft +// @brief Convert meters to feet +// @param u16 m Meters +// @return u16 Feet +// ************************************************************************************************* +s16 convert_m_to_ft(s16 m) +{ + return (((s32) 328 * m) / 100); +} + +// ************************************************************************************************* +// @fn conv_ft_to_m +// @brief Convert feet to meters +// @param u16 ft Feet +// @return u16 Meters +// ************************************************************************************************* +s16 convert_ft_to_m(s16 ft) +{ + return (((s32) ft * 61) / 200); +} + +// ************************************************************************************************* +// @fn is_altitude_measurement +// @brief Altitude measurement check +// @param none +// @return u8 1=Measurement ongoing, 0=measurement off +// ************************************************************************************************* +u8 is_altitude_measurement(void) +{ + return ((sAlt.state == MENU_ITEM_VISIBLE) && (sAlt.timeout > 0)); +} + +// ************************************************************************************************* +// @fn start_altitude_measurement +// @brief Start altitude measurement +// @param none +// @return none +// ************************************************************************************************* +void start_altitude_measurement(void) +{ + // Show warning if pressure sensor was not initialised properly + if (!ps_ok) + { + display_chars(LCD_SEG_L1_2_0, (u8 *) "ERR", SEG_ON); + return; + } + + // Start altitude measurement if timeout has elapsed + if (sAlt.timeout == 0) + { + // Enable DRDY IRQ on rising edge + PS_INT_IFG &= ~PS_INT_PIN; + PS_INT_IE |= PS_INT_PIN; + + // Start pressure sensor + ps_start(); + + // Set timeout counter only if sensor status was OK + sAlt.timeout = ALTITUDE_MEASUREMENT_TIMEOUT; + + // Get updated altitude + while ((PS_INT_IN & PS_INT_PIN) == 0) ; + do_altitude_measurement(FILTER_OFF); + } +} + +// ************************************************************************************************* +// @fn stop_altitude_measurement +// @brief Stop altitude measurement +// @param none +// @return none +// ************************************************************************************************* +void stop_altitude_measurement(void) +{ + // Return if pressure sensor was not initialised properly + if (!ps_ok) + return; + + // Stop pressure sensor + ps_stop(); + + // Disable DRDY IRQ + PS_INT_IE &= ~PS_INT_PIN; + PS_INT_IFG &= ~PS_INT_PIN; + + // Clear timeout counter + sAlt.timeout = 0; +} + +// ************************************************************************************************* +// @fn do_altitude_measurement +// @brief Perform single altitude measurement +// @param u8 filter Filter option +// @return none +// ************************************************************************************************* +void do_altitude_measurement(u8 filter) +{ + volatile u32 pressure; + + // If sensor is not ready, skip data read + if ((PS_INT_IN & PS_INT_PIN) == 0) + return; + + // Get temperature (format is *10 K) from sensor + sAlt.temperature = ps_get_temp(); + + // Get pressure (format is 1Pa) from sensor + pressure = ps_get_pa(); + + // Store measured pressure value + if (filter == FILTER_OFF) //sAlt.pressure == 0) + { + sAlt.pressure = pressure; + } + else + { + // Filter current pressure + pressure = (u32) ((pressure * 0.2) + (sAlt.pressure * 0.8)); + + // Store average pressure + sAlt.pressure = pressure; + } + + // Convert pressure (Pa) and temperature (K) to altitude (m) + sAlt.altitude = conv_pa_to_meter(sAlt.pressure, sAlt.temperature); +} + +// ************************************************************************************************* +// @fn sx_altitude +// @brief Altitude direct function. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void sx_altitude(u8 line) +{ + // Function can be empty + // Restarting of altitude measurement will be done by subsequent full display update +} + +// ************************************************************************************************* +// @fn mx_altitude +// @brief Mx button handler to set the altitude offset. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void mx_altitude(u8 line) +{ + s32 altitude; + s32 limit_high, limit_low; + + // Clear display + clear_display_all(); + + // Set lower and upper limits for offset correction + if (sys.flag.use_metric_units) + { + // Display "m" symbol + display_symbol(LCD_UNIT_L1_M, SEG_ON); + + // Convert global variable to local variable + altitude = sAlt.altitude; + + // Limits for set_value function + limit_low = -100; + limit_high = 4000; + } + else // English units + { + // Display "ft" symbol + display_symbol(LCD_UNIT_L1_FT, SEG_ON); + + // Convert altitude in meters to feet + altitude = sAlt.altitude; + + // Convert from meters to feet + altitude = convert_m_to_ft(altitude); + + // Limits for set_value function + limit_low = -500; + limit_high = 9999; + } + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout: exit without saving + if (sys.flag.idle_timeout) + break; + + // Button STAR (short): save, then exit + if (button.flag.star) + { + // When using English units, convert ft back to m before updating pressure table + if (!sys.flag.use_metric_units) + altitude = convert_ft_to_m((s16) altitude); + + // Update pressure table + update_pressure_table((s16) altitude, sAlt.pressure, sAlt.temperature); + + // Set display update flag + display.flag.line1_full_update = 1; + + break; + } + + // Set current altitude - offset is set when leaving function + set_value(&altitude, 4, 3, limit_low, limit_high, SETVALUE_DISPLAY_VALUE + + SETVALUE_FAST_MODE + SETVALUE_DISPLAY_ARROWS, LCD_SEG_L1_3_0, + display_value); + } + + // Clear button flags + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn display_altitude +// @brief Display routine. Supports display in meters and feet. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_altitude(u8 line, u8 update) +{ + u8 *str; + s16 ft; + + // redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Enable pressure measurement + sAlt.state = MENU_ITEM_VISIBLE; + + // Start measurement + start_altitude_measurement(); + + if (sys.flag.use_metric_units) + { + // Display "m" symbol + display_symbol(LCD_UNIT_L1_M, SEG_ON); + } + else + { + // Display "ft" symbol + display_symbol(LCD_UNIT_L1_FT, SEG_ON); + } + + // Display altitude + display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + // Update display only while measurement is active + if (sAlt.timeout > 0) + { + if (sys.flag.use_metric_units) + { + // Display altitude in xxxx m format, allow 3 leading blank digits + if (sAlt.altitude >= 0) + { + str = int_to_array(sAlt.altitude, 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + else + { + str = int_to_array(sAlt.altitude * (-1), 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + } + else + { + // Convert from meters to feet + ft = convert_m_to_ft(sAlt.altitude); + + // Limit to 9999ft (3047m) + if (ft > 9999) + ft = 9999; + + // Display altitude in xxxx ft format, allow 3 leading blank digits + if (ft >= 0) + { + str = int_to_array(ft, 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + else + { + str = int_to_array(ft * (-1), 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + } + display_chars(LCD_SEG_L1_3_0, str, SEG_ON); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Disable pressure measurement + sAlt.state = MENU_ITEM_NOT_VISIBLE; + + // Stop measurement + stop_altitude_measurement(); + + // Clean up function-specific segments before leaving function + display_symbol(LCD_UNIT_L1_M, SEG_OFF); + display_symbol(LCD_UNIT_L1_FT, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/altitude.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/altitude.h new file mode 100755 index 0000000..5778d44 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/altitude.h @@ -0,0 +1,76 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ALTITUDE_H_ +#define ALTITUDE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_altitude_measurement(void); +extern u8 is_altitude_measurement(void); +extern void start_altitude_measurement(void); +extern void stop_altitude_measurement(void); +extern void do_altitude_measurement(u8 filter); + +// menu functions +extern void sx_altitude(u8 line); +extern void mx_altitude(u8 line); +extern void display_altitude(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section +#define ALTITUDE_MEASUREMENT_TIMEOUT (60 * 60u) // Stop altitude measurement after 60 minutes to + // save battery + +// ************************************************************************************************* +// Global Variable section +struct alt +{ + menu_t state; // MENU_ITEM_NOT_VISIBLE, MENU_ITEM_VISIBLE + u32 pressure; // Pressure (Pa) + u16 temperature; // Temperature (K) + s16 altitude; // Altitude (m) + s16 altitude_offset; // Altitude offset stored during calibration + u16 timeout; // Timeout +}; +extern struct alt sAlt; + +// ************************************************************************************************* +// Extern section + +#endif /*ALTITUDE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/battery.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/battery.c new file mode 100755 index 0000000..78e0dcd --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/battery.c @@ -0,0 +1,184 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Battery voltage measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" +#include "adc12.h" + +// logic +#include "menu.h" +#include "battery.h" + +// ************************************************************************************************* +// Prototypes section +void reset_batt_measurement(void); +void battery_measurement(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct batt sBatt; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn reset_temp_measurement +// @brief Reset temperature measurement module. +// @param none +// @return none +// ************************************************************************************************* +void reset_batt_measurement(void) +{ + // Set flag to off + sBatt.state = MENU_ITEM_NOT_VISIBLE; + + // Reset lobatt display counter + sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE; + + // Start with battery voltage of 3.00V + sBatt.voltage = 300; +} + +// ************************************************************************************************* +// @fn battery_measurement +// @brief Init ADC12. Do single conversion of AVCC voltage. Turn off ADC12. +// @param none +// @return none +// ************************************************************************************************* +void battery_measurement(void) +{ + u16 voltage; + + // Convert external battery voltage (ADC12INCH_11=AVCC-AVSS/2) + voltage = adc12_single_conversion(REFVSEL_1, ADC12SHT0_10, ADC12INCH_11); + + // Convert ADC value to "x.xx V" + // Ideally we have A11=0->AVCC=0V ... A11=4095(2^12-1)->AVCC=4V + // --> (A11/4095)*4V=AVCC --> AVCC=(A11*4)/4095 + voltage = (voltage * 2 * 2) / 41; + + // Correct measured voltage with calibration value + voltage += sBatt.offset; + + // Discard values that are clearly outside the measurement range + if (voltage > BATTERY_HIGH_THRESHOLD) + { + voltage = sBatt.voltage; + } + + // Filter battery voltage + sBatt.voltage = ((voltage * 2) + (sBatt.voltage * 8)) / 10; + + // If battery voltage falls below low battery threshold, set system flag and modify LINE2 + // display function pointer + if (sBatt.voltage < BATTERY_LOW_THRESHOLD) + { + sys.flag.low_battery = 1; + + // Set sticky battery icon + display_symbol(LCD_SYMB_BATTERY, SEG_ON); + } + else + { + sys.flag.low_battery = 0; + + // Clear sticky battery icon + display_symbol(LCD_SYMB_BATTERY, SEG_OFF); + } + // Update LINE2 + display.flag.line2_full_update = 1; + + // Indicate to display function that new value is available + display.flag.update_battery_voltage = 1; +} + +// ************************************************************************************************* +// @fn display_battery_V +// @brief Display routine for battery voltage. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_battery_V(u8 line, u8 update) +{ + u8 *str; + + // Redraw line + if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Set battery and V icon + display_symbol(LCD_SYMB_BATTERY, SEG_ON); + + // Menu item is visible + sBatt.state = MENU_ITEM_VISIBLE; + + // Display result in xx.x format + str = int_to_array(sBatt.voltage, 3, 0); + + display_chars(LCD_SEG_L2_2_0, str, SEG_ON); + display_symbol(LCD_SEG_L2_DP, SEG_ON); + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + // Display result in xx.x format + str = int_to_array(sBatt.voltage, 3, 0); + + display_chars(LCD_SEG_L2_2_0, str, SEG_ON); + + display.flag.update_battery_voltage = 0; + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Menu item is not visible + sBatt.state = MENU_ITEM_NOT_VISIBLE; + + // Clear function-specific symbols + display_symbol(LCD_SYMB_BATTERY, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/battery.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/battery.h new file mode 100755 index 0000000..baf7608 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/battery.h @@ -0,0 +1,78 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BATTERY_H_ +#define BATTERY_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// Internal functions +extern void reset_batt_measurement(void); +extern void battery_measurement(void); + +// Menu functions +extern void display_battery_V(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// Battery high voltage threshold +#define BATTERY_HIGH_THRESHOLD (360u) + +// Battery end of life voltage threshold -> disable radio, show "lobatt" message +#define BATTERY_LOW_THRESHOLD (240u) + +// Show "lobatt" message every n seconds +#define BATTERY_LOW_MESSAGE_CYCLE (15u) + +// ************************************************************************************************* +// Global Variable section +struct batt +{ + menu_t state; // MENU_ITEM_NOT_VISIBLE, MENU_ITEM_VISIBLE + u8 lobatt_display; // Counter for alternating "lobatt" display + u16 voltage; // Battery voltage + s16 offset; // Battery voltage offset +}; +extern struct batt sBatt; + +// ************************************************************************************************* +// Extern section + +#endif /*BATTERY_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/bluerobin.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/bluerobin.c new file mode 100755 index 0000000..38273f2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/bluerobin.c @@ -0,0 +1,705 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// BlueRobin functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "radio.h" +#include "ports.h" +#include "timer.h" +#include "rf1a.h" + +// logic +#include "BlueRobin_RX_API.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section +void display_calories(u8 line, u8 update); +void display_distance(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// Set to TRUE if transmitter ID should be remembered when reconnecting +// Transmitter ID can be cleared by pressing button STAR for more than 3 seconds +#define REMEMBER_TX_ID (FALSE) + +// ************************************************************************************************* +// Global Variable section +struct bluerobin sBlueRobin; + +// Display values for user gender selection +const u8 selection_User_Gender[][4] = { "MALE", "FEMA" }; + +// ************************************************************************************************* +// Extern section + +// Stop BlueRobin timer +extern void BRRX__StopTimer_v(void); + +// Calibration value for FSCTRL0 register (corrects deviation of 26MHz crystal) +extern u8 rf_frequoffset; + +// ************************************************************************************************* +// @fn reset_bluerobin +// @brief Reset BlueRobin data. +// @param none +// @return none +// ************************************************************************************************* +void reset_bluerobin(void) +{ + // Reset state is no connection + sBlueRobin.state = BLUEROBIN_OFF; + + // Reset value of chest strap ID is 0 --> connect to next best chest strap + sBlueRobin.cs_id = 0; + + // No new data available + sBlueRobin.update = BLUEROBIN_NO_UPDATE; + sBlueRobin.heartrate = 0; + sBlueRobin.speed = 0; + sBlueRobin.distance = 0; + sBlueRobin.calories = 0; + + // Set user data to default + sBlueRobin.user_sex = USER_SEX_MALE; + sBlueRobin.user_weight = 75; + + // Display calories as default + sBlueRobin.caldist_view = 0; +} + +// ************************************************************************************************* +// @fn mx_rfblue +// @brief BlueRobin sub menu. +// Button STAR resets chest strap ID to 0 and searches for next chest +// strap in range. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void mx_bluerobin(u8 line) +{ +#if REMEMBER_TX_ID == TRUE + u8 i; + + // Reset chest strap ID + sBlueRobin.cs_id = 0; + + display_chars(LCD_SEG_L1_2_0, (u8 *) "CLR", SEG_ON); + for (i = 0; i < 4; i++) + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); +#endif + + // Clear simulated button event + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn sx_bluerobin +// @brief BlueRobin direct function. Button UP connects/disconnects with sender unit. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void sx_bluerobin(u8 line) +{ + u8 stop = 0; + + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if SimpliciTI stack is active + if (is_rf()) + return; + + // UP: connect / disconnect transmitter + if (button.flag.up) + { + if (sBlueRobin.state == BLUEROBIN_OFF) + { + // Init BlueRobin timer and radio + open_radio(); + + // Initialize BR library + BRRX_Init_v(); + + // Set BR data transmission properties + BRRX_SetPowerdownDelay_v(10); // Power down channel after 10 consecutive lost data + // packets (~9 seconds) + BRRX_SetSearchTimeout_v(8); // Stop searching after 8 seconds + + // Sensitivity in learn mode reduced --> connect only to close transmitters + // Skip this part if chest strap id was set in a previous learn mode run +#if REMEMBER_TX_ID == TRUE + if (sBlueRobin.cs_id == 0) + BRRX_SetSignalLevelReduction_v(5); + +#else + // Forget previously learned transmitter ID and connect to next close transmitter + sBlueRobin.cs_id = 0; + BRRX_SetSignalLevelReduction_v(5); +#endif + + // Apply frequency offset compensation to radio register FSCTRL0 + // If calibration memory was erased, rf_frequoffset defaults to 0x00 and has no effect + WriteSingleReg(FSCTRL0, rf_frequoffset); + + // New state is SEARCH + sBlueRobin.state = BLUEROBIN_SEARCHING; + + // Blink RF icon to show searching + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + + // Turn on radio and establish connection if channel not already started + if (BRRX_GetState_t(HR_CHANNEL) == TX_OFF) + { + // Start in learn mode (connect to closest heart rate transmitter) + BRRX_SetID_v(HR_CHANNEL, sBlueRobin.cs_id); + BRRX_Start_v(HR_CHANNEL); + + // Wait until learning phase is over + while (BRRX_GetState_t(HR_CHANNEL) == TX_SEARCH) + { + Timer0_A4_Delay(CONV_MS_TO_TICKS(200)); + } + } + + // Check if connection attempt was successful + if (BRRX_GetState_t(HR_CHANNEL) == TX_ACTIVE) + { + // Successfully connected to transmitter + sBlueRobin.state = BLUEROBIN_CONNECTED; + + // When in learn mode, copy chest strap ID + if (sBlueRobin.cs_id == 0) + { + sBlueRobin.cs_id = BRRX_GetID_u32(HR_CHANNEL); + } + + // Show steady RF icon to indicate established connection + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF); + + // Show blinking icon + display_symbol(LCD_ICON_HEART, SEG_ON_BLINK_ON); + } + else // Error -> Shutdown connection + { + stop = 1; + } + } + else if (sBlueRobin.state == BLUEROBIN_CONNECTED) + { + // Shutdown connection + stop = 1; + } + } + + // Shutdown connection + if (stop) + { + stop_bluerobin(); + } +} + +// ************************************************************************************************* +// @fn display_selection_User_Gender +// @brief Display the configuration for gender in watch +// @param u8 segments LCD segments where value is displayed +// u32 value Integer value to be displayed +// u8 digits Number of digits to convert +// u8 blanks Number of leadings blanks in +// int_to_array result string +// @return none +// ************************************************************************************************* +void display_selection_User_Gender(u8 segments, u32 index, u8 digits, u8 blanks) +{ + if (index < 2) + display_chars(segments, (u8 *) selection_User_Gender[index], SEG_ON_BLINK_ON); +} + +// ************************************************************************************************* +// @fn mx_caldist +// @brief Calories/Distance sub menu. Mx enables setting of total calories, user sex and +// weight. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void mx_caldist(u8 line) +{ + u8 select; + s32 kcalories; + s32 weight; + s32 sex; + + // Clear display + clear_display_all(); + + // Convert global variables to local variables + sex = sBlueRobin.user_sex; + kcalories = sBlueRobin.calories / 1000; + if (sys.flag.use_metric_units) + weight = sBlueRobin.user_weight; + else + weight = ((s32) sBlueRobin.user_weight * 2205) / 1000; // Convert kg to lb + + // Init value index + select = 0; + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout : exit without saving + if (sys.flag.idle_timeout) + break; + + // Button STAR (short): save, then exit + if (button.flag.star) + { + // Store local variables in global structure + sBlueRobin.calories = kcalories * 1000; + sBlueRobin.user_sex = sex; + if (sys.flag.use_metric_units) + sBlueRobin.user_weight = weight; + else + sBlueRobin.user_weight = (weight * 1000) / 2205; + + // Set display update flag + display.flag.line1_full_update = 1; + + break; + } + + switch (select) + { + case 0: // Set calories + display_symbol(LCD_UNIT_L2_KCAL, SEG_ON); + set_value(&kcalories, 6, 5, 0, 199999, SETVALUE_DISPLAY_VALUE + + SETVALUE_FAST_MODE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_5_0, + display_value); + display_symbol(LCD_UNIT_L2_KCAL, SEG_OFF); + clear_line(LINE2); + select = 1; + break; + case 1: // Set user sex + set_value( + &sex, 1, 0, 0, 1, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_SELECTION + + SETVALUE_NEXT_VALUE, LCD_SEG_L2_3_0, display_selection_User_Gender); + select = 2; + break; + case 2: // Set user weight + if (sys.flag.use_metric_units) + { + display_chars(LCD_SEG_L2_1_0, (u8 *) "KG", SEG_ON); + set_value(&weight, 3, 2, USER_WEIGHT_MIN_KG, USER_WEIGHT_MAX_KG, + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_4_2, + display_value); + } + else + { + display_chars(LCD_SEG_L2_1_0, (u8 *) "LB", SEG_ON); + set_value(&weight, 3, 2, USER_WEIGHT_MIN_LB, USER_WEIGHT_MAX_LB, + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_4_2, + display_value); + } + select = 0; + break; + } + } + + // Clear button flags + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn sx_caldist +// @brief Button DOWN toggles between calories and distance display. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_caldist(u8 line) +{ + // Clean up line + display_caldist(line, DISPLAY_LINE_CLEAR); + + // Toggle display + if (sBlueRobin.caldist_view == 0) + sBlueRobin.caldist_view = 1; + else + sBlueRobin.caldist_view = 0; + + // Draw line + display_caldist(line, DISPLAY_LINE_UPDATE_FULL); +} + +// ************************************************************************************************* +// @fn display_heartrate +// @brief Heart rate display routine. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_heartrate(u8 line, u8 update) +{ + u8 *str; + + if (update != DISPLAY_LINE_CLEAR) + { + if (is_bluerobin()) + { + str = int_to_array(sBlueRobin.heartrate, 3, 2); + display_chars(LCD_SEG_L1_2_0, str, SEG_ON); + } + else + { + display_chars(LCD_SEG_L1_2_0, (u8 *) "---", SEG_ON); + } + } + + // Redraw whole screen + if (!is_bluerobin()) + { + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_symbol(LCD_ICON_HEART, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Clear heart when not connected + display_symbol(LCD_ICON_HEART, SEG_OFF); + } + } +} + +// ************************************************************************************************* +// @fn display_speed_kmh +// @brief Speed display routine. Supports kmh and mph. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_PARTIAL, +// DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_speed(u8 line, u8 update) +{ + u8 milesPerHour; + u8 *str; + + // Speed resolution is 0.1 km/h + // Valid range is 0.0 .. 25.0 km/h + + // Display resolution is 0.1km/h + // For speed less than 1 km/h, force "0.x" display + if (update != DISPLAY_LINE_CLEAR) + { + if (sys.flag.use_metric_units) + { + str = int_to_array(sBlueRobin.speed, 3, 1); + } + else + { + milesPerHour = (u16) (sBlueRobin.speed * 0.6214); + str = int_to_array(milesPerHour, 3, 1); + } + display_chars(LCD_SEG_L1_2_0, str, SEG_ON); + } + + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_symbol(LCD_SEG_L1_DP0, SEG_ON); + if (sys.flag.use_metric_units) + { + display_symbol(LCD_UNIT_L1_K, SEG_ON); + display_symbol(LCD_UNIT_L1_M, SEG_ON); + } + else + { + display_symbol(LCD_UNIT_L1_M, SEG_ON); + display_symbol(LCD_UNIT_L1_I, SEG_ON); + } + display_symbol(LCD_UNIT_L1_PER_H, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + display_symbol(LCD_SEG_L1_DP0, SEG_OFF); + display_symbol(LCD_UNIT_L1_K, SEG_OFF); + display_symbol(LCD_UNIT_L1_M, SEG_OFF); + display_symbol(LCD_UNIT_L1_M, SEG_OFF); + display_symbol(LCD_UNIT_L1_I, SEG_OFF); + display_symbol(LCD_UNIT_L1_PER_H, SEG_OFF); + } +} + +// ************************************************************************************************* +// @fn display_distance +// @brief Distance display routine. Supports km and mi. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_PARTIAL, +// DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_distance(u8 line, u8 update) +{ + u8 *str; + u32 miles; + + if (update != DISPLAY_LINE_CLEAR) + { + if (sys.flag.use_metric_units) + { + // Display distance in x.xx km format (resolution is 10m) up to 2000.00 km + if (sBlueRobin.distance < 2000000) + { + // Convert decimal distance in meters to format "xxxx.xx" km + // If distance is less than 1000m, force display to " 0.xx" + // If distance is less than 100m, force display to " 0.0x" + str = int_to_array(sBlueRobin.distance / 10, 6, 3); + } + else + { + str = int_to_array(199999, 6, 3); + } + } + else + { + // Convert km to miles, take care for "0.xx mi" display + miles = (u32) (sBlueRobin.distance * 0.06214); + + // Display distance in x.xx mi format (resolution is 1/100mi) up to 2000.00 mi + if (miles < 2000000) + { + // If distance is less than 1 mile, force display to " 0.xx" + // If distance is less than 1/10 mile, force display to " 0.0x" + str = int_to_array(miles, 6, 3); + } + else + { + // Display maximum value (1999.99 mi) + str = int_to_array(199999, 6, 3); + } + } + display_chars(LCD_SEG_L2_5_0, str, SEG_ON); + } + + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sys.flag.use_metric_units) + { + display_symbol(LCD_UNIT_L2_KM, SEG_ON); + } + else + { + display_symbol(LCD_UNIT_L2_MI, SEG_ON); + } + display_symbol(LCD_SEG_L2_DP, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + display_symbol(LCD_UNIT_L2_KM, SEG_OFF); + display_symbol(LCD_UNIT_L2_MI, SEG_OFF); + display_symbol(LCD_SEG_L2_DP, SEG_OFF); + } +} + +// ************************************************************************************************* +// @fn display_caldist +// @brief Shared calories/distance display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_PARTIAL, +// DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_caldist(u8 line, u8 update) +{ + if (sBlueRobin.caldist_view == 0) + display_calories(line, update); + else + display_distance(line, update); +} + +// ************************************************************************************************* +// @fn display_calories +// @brief Calories display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_PARTIAL, +// DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_calories(u8 line, u8 update) +{ + u8 *str; + + if (update != DISPLAY_LINE_CLEAR) + { + // Convert decimal calories to string + str = int_to_array(sBlueRobin.calories / 1000, 6, 5); + display_chars(LCD_SEG_L2_5_0, str, SEG_ON); + } + + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_symbol(LCD_UNIT_L2_KCAL, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Clean up symbols when leaving function + display_symbol(LCD_UNIT_L2_KCAL, SEG_OFF); + } +} + +// ************************************************************************************************* +// @fn is_bluerobin +// @brief Returns TRUE if BlueRobin transmitter is connected. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_bluerobin(void) +{ + return (sBlueRobin.state == BLUEROBIN_CONNECTED); +} + +// ************************************************************************************************* +// @fn is_bluerobin_searching +// @brief Returns TRUE if BlueRobin is searching for a transmitter. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_bluerobin_searching(void) +{ + return (sBlueRobin.state == BLUEROBIN_SEARCHING); +} + +// ************************************************************************************************* +// @fn get_bluerobin_data +// @brief Read BlueRobin packet data from API. +// @param none +// @return none +// ************************************************************************************************* +void get_bluerobin_data(void) +{ + u16 calories; + brtx_state_t bChannelState; + + // Check connection status + bChannelState = BRRX_GetState_t(HR_CHANNEL); + + switch (bChannelState) + { + case TX_ACTIVE: // Read heart rate data from BlueRobin API + sBlueRobin.heartrate = BRRX_GetHeartRate_u8(); + + // Read speed from BlueRobin API (only valid if sender is USB dongle) + sBlueRobin.speed = BRRX_GetSpeed_u8(); + + // Read distance from BlueRobin API (only valid if sender is USB dongle) + sBlueRobin.distance = BRRX_GetDistance_u16(); + if (sBlueRobin.distance > 2000000) + sBlueRobin.distance = 0; + + // Heart rate high enough for calorie measurement? + if (sBlueRobin.heartrate >= 65 && sBlueRobin.user_weight != 0) + { + calories = ((sBlueRobin.heartrate - 60) * sBlueRobin.user_weight) / 32; + + // Calorie reduction for female user required? + if (sBlueRobin.user_sex == USER_SEX_FEMALE) + { + calories -= calories / 4; + } + + // Restart from 0 when reaching 199999 kcal + sBlueRobin.calories += calories; + if (sBlueRobin.calories > 200000000) + sBlueRobin.calories = 0; + } + sBlueRobin.update = BLUEROBIN_NEW_DATA; + break; + + case TX_OFF: // Shutdown connection + stop_bluerobin(); + break; + + // BR_SEARCH, BR_LEARN, BR_PAUSE: Keep old values until we receive new data + default: + break; + } +} + +// ************************************************************************************************* +// @fn stop_bluerobin +// @brief Stop communication and put peripherals in power-down mode. +// @param none +// @return none +// ************************************************************************************************* +void stop_bluerobin(void) +{ + // Reset connection status byte + sBlueRobin.state = BLUEROBIN_OFF; + + // Stop channel + BRRX_Stop_v(HR_CHANNEL); + + // Powerdown radio + close_radio(); + + // Force full display update to clear heart rate and speed data + sBlueRobin.heartrate = 0; + sBlueRobin.speed = 0; + sBlueRobin.distance = 0; + display.flag.full_update = 1; + + // Clear heart and RF symbol + display_symbol(LCD_ICON_HEART, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/bluerobin.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/bluerobin.h new file mode 100755 index 0000000..b545d11 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/bluerobin.h @@ -0,0 +1,107 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BLUEROBIN_H_ +#define BLUEROBIN_H_ + +// ************************************************************************************************* +// Include section +#include + +// ************************************************************************************************* +// Prototypes section +extern void reset_bluerobin(void); +extern void mx_bluerobin(u8 line); +extern void sx_bluerobin(u8 line); +extern void mx_caldist(u8 line); +extern void display_heartrate(u8 line, u8 update); +extern void display_speed(u8 line, u8 update); +extern void sx_caldist(u8 line); +extern void mx_caldist(u8 line); +extern void display_caldist(u8 line, u8 update); +extern u8 is_bluerobin(void); +extern u8 is_bluerobin_searching(void); +extern void get_bluerobin_data(void); +extern void stop_bluerobin(void); + +// ************************************************************************************************* +// Defines section + +// BlueRobin connection states +typedef enum +{ + BLUEROBIN_OFF = 0, // Not connected + BLUEROBIN_SEARCHING, // Searching for transmitter + BLUEROBIN_CONNECTED, // Connected + BLUEROBIN_ERROR // Error occurred while trying to connect or while connected +} BlueRobin_state_t; + +// BlueRobin data update states +typedef enum +{ + BLUEROBIN_NO_UPDATE = 0, // No new data available + BLUEROBIN_NEW_DATA // New data arrived +} BlueRobin_update_t; + +#define USER_SEX_MALE 0 +#define USER_SEX_FEMALE 1 +#define USER_WEIGHT_MIN_KG 30 +#define USER_WEIGHT_MAX_KG 150 +#define USER_WEIGHT_MIN_LB 70 +#define USER_WEIGHT_MAX_LB 400 + +// ************************************************************************************************* +// Global Variable section +struct bluerobin +{ + BlueRobin_state_t state; // BLUEROBIN_OFF, BLUEROBIN_SEARCHING, BLUEROBIN_CONNECTED, + // BLUEROBIN_ERROR + BlueRobin_update_t update; // BLUEROBIN_NO_UPDATE, BLUEROBIN_NEW_DATA + u32 cs_id; // Chest strap ID + u8 user_sex; // User settings + u16 user_weight; + u8 heartrate; // Heart rate (1 bpm) + u32 calories; // Calories (1 kCal) - calculated from heart rate, user weight and + // user sex + u8 speed; // Speed (0.1 km/h) - demo version range is 0.0 to 25.5km/h + u32 distance; // Distance (1 m) + u8 caldist_view; // 0=display calories, 1=display distance +}; +extern struct bluerobin sBlueRobin; + +// ************************************************************************************************* +// Extern section + +#endif /*BLUEROBIN_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/clock.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/clock.c new file mode 100755 index 0000000..2eef524 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/clock.c @@ -0,0 +1,444 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Time functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "ports.h" +#include "display.h" +#include "timer.h" + +// logic +#include "menu.h" +#include "clock.h" +#include "user.h" +#include "bluerobin.h" +#include "date.h" + +// ************************************************************************************************* +// Prototypes section +void reset_clock(void); +void clock_tick(void); +void mx_time(u8 line); +void sx_time(u8 line); + +void calc_24H_to_12H(u8 * hours, u8 * timeAM); +void conv_24H_to_12H(u8 * hours24, u8 * hours12, u8 * timeAMorPM); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct time sTime; + +// Display values for time format selection +const u8 selection_Timeformat[][4] = { + "24H", "12H" +}; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); +extern void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn reset_clock +// @brief Resets clock time to 00:00:00, 24H time format. +// @param none +// @return none +// ************************************************************************************************* +void reset_clock(void) +{ + // Set global system time to 0 + sTime.system_time = 0; + + // Set main 24H time to start value + sTime.hour = 4; + sTime.minute = 30; + sTime.second = 0; + + // Display style of both lines is default (HH:MM) + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; + + // Reset timeout detection + sTime.last_activity = 0; +} + +// ************************************************************************************************* +// @fn clock_tick +// @brief Add 1 second to system time and to display time +// @param none +// @return none +// ************************************************************************************************* +void clock_tick(void) +{ + // Use sTime.drawFlag to minimize display updates + // sTime.drawFlag = 1: second + // sTime.drawFlag = 2: minute, second + // sTime.drawFlag = 3: hour, minute + sTime.drawFlag = 1; + + // Increase global system time + sTime.system_time++; + + // Add 1 second + sTime.second++; + + // Add 1 minute + if (sTime.second == 60) + { + sTime.second = 0; + sTime.minute++; + sTime.drawFlag++; + + // Add 1 hour + if (sTime.minute == 60) + { + sTime.minute = 0; + sTime.hour++; + sTime.drawFlag++; + + // Add 1 day + if (sTime.hour == 24) + { + sTime.hour = 0; + add_day(); + } + } + } +} + +// ************************************************************************************************* +// @fn convert_hour_to_12H_format +// @brief Convert internal 24H time to 12H time. +// @param u8 hour Hour in 24H format +// @return u8 Hour in 12H format +// ************************************************************************************************* +u8 convert_hour_to_12H_format(u8 hour) +{ + // 00:00 .. 11:59 --> AM 12:00 .. 11:59 + if (hour == 0) + return (hour + 12); + else if (hour <= 12) + return (hour); + // 13:00 .. 23:59 --> PM 01:00 .. 11:59 + else + return (hour - 12); +} + +// ************************************************************************************************* +// @fn is_hour_am +// @brief Checks if internal 24H time is AM or PM +// @param u8 hour Hour in 24H format +// @return u8 1 = AM, 0 = PM +// ************************************************************************************************* +u8 is_hour_am(u8 hour) +{ + // 00:00 .. 11:59 --> AM 12:00 .. 11:59 + if (hour < 12) + return (1); + // 12:00 .. 23:59 --> PM 12:00 .. 11:59 + else + return (0); +} + +// ************************************************************************************************* +// @fn display_selection_Timeformat +// @brief Display time format 12H / 24H. +// @param u8 segments Target segments where to display information +// u32 index 0 or 1, index for value string +// u8 digits Not used +// u8 blanks Not used +// @return none +// ************************************************************************************************* +void display_selection_Timeformat1(u8 segments, u32 index, u8 digits, u8 blanks) +{ + if (index < 2) + display_chars(segments, (u8 *) selection_Timeformat[index], SEG_ON_BLINK_ON); +} + +// ************************************************************************************************* +// @fn mx_time +// @brief Clock set routine. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void mx_time(u8 line) +{ + u8 select; + s32 timeformat; + s16 timeformat1; + s32 hours; + s32 minutes; + s32 seconds; + u8 *str; + + // Clear display + clear_display_all(); + + // Convert global time to local variables + // Global time keeps on ticking in background until it is overwritten + if (sys.flag.use_metric_units) + { + timeformat = TIMEFORMAT_24H; + } + else + { + timeformat = TIMEFORMAT_12H; + } + timeformat1 = timeformat; + hours = sTime.hour; + minutes = sTime.minute; + seconds = sTime.second; + + // Init value index + select = 0; + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout: exit without saving + if (sys.flag.idle_timeout) + { + // Roll back time format + if (timeformat1 == TIMEFORMAT_24H) + sys.flag.use_metric_units = 1; + else + sys.flag.use_metric_units = 0; + display_symbol(LCD_SYMB_AM, SEG_OFF); + break; + } + + // Button STAR (short): save, then exit + if (button.flag.star) + { + // Stop clock timer + Timer0_Stop(); + + // Store local variables in global clock time + sTime.hour = hours; + sTime.minute = minutes; + sTime.second = seconds; + + // Start clock timer + Timer0_Start(); + + // Full display update is done when returning from function + display_symbol(LCD_SYMB_AM, SEG_OFF); + break; + } + + switch (select) + { + case 0: // Clear LINE1 and LINE2 and AM icon - required when coming back from + // set_value(seconds) + clear_display(); + display_symbol(LCD_SYMB_AM, SEG_OFF); + + // Set 24H / 12H time format + set_value( + &timeformat, 1, 0, 0, 1, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_SELECTION + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_1, display_selection_Timeformat1); + + // Modify global time format variable immediately to update AM/PM icon correctly + if (timeformat == TIMEFORMAT_24H) + sys.flag.use_metric_units = 1; + else + sys.flag.use_metric_units = 0; + select = 1; + break; + + case 1: // Display HH:MM (LINE1) and .SS (LINE2) + str = int_to_array(hours, 2, 0); + display_chars(LCD_SEG_L1_3_2, str, SEG_ON); + display_symbol(LCD_SEG_L1_COL, SEG_ON); + + str = int_to_array(minutes, 2, 0); + display_chars(LCD_SEG_L1_1_0, str, SEG_ON); + + str = int_to_array(seconds, 2, 0); + display_chars(LCD_SEG_L2_1_0, str, SEG_ON); + display_symbol(LCD_SEG_L2_DP, SEG_ON); + + // Set hours + set_value(&hours, 2, 0, 0, 23, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, + display_hours); + select = 2; + break; + + case 2: // Set minutes + set_value(&minutes, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, + display_value); + select = 3; + break; + + case 3: // Set seconds + set_value(&seconds, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L2_1_0, + display_value); + select = 0; + break; + } + } + + // Clear button flags + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn sx_time +// @brief Time user routine. Toggles view style between HH:MM and SS. +// @param line LINE1 +// @return none +// ************************************************************************************************* +void sx_time(u8 line) +{ + // Toggle display view style + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + sTime.line1ViewStyle = DISPLAY_ALTERNATIVE_VIEW; + else + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn display_time +// @brief Clock display routine. Supports 24H and 12H time format. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL +// @return none +// ************************************************************************************************* +void display_time(u8 line, u8 update) +{ + u8 hour12; + + // Partial update + if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + if (sTime.drawFlag != 0) + { + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + { + switch (sTime.drawFlag) + { + case 3: + if (sys.flag.use_metric_units) + { + // Display 24H time "HH" + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(sTime.hour, 2, + 0), SEG_ON); + } + else + { + // Display 12H time "HH" + AM/PM + hour12 = convert_hour_to_12H_format(sTime.hour); + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(hour12, 2, + 0), SEG_ON); + display_am_pm_symbol(sTime.hour); + } + + case 2: + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.minute, 2, + 0), SEG_ON); + } + } + else + { + // Seconds are always updated + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.second, 2, 0), SEG_ON); + } + } + } + else if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Full update + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + { + // Display 24H/12H time + if (sys.flag.use_metric_units) + { + // Display 24H time "HH" + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(sTime.hour, 2, 0), SEG_ON); + } + else + { + // Display 12H time "HH" + AM/PM information + hour12 = convert_hour_to_12H_format(sTime.hour); + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(hour12, 2, 0), SEG_ON); + // Display AM/PM information + if (line == LINE1) + { + display_am_pm_symbol(sTime.hour); + } + } + + // Display minute + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.minute, 2, 0), SEG_ON); + display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_ON_BLINK_ON); + } + else + { + // Display seconds + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.second, 2, 0), SEG_ON); + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_OFF_BLINK_OFF); + // Change display style to default (HH:MM) + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; + // Clean up AM/PM icon + display_symbol(LCD_SYMB_AM, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/clock.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/clock.h new file mode 100755 index 0000000..9084b1b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/clock.h @@ -0,0 +1,74 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef CLOCK_H_ +#define CLOCK_H_ + +// ************************************************************************************************* +// Defines section + +// Definitions for time format +#define TIMEFORMAT_24H (0u) +#define TIMEFORMAT_12H (1u) + +// ************************************************************************************************* +// Prototypes section +extern void reset_clock(void); +extern void sx_time(u8 line); +extern void mx_time(u8 line); +extern void clock_tick(void); +extern void display_selection_Timeformat1(u8 segments, u32 index, u8 digits, u8 blanks); +extern void display_time(u8 line, u8 update); + +// English units support +extern void calc_24H_to_12H(u8 * hours, u8 * timeAM); +extern u8 convert_hour_to_12H_format(u8 hour); +extern u8 is_hour_am(u8 hour); + +// ************************************************************************************************* +// Global Variable section +struct time +{ + u32 system_time; // Global system time. Used to calculate last activity + u32 last_activity; // Inactivity detection (exits set_value() function) + u8 drawFlag; // Flag to minimize display updates + u8 line1ViewStyle; // Viewing style + u8 hour; // Time data + u8 minute; // Time data + u8 second; // Time data +}; +extern struct time sTime; + +#endif /*CLOCK_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/date.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/date.c new file mode 100755 index 0000000..e72ef3d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/date.c @@ -0,0 +1,354 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Date functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" + +// logic +#include "date.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section +void reset_date(void); +u8 get_numberOfDays(u8 month, u16 year); +void add_day(void); +void mx_date(u8 line); +void sx_date(u8 line); +void display_date(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct date sDate; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); +extern void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn reset_date +// @brief Reset date to start value. +// @param none +// @return none +// ************************************************************************************************* +void reset_date(void) +{ + // Set date + sDate.year = 2009; + sDate.month = 8; + sDate.day = 1; + + // Show day and month on display + sDate.display = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn get_NumberOfDays +// @brief Return number of days for a given month +// @param month month as char +// year year as int +// @return day count for given month +// ************************************************************************************************* +u8 get_numberOfDays(u8 month, u16 year) +{ + switch (month) + { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + return (31); + + case 4: + case 6: + case 9: + case 11: + return (30); + + // 1. A year that is divisible by 4 is a leap year. (Y % 4) == 0 + // 2. Exception to rule 1: a year that is divisible by 100 is not a leap year. (Y % 100) != + // 0 + // 3. Exception to rule 2: a year that is divisible by 400 is a leap year. (Y % 400) == 0 + + case 2: + if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))) + return (29); + else + return (28); + + default: + return (0); + } +} + +// ************************************************************************************************* +// @fn add_day +// @brief Add one day to current date. Called when clock changes from 23:59 to 00:00 +// @param none +// @return none +// ************************************************************************************************* +void add_day(void) +{ + // Add 1 day + sDate.day++; + + // Check if day overflows into next month + if (sDate.day > get_numberOfDays(sDate.month, sDate.year)) + { + // Add 1 month and reset to day to 1 + sDate.day = 1; + sDate.month++; + + // Check if month overflows into next year + if (sDate.month > 12) + { + // Add 1 year and reset month and day to 1 + sDate.day = 1; + sDate.month = 1; + sDate.year++; + } + } + + // Indicate to display function that new value is available + display.flag.full_update = 1; +} + +// ************************************************************************************************* +// @fn mx_date +// @brief Date set routine. +// @param line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void mx_date(u8 line) +{ + u8 select; + s32 day; + s32 month; + s32 year; + s16 max_days; + u8 *str; + u8 *str1; + + // Clear display + clear_display_all(); + + // Convert global to local variables + day = sDate.day; + month = sDate.month; + year = sDate.year; + + // Init value index + select = 0; + + // Init display + // LINE1: DD.MM (metric units) or MM.DD (English units) + // LINE2: YYYY (will be drawn by set_value) + + if (sys.flag.use_metric_units) + { + str = int_to_array(day, 2, 0); + display_chars(LCD_SEG_L1_3_2, str, SEG_ON); + + str1 = int_to_array(month, 2, 0); + display_chars(LCD_SEG_L1_1_0, str1, SEG_ON); + } + else // English units + { + str = int_to_array(day, 2, 0); + display_chars(LCD_SEG_L1_1_0, str, SEG_ON); + + str1 = int_to_array(month, 2, 0); + display_chars(LCD_SEG_L1_3_2, str1, SEG_ON); + } + display_symbol(LCD_SEG_L1_DP1, SEG_ON); + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout: exit without saving + if (sys.flag.idle_timeout) + break; + + // Button STAR (short): save, then exit + if (button.flag.star) + { + // Copy local variables to global variables + sDate.day = day; + sDate.month = month; + sDate.year = year; + + // Full display update is done when returning from function + break; + } + + switch (select) + { + case 0: // Set year + set_value(&year, 4, 0, 2008, 2100, SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, + LCD_SEG_L2_3_0, + display_value); + select = 1; + break; + case 1: // Set month + if (sys.flag.use_metric_units) + { + set_value( + &month, 2, 0, 1, 12, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value); + } + else // English units + { + set_value( + &month, 2, 0, 1, 12, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_value); + } + select = 2; + break; + case 2: // Set day + if (sys.flag.use_metric_units) + { + set_value( + &day, 2, 0, 1, max_days, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_value); + } + else // English units + { + set_value( + &day, 2, 0, 1, max_days, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value); + } + select = 0; + break; + } + + // Check if day is still valid, if not clamp to last day of current month + max_days = get_numberOfDays(month, year); + if (day > max_days) + day = max_days; + } + + // Clear button flag + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn sx_date +// @brief Date user routine. Toggles view between DD.MM and YYYY. +// @param line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void sx_date(u8 line) +{ + // Toggle display items + if (sDate.display == DISPLAY_DEFAULT_VIEW) + sDate.display = DISPLAY_ALTERNATIVE_VIEW; + else + sDate.display = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn display_date +// @brief Display date in DD.MM format (metric units) or MM.DD (English units). +// @param u8 line LINE1, LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL +// @return none +// ************************************************************************************************* +void display_date(u8 line, u8 update) +{ + u8 *str; + + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sDate.display == DISPLAY_DEFAULT_VIEW) + { + // Convert day to string + str = int_to_array(sDate.day, 2, 0); + if (sys.flag.use_metric_units) + { + display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); + } + else + { + display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); + } + + // Convert month to string + str = int_to_array(sDate.month, 2, 0); + if (sys.flag.use_metric_units) + { + display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); + } + else + { + display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); + } + + // Display "." to separate day and month + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); + } + else + { + // Convert year to string + str = int_to_array(sDate.year, 4, 0); + display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_3_0), str, SEG_ON); + + // Clear "." + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_OFF); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Show day and month on display when coming around next time + sDate.display = DISPLAY_DEFAULT_VIEW; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/date.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/date.h new file mode 100755 index 0000000..f3a65b8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/date.h @@ -0,0 +1,68 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef DATE_H_ +#define DATE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_date(void); +extern void add_day(void); +extern void mx_date(u8 line); +extern void sx_date(u8 line); +extern void display_date(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct date +{ + u8 display; // Toggles view between DISPLAY_DEFAULT_VIEW = DD.MM and + // DISPLAY_ALTERNATIVE_VIEW = YYYY + u8 day; + u8 month; + u16 year; +}; +extern struct date sDate; + +// ************************************************************************************************* +// Extern section + +#endif /*DATE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/menu.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/menu.c new file mode 100755 index 0000000..05a826a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/menu.c @@ -0,0 +1,254 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Menu management functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" + +// logic +#include "menu.h" +#include "user.h" +#include "clock.h" +#include "date.h" +#include "alarm.h" +#include "stopwatch.h" +#include "temperature.h" +#include "altitude.h" +#include "battery.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "acceleration.h" +#include "rfbsl.h" + +// ************************************************************************************************* +// Defines section +#define FUNCTION(function) function + +// ************************************************************************************************* +// Global Variable section +const struct menu *ptrMenu_L1 = NULL; +const struct menu *ptrMenu_L2 = NULL; + +// ************************************************************************************************* +// Global Variable section + +void display_nothing(u8 line, u8 update) +{ +} + +u8 update_time(void) +{ + return (display.flag.update_time); +} + +u8 update_stopwatch(void) +{ + return (display.flag.update_stopwatch); +} + +u8 update_date(void) +{ + return (display.flag.update_date); +} + +u8 update_alarm(void) +{ + return (display.flag.update_alarm); +} + +u8 update_temperature(void) +{ + return (display.flag.update_temperature); +} + +u8 update_battery_voltage(void) +{ + return (display.flag.update_battery_voltage); +} + +u8 update_acceleration(void) +{ + return (display.flag.update_acceleration); +} + +// ************************************************************************************************* +// User navigation ( [____] = default menu item after reset ) +// +// LINE1: [Time] -> Alarm -> Temperature -> Altitude -> Heart rate -> Speed -> Acceleration +// +// LINE2: [Date] -> Stopwatch -> Battery -> ACC -> PPT -> SYNC -> Calories/Distance --> RFBSL +// ************************************************************************************************* + +// Line1 - Time +const struct menu menu_L1_Time = { + FUNCTION(sx_time), // direct function + FUNCTION(mx_time), // sub menu function + FUNCTION(display_time), // display function + FUNCTION(update_time), // new display data + &menu_L1_Alarm, +}; + +// Line1 - Alarm +const struct menu menu_L1_Alarm = { + FUNCTION(sx_alarm), // direct function + FUNCTION(mx_alarm), // sub menu function + FUNCTION(display_alarm), // display function + FUNCTION(update_alarm), // new display data + &menu_L1_Temperature, +}; + +// Line1 - Temperature +const struct menu menu_L1_Temperature = { + FUNCTION(dummy), // direct function + FUNCTION(mx_temperature), // sub menu function + FUNCTION(display_temperature), // display function + FUNCTION(update_temperature), // new display data + &menu_L1_Altitude, +}; + +// Line1 - Altitude +const struct menu menu_L1_Altitude = { + FUNCTION(sx_altitude), // direct function + FUNCTION(mx_altitude), // sub menu function + FUNCTION(display_altitude), // display function + FUNCTION(update_time), // new display data + &menu_L1_Heartrate, +}; + +// Line1 - Heart Rate +const struct menu menu_L1_Heartrate = { + FUNCTION(sx_bluerobin), // direct function + FUNCTION(mx_bluerobin), // sub menu function + FUNCTION(display_heartrate), // display function + FUNCTION(update_time), // new display data + &menu_L1_Speed, +}; + +// Line1 - Speed +const struct menu menu_L1_Speed = { + FUNCTION(dummy), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_speed), // display function + FUNCTION(update_time), // new display data + &menu_L1_Acceleration, +}; + +// Line1 - Acceleration +const struct menu menu_L1_Acceleration = { + FUNCTION(sx_acceleration), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_acceleration), // display function + FUNCTION(update_acceleration), // new display data + &menu_L1_Time, +}; + +// Line2 - Date +const struct menu menu_L2_Date = { + FUNCTION(sx_date), // direct function + FUNCTION(mx_date), // sub menu function + FUNCTION(display_date), // display function + FUNCTION(update_date), // new display data + &menu_L2_Stopwatch, +}; + +// Line2 - Stopwatch +const struct menu menu_L2_Stopwatch = { + FUNCTION(sx_stopwatch), // direct function + FUNCTION(mx_stopwatch), // sub menu function + FUNCTION(display_stopwatch), // display function + FUNCTION(update_stopwatch), // new display data + &menu_L2_Battery, +}; + +// Line2 - Battery +const struct menu menu_L2_Battery = { + FUNCTION(dummy), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_battery_V), // display function + FUNCTION(update_battery_voltage), // new display data + &menu_L2_Rf, +}; + +// Line2 - ACC (acceleration data + button events via SimpliciTI) +const struct menu menu_L2_Rf = { + FUNCTION(sx_rf), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_rf), // display function + FUNCTION(update_time), // new display data + &menu_L2_Ppt, +}; + +// Line2 - PPT (button events via SimpliciTI) +const struct menu menu_L2_Ppt = { + FUNCTION(sx_ppt), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_ppt), // display function + FUNCTION(update_time), // new display data + &menu_L2_Sync, +}; + +// Line2 - SXNC (synchronization/data download via SimpliciTI) +const struct menu menu_L2_Sync = { + FUNCTION(sx_sync), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_sync), // display function + FUNCTION(update_time), // new display data + &menu_L2_CalDist, +}; + +// Line2 - Calories/Distance +const struct menu menu_L2_CalDist = { + FUNCTION(sx_caldist), // direct function + FUNCTION(mx_caldist), // sub menu function + FUNCTION(display_caldist), // display function + FUNCTION(update_time), // new display data + &menu_L2_RFBSL, +}; + +// Line2 - RFBSL +const struct menu menu_L2_RFBSL = { + FUNCTION(sx_rfbsl), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_rfbsl), // display function + FUNCTION(update_time), // new display data + &menu_L2_Date, +}; diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/menu.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/menu.h new file mode 100755 index 0000000..befb3f6 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/menu.h @@ -0,0 +1,92 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef MENU_H_ +#define MENU_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +struct menu +{ + // Pointer to direct function (start, stop etc) + void (*sx_function)(u8 line); + // Pointer to sub menu function (change settings, reset counter etc) + void (*mx_function)(u8 line); + // Pointer to display function + void (*display_function)(u8 line, u8 mode); + // Display update trigger + u8 (*display_update)(void); + // Pointer to next menu item + const struct menu *next; +}; + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +// Line1 navigation +extern const struct menu menu_L1_Time; +extern const struct menu menu_L1_Alarm; +extern const struct menu menu_L1_Altitude; +extern const struct menu menu_L1_Temperature; +extern const struct menu menu_L1_Altitude; +extern const struct menu menu_L1_Heartrate; +extern const struct menu menu_L1_Speed; +extern const struct menu menu_L1_Acceleration; + +// Line2 navigation +extern const struct menu menu_L2_Date; +extern const struct menu menu_L2_Stopwatch; +extern const struct menu menu_L2_Battery; +extern const struct menu menu_L2_Rf; +extern const struct menu menu_L2_Ppt; +extern const struct menu menu_L2_Sync; +extern const struct menu menu_L2_CalDist; +extern const struct menu menu_L2_RFBSL; + +// Pointers to current menu item +extern const struct menu *ptrMenu_L1; +extern const struct menu *ptrMenu_L2; + +#endif /*MENU_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfbsl.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfbsl.c new file mode 100755 index 0000000..c32c980 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfbsl.c @@ -0,0 +1,118 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Wireless Update functions. +// ************************************************************************************************* + + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" + +// logic +#include "rfbsl.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" + +// ************************************************************************************************* +// Global Variable section +u8 rfBSL_button_confirmation; + +// ************************************************************************************************* +// @fn sx_rfbsl +// @brief This functions starts the RFBSL +// @param line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void sx_rfbsl(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Exit if SimpliciTI stack is active + if (is_rf()) + return; + + rfBSL_button_confirmation++; + + if (rfBSL_button_confirmation == 2) + { + // Before entering RFBSL clear the LINE1 Symbols + display_symbol(LCD_SYMB_AM, SEG_OFF); + + clear_line(LINE1); + + // Write RAM to indicate we will be downloading the RAM Updater first + display_chars(LCD_SEG_L2_5_0, (u8 *) " RFBSL", SEG_ON); + display_chars(LCD_SEG_L1_3_0, (u8 *) " RAM", SEG_ON); + + // Call RFBSL + CALL_RFSBL(); + } +} + +// ************************************************************************************************* +// @fn display_rfbsl +// @brief RFBSL display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_rfbsl(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (rfBSL_button_confirmation == 0) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " RFBSL", SEG_ON); + } + else if (rfBSL_button_confirmation < 2) + { + // Request one more button press to confirm rfBSL call + display_chars(LCD_SEG_L2_5_0, (u8 *) " CONF", SEG_ON); + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfbsl.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfbsl.h new file mode 100755 index 0000000..364749f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfbsl.h @@ -0,0 +1,55 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RFBSL_H_ +#define RFBSL_H_ + +// ************************************************************************************************* +// Prototypes section +extern void sx_rfbsl(u8 line); +extern void display_rfbsl(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// Entry point of of the Flash Updater in BSL memory +#define CALL_RFSBL() ((void (*)()) 0x1000)() + + +// ************************************************************************************************* +// Global Variable section +extern u8 rfBSL_button_confirmation; + +#endif /*RFBSL_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfsimpliciti.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfsimpliciti.c new file mode 100755 index 0000000..d6ba6a3 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfsimpliciti.c @@ -0,0 +1,642 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// SimpliciTI functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "vti_as.h" +#include "ports.h" +#include "timer.h" +#include "radio.h" + +// logic +#include "acceleration.h" +#include "rfsimpliciti.h" +#include "bluerobin.h" +#include "simpliciti.h" +#include "clock.h" +#include "date.h" +#include "alarm.h" +#include "temperature.h" +#include "vti_ps.h" +#include "altitude.h" + +// ************************************************************************************************* +// Prototypes section +void simpliciti_get_data_callback(void); +void start_simpliciti_tx_only(simpliciti_mode_t mode); +void start_simpliciti_sync(void); + +// ************************************************************************************************* +// Defines section + +// Each packet index requires 2 bytes, so we can have 9 packet indizes in 18 bytes usable payload +#define BM_SYNC_BURST_PACKETS_IN_DATA (9u) + +// ************************************************************************************************* +// Global Variable section +struct RFsmpl sRFsmpl; + +// flag contains status information, trigger to send data and trigger to exit SimpliciTI +unsigned char simpliciti_flag; + +// 4 data bytes to send +unsigned char simpliciti_data[SIMPLICITI_MAX_PAYLOAD_LENGTH]; + +// 4 byte device address overrides SimpliciTI end device address set in "smpl_config.dat" +unsigned char simpliciti_ed_address[4]; + +// Length of data +unsigned char simpliciti_payload_length; + +// 1 = send one or more reply packets, 0 = no need to reply +//unsigned char simpliciti_reply; +unsigned char simpliciti_reply_count; + +// 1 = send packets sequentially from burst_start to burst_end, 2 = send packets addressed by their +// index +u8 burst_mode; + +// Start and end index of packets to send out +u16 burst_start, burst_end; + +// Array containing requested packets +u16 burst_packet[BM_SYNC_BURST_PACKETS_IN_DATA]; + +// Current packet index +u8 burst_packet_index; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn reset_rf +// @brief Reset SimpliciTI data. +// @param none +// @return none +// ************************************************************************************************* +void reset_rf(void) +{ + // No connection + sRFsmpl.mode = SIMPLICITI_OFF; + + // Standard packets are 4 bytes long + simpliciti_payload_length = 4; +} + +// ************************************************************************************************* +// @fn sx_rf +// @brief Start SimpliciTI. Button DOWN connects/disconnects to access point. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_rf(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Turn off the backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + + BUTTONS_IE &= ~BUTTON_BACKLIGHT_PIN; + + // Start SimpliciTI in tx only mode + start_simpliciti_tx_only(SIMPLICITI_ACCELERATION); + + BUTTONS_IE |= BUTTON_BACKLIGHT_PIN; + +} + +// ************************************************************************************************* +// @fn sx_ppt +// @brief Start SimpliciTI. Button DOWN connects/disconnects to access point. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_ppt(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Turn off the backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + + BUTTONS_IE &= ~BUTTON_BACKLIGHT_PIN; + + // Start SimpliciTI in tx only mode + start_simpliciti_tx_only(SIMPLICITI_BUTTONS); + + BUTTONS_IE |= BUTTON_BACKLIGHT_PIN; +} + +// ************************************************************************************************* +// @fn sx_sync +// @brief Start SimpliciTI. Button DOWN connects/disconnects to access point. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_sync(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Turn off the backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + + BUTTONS_IE &= ~BUTTON_BACKLIGHT_PIN; + + // Start SimpliciTI in sync mode + start_simpliciti_sync(); + + BUTTONS_IE |= BUTTON_BACKLIGHT_PIN; +} + +// ************************************************************************************************* +// @fn start_simpliciti_tx_only +// @brief Start SimpliciTI (tx only). +// @param simpliciti_state_t SIMPLICITI_ACCELERATION, SIMPLICITI_BUTTONS +// @return none +// ************************************************************************************************* +void start_simpliciti_tx_only(simpliciti_mode_t mode) +{ + // Display time in line 1 + clear_line(LINE1); + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + display_time(LINE1, DISPLAY_LINE_UPDATE_FULL); + + // Preset simpliciti_data with mode (key or mouse click) and clear other data bytes + if (mode == SIMPLICITI_ACCELERATION) + { + simpliciti_data[0] = SIMPLICITI_MOUSE_EVENTS; + } + else + { + simpliciti_data[0] = SIMPLICITI_KEY_EVENTS; + } + simpliciti_data[1] = 0; + simpliciti_data[2] = 0; + simpliciti_data[3] = 0; + + // Turn on beeper icon to show activity + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + + // Debounce button event + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + + // Prepare radio for RF communication + open_radio(); + + // Set SimpliciTI mode + sRFsmpl.mode = mode; + + // Set SimpliciTI timeout to save battery power + sRFsmpl.timeout = SIMPLICITI_TIMEOUT; + + // Start SimpliciTI stack. Try to link to access point. + // Exit with timeout or by a button DOWN press. + if (simpliciti_link()) + { + if (mode == SIMPLICITI_ACCELERATION) + { + // Start acceleration sensor + as_start(); + } + + // Enter TX only routine. This will transfer button events and/or acceleration data to + // access point. + simpliciti_main_tx_only(); + } + + // Set SimpliciTI state to OFF + sRFsmpl.mode = SIMPLICITI_OFF; + + // Stop acceleration sensor + as_stop(); + + // Powerdown radio + close_radio(); + + // Clear last button events + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + BUTTONS_IFG = 0x00; + button.all_flags = 0; + + // Clear icons + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); + + // Clean up line 1 + clear_line(LINE1); + display_time(LINE1, DISPLAY_LINE_CLEAR); + + // Force full display update + display.flag.full_update = 1; +} + +// ************************************************************************************************* +// @fn display_rf +// @brief SimpliciTI display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_rf(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " ACC", SEG_ON); + } +} + +// ************************************************************************************************* +// @fn display_ppt +// @brief SimpliciTI display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_ppt(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " PPT", SEG_ON); + } +} + +// ************************************************************************************************* +// @fn display_sync +// @brief SimpliciTI display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_sync(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " SYNC", SEG_ON); + } +} + +// ************************************************************************************************* +// @fn is_rf +// @brief Returns TRUE if SimpliciTI receiver is connected. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_rf(void) +{ + return (sRFsmpl.mode != SIMPLICITI_OFF); +} + +// ************************************************************************************************* +// @fn simpliciti_get_ed_data_callback +// @brief Callback function to read end device data from acceleration sensor (if available) +// and trigger sending. Can be also be used to transmit other data at +// different packet rates. +// Please observe the applicable duty limit in the chosen ISM band. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_get_ed_data_callback(void) +{ + static u8 packet_counter = 0; + + if (sRFsmpl.mode == SIMPLICITI_ACCELERATION) + { + // Wait for next sample + Timer0_A4_Delay(CONV_MS_TO_TICKS(5)); + + // Read from sensor if DRDY pin indicates new data (set in PORT2 ISR) + if (request.flag.acceleration_measurement && ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN)) + { + // Clear flag + request.flag.acceleration_measurement = 0; + + // Get data from sensor + as_get_data(sAccel.xyz); + + // Transmit only every 3rd data set (= 33 packets / second) + if (packet_counter++ > 1) + { + // Reset counter + packet_counter = 0; + + // Store XYZ data in SimpliciTI variable + simpliciti_data[1] = sAccel.xyz[0]; + simpliciti_data[2] = sAccel.xyz[1]; + simpliciti_data[3] = sAccel.xyz[2]; + + // Trigger packet sending + simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; + } + } + } + else // transmit only button events + { + // New button event is stored in data + if ((packet_counter == 0) && (simpliciti_data[0] & 0xF0) != 0) + { + packet_counter = 5; + } + + // Send packet several times + if (packet_counter > 0) + { + // Clear button event when sending last packet + if (--packet_counter == 0) + { + simpliciti_data[0] &= ~0xF0; + } + else + { + // Trigger packet sending in regular intervals + Timer0_A4_Delay(CONV_MS_TO_TICKS(30)); + simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; + } + } + else + { + // Wait in LPM3 for next button press + _BIS_SR(LPM3_bits + GIE); + __no_operation(); + } + } + + // Update clock every 1/1 second + if (display.flag.update_time) + { + display_time(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + display.flag.update_time = 0; + + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; + } +} + +// ************************************************************************************************* +// @fn start_simpliciti_sync +// @brief Start SimpliciTI (sync mode). +// @param none +// @return none +// ************************************************************************************************* +void start_simpliciti_sync(void) +{ + // Clear LINE1 + clear_line(LINE1); + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + + // Stop acceleration sensor + as_stop(); + + // Get updated altitude + start_altitude_measurement(); + stop_altitude_measurement(); + + // Get updated temperature + temperature_measurement(FILTER_OFF); + + // Turn on beeper icon to show activity + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + + // Debounce button event + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + + // Prepare radio for RF communication + open_radio(); + + // Set SimpliciTI mode + sRFsmpl.mode = SIMPLICITI_SYNC; + + // Set SimpliciTI timeout to save battery power + sRFsmpl.timeout = SIMPLICITI_TIMEOUT; + + // Start SimpliciTI stack. Try to link to access point. + // Exit with timeout or by a button DOWN press. + if (simpliciti_link()) + { + // Enter sync routine. This will send ready-to-receive packets at regular intervals to the + // access point. + // The access point replies with a command (NOP if no other command is set) + simpliciti_main_sync(); + } + + // Set SimpliciTI state to OFF + sRFsmpl.mode = SIMPLICITI_OFF; + + // Powerdown radio + close_radio(); + + // Clear last button events + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + BUTTONS_IFG = 0x00; + button.all_flags = 0; + + // Clear icons + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); + + // Force full display update + display.flag.full_update = 1; +} + +// ************************************************************************************************* +// @fn simpliciti_sync_decode_ap_cmd_callback +// @brief For SYNC mode only: Decode command from access point and trigger actions. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_sync_decode_ap_cmd_callback(void) +{ + u8 i; + s16 t1, offset; + + // Default behaviour is to send no reply packets + simpliciti_reply_count = 0; + + switch (simpliciti_data[0]) + { + case SYNC_AP_CMD_NOP: + break; + + case SYNC_AP_CMD_GET_STATUS: // Send watch parameters + simpliciti_data[0] = SYNC_ED_TYPE_STATUS; + // Send single reply packet + simpliciti_reply_count = 1; + break; + + case SYNC_AP_CMD_SET_WATCH: // Set watch parameters + sys.flag.use_metric_units = (simpliciti_data[1] >> 7) & 0x01; + sTime.hour = simpliciti_data[1] & 0x7F; + sTime.minute = simpliciti_data[2]; + sTime.second = simpliciti_data[3]; + sDate.year = (simpliciti_data[4] << 8) + simpliciti_data[5]; + sDate.month = simpliciti_data[6]; + sDate.day = simpliciti_data[7]; + sAlarm.hour = simpliciti_data[8]; + sAlarm.minute = simpliciti_data[9]; + // Set temperature and temperature offset + t1 = (s16) ((simpliciti_data[10] << 8) + simpliciti_data[11]); + offset = t1 - (sTemp.degrees - sTemp.offset); + sTemp.offset = offset; + sTemp.degrees = t1; + // Set altitude + sAlt.altitude = (s16) ((simpliciti_data[12] << 8) + simpliciti_data[13]); + update_pressure_table(sAlt.altitude, sAlt.pressure, sAlt.temperature); + + display_chars(LCD_SEG_L2_5_0, (u8 *) " DONE", SEG_ON); + sRFsmpl.display_sync_done = 1; + break; + + case SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_1: + // Send sequential packets out in a burst + simpliciti_data[0] = SYNC_ED_TYPE_MEMORY; + // Get burst start and end packet + burst_start = (simpliciti_data[1] << 8) + simpliciti_data[2]; + burst_end = (simpliciti_data[3] << 8) + simpliciti_data[4]; + // Set burst mode + burst_mode = 1; + // Number of packets to send + simpliciti_reply_count = burst_end - burst_start; + break; + + case SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_2: + // Send specified packets out in a burst + simpliciti_data[0] = SYNC_ED_TYPE_MEMORY; + // Store the requested packets + for (i = 0; i < BM_SYNC_BURST_PACKETS_IN_DATA; i++) + { + burst_packet[i] = (simpliciti_data[i * 2 + 1] << 8) + simpliciti_data[i * 2 + 2]; + } + // Set burst mode + burst_mode = 2; + // Number of packets to send + simpliciti_reply_count = BM_SYNC_BURST_PACKETS_IN_DATA; + break; + + case SYNC_AP_CMD_ERASE_MEMORY: // Erase data logger memory + break; + + case SYNC_AP_CMD_EXIT: // Exit sync mode + simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; + break; + } +} + +// ************************************************************************************************* +// @fn simpliciti_sync_get_data_callback +// @brief For SYNC mode only: Access point has requested data. Copy this data into the TX +// buffer now. +// @param u16 index Index used for memory requests +// @return none +// ************************************************************************************************* +void simpliciti_sync_get_data_callback(unsigned int index) +{ + u8 i; + + // simpliciti_data[0] contains data type and needs to be returned to AP + switch (simpliciti_data[0]) + { + case SYNC_ED_TYPE_STATUS: // Assemble status packet + simpliciti_data[1] = (sys.flag.use_metric_units << 7) | (sTime.hour & 0x7F); + simpliciti_data[2] = sTime.minute; + simpliciti_data[3] = sTime.second; + simpliciti_data[4] = sDate.year >> 8; + simpliciti_data[5] = sDate.year & 0xFF; + simpliciti_data[6] = sDate.month; + simpliciti_data[7] = sDate.day; + simpliciti_data[8] = sAlarm.hour; + simpliciti_data[9] = sAlarm.minute; + simpliciti_data[10] = sTemp.degrees >> 8; + simpliciti_data[11] = sTemp.degrees & 0xFF; + simpliciti_data[12] = sAlt.altitude >> 8; + simpliciti_data[13] = sAlt.altitude & 0xFF; + break; + + case SYNC_ED_TYPE_MEMORY: + if (burst_mode == 1) + { + // Set burst packet address + simpliciti_data[1] = ((burst_start + index) >> 8) & 0xFF; + simpliciti_data[2] = (burst_start + index) & 0xFF; + // Assemble payload + for (i = 3; i < BM_SYNC_DATA_LENGTH; i++) + simpliciti_data[i] = index; + } + else if (burst_mode == 2) + { + // Set burst packet address + simpliciti_data[1] = (burst_packet[index] >> 8) & 0xFF; + simpliciti_data[2] = burst_packet[index] & 0xFF; + // Assemble payload + for (i = 3; i < BM_SYNC_DATA_LENGTH; i++) + simpliciti_data[i] = index; + } + break; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfsimpliciti.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfsimpliciti.h new file mode 100755 index 0000000..cd02f41 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/rfsimpliciti.h @@ -0,0 +1,98 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RFSIMPLICITI_H_ +#define RFSIMPLICITI_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_rf(void); +extern void sx_rf(u8 line); +extern void sx_ppt(u8 line); +extern void sx_sync(u8 line); +extern void display_rf(u8 line, u8 update); +extern void display_ppt(u8 line, u8 update); +extern void display_sync(u8 line, u8 update); +extern void send_smpl_data(u16 data); +extern u8 is_rf(void); + +// ************************************************************************************************* +// Defines section + +// SimpliciTI connection states +typedef enum +{ + SIMPLICITI_OFF = 0, // Not connected + SIMPLICITI_ACCELERATION, // Transmitting acceleration data and button events + SIMPLICITI_BUTTONS, // Transmitting button events + SIMPLICITI_SYNC // Syncing +} simpliciti_mode_t; + +// Stop SimpliciTI transmission after 60 minutes to save power +#define SIMPLICITI_TIMEOUT (60 * 60u) + +// Button flags for SimpliciTI data +#define SIMPLICITI_BUTTON_STAR (0x10) +#define SIMPLICITI_BUTTON_NUM (0x20) +#define SIMPLICITI_BUTTON_UP (0x30) + +// SimpliciTI mode flag +#define SIMPLICITI_MOUSE_EVENTS (0x01) +#define SIMPLICITI_KEY_EVENTS (0x02) + +// ************************************************************************************************* +// Global Variable section +struct RFsmpl +{ + // SIMPLICITI_OFF, SIMPLICITI_ACCELERATION, SIMPLICITI_BUTTONS + simpliciti_mode_t mode; + + // Timeout until SimpliciTI transmission is automatically stopped + u16 timeout; + + // Variable to display + u8 display_sync_done; +}; +extern struct RFsmpl sRFsmpl; + +extern unsigned char simpliciti_flag; + +// ************************************************************************************************* +// Extern section + +#endif /*RFSIMPLICITI_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/stopwatch.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/stopwatch.c new file mode 100755 index 0000000..ca61932 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/stopwatch.c @@ -0,0 +1,443 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Stopwatch functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" +#include + +// driver +#include "stopwatch.h" +#include "ports.h" +#include "display.h" +#include "timer.h" + +// logic +#include "menu.h" + +// ************************************************************************************************* +// Prototypes section +void start_stopwatch(void); +void stop_stopwatch(void); +void reset_stopwatch(void); +void stopwatch_tick(void); +void update_stopwatch_timer(void); +void mx_stopwatch(u8 line); +void sx_stopwatch(u8 line); +void display_stopwatch(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct stopwatch sStopwatch; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn update_stopwatch_timer +// @brief Set new compare time for next 1/1Hz or 1/100Hz interrupt. Takes care for exact 1 +// second timing. +// @param ticks (1 tick = 1/32768 sec) +// @return none +// ************************************************************************************************* +void update_stopwatch_timer(void) +{ + u16 value; + + // Load CCR register with next capture time + if (sStopwatch.viewStyle == DISPLAY_DEFAULT_VIEW) + { + // Timer interrupts occur every 32768/100 = 328 ACLK + // --> stopwatch runs too slow (1 sec nominal != 100 interupts * 328 ACLK = 32800 ACLK = + // 1.00098 sec) + // --> ideally correct timer value every 10 ticks by (32768 - 32800)/10 = 3.2 + // --> correct timer value every 10Hz by 3, + // --> correct timer value every 1Hz correct by 5 + value = TA0CCR2 + STOPWATCH_100HZ_TICK; + + if (sStopwatch.swtIs1Hz) + { + value -= 5; + sStopwatch.swtIs1Hz = 0; + sStopwatch.swtIs10Hz = 0; + } + else if (sStopwatch.swtIs10Hz) + { + value -= 3; + sStopwatch.swtIs10Hz = 0; + } + } + else // Alternative view + { + // Timer interrupts occur every 32768/1 = 32768 ACLK + value = TA0CCR2 + STOPWATCH_1HZ_TICK; + } + + // Update CCR + TA0CCR2 = value; +} + +// ************************************************************************************************* +// @fn stopwatch_tick +// @brief Called by 1/100Hz interrupt handler. +// Increases stopwatch counter and triggers display update. +// @param none +// @return none +// ************************************************************************************************* +void stopwatch_tick(void) +{ + static u8 delay = 0; + + // Default view (< 20 minutes): display and count MM:SS:hh + if (sStopwatch.viewStyle == DISPLAY_DEFAULT_VIEW) + { + // Add 1/100 sec + sStopwatch.time[7]++; + + // Draw flag minimizes display update activity + // + // swt.drawFlag = 1: second L + // swt.drawFlag = 2: second H/L + // swt.drawFlag = 3: minutes L, second H/L + // swt.drawFlag = 4: minutes H/L, second H/L + // swt.drawFlag = 5: hours L, minutes H/L, second H/L + // swt.drawFlag = 6: hours H/L, minutes H/L, second H/L + // swt.drawFlag = 7: 1/10 sec, 1/100 sec + // swt.drawFlag = 8: 1/100 sec (every 17/100 sec to reduce display draw activity) + if (delay++ > 17) + { + sStopwatch.drawFlag = 8; + delay = 0; + } + + // Add 1/10 sec + if (sStopwatch.time[7] == 0x3A) + { + sStopwatch.time[7] = '0'; + sStopwatch.time[6]++; + + // 1/10Hz trigger + sStopwatch.swtIs10Hz = 1; + + // Update draw flag + sStopwatch.drawFlag = 7; + } + } + else // Alternative view (20 minutes .. 20 hours): display and count + // HH:MM:SS + { + // Just add 1 second + sStopwatch.time[6] = 0x3A; + } + + // Second overflow? + if (sStopwatch.time[6] == 0x3A) + { + // Reset draw flag + sStopwatch.drawFlag = 1; + + // 1Hz trigger + sStopwatch.swtIs1Hz = 1; + + // Add data + sStopwatch.time[6] = '0'; + sStopwatch.time[5]++; // second L (0 - 9) + if (sStopwatch.time[5] == 0x3A) + { + sStopwatch.drawFlag++; // 2 + sStopwatch.time[5] = '0'; + sStopwatch.time[4]++; // second H (0 - 5) + if (sStopwatch.time[4] == '6') + { + sStopwatch.drawFlag++; // 3 + sStopwatch.time[4] = '0'; + sStopwatch.time[3]++; // minutes L (0 - 9) + if (sStopwatch.time[3] == 0x3A) + { + sStopwatch.drawFlag++; // 4 + sStopwatch.time[3] = '0'; + sStopwatch.time[2]++; // minutes H (0 - 5) + if (sStopwatch.time[2] == '2') + { + // SWT display changes from MM:SS:hh to HH:MM:SS when reaching 20 minutes + sStopwatch.viewStyle = DISPLAY_ALTERNATIVE_VIEW; + display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_FULL); + + } + else if (sStopwatch.time[2] == '6') + { + sStopwatch.drawFlag++; // 5 + sStopwatch.time[2] = '0'; + sStopwatch.time[1]++; // hours L (0-9) + + if (sStopwatch.time[1] == 0x3A) + { + sStopwatch.drawFlag++; // 6 + sStopwatch.time[1] = '0'; + sStopwatch.time[0]++; // hours H (0-1) + + if (sStopwatch.time[0] == '2') + { + // When reaching 20 hours, start over + reset_stopwatch(); + sStopwatch.state = STOPWATCH_RUN; + display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_FULL); + } + } + } + } + } + } + } + + // Always set display update flag + display.flag.update_stopwatch = 1; +} + +// ************************************************************************************************* +// @fn reset_stopwatch +// @brief Clears stopwatch counter and sets stopwatch state to off. +// @param none +// @return none +// ************************************************************************************************* +void reset_stopwatch(void) +{ + // Clear counter + memcpy(sStopwatch.time, "00000000", sizeof(sStopwatch.time)); + + // Clear trigger + sStopwatch.swtIs10Hz = 0; // 1/10Hz trigger + sStopwatch.swtIs1Hz = 0; // 1Hz trigger + + // Init stopwatch state 'Off' + sStopwatch.state = STOPWATCH_STOP; + + // Default display style is MM:SS:HH + sStopwatch.viewStyle = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn is_stopwatch +// @brief Is stopwatch operating and visible? +// @param none +// @return 1=STOPWATCH_RUN, 0=other states +// ************************************************************************************************* +u8 is_stopwatch(void) +{ + return ((sStopwatch.state == STOPWATCH_RUN) && (ptrMenu_L2 == &menu_L2_Stopwatch)); +} + +// ************************************************************************************************* +// @fn start_stopwatch +// @brief Starts stopwatch timer interrupt and sets stopwatch state to on. +// @param none +// @return none +// ************************************************************************************************* +void start_stopwatch(void) +{ + // Set stopwatch run flag + sStopwatch.state = STOPWATCH_RUN; + + // Init CCR register with current time + TA0CCR2 = TA0R; + + // Load CCR register with next capture time + update_stopwatch_timer(); + + // Reset IRQ flag + TA0CCTL2 &= ~CCIFG; + + // Enable timer interrupt + TA0CCTL2 |= CCIE; + + // Set stopwatch icon + display_symbol(LCD_ICON_STOPWATCH, SEG_ON); +} + +// ************************************************************************************************* +// @fn stop_stopwatch +// @brief Stops stopwatch timer interrupt and sets stopwatch state to off. +// Does not reset stopwatch count. +// @param none +// @return none +// ************************************************************************************************* +void stop_stopwatch(void) +{ + // Clear timer interrupt enable + TA0CCTL2 &= ~CCIE; + + // Clear stopwatch run flag + sStopwatch.state = STOPWATCH_STOP; + + // Clear stopwatch icon + display_symbol(LCD_ICON_STOPWATCH, SEG_OFF); + + // Call draw routine immediately + display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_FULL); +} + +// ************************************************************************************************* +// @fn mx_stopwatch +// @brief Stopwatch set routine. Mx stops stopwatch and resets count. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void mx_stopwatch(u8 line) +{ + // Stop stopwatch + stop_stopwatch(); + + // Reset stopwatch count + reset_stopwatch(); + + // Display "00:00:00" + display_stopwatch(line, DISPLAY_LINE_UPDATE_FULL); +} + +// ************************************************************************************************* +// @fn sx_stopwatch +// @brief Stopwatch direct function. Button DOWN starts/stops stopwatch, but does not reset +// count. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_stopwatch(u8 line) +{ + // DOWN: RUN, STOP + if (button.flag.down) + { + if (sStopwatch.state == STOPWATCH_STOP) + { + // (Re)start stopwatch + start_stopwatch(); + } + else + { + // Stop stopwatch + stop_stopwatch(); + } + + } +} + +// ************************************************************************************************* +// @fn display_stopwatch +// @brief Stopwatch user routine. Sx starts/stops stopwatch, but does not reset count. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_PARTIAL, +// DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_stopwatch(u8 line, u8 update) +{ + // Partial line update only + if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + if (display.flag.update_stopwatch) + { + if (sStopwatch.viewStyle == DISPLAY_DEFAULT_VIEW) + { + // Display MM:SS:hh + + // Check draw flag to minimize workload + if (sStopwatch.drawFlag != 0) + { + switch (sStopwatch.drawFlag) + { + case 4: + display_char(LCD_SEG_L2_5, sStopwatch.time[2], SEG_ON); + case 3: + display_char(LCD_SEG_L2_4, sStopwatch.time[3], SEG_ON); + case 2: + display_char(LCD_SEG_L2_3, sStopwatch.time[4], SEG_ON); + case 1: + display_char(LCD_SEG_L2_2, sStopwatch.time[5], SEG_ON); + case 7: + display_char(LCD_SEG_L2_1, sStopwatch.time[6], SEG_ON); + case 8: + display_char(LCD_SEG_L2_0, sStopwatch.time[7], SEG_ON); + } + } + } + else // DISPLAY_ALTERNATIVE_VIEW + { + // Display HH:MM:SS + switch (sStopwatch.drawFlag) + { + case 6: + display_char(LCD_SEG_L2_5, sStopwatch.time[0], SEG_ON); + case 5: + display_char(LCD_SEG_L2_4, sStopwatch.time[1], SEG_ON); + case 4: + display_char(LCD_SEG_L2_3, sStopwatch.time[2], SEG_ON); + case 3: + display_char(LCD_SEG_L2_2, sStopwatch.time[3], SEG_ON); + case 2: + display_char(LCD_SEG_L2_1, sStopwatch.time[4], SEG_ON); + case 1: + display_char(LCD_SEG_L2_0, sStopwatch.time[5], SEG_ON); + } + } + } + } + // Redraw whole line + else if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sStopwatch.viewStyle == DISPLAY_DEFAULT_VIEW) + { + // Display MM:SS:hh + display_chars(LCD_SEG_L2_5_0, sStopwatch.time + 2, SEG_ON); + } + else // DISPLAY_ALTERNATIVE_VIEW + { + // Display HH:MM:SS + display_chars(LCD_SEG_L2_5_0, sStopwatch.time, SEG_ON); + } + display_symbol(LCD_SEG_L2_COL1, SEG_ON); + display_symbol(LCD_SEG_L2_COL0, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Clean up symbols when leaving function + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/stopwatch.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/stopwatch.h new file mode 100755 index 0000000..3676491 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/stopwatch.h @@ -0,0 +1,89 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef STOPWATCH_H_ +#define STOPWATCH_H_ + +// ************************************************************************************************* +// Include section +#include + +// ************************************************************************************************* +// Prototypes section +extern void start_stopwatch(void); +extern void stop_stopwatch(void); +extern void reset_stopwatch(void); +extern u8 is_stopwatch(void); +extern void stopwatch_tick(void); +extern void update_stopwatch_timer(void); +extern void mx_stopwatch(u8 line); +extern void sx_stopwatch(u8 line); +extern void display_stopwatch(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section +#define STOPWATCH_1HZ_TICK (32768 / 1) +#define STOPWATCH_100HZ_TICK (32768 / 100) +#define STOPWATCH_STOP (0u) +#define STOPWATCH_RUN (1u) +#define STOPWATCH_HIDE (2u) + +// ************************************************************************************************* +// Global Variable section +struct stopwatch +{ + u8 state; + u8 drawFlag; + u8 swtIs1Hz; + u8 swtIs10Hz; + + u8 time[8]; // time[0] hour H + // time[1] hour L + // time[2] minute H + // time[3] minute L + // time[4] second H + // time[5] second L + // time[6] 1/10 sec + // time[7] 1/100 sec + + // Display style + u8 viewStyle; +}; +extern struct stopwatch sStopwatch; + +// ************************************************************************************************* +// Extern section + +#endif /*STOPWATCH_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/temperature.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/temperature.c new file mode 100755 index 0000000..8da9472 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/temperature.c @@ -0,0 +1,332 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Temperature measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "temperature.h" +#include "ports.h" +#include "display.h" +#include "adc12.h" +#include "timer.h" + +// logic +#include "user.h" + +// ************************************************************************************************* +// Prototypes section +u8 is_temp_measurement(void); +s16 convert_C_to_F(s16 value); +s16 convert_F_to_C(s16 value); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct temp sTemp; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_temp_measurement +// @brief Reset temperature measurement module. +// @param none +// @return none +// ************************************************************************************************* +void reset_temp_measurement(void) +{ + // Set flag to off + sTemp.state = MENU_ITEM_NOT_VISIBLE; + + // Perform one temperature measurements with disabled filter + temperature_measurement(FILTER_OFF); +} + +// ************************************************************************************************* +// @fn temperature_measurement +// @brief Init ADC12. Do single conversion of temperature sensor voltage. Turn off ADC12. +// @param none +// @return none +// ************************************************************************************************* +void temperature_measurement(u8 filter) +{ + u16 adc_result; + volatile s32 temperature; + + // Convert internal temperature diode voltage + adc_result = adc12_single_conversion(REFVSEL_0, ADC12SHT0_8, ADC12INCH_10); + + // Convert ADC value to "xx.x °C" + // Temperature in Celsius + // ((A10/4096*1500mV) - 680mV)*(1/2.25mV) = (A10/4096*667) - 302 + // = (A10 - 1855) * (667 / 4096) + temperature = (((s32) ((s32) adc_result - 1855)) * 667 * 10) / 4096; + + // Add temperature offset + temperature += sTemp.offset; + + // Store measured temperature + if (filter == FILTER_ON) + { + // Change temperature in 0.1° steps towards measured value + if (temperature > sTemp.degrees) + sTemp.degrees += 1; + else if (temperature < sTemp.degrees) + sTemp.degrees -= 1; + } + else + { + // Override filter + sTemp.degrees = (s16) temperature; + } + + // New data is available --> do display update + display.flag.update_temperature = 1; +} + +// ************************************************************************************************* +// @fn convert_C_to_F +// @brief Convert °C to °F +// @param s16 value Temperature in °C +// @return s16 Temperature in °F +// ************************************************************************************************* +s16 convert_C_to_F(s16 value) +{ + s16 DegF; + + // Celsius in Fahrenheit = (( TCelsius × 9 ) / 5 ) + 32 + DegF = ((value * 9 * 10) / 5 / 10) + 32 * 10; + + return (DegF); +} + +// ************************************************************************************************* +// @fn convert_F_to_C +// @brief Convert °F to °C +// @param s16 value Temperature in 2.1 °F +// @return s16 Temperature in 2.1 °C +// ************************************************************************************************* +s16 convert_F_to_C(s16 value) +{ + s16 DegC; + + // TCelsius =( TFahrenheit - 32 ) × 5 / 9 + DegC = (((value - 320) * 5)) / 9; + + return (DegC); +} + +// ************************************************************************************************* +// @fn is_temp_measurement +// @brief Returns TRUE if temperature measurement is enabled. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_temp_measurement(void) +{ + return (sTemp.state == MENU_ITEM_VISIBLE); +} + +// ************************************************************************************************* +// @fn mx_temperature +// @brief Mx button handler to set the temperature offset. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void mx_temperature(u8 line) +{ + s32 temperature; + s16 temperature0; + volatile s16 temperature1; + volatile s16 offset; + + // Clear display + clear_display_all(); + + // When using English units, convert internal °C to °F before handing over value to set_value + // function + if (!sys.flag.use_metric_units) + { + // Convert global variable to local variable + temperature = convert_C_to_F(sTemp.degrees); + temperature0 = sTemp.degrees; + } + else + { + // Convert global variable to local variable + temperature = sTemp.degrees; + temperature0 = temperature; + } + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout: exit without saving + if (sys.flag.idle_timeout) + break; + + // Button STAR (short): save, then exit + if (button.flag.star) + { + // For English units, convert set °F to °C + if (!sys.flag.use_metric_units) + { + temperature1 = convert_F_to_C(temperature); + } + else + { + temperature1 = temperature; + } + + // New offset is difference between old and new value + offset = temperature1 - temperature0; + sTemp.offset += offset; + + // Force filter to new value + sTemp.degrees = temperature1; + + // Set display update flag + display.flag.line1_full_update = 1; + + break; + } + + // Display °C or °F depending on unit system + if (sys.flag.use_metric_units) + display_char(LCD_SEG_L1_0, 'C', SEG_ON); + else + display_char(LCD_SEG_L1_0, 'F', SEG_ON); + display_symbol(LCD_SEG_L1_DP1, SEG_ON); + display_symbol(LCD_UNIT_L1_DEGREE, SEG_ON); + + // Set current temperature - offset is set when leaving function + set_value(&temperature, 3, 1, -999, 999, SETVALUE_DISPLAY_VALUE + SETVALUE_DISPLAY_ARROWS, + LCD_SEG_L1_3_1, + display_value); + } + + // Clear button flags + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn display_temperature +// @brief Common display routine for metric and English units. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_temperature(u8 line, u8 update) +{ + u8 *str; + s16 temperature; + + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Menu item is visible + sTemp.state = MENU_ITEM_VISIBLE; + + // Display °C / °F + display_symbol(LCD_SEG_L1_DP1, SEG_ON); + display_symbol(LCD_UNIT_L1_DEGREE, SEG_ON); + if (sys.flag.use_metric_units) + display_char(LCD_SEG_L1_0, 'C', SEG_ON); + else + display_char(LCD_SEG_L1_0, 'F', SEG_ON); + + // Perform one temperature measurement with disabled filter + temperature_measurement(FILTER_OFF); + + // Display temperature + display_temperature(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + // When using English units, convert °C to °F (temp*1.8+32) + if (!sys.flag.use_metric_units) + { + temperature = convert_C_to_F(sTemp.degrees); + } + else + { + temperature = sTemp.degrees; + } + + // Indicate temperature sign through arrow up/down icon + if (temperature < 0) + { + // Convert negative to positive number + temperature = ~temperature; + temperature += 1; + + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + else // Temperature is >= 0 + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + + // Limit min/max temperature to +/- 99.9 °C / °F + if (temperature > 999) + temperature = 999; + + // Display result in xx.x format + str = int_to_array(temperature, 3, 1); + display_chars(LCD_SEG_L1_3_1, str, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Menu item is not visible + sTemp.state = MENU_ITEM_NOT_VISIBLE; + + // Clean up function-specific segments before leaving function + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + display_symbol(LCD_UNIT_L1_DEGREE, SEG_OFF); + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/temperature.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/temperature.h new file mode 100755 index 0000000..68a2138 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/temperature.h @@ -0,0 +1,70 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef TEMPERATURE_H_ +#define TEMPERATURE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// internal functions +extern void reset_temp_measurement(void); +extern u8 is_temp_measurement(void); +extern void temperature_measurement(u8 filter); + +// menu functions +extern void mx_temperature(u8 line); +extern void display_temperature(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct temp +{ + menu_t state; // MENU_ITEM_NOT_VISIBLE, MENU_ITEM_VISIBLE + s16 degrees; // Temperature (°C) in 2.1 format + s16 offset; // User set calibration value (°C) in 2.1 format +}; +extern struct temp sTemp; + +// ************************************************************************************************* +// Extern section + +#endif /*TEMPERATURE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/test.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/test.c new file mode 100755 index 0000000..3ef6dcd --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/test.c @@ -0,0 +1,296 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Test functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "vti_as.h" +#include "vti_ps.h" +#include "ports.h" +#include "timer.h" + +// logic +#include "acceleration.h" +#include "altitude.h" +#include "temperature.h" +#include "bluerobin.h" +#include "test.h" + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Prototype section + +// ************************************************************************************************* +// @fn test_mode +// @brief Manual test mode. Activated by holding buttons STAR and UP simultaneously. +// Cancelled by any other button press. +// @param none +// @return none +// ************************************************************************************************* +void test_mode(void) +{ + u8 test_step, start_next_test; + u8 *str; + u8 i; + + // Disable timer - no need for a clock tick + Timer0_Stop(); + + // Disable LCD charge pump while in standby mode + // This reduces current consumption by ca. 5µA to ca. 10µA + LCDBVCTL = 0; + + // Show welcome screen + display_chars(LCD_SEG_L1_3_0, (u8 *) "0430", SEG_ON); + display_chars(LCD_SEG_L2_4_0, (u8 *) "CC430", SEG_ON); + display_symbol(LCD_SEG_L1_COL, SEG_ON); + display_symbol(LCD_ICON_HEART, SEG_ON); + display_symbol(LCD_ICON_STOPWATCH, SEG_ON); + display_symbol(LCD_ICON_RECORD, SEG_ON); + display_symbol(LCD_ICON_ALARM, SEG_ON); + display_symbol(LCD_ICON_BEEPER1, SEG_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON); + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + display_symbol(LCD_SYMB_AM, SEG_ON); + + // Hold watchdog + WDTCTL = WDTPW + WDTHOLD; + + // Wait for button press + _BIS_SR(LPM3_bits + GIE); + __no_operation(); + + // Clear display + display_all_off(); + +#ifdef USE_LCD_CHARGE_PUMP + // Charge pump voltage generated internally, internal bias (V2-V4) generation + // This ensures that the contrast and LCD control is constant for the whole battery lifetime + LCDBVCTL = LCDCPEN | VLCD_2_72; +#endif + + // Renenable timer + Timer0_Start(); + + // Debounce button press + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + + while (1) + { + // Check button event + if (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED) + { + // Start with test #0 + test_step = 0; + start_next_test = 1; + while (1) + { + if (start_next_test) + { + // Clean up previous test display + display_all_off(); + + start_next_test = 0; + + switch (test_step) + { + case 0: // All LCD segments on + display_all_on(); + // Wait until buttons are off + while (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED) ; + break; + case 1: // Altitude measurement + display_altitude(LINE1, DISPLAY_LINE_UPDATE_FULL); + for (i = 0; i < 2; i++) + { + while ((PS_INT_IN & PS_INT_PIN) == 0) ; + do_altitude_measurement(FILTER_OFF); + display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + stop_altitude_measurement(); + break; + case 2: // Temperature measurement + display_temperature(LINE1, DISPLAY_LINE_UPDATE_FULL); + for (i = 0; i < 4; i++) + { + Timer0_A4_Delay(CONV_MS_TO_TICKS(250)); + temperature_measurement(FILTER_OFF); + display_temperature(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + break; + case 3: // Acceleration measurement + as_start(); + for (i = 0; i < 4; i++) + { + Timer0_A4_Delay(CONV_MS_TO_TICKS(250)); + as_get_data(sAccel.xyz); + str = int_to_array(sAccel.xyz[0], 3, 0); + display_chars(LCD_SEG_L1_2_0, str, SEG_ON); + str = int_to_array(sAccel.xyz[2], 3, 0); + display_chars(LCD_SEG_L2_2_0, str, SEG_ON); + } + as_stop(); + break; + case 4: // BlueRobin test + button.flag.up = 1; + sx_bluerobin(LINE1); + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + get_bluerobin_data(); + display_heartrate(LINE1, DISPLAY_LINE_UPDATE_FULL); + stop_bluerobin(); + break; + } + + // Debounce button + Timer0_A4_Delay(CONV_MS_TO_TICKS(200)); + } + + // Check button event + if (BUTTON_STAR_IS_PRESSED) + { + test_step = 1; + start_next_test = 1; + } + else if (BUTTON_NUM_IS_PRESSED) + { + test_step = 2; + start_next_test = 1; + } + else if (BUTTON_UP_IS_PRESSED) + { + test_step = 3; + start_next_test = 1; + } + else if (BUTTON_DOWN_IS_PRESSED) + { + test_step = 4; + start_next_test = 1; + } + else if (BUTTON_BACKLIGHT_IS_PRESSED) + { + // Wait until button has been released (avoid restart) + while (BUTTON_BACKLIGHT_IS_PRESSED) ; + + // Disable LCD and LCD charge pump + LCDBCTL0 &= ~BIT0; + LCDBVCTL = 0; + + // Debounce button press + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); + + // Disable timer - no need for a clock tick + Timer0_Stop(); + + // Hold watchdog + WDTCTL = WDTPW + WDTHOLD; + + // Sleep until button is pressed (ca. 4µA current consumption) + _BIS_SR(LPM4_bits + GIE); + __no_operation(); + + // Force watchdog reset for a clean restart + WDTCTL = 1; + } + +#ifdef USE_WATCHDOG + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; +#endif + // To LPM3 + _BIS_SR(LPM3_bits + GIE); + __no_operation(); + } + } + else + { + // Debounce button + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + button.all_flags = 0; + + // Turn off backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + break; + } + } +} + +// ************************************************************************************************* +// @fn display_all_on +// @brief Turns on all LCD segments +// @param none +// @return none +// ************************************************************************************************* +void display_all_on(void) +{ + u8 *lcdptr = (u8 *) 0x0A20; + u8 i; + + for (i = 1; i <= 12; i++) + { + *lcdptr = 0xFF; + lcdptr++; + } +} + +// ************************************************************************************************* +// @fn display_all_off +// @brief Turns off all LCD segments +// @param none +// @return none +// ************************************************************************************************* +void display_all_off(void) +{ + u8 *lcdptr = (u8 *) 0x0A20; + u8 i; + + for (i = 1; i <= 12; i++) + { + *lcdptr = 0x00; + lcdptr++; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/test.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/test.h new file mode 100755 index 0000000..469426e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/test.h @@ -0,0 +1,47 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Test functions. +// ************************************************************************************************* + +#ifndef TEST_H_ +#define TEST_H_ + +// ************************************************************************************************* +// Extern section +extern void test_mode(void); +extern void display_all_on(void); +extern void display_all_off(void); + +#endif /*TEST_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/user.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/user.c new file mode 100755 index 0000000..3207cbf --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/user.c @@ -0,0 +1,291 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Several user functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "buzzer.h" +#include "ports.h" + +// logic +#include "menu.h" +#include "date.h" +#include "clock.h" +#include "user.h" +#include "stopwatch.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section +extern void idle_loop(void); + +// ************************************************************************************************* +// @fn dummy +// @brief Dummy direct function. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void dummy(u8 line) +{ +} + +// ************************************************************************************************* +// @fn set_value +// @brief Generic value setting routine +// @param s32 * value Pointer to value to +// set +// u8digits +// Number of digits +// u8 blanks +// Number of whitespaces before first valid +// digit +// s32 limitLow Lower limit +// of value +// s32 limitHigh Upper limit +// of value +// u16 mode +// u8 segments +// Segments where value should be drawn +// fptr_setValue_display_function1 Value-specific display +// routine +// @return none +// ************************************************************************************************* +void set_value(s32 * value, u8 digits, u8 blanks, s32 limitLow, s32 limitHigh, u16 mode, + u8 segments, + void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, + u8 blanks)) +{ + u8 update; + s16 stepValue = 1; + u8 doRound = 0; + u8 stopwatch_state; + u32 val; + + // Clear button flags + button.all_flags = 0; + + // Clear blink memory + clear_blink_mem(); + + // For safety only - buzzer on/off and button_repeat share same IRQ + stop_buzzer(); + + // Disable stopwatch display update while function is active + stopwatch_state = sStopwatch.state; + sStopwatch.state = STOPWATCH_HIDE; + + // Init step size and repeat counter + sButton.repeats = 0; + + // Initial display update + update = 1; + + // Turn on 200ms button repeat function + button_repeat_on(200); + + // Start blinking with with 2Hz + set_blink_rate(BIT6 + BIT5); + + // Value set loop + while (1) + { + // Idle timeout: exit function + if (sys.flag.idle_timeout) + break; + + // Button STAR (short) button: exit function + if (button.flag.star) + break; + + // NUM button: exit function and goto to next value (if available) + if (button.flag.num) + { + if ((mode & SETVALUE_NEXT_VALUE) == SETVALUE_NEXT_VALUE) + break; + } + + // UP button: increase value + if (button.flag.up) + { + // Increase value + *value = *value + stepValue; + + // Check value limits + if (*value > limitHigh) + { + // Check if value can roll over, else stick to limit + if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) + *value = limitLow; + else + *value = limitHigh; + + // Reset step size to default + stepValue = 1; + } + + // Trigger display update + update = 1; + + // Clear button flag + button.flag.up = 0; + } + + // DOWN button: decrease value + if (button.flag.down) + { + // Decrease value + *value = *value - stepValue; + + // Check value limits + if (*value < limitLow) + { + // Check if value can roll over, else stick to limit + if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) + *value = limitHigh; + else + *value = limitLow; + + // Reset step size to default + stepValue = 1; + } + + // Trigger display update + update = 1; + + // Clear button flag + button.flag.down = 0; + } + + // When fast mode is enabled, increase step size if Sx button is continuously + if ((mode & SETVALUE_FAST_MODE) == SETVALUE_FAST_MODE) + { + switch (sButton.repeats) + { + case 0: + stepValue = 1; + doRound = 0; + break; + case 10: + case -10: + stepValue = 10; + doRound = 1; + break; + case 20: + case -20: + stepValue = 100; + doRound = 1; + break; + case 30: + case -30: + stepValue = 1000; + doRound = 1; + break; + } + + // Round value to avoid odd numbers on display + if (stepValue != 1 && doRound == 1) + { + *value -= *value % stepValue; + doRound = 0; + } + } + + // Update display when there is new data + if (update) + { + // Display up or down arrow according to sign of value + if ((mode & SETVALUE_DISPLAY_ARROWS) == SETVALUE_DISPLAY_ARROWS) + { + if (*value >= 0) + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + val = *value; + } + else + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + val = *value * (-1); + } + } + else + { + val = *value; + } + + // Display function can either display value directly, modify value before displaying + // or display a string referenced by the value + fptr_setValue_display_function1(segments, val, digits, blanks); + + // Clear update flag + update = 0; + } + + // Call idle loop to serve background tasks + idle_loop(); + + } + + // Clear up and down arrows + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + + // Set blinking rate to 1Hz and stop + set_blink_rate(BIT7 + BIT6 + BIT5); + clear_blink_mem(); + + // Turn off button repeat function + button_repeat_off(); + + // Enable stopwatch display updates again + sStopwatch.state = stopwatch_state; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/user.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/user.h new file mode 100755 index 0000000..f48cea4 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/logic/user.h @@ -0,0 +1,59 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef USER_H_ +#define USER_H_ + +// ************************************************************************************************* +// Defines section +#define SETVALUE_ROLLOVER_VALUE BIT0 +#define SETVALUE_DISPLAY_VALUE BIT1 +#define SETVALUE_DISPLAY_ARROWS BIT2 +#define SETVALUE_DISPLAY_SELECTION BIT3 +#define SETVALUE_FAST_MODE BIT4 +#define SETVALUE_NEXT_VALUE BIT5 + +// ************************************************************************************************* +// Prototypes section +extern u8 *select_view_style(u8 line, u8 * view1, u8 * view2); + +extern void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, u8 blanks); +extern void set_value(s32 * value, u8 digits, u8 blanks, s32 limitLow, s32 limitHigh, u16 mode, + u8 segments, + void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, + u8 blanks)); +extern void dummy(u8 line); + +#endif /*USER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/main.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/main.c new file mode 100755 index 0000000..42eabaa --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/main.c @@ -0,0 +1,743 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//****************************************************************************** +// eZ430-Chronos +// +// Description: This is the standard software for the eZ430-Chronos +// +// P.Francisco +// Version 1.6 +// Texas Instruments, Inc +// November 2010 +// Known working builds: +// IAR Embedded Workbench (Version: 5.10.4) +// Code Composer Studio (Version 4.2.0.10012) +//****************************************************************************** +//Change Log (More detailed information can be found in change_record.txt): +//****************************************************************************** +//Version: 1.6 +//Comments: Several bugs were fixed. +// LCD shows "done" after successfully received data +// rfBSL requires two button presses in order to update watch +// New method detects a long button press +// Removed file display1.c. The content is now in display.c +// Backlight of Chronos stays on for 3 sec after backlight button was pushed. +// After timeout the accelerometer menu shows "----" +// +//Version: 1.5 +//Comments: Changed XT1 drive level to highest +// Modified key lock procedure. +// Negative °C are now converted correctly to Kelvin +// Enabled fast mode when changing altitude offset +// Disabled stopwatch stop when watch buttons are locked +// Added SimpliciTI sources to project. Upgraded to Version 1.1.1. +// Changed button names from M1/M2/S1/S2/BL to STAR/NUM/UP/DOWN/BACKLIGHT +// +//Version: 1.4 +//Comments: Initial Release Version +//********************************************************************************** + +// ************************************************************************************************* +// Initialization and control of application. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" +#include + +// driver +#include "clock.h" +#include "display.h" +#include "vti_as.h" +#include "vti_ps.h" +#include "radio.h" +#include "buzzer.h" +#include "ports.h" +#include "timer.h" +#include "pmm.h" +#include "rf1a.h" + +// logic +#include "menu.h" +#include "date.h" +#include "alarm.h" +#include "stopwatch.h" +#include "battery.h" +#include "temperature.h" +#include "altitude.h" +#include "battery.h" +#include "acceleration.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "rfbsl.h" +#include "test.h" + +// ************************************************************************************************* +// Prototypes section +void init_application(void); +void init_global_variables(void); +void wakeup_event(void); +void process_requests(void); +void display_update(void); +void idle_loop(void); +void configure_ports(void); +void read_calibration_values(void); + +// ************************************************************************************************* +// Defines section + +// Number of calibration data bytes in INFOA memory +#define CALIBRATION_DATA_LENGTH (13u) + +// ************************************************************************************************* +// Global Variable section + +// Variable holding system internal flags +volatile s_system_flags sys; + +// Variable holding flags set by logic modules +volatile s_request_flags request; + +// Variable holding message flags +volatile s_message_flags message; + +// Global radio frequency offset taken from calibration memory +// Compensates crystal deviation from 26MHz nominal value +u8 rf_frequoffset; + +// Function pointers for LINE1 and LINE2 display function +void (*fptr_lcd_function_line1)(u8 line, u8 update); +void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// Extern section + +extern void start_simpliciti_sync(void); + +extern u16 ps_read_register(u8 address, u8 mode); +extern u8 ps_write_register(u8 address, u8 data); + +// ************************************************************************************************* +// @fn main +// @brief Main routine +// @param none +// @return none +// ************************************************************************************************* +int main(void) +{ + // Init MCU + init_application(); + + // Assign initial value to global variables + init_global_variables(); + + // Branch to welcome screen + test_mode(); + + // Main control loop: wait in low power mode until some event needs to be processed + while (1) + { + // When idle go to LPM3 + idle_loop(); + + // Process wake-up events + if (button.all_flags || sys.all_flags) + wakeup_event(); + + // Process actions requested by logic modules + if (request.all_flags) + process_requests(); + + // Before going to LPM3, update display + if (display.all_flags) + display_update(); + } +} + +// ************************************************************************************************* +// @fn init_application +// @brief Initialize the microcontroller. +// @param none +// @return none +// ************************************************************************************************* +void init_application(void) +{ + volatile unsigned char *ptr; + + // --------------------------------------------------------------------- + // Enable watchdog + + // Watchdog triggers after 16 seconds when not cleared +#ifdef USE_WATCHDOG + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK; +#else + WDTCTL = WDTPW + WDTHOLD; +#endif + + // --------------------------------------------------------------------- + // Configure PMM + SetVCore(3); + + // Set global high power request enable + PMMCTL0_H = 0xA5; + PMMCTL0_L |= PMMHPMRE; + PMMCTL0_H = 0x00; + + // --------------------------------------------------------------------- + // Enable 32kHz ACLK + P5SEL |= 0x03; // Select XIN, XOUT on P5.0 and P5.1 + UCSCTL6 &= ~XT1OFF; // XT1 On, Highest drive strength + UCSCTL6 |= XCAP_3; // Internal load cap + + UCSCTL3 = SELA__XT1CLK; // Select XT1 as FLL reference + UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; + + // --------------------------------------------------------------------- + // Configure CPU clock for 12MHz + _BIS_SR(SCG0); // Disable the FLL control loop + UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx + UCSCTL1 = DCORSEL_5; // Select suitable range + UCSCTL2 = FLLD_1 + 0x16E; // Set DCO Multiplier + _BIC_SR(SCG0); // Enable the FLL control loop + + // Worst-case settling time for the DCO when the DCO range bits have been + // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx + // UG for optimization. + // 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle + __delay_cycles(375000); + + // Loop until XT1 & DCO stabilizes, use do-while to insure that + // body is executed at least once + do + { + UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); + SFRIFG1 &= ~OFIFG; // Clear fault flags + } + while ((SFRIFG1 & OFIFG)); + + // --------------------------------------------------------------------- + // Configure port mapping + + // Disable all interrupts + __disable_interrupt(); + // Get write-access to port mapping registers: + PMAPPWD = 0x02D52; + // Allow reconfiguration during runtime: + PMAPCTL = PMAPRECFG; + + // P2.7 = TA0CCR1A or TA1CCR0A output (buzzer output) + ptr = &P2MAP0; + *(ptr + 7) = PM_TA1CCR0A; + P2OUT &= ~BIT7; + P2DIR |= BIT7; + + // P1.5 = SPI MISO input + ptr = &P1MAP0; + *(ptr + 5) = PM_UCA0SOMI; + // P1.6 = SPI MOSI output + *(ptr + 6) = PM_UCA0SIMO; + // P1.7 = SPI CLK output + *(ptr + 7) = PM_UCA0CLK; + + // Disable write-access to port mapping registers: + PMAPPWD = 0; + // Re-enable all interrupts + __enable_interrupt(); + + // --------------------------------------------------------------------- + // Configure ports + + // --------------------------------------------------------------------- + // Reset radio core + radio_reset(); + radio_powerdown(); + + // --------------------------------------------------------------------- + // Init acceleration sensor + as_init(); + + // --------------------------------------------------------------------- + // Init LCD + lcd_init(); + + // --------------------------------------------------------------------- + // Init buttons + init_buttons(); + + // --------------------------------------------------------------------- + // Configure Timer0 for use by the clock and delay functions + Timer0_Init(); + + // --------------------------------------------------------------------- + // Init pressure sensor + ps_init(); +} + +// ************************************************************************************************* +// @fn init_global_variables +// @brief Initialize global variables. +// @param none +// @return none +// ************************************************************************************************* +void init_global_variables(void) +{ + // -------------------------------------------- + // Apply default settings + + // set menu pointers to default menu items + ptrMenu_L1 = &menu_L1_Time; + // ptrMenu_L1 = &menu_L1_Alarm; + // ptrMenu_L1 = &menu_L1_Heartrate; + // ptrMenu_L1 = &menu_L1_Speed; + // ptrMenu_L1 = &menu_L1_Temperature; + // ptrMenu_L1 = &menu_L1_Altitude; + // ptrMenu_L1 = &menu_L1_Acceleration; + ptrMenu_L2 = &menu_L2_Date; + // ptrMenu_L2 = &menu_L2_Stopwatch; + // ptrMenu_L2 = &menu_L2_Rf; + // ptrMenu_L2 = &menu_L2_Ppt; + // ptrMenu_L2 = &menu_L2_Sync; + // ptrMenu_L2 = &menu_L2_Distance; + // ptrMenu_L2 = &menu_L2_Calories; + // ptrMenu_L2 = &menu_L2_Battery; + // ptrMenu_L2 = &menu_L2_RFBSL; + + // Assign LINE1 and LINE2 display functions + fptr_lcd_function_line1 = ptrMenu_L1->display_function; + fptr_lcd_function_line2 = ptrMenu_L2->display_function; + + // Init system flags + button.all_flags = 0; + sys.all_flags = 0; + request.all_flags = 0; + display.all_flags = 0; + message.all_flags = 0; + + // Force full display update when starting up + display.flag.full_update = 1; + +#ifndef ISM_US + // Use metric units when displaying values + sys.flag.use_metric_units = 1; +#endif + + // Read calibration values from info memory + read_calibration_values(); + + // Set system time to default value + reset_clock(); + + // Set date to default value + reset_date(); + + // Set alarm time to default value + reset_alarm(); + + // Set buzzer to default value + reset_buzzer(); + + // Reset stopwatch + reset_stopwatch(); + + // Reset altitude measurement + reset_altitude_measurement(); + + // Reset acceleration measurement + reset_acceleration(); + + // Reset BlueRobin stack + reset_bluerobin(); + + // Reset SimpliciTI stack + reset_rf(); + + // Reset temperature measurement + reset_temp_measurement(); + + // Reset battery measurement + reset_batt_measurement(); + battery_measurement(); +} + +// ************************************************************************************************* +// @fn wakeup_event +// @brief Process external / internal wakeup events. +// @param none +// @return none +// ************************************************************************************************* +void wakeup_event(void) +{ + // Enable idle timeout + sys.flag.idle_timeout_enabled = 1; + + // If buttons are locked, only display "buttons are locked" message + if (button.all_flags && sys.flag.lock_buttons) + { + // Show "buttons are locked" message synchronously with next second tick + if (!(BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED)) + { + message.flag.prepare = 1; + message.flag.type_locked = 1; + } + // Clear buttons + button.all_flags = 0; + } + // Process long button press event (while button is held) + else if (button.flag.star_long) + { + // Clear button event + button.flag.star_long = 0; + + // Call sub menu function + ptrMenu_L1->mx_function(LINE1); + + // Set display update flag + display.flag.full_update = 1; + } + else if (button.flag.num_long) + { + // Clear button event + button.flag.num_long = 0; + + // Call sub menu function + ptrMenu_L2->mx_function(LINE2); + + // Set display update flag + display.flag.full_update = 1; + } + // Process single button press event (after button was released) + else if (button.all_flags) + { + // M1 button event --------------------------------------------------------------------- + // (Short) Advance to next menu item + if (button.flag.star) + { + // Clean up display before activating next menu item + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + + // Go to next menu entry + ptrMenu_L1 = ptrMenu_L1->next; + + // Assign new display function + fptr_lcd_function_line1 = ptrMenu_L1->display_function; + + // Set Line1 display update flag + display.flag.line1_full_update = 1; + + // Clear button flag + button.flag.star = 0; + } + // NUM button event --------------------------------------------------------------------- + // (Short) Advance to next menu item + else if (button.flag.num) + { + // Clear rfBSL confirmation flag + rfBSL_button_confirmation = 0; + + // Clean up display before activating next menu item + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_CLEAR); + + // Go to next menu entry + ptrMenu_L2 = ptrMenu_L2->next; + + // Assign new display function + fptr_lcd_function_line2 = ptrMenu_L2->display_function; + + // Set Line2 display update flag + display.flag.line2_full_update = 1; + + // Clear button flag + button.flag.num = 0; + } + // UP button event --------------------------------------------------------------------- + // Activate user function for Line1 menu item + else if (button.flag.up) + { + // Call direct function + ptrMenu_L1->sx_function(LINE1); + + // Set Line1 display update flag + display.flag.line1_full_update = 1; + + // Clear button flag + button.flag.up = 0; + } + // DOWN button event --------------------------------------------------------------------- + // Activate user function for Line2 menu item + else if (button.flag.down) + { + if (ptrMenu_L2 == &menu_L2_RFBSL) + { + + } + + // Call direct function + ptrMenu_L2->sx_function(LINE2); + + // Set Line1 display update flag + display.flag.line2_full_update = 1; + + // Clear button flag + button.flag.down = 0; + } + } + // Process internal events + if (sys.all_flags) + { + // Idle timeout --------------------------------------------------------------------- + if (sys.flag.idle_timeout) + { + // Clear timeout flag + sys.flag.idle_timeout = 0; + + // Clear display + clear_display(); + + // Set display update flags + display.flag.full_update = 1; + } + } + // Disable idle timeout + sys.flag.idle_timeout_enabled = 0; +} + +// ************************************************************************************************* +// @fn process_requests +// @brief Process requested actions outside ISR context. +// @param none +// @return none +// ************************************************************************************************* +void process_requests(void) +{ + // Do temperature measurement + if (request.flag.temperature_measurement) + temperature_measurement(FILTER_ON); + + // Do pressure measurement + if (request.flag.altitude_measurement) + do_altitude_measurement(FILTER_ON); + + // Do acceleration measurement + if (request.flag.acceleration_measurement) + do_acceleration_measurement(); + + // Do voltage measurement + if (request.flag.voltage_measurement) + battery_measurement(); + + // Generate alarm (two signals every second) + if (request.flag.buzzer) + start_buzzer(2, BUZZER_ON_TICKS, BUZZER_OFF_TICKS); + + // Reset request flag + request.all_flags = 0; +} + +// ************************************************************************************************* +// @fn display_update +// @brief Process display flags and call LCD update routines. +// @param none +// @return none +// ************************************************************************************************* +void display_update(void) +{ + u8 line; + u8 string[8]; + + // --------------------------------------------------------------------- + // Call Line1 display function + if (display.flag.full_update || display.flag.line1_full_update) + { + clear_line(LINE1); + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_UPDATE_FULL); + } else if (ptrMenu_L1->display_update()) + { + // Update line1 only when new data is available + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + + // --------------------------------------------------------------------- + // If message text should be displayed on Line2, skip normal update + if (message.flag.show) + { + line = LINE2; + + // Select message to display + if (message.flag.type_locked) + memcpy(string, " LO?T", 6); + else if (message.flag.type_unlocked) + memcpy(string, " OPEN", 6); + else if (message.flag.type_lobatt) + memcpy(string, "LOBATT", 6); + else if (message.flag.type_alarm_on) + { + memcpy(string, " ON", 4); + line = LINE1; + } else if (message.flag.type_alarm_off) + { + memcpy(string, " OFF", 4); + line = LINE1; + } + // Clear previous content + clear_line(line); + fptr_lcd_function_line2(line, DISPLAY_LINE_CLEAR); + + if (line == LINE2) + display_chars(LCD_SEG_L2_5_0, string, SEG_ON); + else + display_chars(LCD_SEG_L1_3_0, string, SEG_ON); + + // Next second tick erases message and repaints original screen content + message.all_flags = 0; + message.flag.erase = 1; + } + // --------------------------------------------------------------------- + // Call Line2 display function + else if (display.flag.full_update || display.flag.line2_full_update) + { + clear_line(LINE2); + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_UPDATE_FULL); + } else if (ptrMenu_L2->display_update() && !message.all_flags) + { + // Update line2 only when new data is available + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_UPDATE_PARTIAL); + } + // --------------------------------------------------------------------- + // Restore blinking icons (blinking memory is cleared when calling set_value) + if (display.flag.full_update) + { + if (is_bluerobin() == BLUEROBIN_CONNECTED) + { + // Turn on beeper icon to show activity + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF); + } + } + // Clear display flag + display.all_flags = 0; +} + +// ************************************************************************************************* +// @fn to_lpm +// @brief Go to LPM0/3. +// @param none +// @return none +// ************************************************************************************************* +void to_lpm(void) +{ + // Go to LPM3 + _BIS_SR(LPM3_bits + GIE); + __no_operation(); +} + +// ************************************************************************************************* +// @fn idle_loop +// @brief Go to LPM. Service watchdog timer when waking up. +// @param none +// @return none +// ************************************************************************************************* +void idle_loop(void) +{ + // To low power mode + to_lpm(); + +#ifdef USE_WATCHDOG + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; +#endif +} + +// ************************************************************************************************* +// @fn read_calibration_values +// @brief Read calibration values for temperature measurement, voltage measurement +// and radio from INFO memory. +// @param none +// @return none +// ************************************************************************************************* +void read_calibration_values(void) +{ + u8 cal_data[CALIBRATION_DATA_LENGTH]; // Temporary storage for constants + u8 i; + u8 *flash_mem; // Memory pointer + + // Read calibration data from Info D memory + flash_mem = (u8 *) 0x1800; + for (i = 0; i < CALIBRATION_DATA_LENGTH; i++) + { + cal_data[i] = *flash_mem++; + } + + if (cal_data[0] == 0xFF) + { + // If no values are available (i.e. INFO D memory has been erased by user), assign + // experimentally derived values + rf_frequoffset = 4; + sTemp.offset = -250; + sBatt.offset = -10; + simpliciti_ed_address[0] = 0x79; + simpliciti_ed_address[1] = 0x56; + simpliciti_ed_address[2] = 0x34; + simpliciti_ed_address[3] = 0x12; + sAlt.altitude_offset = 0; + } else + { + // Assign calibration data to global variables + rf_frequoffset = cal_data[1]; + // Range check for calibrated FREQEST value (-20 .. + 20 is ok, else use default value) + if ((rf_frequoffset > 20) && (rf_frequoffset < (256 - 20))) + { + rf_frequoffset = 0; + } + sTemp.offset = (s16) ((cal_data[2] << 8) + cal_data[3]); + sBatt.offset = (s16) ((cal_data[4] << 8) + cal_data[5]); + simpliciti_ed_address[0] = cal_data[6]; + simpliciti_ed_address[1] = cal_data[7]; + simpliciti_ed_address[2] = cal_data[8]; + simpliciti_ed_address[3] = cal_data[9]; + // S/W version byte set during calibration? + if (cal_data[12] != 0xFF) + { + sAlt.altitude_offset = (s16) ((cal_data[10] << 8) + cal_data[11]); + } else + { + sAlt.altitude_offset = 0; + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Applications/application/End Device/main_ED_BM.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Applications/application/End Device/main_ED_BM.c new file mode 100755 index 0000000..3c3a5bb --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Applications/application/End Device/main_ED_BM.c @@ -0,0 +1,261 @@ +/********************************************************************************************** + * Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + * + * IMPORTANT: Your use of this Software is limited to those specific rights granted under + * the terms of a software license agreement between the user who downloaded the software, + * his/her employer (which must be your employer) and Texas Instruments Incorporated (the + * "License"). You may not use this Software unless you agree to abide by the terms of the + * License. The License limits your use, and you acknowledge, that the Software may not be + * modified, copied or distributed unless embedded on a Texas Instruments microcontroller + * or used solely and exclusively in conjunction with a Texas Instruments radio frequency + * transceiver, which is integrated into your product. Other than for the foregoing purpose, + * you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + * perform, display or sell this Software and/or its documentation for any purpose. + * + * YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + * NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + * THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + * INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + * DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + * THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + * + * Should you have any questions regarding your right to use this Software, + * contact Texas Instruments Incorporated at www.TI.com. + **************************************************************************************************/ + +// ************************************************************************************************* +// Include section +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "bsp_leds.h" +#include "bsp_buttons.h" +#include "simpliciti.h" + + +// ************************************************************************************************* +// Defines section +#define TIMEOUT (10u) + +// Conversion from msec to ACLK timer ticks +#define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000) + +// U16 +typedef unsigned short u16; + +// ************************************************************************************************* +// Prototypes section + + +// ************************************************************************************************* +// Extern section +extern uint8_t sInit_done; + +// SimpliciTI has no low power delay function, so we have to use ours +extern void Timer0_A4_Delay(u16 ticks); + + +// ************************************************************************************************* +// Global Variable section +static linkID_t sLinkID1; + + + +// ************************************************************************************************* +// @fn simpliciti_link +// @brief Init hardware and try to link to access point. +// @param none +// @return unsigned char 0 = Could not link, timeout or external cancel. +// 1 = Linked successful. +// ************************************************************************************************* +unsigned char simpliciti_link(void) +{ + uint8_t timeout; + addr_t lAddr; + uint8_t i; + uint8_t pwr; + + // Configure timer + BSP_InitBoard(); + + // Change network address to value set in calling function + for (i = 0; i < NET_ADDR_SIZE; i++) + { + lAddr.addr[i] = simpliciti_ed_address[i]; + } + SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr); + + // Set flag + simpliciti_flag = SIMPLICITI_STATUS_LINKING; + + /* Keep trying to join (a side effect of successful initialization) until + * successful. Toggle LEDS to indicate that joining has not occurred. + */ + timeout = 0; + while (SMPL_SUCCESS != SMPL_Init(0)) + { + NWK_DELAY(1000); + + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; + + // Stop connecting after defined numbers of seconds (15) + if (timeout++ > TIMEOUT) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + simpliciti_flag = SIMPLICITI_STATUS_ERROR; + return (0); + } + + // Break when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + return (0); + } + } + + // Set output power to +3.3dmB + pwr = IOCTL_LEVEL_2; + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &pwr); + + /* Unconditional link to AP which is listening due to successful join. */ + timeout = 0; + while (SMPL_SUCCESS != SMPL_Link(&sLinkID1)) + { + NWK_DELAY(1000); + + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; + + // Stop linking after timeout + if (timeout++ > TIMEOUT) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + simpliciti_flag = SIMPLICITI_STATUS_ERROR; + return (0); + } + + // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + return (0); + } + } + simpliciti_flag = SIMPLICITI_STATUS_LINKED; + + return (1); +} + +// ************************************************************************************************* +// @fn simpliciti_main_tx_only +// @brief Get data through callback. Transfer data when external trigger is set. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_main_tx_only(void) +{ + while (1) + { + // Get end device data from callback function + simpliciti_get_ed_data_callback(); + + // Send data when flag bit SIMPLICITI_TRIGGER_SEND_DATA is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA)) + { + // Get radio ready. Wakes up in IDLE state. + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); + + // Acceleration / button events packets are 4 bytes long + SMPL_SendOpt(sLinkID1, simpliciti_data, 4, SMPL_TXOPTION_NONE); + + // Put radio back to SLEEP state + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); + + clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA); + } + + // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + break; + } + } +} + +// ************************************************************************************************* +// @fn simpliciti_main_sync +// @brief Send ready-to-receive packets in regular intervals. Listen shortly for host reply. +// Decode received host command and trigger action. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_main_sync(void) +{ + uint8_t len, i; + uint8_t ed_data[2]; + + while (1) + { + // Sleep 0.5sec between ready-to-receive packets + // SimpliciTI has no low power delay function, so we have to use ours + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); + + // Get radio ready. Radio wakes up in IDLE state. + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); + + // Send 2 byte long ready-to-receive packet to stimulate host reply + ed_data[0] = SYNC_ED_TYPE_R2R; + ed_data[1] = 0xCB; + SMPL_SendOpt(sLinkID1, ed_data, 2, SMPL_TXOPTION_NONE); + + // Wait shortly for host reply + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); + NWK_DELAY(10); + + // Check if a command packet was received + while (SMPL_Receive(sLinkID1, simpliciti_data, &len) == SMPL_SUCCESS) + { + // Decode received data + if (len > 0) + { + // Use callback function in application to decode data and react + simpliciti_sync_decode_ap_cmd_callback(); + + // Get reply data and send out reply packet burst (19 bytes each) + for (i = 0; i < simpliciti_reply_count; i++) + { + NWK_DELAY(10); + simpliciti_sync_get_data_callback(i); + SMPL_SendOpt(sLinkID1, simpliciti_data, BM_SYNC_DATA_LENGTH, SMPL_TXOPTION_NONE); + } + } + } + + // Put radio back to sleep + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); + + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; + + // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + break; + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Applications/configuration/End Device/smpl_config.dat b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Applications/configuration/End Device/smpl_config.dat new file mode 100755 index 0000000..59bfa8a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Applications/configuration/End Device/smpl_config.dat @@ -0,0 +1,72 @@ +# +# Filename: smpl_config.dat +# Revised: $Date: 2008-11-18 16:54:54 -0800 (Tue, 18 Nov 2008) $ +# Revision: $Revision: 18453 $ +# Author: $Author: lfriedman $ +# +# Description: This file supports the SimpliciTI Customer Configuration for End Devices. +# +# Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. +# +# IMPORTANT: Your use of this Software is limited to those specific rights granted under +# the terms of a software license agreement between the user who downloaded the software, +# his/her employer (which must be your employer) and Texas Instruments Incorporated (the +# "License"). You may not use this Software unless you agree to abide by the terms of the +# License. The License limits your use, and you acknowledge, that the Software may not be +# modified, copied or distributed unless embedded on a Texas Instruments microcontroller +# or used solely and exclusively in conjunction with a Texas Instruments radio frequency +# transceiver, which is integrated into your product. Other than for the foregoing purpose, +# you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +# perform, display or sell this Software and/or its documentation for any purpose. +# +# YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +# IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +# NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +# THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +# INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +# DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +# THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +# +# Should you have any questions regarding your right to use this Software, +# contact Texas Instruments Incorporated at www.TI.com. + + +# Number of connections supported. Each connection supports bi-directional +# communication. Access Points and Range Extenders can set this to 0 if they +# do not host End Device objects. +#--define=NUM_CONNECTIONS=2 +# [BM] Only allow 1 connection to RF access point +--define=NUM_CONNECTIONS=1 + +# Size of low level queues for sent and received frames. Affects RAM usage + +# AP needs larger input frame queue if it is supporting store-and-forward +# clients because the forwarded messages are held here. +--define=SIZE_INFRAME_Q=2 + +# The output frame queue can be small since Tx is done synchronously. Actually +# 1 is probably enough. If an Access Point device is also hosting an End Device +# that sends to a sleeping peer the output queue should be larger -- the waiting +# frames in this case are held here. In that case the output frame queue should +# be bigger. +--define=SIZE_OUTFRAME_Q=2 + +# This device's address. The first byte is used as a filter on the CC1100/CC2500 +# radios so THE FIRST BYTE MUST NOT BE either 0x00 or 0xFF. Also, for these radios +# on End Devices the first byte should be the least significant byte so the filtering +# is maximally effective. Otherwise the frame has to be processed by the MCU before it +# is recognized as not intended for the device. APs and REs run in promiscuous mode so +# the filtering is not done. This macro intializes a static const array of unsigned +# characters of length NET_ADDR_SIZE (found in nwk_types.h). The quotes (") are +# necessary below unless the spaces are removed. +--define=THIS_DEVICE_ADDRESS="{0x79, 0x56, 0x34, 0x12}" + +--define=END_DEVICE + +# For polling End Devices we need to specify that they do so. Uncomment the +# macro definition below if this is a polling device. This field is used +# by the Access Point to know whether to reserve store-and-forward support +# for the polling End Device during the Join exchange. +# --define=RX_POLLS diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Applications/configuration/smpl_nwk_config.dat b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Applications/configuration/smpl_nwk_config.dat new file mode 100755 index 0000000..d14b792 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Applications/configuration/smpl_nwk_config.dat @@ -0,0 +1,77 @@ +# +# Filename: smpl_nwk_config.dat +# Revised: $Date: 2009-02-07 14:21:07 -0700 (Sat, 07 Feb 2009) $ +# Revision: $Revision: 19010 $ +# Author: $Author: lfriedman $ +# +# Description: This file supports the SimpliciTI Customer Configuration for overall network. +# +# Copyright 2009 Texas Instruments Incorporated. All rights reserved. +# +# IMPORTANT: Your use of this Software is limited to those specific rights granted under +# the terms of a software license agreement between the user who downloaded the software, +# his/her employer (which must be your employer) and Texas Instruments Incorporated (the +# "License"). You may not use this Software unless you agree to abide by the terms of the +# License. The License limits your use, and you acknowledge, that the Software may not be +# modified, copied or distributed unless embedded on a Texas Instruments microcontroller +# or used solely and exclusively in conjunction with a Texas Instruments radio frequency +# transceiver, which is integrated into your product. Other than for the foregoing purpose, +# you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +# perform, display or sell this Software and/or its documentation for any purpose. +# +# YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +# IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +# NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +# THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +# INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +# DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +# THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +# +# Should you have any questions regarding your right to use this Software, +# contact Texas Instruments Incorporated at www.TI.com. + + +# Max hop count +--define=MAX_HOPS=3 + +# Max hops away from and AP. Keeps hop count and therefore replay +# storms down for sending to and from polling End Devices. Also used +# when joining since the EDs can't be more than 1 hop away. +--define=MAX_HOPS_FROM_AP=1 + +# Maximum size of Network application payload. Do not change unless +# protocol changes are reflected in different maximum network +# application payload size. +--define=MAX_NWK_PAYLOAD=9 + +# Maximum size of application payload +#--define=MAX_APP_PAYLOAD=10 +# [BM] Need to increase max payload for sync application +--define=MAX_APP_PAYLOAD=19 + +# Default Link token +--define=DEFAULT_LINK_TOKEN=0x01020304 + +# Default Join token +--define=DEFAULT_JOIN_TOKEN=0x05060708 + +# Define Frequency Agility as active for this build +# [BM] No need for frequency hopping +#--define=FREQUENCY_AGILITY + +# Enable application autoacknowledge support. Requires extended API as well +--define=APP_AUTO_ACK + +# Enable Extended API +--define=EXTENDED_API + +# Remove '#' corruption to enable security. +#--define=SMPL_SECURE + +# Remove '#' to enable NV object support +#--define=NVOBJECT_SUPPORT + +# Insert '#' to disable software timer +--define=SW_TIMER diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/CC430_End_Device_433MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/CC430_End_Device_433MHz.lib new file mode 100755 index 0000000..39953df Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/CC430_End_Device_433MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/CC430_End_Device_868MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/CC430_End_Device_868MHz.lib new file mode 100755 index 0000000..dd55c0e Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/CC430_End_Device_868MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/CC430_End_Device_915MHz.lib b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/CC430_End_Device_915MHz.lib new file mode 100755 index 0000000..9363600 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/CC430_End_Device_915MHz.lib differ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_board.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_board.c new file mode 100755 index 0000000..27f627b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_board.c @@ -0,0 +1,309 @@ +/************************************************************************************************** +* Filename: bsp_board.c +* Revised: $Date: 2009-10-11 16:48:20 -0700 (Sun, 11 Oct 2009) $ +* Revision: $Revision: 20896 $ +* +* Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Top-level board code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "bsp_config.h" + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +static void SetVCore(uint8_t level); +static void SetVCoreUp(uint8_t level); +static void SetVCoreDown(uint8_t level); +static void Bsp_SetVCore(void); +static void Bsp_SetClocks(void); + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_TIMER_CLK_MHZ 12 /* 12 MHz MCLKC and SMCLK */ +#define BSP_DELAY_MAX_USEC (0xFFFF / BSP_TIMER_CLK_MHZ) + +/************************************************************************************************** + * @fn SetVCore + * + * @brief SetVCore level is called from the user API. Change level by one step only. + * + * @param level - VcCore level + * + * @return none + ************************************************************************************************** + */ + +static void SetVCore(uint8_t level) +{ + uint8_t actLevel; + + do { + actLevel = PMMCTL0_L & PMMCOREV_3; + if (actLevel < level) + SetVCoreUp(++actLevel); /* Set VCore (step by step) */ + if (actLevel > level) + SetVCoreDown(--actLevel); /* Set VCore (step by step) */ + } while (actLevel != level); +} + +/************************************************************************************************** + * @fn SetVCoreUp + * + * @brief Set VCore up. Change level by one step only. + * + * @param level - VcCore level + * + * @return none + ************************************************************************************************* + */ + +static void SetVCoreUp(uint8_t level) +{ + PMMCTL0_H = 0xA5; /* Open PMM module registers + *for write access */ + + SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; /* Set SVS/M high side to new + *level */ + + SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; /* Set SVM new Level */ + while ((PMMIFG & SVSMLDLYIFG) == 0) ; /* Wait till SVM is settled + *(Delay) */ + PMMCTL0_L = PMMCOREV0 * level; /* Set VCore to x */ + PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); /* Clear already set flags */ + if ((PMMIFG & SVMLIFG)) + while ((PMMIFG & SVMLVLRIFG) == 0) ; /* Wait till level is reached + **/ + + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; /* Set SVS/M Low side to new + *level */ + PMMCTL0_H = 0x00; /* Lock PMM module registers + *for write access */ +} + +/************************************************************************************************** + * @fn SetVCoreDown + * + * @brief Set VCore down + * + * @param level - VcCore level + * + * @return none + ************************************************************************************************** + */ + +static void SetVCoreDown(uint8_t level) +{ + PMMCTL0_H = 0xA5; /* Open PMM module registers + *for write access */ + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; /* Set SVS/M Low side to new + *level */ + while ((PMMIFG & SVSMLDLYIFG) == 0) ; /* Wait till SVM is settled + *(Delay) */ + PMMCTL0_L = (level * PMMCOREV0); /* Set VCore to 1.85 V for Max + *Speed. */ + PMMCTL0_H = 0x00; /* Lock PMM module registers + *for write access */ +} + +/************************************************************************************************** + * @fn Bsp_SetVCore + * + * @brief Setup the core voltage. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Bsp_SetVCore(void) +{ + SetVCore(3); +} + +/************************************************************************************************** + * @fn Bsp_SetClocks + * + * @brief Set up system clocks. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Bsp_SetClocks(void) +{ + /* Configure CPU clock for 12MHz */ + + /* If clock settings are changed, remember to update BSP_TIMER_CLK_MHZ. + * Otherwise, all timer settings would be incorrect. + */ + UCSCTL3 |= SELREF_2; /* Set DCO FLL reference = REFO */ + UCSCTL4 |= SELA_2; /* Set ACLK = REFO */ + + __bis_SR_register(SCG0); /* Disable the FLL control loop */ + UCSCTL0 = 0x0000; /* Set lowest possible DCOx, MODx */ + UCSCTL1 = DCORSEL_5; /* Select DCO range 24MHz operation */ + UCSCTL2 = FLLD_1 + 374; /* Set DCO Multiplier for 12MHz + * (N + 1) * FLLRef = Fdco + * (374 + 1) * 32768 = 12MHz + * Set FLL Div = fDCOCLK/2 */ + __bic_SR_register(SCG0); /* Enable the FLL control loop */ + + /* Worst-case settling time for the DCO when the DCO range bits have been + * changed is n x 32 x 32 x f_MCLK / f_FLL_reference. + * 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle + */ + __delay_cycles(375000); + + /* Loop until XT1,XT2 & DCO fault flag is cleared */ + do + { + UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); + /* Clear XT2,XT1,DCO fault flags */ + SFRIFG1 &= ~OFIFG; /* Clear fault flags */ + } while (SFRIFG1 & OFIFG); /* Test oscillator fault flag */ + + /* Select REFO as ACLK source and DCOCLK as MCLK and SMCLK source */ + UCSCTL4 = SELA__REFOCLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; +} + +/************************************************************************************************** + * @fn BSP_EARLY_INIT + * + * @brief This function is called by start-up code before doing the normal initialization + * of data segments. If the return value is zero, initialization is not performed. + * The global macro label "BSP_EARLY_INIT" gets #defined in the bsp_msp430_defs.h + * file, according to the specific compiler environment (CCE or IAR). In the CCE + * environment this macro invokes "_system_pre_init()" and in the IAR environment + * this macro invokes "__low_level_init()". + * + * @param None + * + * @return 0 - don't intialize data segments / 1 - do initialization + ************************************************************************************************* + */ +BSP_EARLY_INIT(void) +{ + /* Disable watchdog timer */ + WDTCTL = WDTPW | WDTHOLD; + + /* Setup Vcore */ + Bsp_SetVCore(); + + /* Configure System clocks */ + Bsp_SetClocks(); + + /* Return 1 - run seg_init */ + return (1); +} + +/************************************************************************************************** + * @fn BSP_InitBoard + * + * @brief Initialize the board. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void BSP_InitBoard(void) +{ + /* Configure TimerA for use by the delay function */ + + /* Reset the timer */ + //TA0CTL |= TACLR; /* Set the TACLR */ + + /* Clear all settings */ + //TA0CTL = 0x0; + + /* Select the clk source to be - SMCLK (Sub-Main CLK)*/ + //TA0CTL |= TASSEL_2; + + // [BM] We need to use TA1 for delay function, because TA0 is already occupied + TA1CTL |= TACLR; /* Set the TACLR */ + TA1CTL = 0x0; + TA1CTL |= TASSEL_2; +} + +/************************************************************************************************** + * @fn BSP_Delay + * + * @brief Delay for the requested amount of time. + * + * @param # of microseconds to delay. + * + * @return none + ************************************************************************************************** + */ + +void BSP_Delay(uint16_t usec) +{ + BSP_ASSERT(usec < BSP_DELAY_MAX_USEC); + + //TA0R = 0; /* initial count */ + //TA0CCR0 = BSP_TIMER_CLK_MHZ*usec; /* compare count. (delay in ticks) */ + + /* Start the timer in UP mode */ + //TA0CTL |= MC_1; + + /* Loop till compare interrupt flag is set */ + //while(!(TA0CCTL0 & CCIFG)); + + /* Stop the timer */ + //TA0CTL &= ~(MC_1); + + /* Clear the interrupt flag */ + //TA0CCTL0 &= ~CCIFG; + + // [BM] We need to use TA1 for delay function, because TA0 is already occupied + TA1R = 0; + TA1CCR0 = BSP_TIMER_CLK_MHZ * usec; + TA1CTL |= MC_1; + while (!(TA1CCTL0 & CCIFG)) ; + TA1CTL &= ~(MC_1); + TA1CCTL0 &= ~CCIFG; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h new file mode 100755 index 0000000..ed67c36 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h @@ -0,0 +1,83 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Board definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BOARD_DEFS_H +#define BSP_BOARD_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Board Unique Define + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BOARD_CC430EM + + +/* ------------------------------------------------------------------------------------------------ + * Mcu + * ------------------------------------------------------------------------------------------------ + */ +#include "mcus/bsp_msp430_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Clock + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_config.h" +#define __bsp_CLOCK_MHZ__ BSP_CONFIG_CLOCK_MHZ + + +/* ------------------------------------------------------------------------------------------------ + * Board Initialization + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BOARD_C "bsp_board.c" +#define BSP_INIT_BOARD() BSP_InitBoard() +#define BSP_DELAY_USECS(x) BSP_Delay(x) + +void BSP_InitBoard(void); +void BSP_Delay(uint16_t usec); + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h new file mode 100755 index 0000000..beac8c7 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h @@ -0,0 +1,92 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Button definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BUTTON_DEFS_H +#define BSP_BUTTON_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Button Configuration + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_NUM_BUTTONS__ 1 +#define __bsp_BUTTON_DEBOUNCE_WAIT__(expr) st( \ + int i; for (i = 0; i < 500; i++){ if (!(expr)) i = 0; }) + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * BUTTON #1 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : S2 + * Description : Push Button + * Polarity : Active Low + * GPIO : P1.7 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_BUTTON1_BIT__ 7 +#define __bsp_BUTTON1_PORT__ P1IN +#define __bsp_BUTTON1_IS_ACTIVE_LOW__ 1 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Extended Configuration + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +/* Enable the internal PullUp for button #1. */ +#define __bsp_BUTTON_EXTENDED_CONFIG__() st(P1OUT |= BV(__bsp_BUTTON1_BIT__); /* PullUp */ \ + P1REN |= BV(__bsp_BUTTON1_BIT__); ) /* Enable PullUp */ + + +/* ------------------------------------------------------------------------------------------------ + * Include Generic Button Macros + * ------------------------------------------------------------------------------------------------ + */ +#include "code/bsp_generic_buttons.h" + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h new file mode 100755 index 0000000..fd29193 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h @@ -0,0 +1,47 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Board configuration file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_CONFIG_H +#define BSP_CONFIG_H + + +/* Nothing needed for this platform. */ + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h new file mode 100755 index 0000000..2dc5732 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h @@ -0,0 +1,54 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Driver definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_DRIVER_DEFS_H +#define BSP_DRIVER_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Driver Initialization + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_DRIVERS_C "bsp_drivers.c" +#define BSP_INIT_DRIVERS() BSP_InitDrivers() +void BSP_InitDrivers(void); + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c new file mode 100755 index 0000000..0e08bb2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c @@ -0,0 +1,88 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Top-level driver file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_driver_defs.h" +#include "bsp_leds.h" +#include "bsp_buttons.h" +#include "bsp_config.h" + + +/************************************************************************************************** + * @fn BSP_InitDrivers + * + * @brief Initialize all enabled BSP drivers. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void BSP_InitDrivers(void) +{ +#if (!defined BSP_NO_LEDS) + BSP_InitLeds(); +#endif + +#if (!defined BSP_NO_BUTTONS) + BSP_InitButtons(); +#endif +} + +/* ================================================================================================ + * C Code Includes + * ================================================================================================ + */ +#ifndef BSP_NO_LEDS +# include "drivers/code/bsp_leds.c" +#endif + +#ifndef BSP_NO_BUTTONS +# include "drivers/code/bsp_buttons.c" +#endif + + +/************************************************************************************************** + */ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h new file mode 100755 index 0000000..4e8ff55 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h @@ -0,0 +1,81 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Board definition file. + * Target : Texas Instruments CC430EM + * Radios : CC430 + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_BOARD_DEFS_H +#define MRFI_BOARD_DEFS_H + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + + +/* ------------------------------------------------------------------------------------------------ + * Radio Selection + * ------------------------------------------------------------------------------------------------ + */ +#if (!defined MRFI_CC430) +# error "ERROR: A compatible radio must be specified for the CC430EM board." +#endif + + +/* Radio Interface critical section macros */ +typedef bspIState_t mrfiRIFIState_t; +#define MRFI_RIF_ENTER_CRITICAL_SECTION(x) BSP_ENTER_CRITICAL_SECTION(x) +#define MRFI_RIF_EXIT_CRITICAL_SECTION(x) BSP_EXIT_CRITICAL_SECTION(x) + + +/************************************************************************************************** + * Compile Time Integrity Checks + ************************************************************************************************** + */ +#ifndef BSP_BOARD_CC430EM +# error "ERROR: Mismatch between specified board and MRFI configuration." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h new file mode 100755 index 0000000..e213c25 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h @@ -0,0 +1,97 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * LED definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_LED_DEFS_H +#define BSP_LED_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Configuration + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_NUM_LEDS__ 2 +#define __bsp_LED_BLINK_LOOP_COUNT__ 0x34000 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * LED #1 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : LED1 + * Color : Green + * Polarity : Active High + * GPIO : P1.0 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_LED1_BIT__ 0 +#define __bsp_LED1_PORT__ P1OUT +#define __bsp_LED1_DDR__ P1DIR +#define __bsp_LED1_IS_ACTIVE_LOW__ 0 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * LED #2 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : LED2 + * Color : Green + * Polarity : Active High + * GPIO : P3.6 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_LED2_BIT__ 6 +#define __bsp_LED2_PORT__ P3OUT +#define __bsp_LED2_DDR__ P3DIR +#define __bsp_LED2_IS_ACTIVE_LOW__ 0 + + +/* ------------------------------------------------------------------------------------------------ + * Include Generic LED Macros + * ------------------------------------------------------------------------------------------------ + */ +#include "code/bsp_generic_leds.h" + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/bsp.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/bsp.c new file mode 100755 index 0000000..c0bedd3 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/bsp.c @@ -0,0 +1,102 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Top-level BSP code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "bsp_driver_defs.h" + + +/************************************************************************************************** + * @fn BSP_Init + * + * @brief Initialize the board and drivers. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void BSP_Init(void) +{ + BSP_INIT_BOARD(); + BSP_INIT_DRIVERS(); + + /*------------------------------------------------------------- + * Run time integrity checks. Perform only if asserts + * are enabled. + */ +#ifdef BSP_ASSERTS_ARE_ON + /* verify endianess is correctly specified */ + { + uint16_t test = 0x00AA; /* first storage byte of 'test' is + *non-zero for little endian */ + BSP_ASSERT(!(*((uint8_t *)&test)) == !BSP_LITTLE_ENDIAN); /* endianess mismatch */ + } +#endif +} + +/* ================================================================================================ + * C Code Includes + * ================================================================================================ + */ +#ifdef BSP_BOARD_C +# include BSP_BOARD_C +#endif + +#ifdef BSP_DRIVERS_C +# include BSP_DRIVERS_C +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +BSP_STATIC_ASSERT(sizeof(uint8_t) == 1); +BSP_STATIC_ASSERT(sizeof(int8_t) == 1); +BSP_STATIC_ASSERT(sizeof(uint16_t) == 2); +BSP_STATIC_ASSERT(sizeof(int16_t) == 2); +BSP_STATIC_ASSERT(sizeof(uint32_t) == 4); +BSP_STATIC_ASSERT(sizeof(int32_t) == 4); + + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/bsp.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/bsp.h new file mode 100755 index 0000000..d249d39 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/bsp.h @@ -0,0 +1,184 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Include file for core BSP services. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_H +#define BSP_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + +/* ------------------------------------------------------------------------------------------------ + * BSP Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP +#define BSP_VER 100 /* BSP version 1.00a */ +#define BSP_SUBVER a + + +/* ------------------------------------------------------------------------------------------------ + * Clock + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CLOCK_MHZ __bsp_CLOCK_MHZ__ + + +/* ------------------------------------------------------------------------------------------------ + * Memory + * ------------------------------------------------------------------------------------------------ + */ +#ifndef __bsp_LITTLE_ENDIAN__ +# error ERROR: Endianess not defined +#endif + +#define BSP_LITTLE_ENDIAN __bsp_LITTLE_ENDIAN__ + +#define CODE __bsp_CODE_MEMSPACE__ +#define XDATA __bsp_XDATA_MEMSPACE__ + +/* ------------------------------------------------------------------------------------------------ + * Interrupts + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_ISR_FUNCTION(func, vect) __bsp_ISR_FUNCTION__(func, vect) + +#define BSP_ENABLE_INTERRUPTS() __bsp_ENABLE_INTERRUPTS__() +#define BSP_DISABLE_INTERRUPTS() __bsp_DISABLE_INTERRUPTS__() +#define BSP_INTERRUPTS_ARE_ENABLED() __bsp_INTERRUPTS_ARE_ENABLED__() + + +/* ------------------------------------------------------------------------------------------------ + * Critical Sections + * ------------------------------------------------------------------------------------------------ + */ +typedef __bsp_ISTATE_T__ bspIState_t; + +#define BSP_ENTER_CRITICAL_SECTION(x) st(x = __bsp_GET_ISTATE__(); __bsp_DISABLE_INTERRUPTS__(); ) +#define BSP_EXIT_CRITICAL_SECTION(x) __bsp_RESTORE_ISTATE__(x) +#define BSP_CRITICAL_STATEMENT(x) st(bspIState_t s; \ + BSP_ENTER_CRITICAL_SECTION(s); \ + x; \ + BSP_EXIT_CRITICAL_SECTION(s); ) + + +/* ------------------------------------------------------------------------------------------------ + * Asserts + * ------------------------------------------------------------------------------------------------ + */ + +/* + * BSP_ASSERT( expression ) - The given expression must evaluate as "true" or else the assert + * handler is called. From here, the call stack feature of the debugger can pinpoint where + * the problem occurred. + * + * BSP_FORCE_ASSERT() - If asserts are in use, immediately calls the assert handler. + * + * BSP_ASSERTS_ARE_ON - can use #ifdef to see if asserts are enabled + * + * Asserts can be disabled for optimum performance and minimum code size (ideal for + * finalized, debugged production code). + */ + +#if (!defined BSP_NO_DEBUG) +# ifndef BSP_ASSERT_HANDLER +# define BSP_ASSERT_HANDLER() st(__bsp_DISABLE_INTERRUPTS__(); while (1) ; ) +# endif +# define BSP_ASSERT(expr) st(if (!(expr)) BSP_ASSERT_HANDLER(); ) +# define BSP_FORCE_ASSERT() BSP_ASSERT_HANDLER() +# define BSP_ASSERTS_ARE_ON +#else +# define BSP_ASSERT(expr) /* empty */ +# define BSP_FORCE_ASSERT() /* empty */ +#endif + +/* static assert */ +#define BSP_STATIC_ASSERT(expr) void bspDummyPrototype(char dummy[1 / ((expr) != 0)]) + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_Init(void); + +/************************************************************************************************** + */ + +/**************************************************************************************** +* BEGIN ENDIAN SUPPORT +* +* Security encrypt/decrypt operates on unsigned long quantities. These must match on +* source and destination platforms. These macros enforce the standard conversions. +* Currently all platforms (CC2520/CC2x30 and MSP430) are little endian. +* +******************* Network order for encryption is LITTLE ENDIAN ****************** +* +****************************************************************************************/ + +#if (BSP_LITTLE_ENDIAN != 0) +# define ntohs(x) (x) +# define htons(x) (x) + +# define ntohl(x) (x) +# define htonl(x) (x) + +#else + +# define ntohs(x) (((x >> 8) & 0xFF) | ((x & 0xFF) << 8)) +# define htons(x) (((x >> 8) & 0xFF) | ((x & 0xFF) << 8)) + +# define ntohl(x) (((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | \ + ((x & 0xFF00) << 8) | ((x & 0xFF) << 24) \ + ) +# define htonl(x) (((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | \ + ((x & 0xFF00) << 8) | ((x & 0xFF) << 24) \ + ) + +#endif /* (BSP_LITTLE_ENDIAN != 0) */ + +/*************************************************************************************** +* END ENDIAN SUPPORT +***************************************************************************************/ + + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/bsp_macros.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/bsp_macros.h new file mode 100755 index 0000000..60392ba --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/bsp_macros.h @@ -0,0 +1,79 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Include file for BSP utility macros. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_MACROS_H +#define BSP_MACROS_H + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +/* bit value */ +#ifndef BV +# define BV(n) (1 << (n)) +#endif + +/* + * This macro is for use by other macros to form a fully valid C statement. + * Without this, the if/else conditionals could show unexpected behavior. + * + * For example, use... + * #define SET_REGS() st( ioreg1 = 0; ioreg2 = 0; ) + * instead of ... + * #define SET_REGS() { ioreg1 = 0; ioreg2 = 0; } + * or + * #define SET_REGS() ioreg1 = 0; ioreg2 = 0; + * The last macro would not behave as expected in the if/else construct. + * The second to last macro will cause a compiler error in certain uses + * of if/else construct + * + * It is not necessary, or recommended, to use this macro where there is + * already a valid C statement. For example, the following is redundant... + * #define CALL_FUNC() st( func(); ) + * This should simply be... + * #define CALL_FUNC() func() + * + * (The while condition below evaluates false without generating a + * constant-controlling-loop type of warning on most compilers.) + */ +#define st(x) do { x } while (__LINE__ == -1) + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/bsp_buttons.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/bsp_buttons.h new file mode 100755 index 0000000..6ec3d99 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/bsp_buttons.h @@ -0,0 +1,90 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Button driver include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BUTTONS_H +#define BSP_BUTTONS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_button_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_NUM_BUTTONS __bsp_NUM_BUTTONS__ + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BUTTON_DEBOUNCE_WAIT(expr) __bsp_BUTTON_DEBOUNCE_WAIT__(expr) + +#define BSP_BUTTON1() __bsp_BUTTON1__() +#define BSP_BUTTON2() __bsp_BUTTON2__() +#define BSP_BUTTON3() __bsp_BUTTON3__() +#define BSP_BUTTON4() __bsp_BUTTON4__() +#define BSP_BUTTON5() __bsp_BUTTON5__() +#define BSP_BUTTON6() __bsp_BUTTON6__() +#define BSP_BUTTON7() __bsp_BUTTON7__() +#define BSP_BUTTON8() __bsp_BUTTON8__() + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_InitButtons(void); + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +#ifdef BSP_NO_BUTTONS +# error "ERROR: The button driver is disabled. This file should not be included." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/bsp_leds.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/bsp_leds.h new file mode 100755 index 0000000..2d0195e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/bsp_leds.h @@ -0,0 +1,133 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * LED driver include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_LEDS_H +#define BSP_LEDS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_led_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_NUM_LEDS __bsp_NUM_LEDS__ + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ + +/* blink delay loop */ +#define BSP_LED_BLINK_DELAY() st({ volatile uint32_t i; \ + for (i = 0; i < __bsp_LED_BLINK_LOOP_COUNT__; i++){ }; }) + +/* LED1 */ +#define BSP_TURN_ON_LED1() __bsp_LED1_TURN_ON__() +#define BSP_TURN_OFF_LED1() __bsp_LED1_TURN_OFF__() +#define BSP_TOGGLE_LED1() __bsp_LED1_TOGGLE__() +#define BSP_LED1_IS_ON() __bsp_LED1_IS_ON__() + +/* LED2 */ +#define BSP_TURN_ON_LED2() __bsp_LED2_TURN_ON__() +#define BSP_TURN_OFF_LED2() __bsp_LED2_TURN_OFF__() +#define BSP_TOGGLE_LED2() __bsp_LED2_TOGGLE__() +#define BSP_LED2_IS_ON() __bsp_LED2_IS_ON__() + +/* LED3 */ +#define BSP_TURN_ON_LED3() __bsp_LED3_TURN_ON__() +#define BSP_TURN_OFF_LED3() __bsp_LED3_TURN_OFF__() +#define BSP_TOGGLE_LED3() __bsp_LED3_TOGGLE__() +#define BSP_LED3_IS_ON() __bsp_LED3_IS_ON__() + +/* LED4 */ +#define BSP_TURN_ON_LED4() __bsp_LED4_TURN_ON__() +#define BSP_TURN_OFF_LED4() __bsp_LED4_TURN_OFF__() +#define BSP_TOGGLE_LED4() __bsp_LED4_TOGGLE__() +#define BSP_LED4_IS_ON() __bsp_LED4_IS_ON__() + +/* LED5 */ +#define BSP_TURN_ON_LED5() __bsp_LED5_TURN_ON__() +#define BSP_TURN_OFF_LED5() __bsp_LED5_TURN_OFF__() +#define BSP_TOGGLE_LED5() __bsp_LED5_TOGGLE__() +#define BSP_LED5_IS_ON() __bsp_LED5_IS_ON__() + +/* LED6 */ +#define BSP_TURN_ON_LED6() __bsp_LED6_TURN_ON__() +#define BSP_TURN_OFF_LED6() __bsp_LED6_TURN_OFF__() +#define BSP_TOGGLE_LED6() __bsp_LED6_TOGGLE__() +#define BSP_LED6_IS_ON() __bsp_LED6_IS_ON__() + +/* LED7 */ +#define BSP_TURN_ON_LED7() __bsp_LED7_TURN_ON__() +#define BSP_TURN_OFF_LED7() __bsp_LED7_TURN_OFF__() +#define BSP_TOGGLE_LED7() __bsp_LED7_TOGGLE__() +#define BSP_LED7_IS_ON() __bsp_LED7_IS_ON__() + +/* LED8 */ +#define BSP_TURN_ON_LED8() __bsp_LED8_TURN_ON__() +#define BSP_TURN_OFF_LED8() __bsp_LED8_TURN_OFF__() +#define BSP_TOGGLE_LED8() __bsp_LED8_TOGGLE__() +#define BSP_LED8_IS_ON() __bsp_LED8_IS_ON__() + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_InitLeds(void); + + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +#ifdef BSP_NO_LEDS +# error "ERROR: The LED driver is disabled. This file should not be included." +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_buttons.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_buttons.c new file mode 100755 index 0000000..bff3d5d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_buttons.c @@ -0,0 +1,97 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic button driver code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_buttons.h" +#include "bsp_button_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CONFIG_BUTTON1() __bsp_BUTTON1_CONFIG__() +#define BSP_CONFIG_BUTTON2() __bsp_BUTTON2_CONFIG__() +#define BSP_CONFIG_BUTTON3() __bsp_BUTTON3_CONFIG__() +#define BSP_CONFIG_BUTTON4() __bsp_BUTTON4_CONFIG__() +#define BSP_CONFIG_BUTTON5() __bsp_BUTTON5_CONFIG__() +#define BSP_CONFIG_BUTTON6() __bsp_BUTTON6_CONFIG__() +#define BSP_CONFIG_BUTTON7() __bsp_BUTTON7_CONFIG__() +#define BSP_CONFIG_BUTTON8() __bsp_BUTTON8_CONFIG__() + +#ifdef __bsp_BUTTON_EXTENDED_CONFIG__ +# define BSP_BUTTON_EXTENDED_CONFIG() __bsp_BUTTON_EXTENDED_CONFIG__() +#else +# define BSP_BUTTON_EXTENDED_CONFIG() +#endif + + +/************************************************************************************************** + * @fn BSP_InitButtons + * + * @brief Initialize button hardware and driver code. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void BSP_InitButtons(void) +{ + /* configure LEDs */ + BSP_CONFIG_BUTTON1(); + BSP_CONFIG_BUTTON2(); + BSP_CONFIG_BUTTON3(); + BSP_CONFIG_BUTTON4(); + BSP_CONFIG_BUTTON5(); + BSP_CONFIG_BUTTON6(); + BSP_CONFIG_BUTTON7(); + BSP_CONFIG_BUTTON8(); + + /* peform extended configuration if needed */ + BSP_BUTTON_EXTENDED_CONFIG(); +} + +/************************************************************************************************** + */ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h new file mode 100755 index 0000000..5a244bd --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h @@ -0,0 +1,211 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic button macro include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_GENERIC_BUTTONS_H +#define BSP_GENERIC_BUTTONS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_BUTTON__(port, bit, low) ((low) ? (!((port) & BV(bit))) : ((port) & BV(bit))) + + +/* ------------------------- populate BUTTON #1 macros ------------------------- */ +#define __bsp_NUM_BUTTON1_DEFINES__ ((defined __bsp_BUTTON1_PORT__) + \ + (defined __bsp_BUTTON1_BIT__) + \ + (defined __bsp_BUTTON1_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON1_DEFINES__ == 3) +# define __bsp_BUTTON1__() __bsp_BUTTON__(__bsp_BUTTON1_PORT__, __bsp_BUTTON1_BIT__, \ + __bsp_BUTTON1_IS_ACTIVE_LOW__) +# define __bsp_BUTTON1_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON1_DEFINES__ == 0) +# define __bsp_BUTTON1__() /* no button */ 0 +# define __bsp_BUTTON1_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON1." +#endif + +/* ------------------------- populate BUTTON #2 macros ------------------------- */ +#define __bsp_NUM_BUTTON2_DEFINES__ ((defined __bsp_BUTTON2_PORT__) + \ + (defined __bsp_BUTTON2_BIT__) + \ + (defined __bsp_BUTTON2_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON2_DEFINES__ == 3) +# define __bsp_BUTTON2__() __bsp_BUTTON__(__bsp_BUTTON2_PORT__, __bsp_BUTTON2_BIT__, \ + __bsp_BUTTON2_IS_ACTIVE_LOW__) +# define __bsp_BUTTON2_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON2_DEFINES__ == 0) +# define __bsp_BUTTON2__() /* no button */ 0 +# define __bsp_BUTTON2_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON2." +#endif + +/* ------------------------- populate BUTTON #3 macros ------------------------- */ +#define __bsp_NUM_BUTTON3_DEFINES__ ((defined __bsp_BUTTON3_PORT__) + \ + (defined __bsp_BUTTON3_BIT__) + \ + (defined __bsp_BUTTON3_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON3_DEFINES__ == 3) +# define __bsp_BUTTON3__() __bsp_BUTTON__(__bsp_BUTTON3_PORT__, __bsp_BUTTON3_BIT__, \ + __bsp_BUTTON3_IS_ACTIVE_LOW__) +# define __bsp_BUTTON3_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON3_DEFINES__ == 0) +# define __bsp_BUTTON3__() /* no button */ 0 +# define __bsp_BUTTON3_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON3." +#endif + +/* ------------------------- populate BUTTON #4 macros ------------------------- */ +#define __bsp_NUM_BUTTON4_DEFINES__ ((defined __bsp_BUTTON4_PORT__) + \ + (defined __bsp_BUTTON4_BIT__) + \ + (defined __bsp_BUTTON4_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON4_DEFINES__ == 3) +# define __bsp_BUTTON4__() __bsp_BUTTON__(__bsp_BUTTON4_PORT__, __bsp_BUTTON4_BIT__, \ + __bsp_BUTTON4_IS_ACTIVE_LOW__) +# define __bsp_BUTTON4_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON4_DEFINES__ == 0) +# define __bsp_BUTTON4__() /* no button */ 0 +# define __bsp_BUTTON4_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON4." +#endif + +/* ------------------------- populate BUTTON #5 macros ------------------------- */ +#define __bsp_NUM_BUTTON5_DEFINES__ ((defined __bsp_BUTTON5_PORT__) + \ + (defined __bsp_BUTTON5_BIT__) + \ + (defined __bsp_BUTTON5_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON5_DEFINES__ == 3) +# define __bsp_BUTTON5__() __bsp_BUTTON__(__bsp_BUTTON5_PORT__, __bsp_BUTTON5_BIT__, \ + __bsp_BUTTON5_IS_ACTIVE_LOW__) +# define __bsp_BUTTON5_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON5_DEFINES__ == 0) +# define __bsp_BUTTON5__() /* no button */ 0 +# define __bsp_BUTTON5_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON5." +#endif + +/* ------------------------- populate BUTTON #6 macros ------------------------- */ +#define __bsp_NUM_BUTTON6_DEFINES__ ((defined __bsp_BUTTON6_PORT__) + \ + (defined __bsp_BUTTON6_BIT__) + \ + (defined __bsp_BUTTON6_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON6_DEFINES__ == 3) +# define __bsp_BUTTON6__() __bsp_BUTTON__(__bsp_BUTTON6_PORT__, __bsp_BUTTON6_BIT__, \ + __bsp_BUTTON6_IS_ACTIVE_LOW__) +# define __bsp_BUTTON6_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON6_DEFINES__ == 0) +# define __bsp_BUTTON6__() /* no button */ 0 +# define __bsp_BUTTON6_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON6." +#endif + +/* ------------------------- populate BUTTON #7 macros ------------------------- */ +#define __bsp_NUM_BUTTON7_DEFINES__ ((defined __bsp_BUTTON7_PORT__) + \ + (defined __bsp_BUTTON7_BIT__) + \ + (defined __bsp_BUTTON7_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON7_DEFINES__ == 3) +# define __bsp_BUTTON7__() __bsp_BUTTON__(__bsp_BUTTON7_PORT__, __bsp_BUTTON7_BIT__, \ + __bsp_BUTTON7_IS_ACTIVE_LOW__) +# define __bsp_BUTTON7_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON7_DEFINES__ == 0) +# define __bsp_BUTTON7__() /* no button */ 0 +# define __bsp_BUTTON7_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON7." +#endif + +/* ------------------------- populate BUTTON #8 macros ------------------------- */ +#define __bsp_NUM_BUTTON8_DEFINES__ ((defined __bsp_BUTTON8_PORT__) + \ + (defined __bsp_BUTTON8_BIT__) + \ + (defined __bsp_BUTTON8_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON8_DEFINES__ == 3) +# define __bsp_BUTTON8__() __bsp_BUTTON__(__bsp_BUTTON8_PORT__, __bsp_BUTTON8_BIT__, \ + __bsp_BUTTON8_IS_ACTIVE_LOW__) +# define __bsp_BUTTON8_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON8_DEFINES__ == 0) +# define __bsp_BUTTON8__() /* no button */ 0 +# define __bsp_BUTTON8_CONFIG__() /* no button */ +#else +# error "ERROR: Incomplete number of macros for BUTTON8." +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* -------------------- number of buttons defined -------------------- */ +#ifndef __bsp_NUM_BUTTONS__ +# error "ERROR: Number of buttons is not specified." +#else +# if ((__bsp_NUM_BUTTONS__ > 8) || (__bsp_NUM_BUTTONS__ < 0)) +# error "ERROR: Unsupported number of buttons specified. Maximum is eight." +# endif +#endif + +#if (((__bsp_NUM_BUTTON1_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON2_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON3_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON4_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON5_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON6_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON7_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON8_DEFINES__ != 0)) != __bsp_NUM_BUTTONS__) +# error "ERROR: Inconsistency between defined macros and specified number of buttons." +#endif + +/* -------------------- debounce macro -------------------- */ +#ifndef __bsp_BUTTON_DEBOUNCE_WAIT__ +# error "ERROR: Debounce delay macro is missing." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h new file mode 100755 index 0000000..f356d46 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h @@ -0,0 +1,358 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic LED macro include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_GENERIC_LEDS_H +#define BSP_GENERIC_LEDS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ + +/* + * Note : The conditionals in the following macros evaulate compile time constants. + * Any compiler worth its salt will optimize these conditionals out for the + * smallest possible code. + */ + +#define __bsp_LED_TURN_ON__(bit, port, ddr, low) \ + st(if (low){ port &= ~BV(bit); } else { port |= BV(bit); }) + +#define __bsp_LED_TURN_OFF__(bit, port, ddr, low) \ + st(if (low){ port |= BV(bit); } else { port &= ~BV(bit); }) + +#define __bsp_LED_IS_ON__(bit, port, ddr, low) \ + ((low) ? (!((port) & BV(bit))) : ((port) & BV(bit))) + +#define __bsp_LED_TOGGLE__(bit, port, ddr, low) st(port ^= BV(bit); ) +#define __bsp_LED_CONFIG__(bit, port, ddr, low) st(ddr |= BV(bit); ) + + + +/* ------------------------- populate LED1 macros ------------------------- */ +#define __bsp_NUM_LED1_DEFINES__ ((defined __bsp_LED1_BIT__) + \ + (defined __bsp_LED1_PORT__) + \ + (defined __bsp_LED1_DDR__) + \ + (defined __bsp_LED1_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED1_DEFINES__ == 4) +# define __bsp_LED1_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED1_BIT__, __bsp_LED1_PORT__, \ + __bsp_LED1_DDR__, \ + __bsp_LED1_IS_ACTIVE_LOW__) +# define __bsp_LED1_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED1_BIT__, __bsp_LED1_PORT__, \ + __bsp_LED1_DDR__, \ + __bsp_LED1_IS_ACTIVE_LOW__) +# define __bsp_LED1_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED1_BIT__, __bsp_LED1_PORT__, \ + __bsp_LED1_DDR__, \ + __bsp_LED1_IS_ACTIVE_LOW__) +# define __bsp_LED1_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED1_BIT__, __bsp_LED1_PORT__, \ + __bsp_LED1_DDR__, \ + __bsp_LED1_IS_ACTIVE_LOW__) +# define __bsp_LED1_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED1_BIT__, __bsp_LED1_PORT__, \ + __bsp_LED1_DDR__, \ + __bsp_LED1_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED1_DEFINES__ == 0) +# define __bsp_LED1_TURN_ON__() /* no LED */ +# define __bsp_LED1_TURN_OFF__() /* no LED */ +# define __bsp_LED1_TOGGLE__() /* no LED */ +# define __bsp_LED1_IS_ON__() /* no LED */ 0 +# define __bsp_LED1_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED1." +#endif + + +/* ------------------------- populate LED2 macros ------------------------- */ +#define __bsp_NUM_LED2_DEFINES__ ((defined __bsp_LED2_BIT__) + \ + (defined __bsp_LED2_PORT__) + \ + (defined __bsp_LED2_DDR__) + \ + (defined __bsp_LED2_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED2_DEFINES__ == 4) +# define __bsp_LED2_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED2_BIT__, __bsp_LED2_PORT__, \ + __bsp_LED2_DDR__, \ + __bsp_LED2_IS_ACTIVE_LOW__) +# define __bsp_LED2_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED2_BIT__, __bsp_LED2_PORT__, \ + __bsp_LED2_DDR__, \ + __bsp_LED2_IS_ACTIVE_LOW__) +# define __bsp_LED2_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED2_BIT__, __bsp_LED2_PORT__, \ + __bsp_LED2_DDR__, \ + __bsp_LED2_IS_ACTIVE_LOW__) +# define __bsp_LED2_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED2_BIT__, __bsp_LED2_PORT__, \ + __bsp_LED2_DDR__, \ + __bsp_LED2_IS_ACTIVE_LOW__) +# define __bsp_LED2_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED2_BIT__, __bsp_LED2_PORT__, \ + __bsp_LED2_DDR__, \ + __bsp_LED2_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED2_DEFINES__ == 0) +# define __bsp_LED2_TURN_ON__() /* no LED */ +# define __bsp_LED2_TURN_OFF__() /* no LED */ +# define __bsp_LED2_TOGGLE__() /* no LED */ +# define __bsp_LED2_IS_ON__() /* no LED */ 0 +# define __bsp_LED2_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED2." +#endif + + +/* ------------------------- populate LED3 macros ------------------------- */ +#define __bsp_NUM_LED3_DEFINES__ ((defined __bsp_LED3_BIT__) + \ + (defined __bsp_LED3_PORT__) + \ + (defined __bsp_LED3_DDR__) + \ + (defined __bsp_LED3_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED3_DEFINES__ == 4) +# define __bsp_LED3_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED3_BIT__, __bsp_LED3_PORT__, \ + __bsp_LED3_DDR__, \ + __bsp_LED3_IS_ACTIVE_LOW__) +# define __bsp_LED3_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED3_BIT__, __bsp_LED3_PORT__, \ + __bsp_LED3_DDR__, \ + __bsp_LED3_IS_ACTIVE_LOW__) +# define __bsp_LED3_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED3_BIT__, __bsp_LED3_PORT__, \ + __bsp_LED3_DDR__, \ + __bsp_LED3_IS_ACTIVE_LOW__) +# define __bsp_LED3_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED3_BIT__, __bsp_LED3_PORT__, \ + __bsp_LED3_DDR__, \ + __bsp_LED3_IS_ACTIVE_LOW__) +# define __bsp_LED3_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED3_BIT__, __bsp_LED3_PORT__, \ + __bsp_LED3_DDR__, \ + __bsp_LED3_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED3_DEFINES__ == 0) +# define __bsp_LED3_TURN_ON__() /* no LED */ +# define __bsp_LED3_TURN_OFF__() /* no LED */ +# define __bsp_LED3_TOGGLE__() /* no LED */ +# define __bsp_LED3_IS_ON__() /* no LED */ 0 +# define __bsp_LED3_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED3." +#endif + + +/* ------------------------- populate LED4 macros ------------------------- */ +#define __bsp_NUM_LED4_DEFINES__ ((defined __bsp_LED4_BIT__) + \ + (defined __bsp_LED4_PORT__) + \ + (defined __bsp_LED4_DDR__) + \ + (defined __bsp_LED4_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED4_DEFINES__ == 4) +# define __bsp_LED4_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED4_BIT__, __bsp_LED4_PORT__, \ + __bsp_LED4_DDR__, \ + __bsp_LED4_IS_ACTIVE_LOW__) +# define __bsp_LED4_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED4_BIT__, __bsp_LED4_PORT__, \ + __bsp_LED4_DDR__, \ + __bsp_LED4_IS_ACTIVE_LOW__) +# define __bsp_LED4_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED4_BIT__, __bsp_LED4_PORT__, \ + __bsp_LED4_DDR__, \ + __bsp_LED4_IS_ACTIVE_LOW__) +# define __bsp_LED4_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED4_BIT__, __bsp_LED4_PORT__, \ + __bsp_LED4_DDR__, \ + __bsp_LED4_IS_ACTIVE_LOW__) +# define __bsp_LED4_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED4_BIT__, __bsp_LED4_PORT__, \ + __bsp_LED4_DDR__, \ + __bsp_LED4_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED4_DEFINES__ == 0) +# define __bsp_LED4_TURN_ON__() /* no LED */ +# define __bsp_LED4_TURN_OFF__() /* no LED */ +# define __bsp_LED4_TOGGLE__() /* no LED */ +# define __bsp_LED4_IS_ON__() /* no LED */ 0 +# define __bsp_LED4_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED4." +#endif + +/* ------------------------- populate LED5 macros ------------------------- */ +#define __bsp_NUM_LED5_DEFINES__ ((defined __bsp_LED5_BIT__) + \ + (defined __bsp_LED5_PORT__) + \ + (defined __bsp_LED5_DDR__) + \ + (defined __bsp_LED5_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED5_DEFINES__ == 4) +# define __bsp_LED5_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED5_BIT__, __bsp_LED5_PORT__, \ + __bsp_LED5_DDR__, \ + __bsp_LED5_IS_ACTIVE_LOW__) +# define __bsp_LED5_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED5_BIT__, __bsp_LED5_PORT__, \ + __bsp_LED5_DDR__, \ + __bsp_LED5_IS_ACTIVE_LOW__) +# define __bsp_LED5_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED5_BIT__, __bsp_LED5_PORT__, \ + __bsp_LED5_DDR__, \ + __bsp_LED5_IS_ACTIVE_LOW__) +# define __bsp_LED5_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED5_BIT__, __bsp_LED5_PORT__, \ + __bsp_LED5_DDR__, \ + __bsp_LED5_IS_ACTIVE_LOW__) +# define __bsp_LED5_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED5_BIT__, __bsp_LED5_PORT__, \ + __bsp_LED5_DDR__, \ + __bsp_LED5_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED5_DEFINES__ == 0) +# define __bsp_LED5_TURN_ON__() /* no LED */ +# define __bsp_LED5_TURN_OFF__() /* no LED */ +# define __bsp_LED5_TOGGLE__() /* no LED */ +# define __bsp_LED5_IS_ON__() /* no LED */ 0 +# define __bsp_LED5_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED5." +#endif + +/* ------------------------- populate LED6 macros ------------------------- */ +#define __bsp_NUM_LED6_DEFINES__ ((defined __bsp_LED6_BIT__) + \ + (defined __bsp_LED6_PORT__) + \ + (defined __bsp_LED6_DDR__) + \ + (defined __bsp_LED6_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED6_DEFINES__ == 4) +# define __bsp_LED6_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED6_BIT__, __bsp_LED6_PORT__, \ + __bsp_LED6_DDR__, \ + __bsp_LED6_IS_ACTIVE_LOW__) +# define __bsp_LED6_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED6_BIT__, __bsp_LED6_PORT__, \ + __bsp_LED6_DDR__, \ + __bsp_LED6_IS_ACTIVE_LOW__) +# define __bsp_LED6_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED6_BIT__, __bsp_LED6_PORT__, \ + __bsp_LED6_DDR__, \ + __bsp_LED6_IS_ACTIVE_LOW__) +# define __bsp_LED6_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED6_BIT__, __bsp_LED6_PORT__, \ + __bsp_LED6_DDR__, \ + __bsp_LED6_IS_ACTIVE_LOW__) +# define __bsp_LED6_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED6_BIT__, __bsp_LED6_PORT__, \ + __bsp_LED6_DDR__, \ + __bsp_LED6_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED6_DEFINES__ == 0) +# define __bsp_LED6_TURN_ON__() /* no LED */ +# define __bsp_LED6_TURN_OFF__() /* no LED */ +# define __bsp_LED6_TOGGLE__() /* no LED */ +# define __bsp_LED6_IS_ON__() /* no LED */ 0 +# define __bsp_LED6_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED6." +#endif + +/* ------------------------- populate LED7 macros ------------------------- */ +#define __bsp_NUM_LED7_DEFINES__ ((defined __bsp_LED7_BIT__) + \ + (defined __bsp_LED7_PORT__) + \ + (defined __bsp_LED7_DDR__) + \ + (defined __bsp_LED7_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED7_DEFINES__ == 4) +# define __bsp_LED7_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED7_BIT__, __bsp_LED7_PORT__, \ + __bsp_LED7_DDR__, \ + __bsp_LED7_IS_ACTIVE_LOW__) +# define __bsp_LED7_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED7_BIT__, __bsp_LED7_PORT__, \ + __bsp_LED7_DDR__, \ + __bsp_LED7_IS_ACTIVE_LOW__) +# define __bsp_LED7_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED7_BIT__, __bsp_LED7_PORT__, \ + __bsp_LED7_DDR__, \ + __bsp_LED7_IS_ACTIVE_LOW__) +# define __bsp_LED7_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED7_BIT__, __bsp_LED7_PORT__, \ + __bsp_LED7_DDR__, \ + __bsp_LED7_IS_ACTIVE_LOW__) +# define __bsp_LED7_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED7_BIT__, __bsp_LED7_PORT__, \ + __bsp_LED7_DDR__, \ + __bsp_LED7_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED7_DEFINES__ == 0) +# define __bsp_LED7_TURN_ON__() /* no LED */ +# define __bsp_LED7_TURN_OFF__() /* no LED */ +# define __bsp_LED7_TOGGLE__() /* no LED */ +# define __bsp_LED7_IS_ON__() /* no LED */ 0 +# define __bsp_LED7_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED7." +#endif + +/* ------------------------- populate LED8 macros ------------------------- */ +#define __bsp_NUM_LED8_DEFINES__ ((defined __bsp_LED8_BIT__) + \ + (defined __bsp_LED8_PORT__) + \ + (defined __bsp_LED8_DDR__) + \ + (defined __bsp_LED8_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED8_DEFINES__ == 4) +# define __bsp_LED8_TURN_ON__() __bsp_LED_TURN_ON__(__bsp_LED8_BIT__, __bsp_LED8_PORT__, \ + __bsp_LED8_DDR__, \ + __bsp_LED8_IS_ACTIVE_LOW__) +# define __bsp_LED8_TURN_OFF__() __bsp_LED_TURN_OFF__(__bsp_LED8_BIT__, __bsp_LED8_PORT__, \ + __bsp_LED8_DDR__, \ + __bsp_LED8_IS_ACTIVE_LOW__) +# define __bsp_LED8_TOGGLE__() __bsp_LED_TOGGLE__(__bsp_LED8_BIT__, __bsp_LED8_PORT__, \ + __bsp_LED8_DDR__, \ + __bsp_LED8_IS_ACTIVE_LOW__) +# define __bsp_LED8_IS_ON__() __bsp_LED_IS_ON__(__bsp_LED8_BIT__, __bsp_LED8_PORT__, \ + __bsp_LED8_DDR__, \ + __bsp_LED8_IS_ACTIVE_LOW__) +# define __bsp_LED8_CONFIG__() __bsp_LED_CONFIG__(__bsp_LED8_BIT__, __bsp_LED8_PORT__, \ + __bsp_LED8_DDR__, \ + __bsp_LED8_IS_ACTIVE_LOW__) +#elif (__bsp_NUM_LED8_DEFINES__ == 0) +# define __bsp_LED8_TURN_ON__() /* no LED */ +# define __bsp_LED8_TURN_OFF__() /* no LED */ +# define __bsp_LED8_TOGGLE__() /* no LED */ +# define __bsp_LED8_IS_ON__() /* no LED */ 0 +# define __bsp_LED8_CONFIG__() /* no LED */ +#else +# error "ERROR: Incomplete number of macros for LED8." +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* -------------------- number of LEDs defined -------------------- */ +#ifndef __bsp_NUM_LEDS__ +# error "ERROR: Number of LEDs is not specified." +#else +# if ((__bsp_NUM_LEDS__ > 8) || (__bsp_NUM_LEDS__ < 0)) +# error "ERROR: Unsupported number of LEDs specified. Maximum is eight." +# endif +#endif + +#if (((__bsp_NUM_LED1_DEFINES__ != 0) + \ + (__bsp_NUM_LED2_DEFINES__ != 0) + \ + (__bsp_NUM_LED3_DEFINES__ != 0) + \ + (__bsp_NUM_LED4_DEFINES__ != 0) + \ + (__bsp_NUM_LED5_DEFINES__ != 0) + \ + (__bsp_NUM_LED6_DEFINES__ != 0) + \ + (__bsp_NUM_LED7_DEFINES__ != 0) + \ + (__bsp_NUM_LED8_DEFINES__ != 0)) != __bsp_NUM_LEDS__) +# error "ERROR: Inconsistency between defined macros and specified number of LEDs." +#endif + +/* -------------------- blink delay loop count -------------------- */ +#ifndef __bsp_LED_BLINK_LOOP_COUNT__ +# error "ERROR: Blink delay count is missing." +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_leds.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_leds.c new file mode 100755 index 0000000..eac9f5f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_leds.c @@ -0,0 +1,107 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic LED driver code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_leds.h" +#include "bsp_led_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CONFIG_LED1() __bsp_LED1_CONFIG__() +#define BSP_CONFIG_LED2() __bsp_LED2_CONFIG__() +#define BSP_CONFIG_LED3() __bsp_LED3_CONFIG__() +#define BSP_CONFIG_LED4() __bsp_LED4_CONFIG__() +#define BSP_CONFIG_LED5() __bsp_LED5_CONFIG__() +#define BSP_CONFIG_LED6() __bsp_LED6_CONFIG__() +#define BSP_CONFIG_LED7() __bsp_LED7_CONFIG__() +#define BSP_CONFIG_LED8() __bsp_LED8_CONFIG__() + +#ifdef __bsp_LED_EXTENDED_CONFIG__ +# define BSP_LED_EXTENDED_CONFIG() __bsp_LED_EXTENDED_CONFIG__() +#else +# define BSP_LED_EXTENDED_CONFIG() +#endif + + +/************************************************************************************************** + * @fn BSP_InitLeds + * + * @brief Initialize LED hardware and driver. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void BSP_InitLeds(void) +{ + /* configure LEDs */ + BSP_CONFIG_LED1(); + BSP_CONFIG_LED2(); + BSP_CONFIG_LED3(); + BSP_CONFIG_LED4(); + BSP_CONFIG_LED5(); + BSP_CONFIG_LED6(); + BSP_CONFIG_LED7(); + BSP_CONFIG_LED8(); + + /* peform extended configuration if needed */ + BSP_LED_EXTENDED_CONFIG(); + + /* turn all LEDs off as power-up default */ + BSP_TURN_OFF_LED1(); + BSP_TURN_OFF_LED2(); + BSP_TURN_OFF_LED3(); + BSP_TURN_OFF_LED4(); + BSP_TURN_OFF_LED5(); + BSP_TURN_OFF_LED6(); + BSP_TURN_OFF_LED7(); + BSP_TURN_OFF_LED8(); +} + +/************************************************************************************************** + */ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h new file mode 100755 index 0000000..9e08426 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h @@ -0,0 +1,142 @@ +/************************************************************************************************** +* Filename: bsp_msp430_defs.h +* Revised: $Date: 2009-10-11 18:52:46 -0700 (Sun, 11 Oct 2009) $ +* Revision: $Revision: 20897 $ +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * MCU : Texas Instruments MSP430 family + * Microcontroller definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_MSP430_DEFS_H +#define BSP_MSP430_DEFS_H + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_MCU_MSP430 + +/* ------------------------------------------------------------------------------------------------ + * Compiler Abstraction + * ------------------------------------------------------------------------------------------------ + */ + +/* ---------------------- IAR Compiler ---------------------- */ +#ifdef __IAR_SYSTEMS_ICC__ +# define BSP_COMPILER_IAR + +# if (__VER__ < 342) +# error "ERROR: This IAR compiler port requires at least revision v3.42A." + +/* + * Compiler versions previous to v3.42A do not have the universal msp430.h include file. + * To use an earlier version of the compiler, replace the above #error statement with + * the appropriate, device specific #include statement. + */ +# endif + +/* Workaround for release v3.42A - the msp430.h file did not include support for some devices */ +# if ((__VER__ == 342) && (__SUBVERSION__ == 'A')) && \ + (defined (__MSP430F1610__) || defined (__MSP430F1611__) || defined (__MSP430F1612__)) +# include +# else +# include +# endif + +# define __bsp_ISTATE_T__ istate_t +# define __bsp_ISR_FUNCTION__(f, v) __bsp_QUOTED_PRAGMA__(vector = v) __interrupt void f(void); \ + __bsp_QUOTED_PRAGMA__(vector = v) __interrupt void f(void) + +/* Initialization call provided in IAR environment before standard C-startup */ +# include +# define BSP_EARLY_INIT(void) __intrinsic int __low_level_init(void) + +/* ---------------------- Code Composer ---------------------- */ +#elif (defined __TI_COMPILER_VERSION__) && (defined __MSP430__) +# define BSP_COMPILER_CODE_COMPOSER + +/* At time of 1.1.0 release, CC430 support not in msp430.h */ +# if (__CC430F6137__) +# include +# else +# include +# endif + +# define __bsp_ISTATE_T__ unsigned short +# define __bsp_ISR_FUNCTION__(f, v) __bsp_QUOTED_PRAGMA__(vector = v) __interrupt void f(void) + +/* Initialization call provided in CCE environment before standard C-startup */ +// [BM] Cannot have a second low level init! Already done by application! +//#define BSP_EARLY_INIT(void) int _system_pre_init(void) + +/* ------------------ Unrecognized Compiler ------------------ */ +#else +# error "ERROR: Unknown compiler." +#endif + +#if (defined BSP_COMPILER_IAR) || (defined BSP_COMPILER_CODE_COMPOSER) +# include +# define __bsp_ENABLE_INTERRUPTS__() __enable_interrupt() +# define __bsp_DISABLE_INTERRUPTS__() __disable_interrupt() +# define __bsp_INTERRUPTS_ARE_ENABLED__() (__get_SR_register() & GIE) + +# define __bsp_GET_ISTATE__() __get_interrupt_state() +# define __bsp_RESTORE_ISTATE__(x) __set_interrupt_state(x) + +# define __bsp_QUOTED_PRAGMA__(x) _Pragma(# x) + +#endif + +/* ------------------------------------------------------------------------------------------------ + * Common + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_LITTLE_ENDIAN__ 1 +#define __bsp_CODE_MEMSPACE__ /* blank */ +#define __bsp_XDATA_MEMSPACE__ /* blank */ + +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed long int32_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; + +#ifndef NULL +# define NULL 0 +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/mrfi.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/mrfi.c new file mode 100755 index 0000000..a8b40cf --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/mrfi.c @@ -0,0 +1,87 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Top-level code file. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "mrfi_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * C Code Includes + * ------------------------------------------------------------------------------------------------ + */ + +/* ----- Radio Family 1 ----- */ +#if (defined MRFI_RADIO_FAMILY1) +# include "radios/family1/mrfi_radio.c" +# include "radios/family1/mrfi_spi.c" +# include "radios/common/mrfi_f1f2.c" +# include "bsp_external/mrfi_board.c" + +/* ----- Radio Family 2 ----- */ +#elif (defined MRFI_RADIO_FAMILY2) +# include "radios/family2/mrfi_radio.c" +# include "radios/common/mrfi_f1f2.c" + +/* ----- Radio Family 3 ----- */ +#elif (defined MRFI_RADIO_FAMILY3) +# include "bsp_external/mrfi_board.c" +# include "radios/family3/mrfi_spi.c" +# include "radios/family3/mrfi_radio.c" + +/* ----- Radio Family 4 ----- */ +#elif (defined MRFI_RADIO_FAMILY4) +# include "radios/family4/mrfi_radio.c" + +/* ----- Radio Family 5 ----- */ +#elif (defined MRFI_RADIO_FAMILY5) +# include "radios/family5/mrfi_radio.c" +# include "radios/family5/mrfi_radio_interface.c" + +/* ----- Radio Family 6 ----- */ +#elif (defined MRFI_RADIO_FAMILY6) +# include "radios/family6/mrfi_radio.c" + +#else +# error "ERROR: Radio family is not defined." +#endif + + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/mrfi.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/mrfi.h new file mode 100755 index 0000000..a976435 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/mrfi.h @@ -0,0 +1,190 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Include file for all MRFI services. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_H +#define MRFI_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "mrfi_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_NUM_LOGICAL_CHANS __mrfi_NUM_LOGICAL_CHANS__ + +#define MRFI_NUM_POWER_SETTINGS __mrfi_NUM_POWER_SETTINGS__ + +/* return values for MRFI_Transmit */ +#define MRFI_TX_RESULT_SUCCESS 0 +#define MRFI_TX_RESULT_FAILED 1 + +/* transmit type parameter for MRFI_Transmit */ +#define MRFI_TX_TYPE_FORCED 0 +#define MRFI_TX_TYPE_CCA 1 + +/* Network header size definition */ + +/* ********************************* NOTE **************************************** + * There is a dependency here that really shouldn't exist. A reimplementation + * is necessary to avoid it. + * + * MRFI allocates the frame buffer which means it needs to know at compile time + * how big the buffer is. This means in must know the NWK header size, the + * maximum NWK and User application payload sizes and whether Security is enabled. + * ******************************************************************************** + */ +#ifndef SMPL_SECURE +# define NWK_HDR_SIZE 3 +# define NWK_PAYLOAD MAX_NWK_PAYLOAD +#else +# define NWK_HDR_SIZE 6 +# define NWK_PAYLOAD (MAX_NWK_PAYLOAD + 4) +#endif + +/* if external code has defined a maximum payload, use that instead of default */ +#ifdef MAX_APP_PAYLOAD +# ifndef MAX_NWK_PAYLOAD +# error ERROR: MAX_NWK_PAYLOAD not defined +# endif +# if MAX_APP_PAYLOAD < NWK_PAYLOAD +# define MAX_PAYLOAD NWK_PAYLOAD +# else +# define MAX_PAYLOAD MAX_APP_PAYLOAD +# endif +# define MRFI_MAX_PAYLOAD_SIZE (MAX_PAYLOAD + NWK_HDR_SIZE) /* SimpliciTI payload size plus six + *byte overhead */ +#endif + + +/* frame definitions */ +#define MRFI_ADDR_SIZE __mrfi_ADDR_SIZE__ +#ifndef MRFI_MAX_PAYLOAD_SIZE +# define MRFI_MAX_PAYLOAD_SIZE __mrfi_MAX_PAYLOAD_SIZE__ +#endif +#define MRFI_MAX_FRAME_SIZE (MRFI_MAX_PAYLOAD_SIZE + __mrfi_FRAME_OVERHEAD_SIZE__) +#define MRFI_RX_METRICS_SIZE __mrfi_RX_METRICS_SIZE__ +#define MRFI_RX_METRICS_RSSI_OFS __mrfi_RX_METRICS_RSSI_OFS__ +#define MRFI_RX_METRICS_CRC_LQI_OFS __mrfi_RX_METRICS_CRC_LQI_OFS__ + +/* Radio States */ +#define MRFI_RADIO_STATE_UNKNOWN 0 +#define MRFI_RADIO_STATE_OFF 1 +#define MRFI_RADIO_STATE_IDLE 2 +#define MRFI_RADIO_STATE_RX 3 + +/* Platform constant used to calculate worst-case for an application + * acknowledgment delay. Used in the NWK_REPLY_DELAY() macro. + * + * + * processing time on peer + | round trip + | | max number of replays + | | | number of backoff opportunities + | | | | average number of backoffs + | | | | | */ +#define PLATFORM_FACTOR_CONSTANT (2 + 2 * \ + (MAX_HOPS * \ + (MRFI_CCA_RETRIES * (8 * MRFI_BACKOFF_PERIOD_USECS) / 1000))) + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_GET_PAYLOAD_LEN(p) __mrfi_GET_PAYLOAD_LEN__(p) +#define MRFI_SET_PAYLOAD_LEN(p, x) __mrfi_SET_PAYLOAD_LEN__(p, x) + +#define MRFI_P_DST_ADDR(p) __mrfi_P_DST_ADDR__(p) +#define MRFI_P_SRC_ADDR(p) __mrfi_P_SRC_ADDR__(p) +#define MRFI_P_PAYLOAD(p) __mrfi_P_PAYLOAD__(p) + +/* ------------------------------------------------------------------------------------------------ + * Typdefs + * ------------------------------------------------------------------------------------------------ + */ +typedef struct +{ + uint8_t frame[MRFI_MAX_FRAME_SIZE]; + uint8_t rxMetrics[MRFI_RX_METRICS_SIZE]; +} mrfiPacket_t; + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void MRFI_Init(void); + +uint8_t MRFI_Transmit(mrfiPacket_t *, uint8_t); +void MRFI_Receive(mrfiPacket_t *); +void MRFI_RxCompleteISR(void); /* populated by code using MRFI */ +uint8_t MRFI_GetRadioState(void); +void MRFI_RxOn(void); +void MRFI_RxIdle(void); +int8_t MRFI_Rssi(void); + +void MRFI_SetLogicalChannel(uint8_t); +uint8_t MRFI_SetRxAddrFilter(uint8_t *); +void MRFI_EnableRxAddrFilter(void); +void MRFI_DisableRxAddrFilter(void); +void MRFI_Sleep(void); +void MRFI_WakeUp(void); +uint8_t MRFI_RandomByte(void); + +void MRFI_DelayMs(uint16_t); +void MRFI_ReplyDelay(void); +void MRFI_PostKillSem(void); + +void MRFI_SetRFPwr(uint8_t); + +/* ------------------------------------------------------------------------------------------------ + * Global Constants + * ------------------------------------------------------------------------------------------------ + */ +extern const uint8_t mrfiBroadcastAddr[]; + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/mrfi_defs.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/mrfi_defs.h new file mode 100755 index 0000000..60d1d72 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/mrfi_defs.h @@ -0,0 +1,233 @@ +/************************************************************************************************** +* Revised: $Date: 2009-01-13 16:32:00 -0700 (Wed, 13 Jan 2009) $ +* Revision: $Revision: 18768 $ +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Definition and abstraction for radio targets. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ +#ifndef MRFI_DEFS_H +#define MRFI_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + + +/* ------------------------------------------------------------------------------------------------ + * Common Defines + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_CCA_RETRIES 4 + +#define MRFI_ASSERT(x) BSP_ASSERT(x) +#define MRFI_FORCE_ASSERT() BSP_FORCE_ASSERT() +#define MRFI_ASSERTS_ARE_ON BSP_ASSERTS_ARE_ON + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family Assigment + * ------------------------------------------------------------------------------------------------ + */ + +/* ------ Radio Family 1 ------ */ +#if (defined MRFI_CC1100) /* Sub 1 GHz RF Transceiver */ || \ + (defined MRFI_CC1101) /* Sub 1 GHz RF Transceiver */ || \ + (defined MRFI_CC1100E_470) /* Sub 1 GHz RF Transceiver (CC1100E Asia) */ || \ + (defined MRFI_CC1100E_950) /* Sub 1 GHz RF Transceiver (CC1100E Asia) */ || \ + (defined MRFI_CC2500) /* 2.4 GHz RF Transceiver */ +# define MRFI_RADIO_FAMILY1 + +/* ------ Radio Family 2 ------ */ +#elif (defined MRFI_CC1110) /* Sub 1 GHz SoC */ || \ + (defined MRFI_CC1111) /* Sub 1 GHz SoC with USB controller */ || \ + (defined MRFI_CC2510) /* 2.4 GHz SoC */ || \ + (defined MRFI_CC2511) /* 2.4 GHz SoC with USB controller */ +# define MRFI_RADIO_FAMILY2 + +/* ------ Radio Family 3 ------ */ +#elif (defined MRFI_CC2420) /* 2.4 GHz IEEE 802.15.4 RF Transceiver */ || \ + (defined MRFI_CC2520) /* 2.4 GHz IEEE 802.15.4 RF Transceiver */ + +# define MRFI_RADIO_FAMILY3 + +/* ------ Radio Family 4 ------ */ +#elif (defined MRFI_CC2430) /* 2.4 GHz IEEE 802.15.4 SoC */ || \ + (defined MRFI_CC2431) /* 2.4 GHz IEEE 802.15.4 SoC */ +# define MRFI_RADIO_FAMILY4 + +/* ------ Radio Family 5 ------ */ +#elif (defined MRFI_CC430) /* Sub 1 GHz MSP SoC */ +# define MRFI_RADIO_FAMILY5 + +/* ------ Radio Family 6 ------ */ +#elif (defined MRFI_CC2530) /* 2.4 GHz IEEE 802.15.4 SoC */ + +# define MRFI_RADIO_FAMILY6 + +#else +# error "ERROR: Unknown or missing radio selection." +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family 1 / Radio Family 2 / Radio Family 5 + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_RADIO_FAMILY1) || (defined MRFI_RADIO_FAMILY2) || (defined MRFI_RADIO_FAMILY5) + +# define __mrfi_LENGTH_FIELD_SIZE__ 1 +# define __mrfi_ADDR_SIZE__ 4 +# define __mrfi_MAX_PAYLOAD_SIZE__ 20 + +# define __mrfi_RX_METRICS_SIZE__ 2 +# define __mrfi_RX_METRICS_RSSI_OFS__ 0 +# define __mrfi_RX_METRICS_CRC_LQI_OFS__ 1 +# define __mrfi_RX_METRICS_CRC_OK_MASK__ 0x80 +# define __mrfi_RX_METRICS_LQI_MASK__ 0x7F + +# define __mrfi_NUM_LOGICAL_CHANS__ 4 +# define __mrfi_NUM_POWER_SETTINGS__ 3 + +# define __mrfi_BACKOFF_PERIOD_USECS__ 250 + +# define __mrfi_LENGTH_FIELD_OFS__ 0 +# define __mrfi_DST_ADDR_OFS__ (__mrfi_LENGTH_FIELD_OFS__ + __mrfi_LENGTH_FIELD_SIZE__) +# define __mrfi_SRC_ADDR_OFS__ (__mrfi_DST_ADDR_OFS__ + __mrfi_ADDR_SIZE__) +# define __mrfi_PAYLOAD_OFS__ (__mrfi_SRC_ADDR_OFS__ + __mrfi_ADDR_SIZE__) + +# define __mrfi_HEADER_SIZE__ (2 * __mrfi_ADDR_SIZE__) +# define __mrfi_FRAME_OVERHEAD_SIZE__ (__mrfi_LENGTH_FIELD_SIZE__ + __mrfi_HEADER_SIZE__) + +# define __mrfi_GET_PAYLOAD_LEN__(p) ((p)->frame[__mrfi_LENGTH_FIELD_OFS__] - \ + __mrfi_HEADER_SIZE__) +# define __mrfi_SET_PAYLOAD_LEN__(p, x) st( \ + (p)->frame[__mrfi_LENGTH_FIELD_OFS__] = x + __mrfi_HEADER_SIZE__; ) + +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family 3 / Radio Family 4 / Radio Family 6 + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_RADIO_FAMILY3) || (defined MRFI_RADIO_FAMILY4) || (defined MRFI_RADIO_FAMILY6) + +# define __mrfi_LENGTH_FIELD_SIZE__ 1 +# define __mrfi_FCF_SIZE__ 2 +# define __mrfi_DSN_SIZE__ 1 +# define __mrfi_ADDR_SIZE__ 4 +# define __mrfi_MAX_PAYLOAD_SIZE__ 20 + +# define __mrfi_RX_METRICS_SIZE__ 2 +# define __mrfi_RX_METRICS_RSSI_OFS__ 0 +# define __mrfi_RX_METRICS_CRC_LQI_OFS__ 1 +# define __mrfi_RX_METRICS_CRC_OK_MASK__ 0x80 +# define __mrfi_RX_METRICS_LQI_MASK__ 0x7F + +# define __mrfi_NUM_LOGICAL_CHANS__ 4 +# define __mrfi_NUM_POWER_SETTINGS__ 3 + +# define __mrfi_BACKOFF_PERIOD_USECS__ 250 + +# define __mrfi_LENGTH_FIELD_OFS__ 0 +# define __mrfi_FCF_OFS__ (__mrfi_LENGTH_FIELD_OFS__ + \ + __mrfi_LENGTH_FIELD_SIZE__) +# define __mrfi_DSN_OFS__ (__mrfi_FCF_OFS__ + __mrfi_FCF_SIZE__) +# define __mrfi_DST_ADDR_OFS__ (__mrfi_DSN_OFS__ + __mrfi_DSN_SIZE__) +# define __mrfi_SRC_ADDR_OFS__ (__mrfi_DST_ADDR_OFS__ + __mrfi_ADDR_SIZE__) +# define __mrfi_PAYLOAD_OFS__ (__mrfi_SRC_ADDR_OFS__ + __mrfi_ADDR_SIZE__) + +# define __mrfi_HEADER_SIZE__ ((2 * \ + __mrfi_ADDR_SIZE__) + __mrfi_FCF_SIZE__ + \ + __mrfi_DSN_SIZE__) +# define __mrfi_FRAME_OVERHEAD_SIZE__ (__mrfi_LENGTH_FIELD_SIZE__ + __mrfi_HEADER_SIZE__) + +# define __mrfi_GET_PAYLOAD_LEN__(p) ((p)->frame[__mrfi_LENGTH_FIELD_OFS__] - \ + __mrfi_HEADER_SIZE__) +# define __mrfi_SET_PAYLOAD_LEN__(p, x) st( \ + (p)->frame[__mrfi_LENGTH_FIELD_OFS__] = x + __mrfi_HEADER_SIZE__; ) + +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family Commonality + * ------------------------------------------------------------------------------------------------ + */ +#define __mrfi_P_DST_ADDR__(p) (&((p)->frame[__mrfi_DST_ADDR_OFS__])) +#define __mrfi_P_SRC_ADDR__(p) (&((p)->frame[__mrfi_SRC_ADDR_OFS__])) +#define __mrfi_P_PAYLOAD__(p) (&((p)->frame[__mrfi_PAYLOAD_OFS__])) + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* verify that only one supported radio is selected */ +#define MRFI_NUM_SUPPORTED_RADIOS_SELECTED ((defined MRFI_CC1100) + \ + (defined MRFI_CC1101) + \ + (defined MRFI_CC1110) + \ + (defined MRFI_CC1111) + \ + (defined MRFI_CC1100E_470) + \ + (defined MRFI_CC1100E_950) + \ + (defined MRFI_CC2500) + \ + (defined MRFI_CC2510) + \ + (defined MRFI_CC2511) + \ + (defined MRFI_CC2430) + \ + (defined MRFI_CC2431) + \ + (defined MRFI_CC2520) + \ + (defined MRFI_CC430) + \ + (defined MRFI_CC2530)) +#if (MRFI_NUM_SUPPORTED_RADIOS_SELECTED == 0) +# error "ERROR: A valid radio is not selected." +#elif (MRFI_NUM_SUPPORTED_RADIOS_SELECTED > 1) +# error "ERROR: More than one radio is selected." +#endif + +/* verify that a radio family is selected */ +#if (!defined MRFI_RADIO_FAMILY1) && \ + (!defined MRFI_RADIO_FAMILY2) && \ + (!defined MRFI_RADIO_FAMILY3) && \ + (!defined MRFI_RADIO_FAMILY4) && \ + (!defined MRFI_RADIO_FAMILY5) && \ + (!defined MRFI_RADIO_FAMILY6) +# error "ERROR: A radio family has not been assigned." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c new file mode 100755 index 0000000..5569553 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c @@ -0,0 +1,1824 @@ +/************************************************************************************************** +* Revised: $Date: 2009-11-23 07:50:43 -0800 (Mon, 23 Nov 2009) $ +* Revision: $Revision: 21225 $ +* +* Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS? +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radios: CC430 + * Primary code file for supported radios. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include +#include "mrfi.h" +#include "bsp.h" +#include "bsp_macros.h" +#include "bsp_external/mrfi_board_defs.h" +#include "mrfi_defs.h" +#include "mrfi_radio_interface.h" +#include "smartrf/CC430/smartrf_CC430.h" + +/* ------------------------------------------------------------------------------------------------ + * Global Constants + * ------------------------------------------------------------------------------------------------ + */ +const uint8_t mrfiBroadcastAddr[] = { 0xFF, 0xFF, 0xFF, 0xFF }; + +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(MRFI_ADDR_SIZE == + ((sizeof(mrfiBroadcastAddr) / + sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0]))); + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_CC430) +# define MRFI_RSSI_OFFSET 74 /* no units */ +#else +# error "ERROR: RSSI offset value not defined for this radio" +#endif + +#define MRFI_LENGTH_FIELD_OFS __mrfi_LENGTH_FIELD_OFS__ +#define MRFI_LENGTH_FIELD_SIZE __mrfi_LENGTH_FIELD_SIZE__ +#define MRFI_HEADER_SIZE __mrfi_HEADER_SIZE__ +#define MRFI_FRAME_BODY_OFS __mrfi_DST_ADDR_OFS__ +#define MRFI_BACKOFF_PERIOD_USECS __mrfi_BACKOFF_PERIOD_USECS__ + +#define MRFI_RANDOM_OFFSET 67 +#define MRFI_RANDOM_MULTIPLIER 109 +#define MRFI_MIN_SMPL_FRAME_SIZE (MRFI_HEADER_SIZE + NWK_HDR_SIZE) + +/* rx metrics definitions, known as appended "packet status bytes" in datasheet parlance */ +#define MRFI_RX_METRICS_CRC_OK_MASK __mrfi_RX_METRICS_CRC_OK_MASK__ +#define MRFI_RX_METRICS_LQI_MASK __mrfi_RX_METRICS_LQI_MASK__ + + +/* ---------- Radio Abstraction ---------- */ + +#define MRFI_RADIO_PARTNUM 0x00 +#define MRFI_RADIO_VERSION 0x06 + +/* GDO0 == PA_PD signal */ +#define MRFI_SETTING_IOCFG0 27 + +/* GDO1 == RSSI_VALID signal */ +#define MRFI_SETTING_IOCFG1 30 + +/* Main Radio Control State Machine control configuration: + * Auto Calibrate - when going from IDLE to RX/TX + * XOSC is OFF in Sleep state. + */ +#define MRFI_SETTING_MCSM0 (0x10) + +/* Main Radio Control State Machine control configuration: + * - Remain RX state after RX + * - Go to IDLE after TX + * - RSSI below threshold and NOT receiving. + */ +#define MRFI_SETTING_MCSM1 0x3C + +/* + * Packet Length - Setting for maximum allowed packet length. + * The PKTLEN setting does not include the length field but maximum frame size does. + * Subtract length field size from maximum frame size to get value for PKTLEN. + */ +#define MRFI_SETTING_PKTLEN (MRFI_MAX_FRAME_SIZE - MRFI_LENGTH_FIELD_SIZE) + +/* Packet automation control - Original value except WHITE_DATA is extracted from SmartRF setting. + **/ +#define MRFI_SETTING_PKTCTRL0 (0x05 | (SMARTRF_SETTING_PKTCTRL0 & BV(6))) + +/* FIFO threshold - this register has fields that need to be configured for the CC1101 */ +#define MRFI_SETTING_FIFOTHR (0x07 | (SMARTRF_SETTING_FIFOTHR & (BV(4) | BV(5) | BV(6) | BV(7)))) + +/* Max time we can be in a critical section within the delay function. + * This could be fine-tuned by observing the overhead is calling the bsp delay + * function. The overhead should be very small compared to this value. + */ +#define MRFI_MAX_DELAY_US 16 /* usec */ + +/* Packet automation control - base value is power up value whick has APPEND_STATUS enabled; no CRC + *autoflush */ +#define PKTCTRL1_BASE_VALUE BV(2) +#define PKTCTRL1_ADDR_FILTER_OFF PKTCTRL1_BASE_VALUE +#define PKTCTRL1_ADDR_FILTER_ON (PKTCTRL1_BASE_VALUE | (BV(0) | BV(1))) + +#ifdef MRFI_ASSERTS_ARE_ON +# define RX_FILTER_ADDR_INITIAL_VALUE 0xFF +#endif + +/* The SW timer is calibrated by adjusting the call to the microsecond delay + * routine. This allows maximum calibration control with repects to the longer + * times requested by applicationsd and decouples internal from external calls + * to the microsecond routine which can be calibrated independently. + */ +#if defined(SW_TIMER) +# define APP_USEC_VALUE 1000 +#else +# define APP_USEC_VALUE 1000 +#endif + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_ENABLE_SYNC_PIN_INT() (RF1AIE |= BV(9)) +#define MRFI_DISABLE_SYNC_PIN_INT() (RF1AIE &= ~BV(9)) +#define MRFI_CLEAR_SYNC_PIN_INT_FLAG() (RF1AIFG &= ~BV(9)) +#define MRFI_SYNC_PIN_INT_IS_ENABLED() (RF1AIE & BV(9)) +#define MRFI_SYNC_PIN_IS_HIGH() (RF1AIN & BV(9)) +#define MRFI_SYNC_PIN_INT_FLAG_IS_SET() (RF1AIFG & BV(9)) + + +#define MRFI_CLEAR_PAPD_PIN_INT_FLAG() (RF1AIFG &= ~BV(0)) +#define MRFI_PAPD_PIN_IS_HIGH() (RF1AIN & BV(0)) +#define MRFI_PAPD_INT_FLAG_IS_SET() (RF1AIFG & BV(0)) + + +/* RSSI valid signal is available on the GDO_1 */ +#define MRFI_RSSI_VALID_WAIT() while (!(RF1AIN & BV(1))) ; + + +/* Abstract radio interface calls. Could use these later to + * merge code from similar radio but different interface. + */ +#define MRFI_STROBE(cmd) mrfiRadioInterfaceCmdStrobe(cmd) +#define MRFI_RADIO_REG_READ(reg) mrfiRadioInterfaceReadReg(reg) +#define MRFI_RADIO_REG_WRITE(reg, value) mrfiRadioInterfaceWriteReg(reg, value) +#define MRFI_RADIO_WRITE_TX_FIFO(pData, len) mrfiRadioInterfaceWriteTxFifo(pData, len) +#define MRFI_RADIO_READ_RX_FIFO(pData, len) mrfiRadioInterfaceReadRxFifo(pData, len) + + +#define MRFI_STROBE_IDLE_AND_WAIT() \ + { \ + MRFI_STROBE(SIDLE); \ + /* Wait for XOSC to be stable and radio in IDLE state */ \ + while (MRFI_STROBE(SNOP) & 0xF0) ; \ + } + + +/* ------------------------------------------------------------------------------------------------ + * Local Constants + * ------------------------------------------------------------------------------------------------ + */ +const uint8_t mrfiRadioCfg[][2] = +{ + /* internal radio configuration */ + { IOCFG0, MRFI_SETTING_IOCFG0 }, /* Configure GDO_0 to output PA_PD signal (low during + *TX, high otherwise). */ + { IOCFG1, MRFI_SETTING_IOCFG1 }, /* Configure GDO_1 to output RSSI_VALID signal (high + *when RSSI is valid, low otherwise). */ + { MCSM1, MRFI_SETTING_MCSM1 }, /* CCA mode, RX_OFF_MODE and TX_OFF_MODE */ + { MCSM0, MRFI_SETTING_MCSM0 }, /* AUTO_CAL and XOSC state in sleep */ + { PKTLEN, MRFI_SETTING_PKTLEN }, + { PKTCTRL0, MRFI_SETTING_PKTCTRL0 }, + { FIFOTHR, MRFI_SETTING_FIFOTHR }, + + /* imported SmartRF radio configuration */ + + { FSCTRL1, SMARTRF_SETTING_FSCTRL1 }, + { FSCTRL0, SMARTRF_SETTING_FSCTRL0 }, + { FREQ2, SMARTRF_SETTING_FREQ2 }, + { FREQ1, SMARTRF_SETTING_FREQ1 }, + { FREQ0, SMARTRF_SETTING_FREQ0 }, + { MDMCFG4, SMARTRF_SETTING_MDMCFG4 }, + { MDMCFG3, SMARTRF_SETTING_MDMCFG3 }, + { MDMCFG2, SMARTRF_SETTING_MDMCFG2 }, + { MDMCFG1, SMARTRF_SETTING_MDMCFG1 }, + { MDMCFG0, SMARTRF_SETTING_MDMCFG0 }, + { DEVIATN, SMARTRF_SETTING_DEVIATN }, + { FOCCFG, SMARTRF_SETTING_FOCCFG }, + { BSCFG, SMARTRF_SETTING_BSCFG }, + { AGCCTRL2, SMARTRF_SETTING_AGCCTRL2 }, + { AGCCTRL1, SMARTRF_SETTING_AGCCTRL1 }, + { AGCCTRL0, SMARTRF_SETTING_AGCCTRL0 }, + { FREND1, SMARTRF_SETTING_FREND1 }, + { FREND0, SMARTRF_SETTING_FREND0 }, + { FSCAL3, SMARTRF_SETTING_FSCAL3 }, + { FSCAL2, SMARTRF_SETTING_FSCAL2 }, + { FSCAL1, SMARTRF_SETTING_FSCAL1 }, + { FSCAL0, SMARTRF_SETTING_FSCAL0 }, + { TEST2, SMARTRF_SETTING_TEST2 }, + { TEST1, SMARTRF_SETTING_TEST1 }, + { TEST0, SMARTRF_SETTING_TEST0 }, +}; + + +/* + * Logical channel table - this table translates logical channel into + * actual radio channel number. Channel 0, the default channel, is + * determined by the channel exported from SmartRF Studio. The other + * table entries are derived from that default. Each derived channel is + * masked with 0xFF to prevent generation of an illegal channel number. + * + * This table is easily customized. Just replace or add entries as needed. + * If the number of entries changes, the corresponding #define must also + * be adjusted. It is located in mrfi_defs.h and is called __mrfi_NUM_LOGICAL_CHANS__. + * The static assert below ensures that there is no mismatch. + */ +// [BM] Changed channel assignment to comply with local regulations +#ifdef ISM_EU +static const uint8_t mrfiLogicalChanTable[] = +{ + 0, + 50, + 80, + 110 +}; +#else +# ifdef ISM_US +static const uint8_t mrfiLogicalChanTable[] = +{ + 20, + 50, + 80, + 110 +}; +# else +# ifdef ISM_LF +static const uint8_t mrfiLogicalChanTable[] = +{ + 0, + 50, + 80, + 110 +}; +# else +# error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" +# endif +# endif +#endif +//static const uint8_t mrfiLogicalChanTable[] = +//{ +// SMARTRF_SETTING_CHANNR, +// 50, +// 80, +// 110 +//}; +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(__mrfi_NUM_LOGICAL_CHANS__ == + ((sizeof(mrfiLogicalChanTable) / + sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0]))); + +/* + * RF Power setting table - this table translates logical power value + * to radio register setting. The logical power value is used directly + * as an index into the power setting table. The values in the table are + * from low to high. The default settings set 3 values: -20 dBm, -10 dBm, + * and 0 dBm. The default at startup is the highest value. Note that these + * are approximate depending on the radio. Information is taken from the + * data sheet. + * + * This table is easily customized. Just replace or add entries as needed. + * If the number of entries changes, the corresponding #define must also + * be adjusted. It is located in mrfi_defs.h and is called __mrfi_NUM_POWER_SETTINGS__. + * The static assert below ensures that there is no mismatch. + * + * For the CC430 use the CC1100 values. + */ +static const uint8_t mrfiRFPowerTable[] = +{ + // [BM] Changed default output power to comply with dongle settings + 0x0F, + 0x27, + // [BM] Increase output power from -0.3dBm to +1.4dBm (433MHz) / +1.1dBm (868MHz) / +1.3dBm + // (915MHz) to compensate antenna loss +#ifdef ISM_EU + 0x8C +#else +# ifdef ISM_US + 0x8B +# else +# ifdef ISM_LF + 0x8D +# else +# error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" +# endif +# endif +#endif +}; +//static const uint8_t mrfiRFPowerTable[] = +//{ +// 0x0D, +// 0x34, +// 0x8E +//}; + +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(__mrfi_NUM_POWER_SETTINGS__ == + ((sizeof(mrfiRFPowerTable) / + sizeof(mrfiRFPowerTable[0])) * sizeof(mrfiRFPowerTable[0]))); + +/* ------------------------------------------------------------------------------------------------ + * Local Prototypes + * ------------------------------------------------------------------------------------------------ + */ +static void Mrfi_SyncPinRxIsr(void); +static void Mrfi_RxModeOn(void); +static void Mrfi_RandomBackoffDelay(void); +static void Mrfi_RxModeOff(void); +static void Mrfi_DelayUsec(uint16_t howLong); +static void Mrfi_DelayUsecSem(uint16_t howLong); +static int8_t Mrfi_CalculateRssi(uint8_t rawValue); +static uint8_t Mrfi_RxAddrIsFiltered(uint8_t * pAddr); + + +/* ------------------------------------------------------------------------------------------------ + * Local Variables + * ------------------------------------------------------------------------------------------------ + */ +static uint8_t mrfiRadioState = MRFI_RADIO_STATE_UNKNOWN; +static mrfiPacket_t mrfiIncomingPacket; +static uint8_t mrfiRndSeed = 0; + +/* reply delay support */ +static volatile uint8_t sKillSem = 0; +static volatile uint8_t sReplyDelayContext = 0; +static uint16_t sReplyDelayScalar = 0; +static uint16_t sBackoffHelper = 0; + +static uint8_t mrfiRxFilterEnabled = 0; +static uint8_t mrfiRxFilterAddr[MRFI_ADDR_SIZE] = { RX_FILTER_ADDR_INITIAL_VALUE }; + +/* These counters are only for diagnostic purpose */ +static uint32_t crcFail = 0; +static uint32_t crcPass = 0; +static uint32_t noFrame = 0; + +// [BM] Radio frequency offset read from calibration memory +// Compensates crystal deviation from 26MHz nominal value +extern unsigned char rf_frequoffset; + +/************************************************************************************************** + * @fn MRFI_Init + * + * @brief Initialize MRFI. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_Init(void) +{ + /* ------------------------------------------------------------------ + * Radio power-up reset + * ---------------------- + */ + memset(&mrfiIncomingPacket, 0x0, sizeof(mrfiIncomingPacket)); + + /* Initialize the radio interface */ + mrfiRadioInterfaceInit(); + + /* Strobe Reset: Resets the radio and puts it in SLEEP state. */ + MRFI_STROBE(SRES); + + /* verify the correct radio is installed */ + MRFI_ASSERT(MRFI_RADIO_REG_READ(PARTNUM) == MRFI_RADIO_PARTNUM); /* incorrect radio specified + **/ + MRFI_ASSERT(MRFI_RADIO_REG_READ(VERSION) == MRFI_RADIO_VERSION); /* incorrect radio specified + * */ + + /* Put radio in Idle state */ + MRFI_STROBE_IDLE_AND_WAIT(); + + + /* ------------------------------------------------------------------ + * Configure radio + * ----------------- + */ + + /* Configure Radio interrupts: + * + * RF1AIN_0 => Programmed to PA_PD signal. + * Configure it to interrupt on falling edge. + * + * RF1AIN_1 => Programmed to RSSI Valid signal. + * No need to configure for interrupt. This value will be read + * through polling. + * + * RF1AIN_9 => Rising edge indicates SYNC sent/received and + * Falling edge indicates end of packet. + * Configure it to interrupt on falling edge. + */ + + /* Select Interrupt edge for PA_PD and SYNC signal: + * Interrupt Edge select register: 1 == Interrupt on High to Low transition. + */ + RF1AIES = BV(0) | BV(9); + + /* Write the power output to the PA_TABLE and verify the write operation. */ + { + uint8_t readbackPATableValue = 0; + bspIState_t s; + + BSP_ENTER_CRITICAL_SECTION(s); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRW = 0x7E51; /* PA Table write (burst) */ + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; /* reset pointer */ + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = 0xFE; /* PA Table read (burst) */ + + while (!(RF1AIFCTL1 & RFDINIFG)) ; + RF1ADINB = 0x00; /* dummy write */ + + while (!(RF1AIFCTL1 & RFDOUTIFG)) ; + readbackPATableValue = RF1ADOUT0B; + + MRFI_ASSERT(readbackPATableValue == 0x51); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; + + BSP_EXIT_CRITICAL_SECTION(s); + } + + /* initialize radio registers */ + { + uint8_t i; + + for (i = 0; i < (sizeof(mrfiRadioCfg) / sizeof(mrfiRadioCfg[0])); i++) + { + MRFI_RADIO_REG_WRITE(mrfiRadioCfg[i][0], mrfiRadioCfg[i][1]); + } + } + + /* Confirm that the values were written correctly. + */ + { + uint8_t i; + + for (i = 0; i < (sizeof(mrfiRadioCfg) / sizeof(mrfiRadioCfg[0])); i++) + { + MRFI_ASSERT(mrfiRadioCfg[i][1] == MRFI_RADIO_REG_READ(mrfiRadioCfg[i][0])); + } + } + + // [BM] Apply global frequency offset to FSCTRL0 + MRFI_STROBE_IDLE_AND_WAIT(); + MRFI_RADIO_REG_WRITE(FSCTRL0, rf_frequoffset); + + /* set default channel */ + MRFI_SetLogicalChannel(0); + + /* Set default power level */ + MRFI_SetRFPwr(MRFI_NUM_POWER_SETTINGS - 1); + + /* Generate Random seed: + * We will use the RSSI value to generate our random seed. + */ + + /* Put the radio in RX state */ + MRFI_STROBE(SRX); + + /* delay for the rssi to be valid */ + MRFI_RSSI_VALID_WAIT(); + + { + uint8_t i; + for (i = 0; i < 16; i++) + { + /* use most random bit of rssi to populate the random seed */ + mrfiRndSeed = (mrfiRndSeed << 1) | (MRFI_RADIO_REG_READ(RSSI) & 0x01); + } + } + + /* Force the seed to be non-zero by setting one bit, just in case... */ + mrfiRndSeed |= 0x0080; + + /* Turn off RF. */ + Mrfi_RxModeOff(); + + /* Strobe Power Down (SPWD): puts the radio in SLEEP state. */ + + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + MRFI_STROBE(SXOFF); + + /* Initial radio state is IDLE state */ + mrfiRadioState = MRFI_RADIO_STATE_OFF; + + /***************************************************************************************** + * Compute reply delay scalar + * + * Formula from data sheet for all the narrow band radios is: + * + * (256 + DATAR_Mantissa) * 2^(DATAR_Exponent) + * DATA_RATE = ------------------------------------------ * f(xosc) + * 2^28 + * + * To try and keep some accuracy we change the exponent of the denominator + * to (28 - (exponent from the configuration register)) so we do a division + * by a smaller number. We find the power of 2 by shifting. + * + * The maximum delay needed depends on the MAX_APP_PAYLOAD parameter. Figure + * out how many bits that will be when overhead is included. Bits/bits-per-second + * is seconds to transmit (or receive) the maximum frame. We multiply this number + * by 1000 to find the time in milliseconds. We then additionally multiply by + * 10 so we can add 5 and divide by 10 later, thus rounding up to the number of + * milliseconds. This last won't matter for slow transmissions but for faster ones + * we want to err on the side of being conservative and making sure the radio is on + * to receive the reply. The semaphore monitor will shut it down. The delay adds in + * a fudge factor that includes processing time on peer plus lags in Rx and processing + * time on receiver's side. + * + * Note that we assume a 26 MHz clock for the radio... + * *************************************************************************************** + */ +#define MRFI_RADIO_OSC_FREQ 26000000 +#define PHY_PREAMBLE_SYNC_BYTES 8 + + { + uint32_t dataRate, bits; + uint16_t exponent, mantissa; + + /* mantissa is in MDMCFG3 */ + mantissa = 256 + SMARTRF_SETTING_MDMCFG3; + + /* exponent is lower nibble of MDMCFG4. */ + exponent = 28 - (SMARTRF_SETTING_MDMCFG4 & 0x0F); + + /* we can now get data rate */ + dataRate = mantissa * (MRFI_RADIO_OSC_FREQ >> exponent); + + bits = ((uint32_t)((PHY_PREAMBLE_SYNC_BYTES + MRFI_MAX_FRAME_SIZE) * 8)) * 10000; + + /* processing on the peer + the Tx/Rx time plus more */ + sReplyDelayScalar = PLATFORM_FACTOR_CONSTANT + (((bits / dataRate) + 5) / 10); + + /* This helper value is used to scale the backoffs during CCA. At very + * low data rates we need to backoff longer to prevent continual sampling + * of valid frames which take longer to send at lower rates. Use the scalar + * we just calculated divided by 32. With the backoff algorithm backing + * off up to 16 periods this will result in waiting up to about 1/2 the total + * scalar value. For high data rates this does not contribute at all. Value + * is in microseconds. + */ + sBackoffHelper = MRFI_BACKOFF_PERIOD_USECS + (sReplyDelayScalar >> 5) * 1000; + } + + /* Clean out buffer to protect against spurious frames */ + memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame)); + memset(mrfiIncomingPacket.rxMetrics, 0x00, sizeof(mrfiIncomingPacket.rxMetrics)); + + /* enable global interrupts */ + BSP_ENABLE_INTERRUPTS(); +} + +/************************************************************************************************** + * @fn MRFI_Transmit + * + * @brief Transmit a packet using CCA algorithm. + * + * @param pPacket - pointer to packet to transmit + * + * @return Return code indicates success or failure of transmit: + * MRFI_TX_RESULT_SUCCESS - transmit succeeded + * MRFI_TX_RESULT_FAILED - transmit failed because CCA failed + ************************************************************************************************** + */ + +uint8_t MRFI_Transmit(mrfiPacket_t * pPacket, uint8_t txType) +{ + uint8_t ccaRetries; + uint8_t txBufLen; + uint8_t returnValue = MRFI_TX_RESULT_SUCCESS; + + /* radio must be awake to transmit */ + MRFI_ASSERT(mrfiRadioState != MRFI_RADIO_STATE_OFF); + + /* Turn off reciever. We can ignore/drop incoming packets during transmit. */ + Mrfi_RxModeOff(); + + /* compute number of bytes to write to transmit FIFO */ + txBufLen = pPacket->frame[MRFI_LENGTH_FIELD_OFS] + MRFI_LENGTH_FIELD_SIZE; + + /* ------------------------------------------------------------------ + * Write packet to transmit FIFO + * -------------------------------- + */ + MRFI_RADIO_WRITE_TX_FIFO(&(pPacket->frame[0]), txBufLen); + + + /* ------------------------------------------------------------------ + * Immediate transmit + * --------------------- + */ + if (txType == MRFI_TX_TYPE_FORCED) + { + /* Issue the TX strobe. */ + MRFI_STROBE(STX); + + /* Wait for transmit to complete */ + while (!MRFI_SYNC_PIN_INT_FLAG_IS_SET()) ; + + /* Clear the interrupt flag */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + } + else + { + /* ------------------------------------------------------------------ + * CCA transmit + * --------------- + */ + + MRFI_ASSERT(txType == MRFI_TX_TYPE_CCA); + + /* set number of CCA retries */ + ccaRetries = MRFI_CCA_RETRIES; + + + /* =============================================================================== + * Main Loop + * ============= + */ + for (;;) + { + /* Radio must be in RX mode for CCA to happen. + * Otherwise it will transmit without CCA happening. + */ + + /* Can not use the Mrfi_RxModeOn() function here since it turns on the + * Rx interrupt, which we don't want in this case. + */ + MRFI_STROBE(SRX); + + /* wait for the rssi to be valid. */ + MRFI_RSSI_VALID_WAIT(); + + /* + * Clear the PA_PD pin interrupt flag. This flag, not the interrupt itself, + * is used to capture the transition that indicates a transmit was started. + * The pin level cannot be used to indicate transmit success as timing may + * prevent the transition from being detected. The interrupt latch captures + * the event regardless of timing. + */ + MRFI_CLEAR_PAPD_PIN_INT_FLAG(); + + /* send strobe to initiate transmit */ + MRFI_STROBE(STX); + + /* Delay long enough for the PA_PD signal to indicate a + * successful transmit. This is the 250 XOSC periods + * (9.6 us for a 26 MHz crystal). + * Found out that we need a delay of atleast 25 us on CC1100 to see + * the PA_PD signal change. Hence keeping the same for CC430 + */ + Mrfi_DelayUsec(25); + + + /* PA_PD signal goes from HIGH to LOW when going from RX to TX state. + * This transition is trapped as a falling edge interrupt flag + * to indicate that CCA passed and the transmit has started. + */ + if (MRFI_PAPD_INT_FLAG_IS_SET()) + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment passed. + * ---------------------------------- + */ + + /* Clear the PA_PD int flag */ + MRFI_CLEAR_PAPD_PIN_INT_FLAG(); + + /* PA_PD signal stays LOW while in TX state and goes back to HIGH when + * the radio transitions to RX state. + */ + /* wait for transmit to complete */ + while (!MRFI_PAPD_PIN_IS_HIGH()) ; + + /* transmit done, break */ + break; + } + else + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment failed. + * ---------------------------------- + */ + + /* Turn off radio and save some power during backoff */ + + /* NOTE: Can't use Mrfi_RxModeOff() - since it tries to update the + * sync signal status which we are not using during the TX operation. + */ + MRFI_STROBE_IDLE_AND_WAIT(); + + /* flush the receive FIFO of any residual data */ + MRFI_STROBE(SFRX); + + /* Retry ? */ + if (ccaRetries != 0) + { + /* delay for a random number of backoffs */ + Mrfi_RandomBackoffDelay(); + + /* decrement CCA retries before loop continues */ + ccaRetries--; + } + else /* No CCA retries are left, abort */ + { + /* set return value for failed transmit and break */ + returnValue = MRFI_TX_RESULT_FAILED; + break; + } + } /* CCA Failed */ + } /* CCA loop */ + } /* txType is CCA */ + + + /* Done with TX. Clean up time... */ + + /* Radio is already in IDLE state */ + + /* + * Flush the transmit FIFO. It must be flushed so that + * the next transmit can start with a clean slate. + */ + MRFI_STROBE(SFTX); + + /* If the radio was in RX state when transmit was attempted, + * put it back to Rx On state. + */ + if (mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOn(); + } + + return (returnValue); +} + +/************************************************************************************************** + * @fn MRFI_Receive + * + * @brief Copies last packet received to the location specified. + * This function is meant to be called after the ISR informs + * higher level code that there is a newly received packet. + * + * @param pPacket - pointer to location of where to copy received packet + * + * @return none + ************************************************************************************************** + */ + +void MRFI_Receive(mrfiPacket_t * pPacket) +{ + *pPacket = mrfiIncomingPacket; +} + +/************************************************************************************************** + * @fn Mrfi_SyncPinRxIsr + * + * @brief This interrupt is called when the SYNC signal transition from high to low. + * The sync signal is routed to the sync pin which is a GPIO pin. This high-to-low + * transition signifies a receive has completed. The SYNC signal also goes from + * high to low when a transmit completes. This is protected against within the + * transmit function by disabling sync pin interrupts until transmit completes. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Mrfi_SyncPinRxIsr(void) +{ + uint8_t frameLen = 0x00; + uint8_t rxBytes; + + /* We should receive this interrupt only in RX state + * Should never receive it if RX was turned On only for + * some internal mrfi processing like - during CCA. + * Otherwise something is terribly wrong. + */ + MRFI_ASSERT(mrfiRadioState == MRFI_RADIO_STATE_RX); + + /* ------------------------------------------------------------------ + * Get RXBYTES + * ------------- + */ + + /* + * Read the RXBYTES register from the radio. + * Bit description of RXBYTES register: + * bit 7 - RXFIFO_OVERFLOW, set if receive overflow occurred + * bits 6:0 - NUM_BYTES, number of bytes in receive FIFO + * + * Due a chip bug, the RXBYTES register must read the same value twice + * in a row to guarantee an accurate value. + */ + { + uint8_t rxBytesVerify; + + rxBytesVerify = MRFI_RADIO_REG_READ(RXBYTES); + + do + { + rxBytes = rxBytesVerify; + rxBytesVerify = MRFI_RADIO_REG_READ(RXBYTES); + } + while (rxBytes != rxBytesVerify); + } + + + /* ------------------------------------------------------------------ + * FIFO empty? + * ------------- + */ + + /* + * See if the receive FIFIO is empty before attempting to read from it. + * It is possible nothing the FIFO is empty even though the interrupt fired. + * This can happen if address check is enabled and a non-matching packet is + * received. In that case, the radio automatically removes the packet from + * the FIFO. + */ + if (rxBytes == 0) + { + /* receive FIFO is empty - do nothing, skip to end */ + } + else + { + /* receive FIFO is not empty, continue processing */ + + /* ------------------------------------------------------------------ + * Process frame length + * ---------------------- + */ + + /* read the first byte from FIFO - the packet length */ + MRFI_RADIO_READ_RX_FIFO(&frameLen, MRFI_LENGTH_FIELD_SIZE); + + + /* + * Make sure that the frame length just read corresponds to number of bytes in the buffer. + * If these do not match up something is wrong. + * + * This can happen for several reasons: + * 1) Incoming packet has an incorrect format or is corrupted. + * 2) The receive FIFO overflowed. Overflow is indicated by the high + * bit of rxBytes. This guarantees the value of rxBytes value will not + * match the number of bytes in the FIFO for overflow condition. + * 3) Interrupts were blocked for an abnormally long time which + * allowed a following packet to at least start filling the + * receive FIFO. In this case, all received and partially received + * packets will be lost - the packet in the FIFO and the packet coming in. + * This is the price the user pays if they implement a giant + * critical section. + * 4) A failed transmit forced radio to IDLE state to flush the transmit FIFO. + * This could cause an active receive to be cut short. + * + * Also check the sanity of the length to guard against rogue frames. + */ + if ((rxBytes != (frameLen + MRFI_LENGTH_FIELD_SIZE + MRFI_RX_METRICS_SIZE)) || + ((frameLen + MRFI_LENGTH_FIELD_SIZE) > MRFI_MAX_FRAME_SIZE) || + (frameLen < MRFI_MIN_SMPL_FRAME_SIZE) + ) + { + bspIState_t s; + noFrame++; + + /* mismatch between bytes-in-FIFO and frame length */ + + /* + * Flush receive FIFO to reset receive. Must go to IDLE state to do this. + * The critical section guarantees a transmit does not occur while cleaning up. + */ + BSP_ENTER_CRITICAL_SECTION(s); + MRFI_STROBE_IDLE_AND_WAIT(); + MRFI_STROBE(SFRX); + MRFI_STROBE(SRX); + BSP_EXIT_CRITICAL_SECTION(s); + + /* flush complete, skip to end */ + } + else + { + /* bytes-in-FIFO and frame length match up - continue processing */ + + /* ------------------------------------------------------------------ + * Get packet + * ------------ + */ + + /* clean out buffer to help protect against spurious frames */ + memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame)); + + /* set length field */ + mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFS] = frameLen; + + /* get packet from FIFO */ + MRFI_RADIO_READ_RX_FIFO(&(mrfiIncomingPacket.frame[MRFI_FRAME_BODY_OFS]), frameLen); + + /* get receive metrics from FIFO */ + MRFI_RADIO_READ_RX_FIFO(&(mrfiIncomingPacket.rxMetrics[0]), MRFI_RX_METRICS_SIZE); + + + /* ------------------------------------------------------------------ + * CRC check + * ------------ + */ + + /* + * Note! Automatic CRC check is not, and must not, be enabled. This feature + * flushes the *entire* receive FIFO when CRC fails. If this feature is + * enabled it is possible to be reading from the FIFO and have a second + * receive occur that fails CRC and automatically flushes the receive FIFO. + * This could cause reads from an empty receive FIFO which puts the radio + * into an undefined state. + */ + + /* determine if CRC failed */ + if (!(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & + MRFI_RX_METRICS_CRC_OK_MASK)) + { + /* CRC failed - do nothing, skip to end */ + crcFail++; + } + else + { + /* CRC passed - continue processing */ + crcPass++; + + /* ------------------------------------------------------------------ + * Filtering + * ----------- + */ + + /* if address is not filtered, receive is successful */ + if (!Mrfi_RxAddrIsFiltered(MRFI_P_DST_ADDR(&mrfiIncomingPacket))) + { + { + /* ------------------------------------------------------------------ + * Receive successful + * -------------------- + */ + + /* Convert the raw RSSI value and do offset compensation for this radio */ + mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS] = + Mrfi_CalculateRssi(mrfiIncomingPacket.rxMetrics[ + MRFI_RX_METRICS_RSSI_OFS]); + + /* Remove the CRC valid bit from the LQI byte */ + mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] = + (mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & + MRFI_RX_METRICS_LQI_MASK); + + + /* call external, higher level "receive complete" processing routine */ + MRFI_RxCompleteISR(); + } + } + } + } + } + + /* ------------------------------------------------------------------ + * End of function + * ------------------- + */ + +} + +/************************************************************************************************** + * @fn Mrfi_RxModeOn + * + * @brief Put radio into receive mode. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Mrfi_RxModeOn(void) +{ + /* clear any residual receive interrupt */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + + /* send strobe to enter receive mode */ + MRFI_STROBE(SRX); + + /* enable receive interrupts */ + MRFI_ENABLE_SYNC_PIN_INT(); +} + +/************************************************************************************************** + * @fn MRFI_RxOn + * + * @brief Turn on the receiver. No harm is done if this function is called when + * receiver is already on. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_RxOn(void) +{ + /* radio must be awake before we can move it to RX state */ + MRFI_ASSERT(mrfiRadioState != MRFI_RADIO_STATE_OFF); + + /* if radio is off, turn it on */ + if (mrfiRadioState != MRFI_RADIO_STATE_RX) + { + mrfiRadioState = MRFI_RADIO_STATE_RX; + Mrfi_RxModeOn(); + } +} + +/************************************************************************************************** + * @fn Mrfi_RxModeOff + * + * @brief - + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Mrfi_RxModeOff(void) +{ + /* disable receive interrupts */ + MRFI_DISABLE_SYNC_PIN_INT(); + + /* turn off radio */ + MRFI_STROBE_IDLE_AND_WAIT(); + + /* flush the receive FIFO of any residual data */ + MRFI_STROBE(SFRX); + + /* clear receive interrupt */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); +} + +/************************************************************************************************** + * @fn MRFI_RxIdle + * + * @brief Put radio in idle mode (receiver if off). No harm is done this function is + * called when radio is already idle. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_RxIdle(void) +{ + /* radio must be awake to move it to idle mode */ + MRFI_ASSERT(mrfiRadioState != MRFI_RADIO_STATE_OFF); + + /* if radio is on, turn it off */ + if (mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOff(); + mrfiRadioState = MRFI_RADIO_STATE_IDLE; + } +} + +/************************************************************************************************** + * @fn MRFI_Sleep + * + * @brief Request radio go to sleep. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_Sleep(void) +{ + bspIState_t s; + + /* Critical section necessary for watertight testing and + * setting of state variables. + */ + BSP_ENTER_CRITICAL_SECTION(s); + + /* If radio is not asleep, put it to sleep */ + if (mrfiRadioState != MRFI_RADIO_STATE_OFF) + { + /* go to idle so radio is in a known state before sleeping */ + MRFI_RxIdle(); + + /* Strobe Power Down (SPWD): puts the radio in SLEEP state. */ + + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + MRFI_STROBE(SXOFF); + + /* Our new state is OFF */ + mrfiRadioState = MRFI_RADIO_STATE_OFF; + } + + BSP_EXIT_CRITICAL_SECTION(s); +} + +/************************************************************************************************** + * @fn MRFI_WakeUp + * + * @brief Wake up radio from sleep state. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_WakeUp(void) +{ + /* if radio is already awake, just ignore wakeup request */ + if (mrfiRadioState != MRFI_RADIO_STATE_OFF) + { + return; + } + + MRFI_STROBE_IDLE_AND_WAIT(); + + /* enter idle mode */ + mrfiRadioState = MRFI_RADIO_STATE_IDLE; +} + +/************************************************************************************************** + * @fn MRFI_RadioIsr + * + * @brief Radio Interface interrupts as well as Radio interrupts are + * mapped to this interrupt vector. + * + * @param - + * + * @return - + ************************************************************************************************** + */ +// [BM] Changed because CC1101_VECTOR ISR is declared of source code and this handler is called +// indirect +//BSP_ISR_FUNCTION( MRFI_RadioIsr, CC1101_VECTOR ) +void MRFI_RadioIsr(void) +{ + uint16_t coreIntSource = RF1AIV; /* Radio Core interrupt register */ + uint16_t interfaceIntSource = RF1AIFIV; /* Radio Interface interrupt register */ + + /* Interface interrupt */ + if (interfaceIntSource) + { + if (interfaceIntSource == RF1AIFIV_RFERRIFG) + { + uint16_t interfaceError = RF1AIFERRV; + + if (interfaceError == RF1AIFERRV_LVERR) + { + /* Low core voltage error */ + } + else if (interfaceError == RF1AIFERRV_OPERR) + { + /* Operand error */ + } + else if (interfaceError == RF1AIFERRV_OUTERR) + { + /* output data not available error */ + } + else if (interfaceError == RF1AIFERRV_OPOVERR) + { + /* Operand overwrite error */ + } + else + { + /* Can't possibly happen. If interface error flag was set, + * then one of the interface errors must be set. + */ + MRFI_FORCE_ASSERT(); + } + + /* Assert anyways. No error handling implemented. */ + MRFI_FORCE_ASSERT(); + } + else + { + /* Not expecting any other interface interrupts (data in/out, status/instr in, fifo + *rx/tx) */ + MRFI_FORCE_ASSERT(); + } + } + + /* Radio Core interrupt */ + if (coreIntSource) + { + /* Check for SYNC interrupt */ + if (coreIntSource == RF1AIV_RFIFG9) + { + if (MRFI_SYNC_PIN_INT_IS_ENABLED()) + { + /* clear the sync pin interrupt, run sync pin ISR */ + + /* + * NOTE! The following macro clears the interrupt flag but it also *must* + * reset the interrupt capture. In other words, if a second interrupt + * occurs after the flag is cleared it must be processed, i.e. this interrupt + * exits then immediately starts again. Most microcontrollers handle this + * naturally but it must be verified for every target. + */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + + Mrfi_SyncPinRxIsr(); + } + else + { + /* Fatal error. SYNC interrupt is not supposed to happen at this time. */ + MRFI_FORCE_ASSERT(); + } + } + else + { + /* Fatal error. No other Radio interurpt is enabled. */ + MRFI_FORCE_ASSERT(); + } + } +} + +/************************************************************************************************** + * @fn MRFI_Rssi + * + * @brief Returns "live" RSSI value + * + * @param none + * + * @return RSSI value in units of dBm. + ************************************************************************************************** + */ + +int8_t MRFI_Rssi(void) +{ + uint8_t regValue; + + /* Radio must be in RX state to measure rssi. */ + MRFI_ASSERT(mrfiRadioState == MRFI_RADIO_STATE_RX); + + /* Wait for the RSSI to be valid: + * Just having the Radio ON is not enough to read + * the correct RSSI value. The Radio must in RX mode for + * a certain duration. This duration depends on + * the baud rate and the received signal strength itself. + */ + MRFI_RSSI_VALID_WAIT(); + + /* Read the RSSI value */ + regValue = MRFI_RADIO_REG_READ(RSSI); + + /* convert and do offset compensation */ + return (Mrfi_CalculateRssi(regValue)); +} + +/************************************************************************************************** + * @fn Mrfi_CalculateRssi + * + * @brief Does binary to decimal conversion and offset compensation. + * + * @param none + * + * @return RSSI value in units of dBm. + ************************************************************************************************** + */ + +int8_t Mrfi_CalculateRssi(uint8_t rawValue) +{ + int16_t rssi; + + /* The raw value is in 2's complement and in half db steps. Convert it to + * decimal taking into account the offset value. + */ + if (rawValue >= 128) + { + rssi = (int16_t)(rawValue - 256) / 2 - MRFI_RSSI_OFFSET; + } + else + { + rssi = (rawValue / 2) - MRFI_RSSI_OFFSET; + } + + /* Restrict this value to least value can be held in an 8 bit signed int */ + if (rssi < -128) + { + rssi = -128; + } + + return rssi; +} + +/************************************************************************************************** + * @fn MRFI_RandomByte + * + * @brief Returns a random byte. This is a pseudo-random number generator. + * The generated sequence will repeat every 256 values. + * The sequence itself depends on the initial seed value. + * + * @param none + * + * @return a random byte + ************************************************************************************************** + */ + +uint8_t MRFI_RandomByte(void) +{ + mrfiRndSeed = (mrfiRndSeed * MRFI_RANDOM_MULTIPLIER) + MRFI_RANDOM_OFFSET; + + return mrfiRndSeed; +} + +/************************************************************************************************** + * @fn Mrfi_RandomBackoffDelay + * + * @brief - + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +static void Mrfi_RandomBackoffDelay(void) +{ + uint8_t backoffs; + uint8_t i; + + /* calculate random value for backoffs - 1 to 16 */ + backoffs = (MRFI_RandomByte() & 0x0F) + 1; + + /* delay for randomly computed number of backoff periods */ + for (i = 0; i < backoffs; i++) + { + Mrfi_DelayUsec(sBackoffHelper); + } +} + +/**************************************************************************************************** + * @fn Mrfi_DelayUsec + * + * @brief Execute a delay loop using HW timer. The macro actually used to do the delay + * is not thread-safe. This routine makes the delay execution thread-safe by breaking + * up the requested delay up into small chunks and executing each chunk as a critical + * section. The chunk size is choosen to be the smallest value used by MRFI. The delay + * is only approximate because of the overhead computations. It errs on the side of + * being too long. + * + * input parameters + * @param howLong - number of microseconds to delay + * + * @return none + **************************************************************************************************** + */ + +static void Mrfi_DelayUsec(uint16_t howLong) +{ + bspIState_t s; + uint16_t count = howLong / MRFI_MAX_DELAY_US; + + if (howLong) + { + do + { + BSP_ENTER_CRITICAL_SECTION(s); + BSP_DELAY_USECS(MRFI_MAX_DELAY_US); + BSP_EXIT_CRITICAL_SECTION(s); + } while (count--); + } + + return; +} + +/**************************************************************************************************** + * @fn Mrfi_DelayUsecSem + * + * @brief Execute a delay loop using a HW timer. See comments for Mrfi_DelayUsec(). + * Delay specified number of microseconds checking semaphore for + * early-out. Run in a separate thread when the reply delay is + * invoked. Cleaner then trying to make MRFI_DelayUsec() thread-safe + * and reentrant. + * + * input parameters + * @param howLong - number of microseconds to delay + * + * @return none + **************************************************************************************************** + */ + +static void Mrfi_DelayUsecSem(uint16_t howLong) +{ + bspIState_t s; + uint16_t count = howLong / MRFI_MAX_DELAY_US; + + if (howLong) + { + do + { + BSP_ENTER_CRITICAL_SECTION(s); + BSP_DELAY_USECS(MRFI_MAX_DELAY_US); + BSP_EXIT_CRITICAL_SECTION(s); + if (sKillSem) + { + break; + } + } while (count--); + } + + return; +} + +/************************************************************************************************** + * @fn MRFI_DelayMs + * + * @brief Delay the specified number of milliseconds. + * + * @param milliseconds - delay time + * + * @return none + ************************************************************************************************** + */ + +void MRFI_DelayMs(uint16_t milliseconds) +{ + while (milliseconds) + { + Mrfi_DelayUsec(APP_USEC_VALUE); + milliseconds--; + } +} + +/************************************************************************************************** + * @fn MRFI_ReplyDelay + * + * @brief Delay number of milliseconds scaled by data rate. Check semaphore for + * early-out. Run in a separate thread when the reply delay is + * invoked. Cleaner then trying to make MRFI_DelayMs() thread-safe + * and reentrant. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_ReplyDelay(void) +{ + bspIState_t s; + uint16_t milliseconds = sReplyDelayScalar; + + BSP_ENTER_CRITICAL_SECTION(s); + sReplyDelayContext = 1; + BSP_EXIT_CRITICAL_SECTION(s); + + while (milliseconds) + { + Mrfi_DelayUsecSem(APP_USEC_VALUE); + if (sKillSem) + { + break; + } + milliseconds--; + } + + BSP_ENTER_CRITICAL_SECTION(s); + sKillSem = 0; + sReplyDelayContext = 0; + BSP_EXIT_CRITICAL_SECTION(s); +} + +/************************************************************************************************** + * @fn MRFI_PostKillSem + * + * @brief Post to the loop-kill semaphore that will be checked by the iteration loops + * that control the delay thread. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_PostKillSem(void) +{ + + if (sReplyDelayContext) + { + sKillSem = 1; + } + + return; +} + +/************************************************************************************************** + * @fn MRFI_GetRadioState + * + * @brief Returns the current radio state. + * + * @param none + * + * @return radio state - off/idle/rx + ************************************************************************************************** + */ + +uint8_t MRFI_GetRadioState(void) +{ + return mrfiRadioState; +} + +/************************************************************************************************** + * @fn MRFI_SetLogicalChannel + * + * @brief Set logical channel. + * + * @param chan - logical channel number + * + * @return none + ************************************************************************************************** + */ + +void MRFI_SetLogicalChannel(uint8_t chan) +{ + /* logical channel is not valid? */ + MRFI_ASSERT(chan < MRFI_NUM_LOGICAL_CHANS); + + /* make sure radio is off before changing channels */ + Mrfi_RxModeOff(); + + MRFI_RADIO_REG_WRITE(CHANNR, mrfiLogicalChanTable[chan]); + + /* turn radio back on if it was on before channel change */ + if (mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOn(); + } +} + +/************************************************************************************************** + * @fn MRFI_SetRFPwr + * + * @brief Set ouput RF power level. + * + * @param level - power level to be set + * + * @return none + ************************************************************************************************** + */ + +void MRFI_SetRFPwr(uint8_t level) +{ + /* Power level is not valid? */ + MRFI_ASSERT(level < MRFI_NUM_POWER_SETTINGS); + + MRFI_RADIO_REG_WRITE(PATABLE, mrfiRFPowerTable[level]); + + return; +} + +/************************************************************************************************** + * @fn MRFI_SetRxAddrFilter + * + * @brief Set the address used for filtering received packets. + * + * @param pAddr - pointer to address to use for filtering + * + * @return zero : successfully set filter address + * non-zero : illegal address + ************************************************************************************************** + */ + +uint8_t MRFI_SetRxAddrFilter(uint8_t * pAddr) +{ + /* + * If first byte of filter address match fir byte of broadcast address, + * there is a conflict with hardware filtering. + */ + if (pAddr[0] == mrfiBroadcastAddr[0]) + { + /* unable to set filter address */ + return (1); + } + + /* + * Set the hardware address register. The hardware address filtering only recognizes + * a single byte but this does provide at least some automatic hardware filtering. + */ + MRFI_RADIO_REG_WRITE(ADDR, pAddr[0]); + + /* save a copy of the filter address */ + { + uint8_t i; + + for (i = 0; i < MRFI_ADDR_SIZE; i++) + { + mrfiRxFilterAddr[i] = pAddr[i]; + } + } + + /* successfully set filter address */ + return (0); +} + +/************************************************************************************************** + * @fn MRFI_EnableRxAddrFilter + * + * @brief Enable received packet filtering. + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void MRFI_EnableRxAddrFilter(void) +{ + MRFI_ASSERT(mrfiRxFilterAddr[0] != mrfiBroadcastAddr[0]); /* filter address must be set before + *enabling filter */ + + /* set flag to indicate filtering is enabled */ + mrfiRxFilterEnabled = 1; + + /* enable hardware filtering on the radio */ + MRFI_RADIO_REG_WRITE(PKTCTRL1, PKTCTRL1_ADDR_FILTER_ON); +} + +/************************************************************************************************** + * @fn MRFI_DisableRxAddrFilter + * + * @brief Disable received packet filtering. + * + * @param pAddr - pointer to address to test for filtering + * + * @return none + ************************************************************************************************** + */ + +void MRFI_DisableRxAddrFilter(void) +{ + /* clear flag that indicates filtering is enabled */ + mrfiRxFilterEnabled = 0; + + /* disable hardware filtering on the radio */ + MRFI_RADIO_REG_WRITE(PKTCTRL1, PKTCTRL1_ADDR_FILTER_OFF); +} + +/************************************************************************************************** + * @fn Mrfi_RxAddrIsFiltered + * + * @brief Determine if address is filtered. + * + * @param none + * + * @return zero : address is not filtered + * non-zero : address is filtered + ************************************************************************************************** + */ + +uint8_t Mrfi_RxAddrIsFiltered(uint8_t * pAddr) +{ + uint8_t i; + uint8_t addrByte; + uint8_t filterAddrMatches; + uint8_t broadcastAddrMatches; + + /* first check to see if filtering is even enabled */ + if (!mrfiRxFilterEnabled) + { + /* + * Filtering is not enabled, so by definition the address is + * not filtered. Return zero to indicate address is not filtered. + */ + return (0); + } + + /* clear address byte match counts */ + filterAddrMatches = 0; + broadcastAddrMatches = 0; + + /* loop through address to see if there is a match to filter address of broadcast address */ + for (i = 0; i < MRFI_ADDR_SIZE; i++) + { + /* get byte from address to check */ + addrByte = pAddr[i]; + + /* compare byte to filter address byte */ + if (addrByte == mrfiRxFilterAddr[i]) + { + filterAddrMatches++; + } + if (addrByte == mrfiBroadcastAddr[i]) + { + broadcastAddrMatches++; + } + } + + /* + * If address is *not* filtered, either the "filter address match count" or + * the "broadcast address match count" will equal the total number of bytes + * in the address. + */ + if ((broadcastAddrMatches == MRFI_ADDR_SIZE) || (filterAddrMatches == MRFI_ADDR_SIZE)) + { + /* address *not* filtered, return zero */ + return (0); + } + else + { + /* address filtered, return non-zero */ + return (1); + } +} + +/************************************************************************************************** + * Compile Time Integrity Checks + ************************************************************************************************** + */ + +/* calculate maximum value for PKTLEN and verify it directly */ +#define MRFI_RADIO_TX_FIFO_SIZE 64 /* from datasheet */ +#define MRFI_RADIO_MAX_PKTLEN (MRFI_RADIO_TX_FIFO_SIZE - MRFI_LENGTH_FIELD_SIZE - \ + MRFI_RX_METRICS_SIZE) +#if (MRFI_RADIO_MAX_PKTLEN != 61) +# error "ERROR: The maximum value for PKTLEN is not correct." +#endif + +/* verify setting for PKTLEN does not exceed maximum */ +#if (MRFI_SETTING_PKTLEN > MRFI_RADIO_MAX_PKTLEN) +# error \ + "ERROR: Maximum possible value for PKTLEN exceeded. Decrease value of maximum payload." +#endif + +/* verify largest possible packet fits within FIFO buffer */ +#if ((MRFI_MAX_FRAME_SIZE + MRFI_RX_METRICS_SIZE) > MRFI_RADIO_TX_FIFO_SIZE) +# error \ + "ERROR: Maximum possible packet length exceeds FIFO buffer. Decrease value of maximum payload." +#endif + +/* verify that the SmartRF file supplied is compatible */ +#if ((!defined SMARTRF_RADIO_CC430)) +# error "ERROR: The SmartRF export file is not compatible." +#endif + +/* + * These asserts happen if there is extraneous compiler padding of arrays. + * Modify compiler settings for no padding, or, if that is not possible, + * comment out the offending asserts. + */ +BSP_STATIC_ASSERT(sizeof(mrfiRadioCfg) == + ((sizeof(mrfiRadioCfg) / sizeof(mrfiRadioCfg[0])) * sizeof(mrfiRadioCfg[0]))); + + +/* + * These asserts happen if there is extraneous compiler padding of arrays. + * Modify compiler settings for no padding, or, if that is not possible, + * comment out the offending asserts. + */ +BSP_STATIC_ASSERT(sizeof(mrfiLogicalChanTable) == + ((sizeof(mrfiLogicalChanTable) / + sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0]))); +BSP_STATIC_ASSERT(sizeof(mrfiBroadcastAddr) == + ((sizeof(mrfiBroadcastAddr) / + sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0]))); + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c new file mode 100755 index 0000000..a8a85f6 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c @@ -0,0 +1,373 @@ +/************************************************************************************************** +* Revised: $Date: 2009-11-23 07:50:43 -0800 (Mon, 23 Nov 2009) $ +* Revision: $Revision: 21225 $ +* +* Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS? +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radios: CC430 + * Radio Interface (RIF) code. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "mrfi_radio_interface.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_RADIO_STATUS_READ_CLEAR() RF1AIFCTL1 &= ~(RFSTATIFG); + +#define MRFI_RADIO_STATUS_READ_WAIT() while (!(RF1AIFCTL1 & RFSTATIFG)) ; +#define MRFI_RADIO_INST_WRITE_WAIT() while (!(RF1AIFCTL1 & RFINSTRIFG)) ; +#define MRFI_RADIO_DATA_WRITE_WAIT() while (!(RF1AIFCTL1 & RFDINIFG)) ; +#define MRFI_RADIO_DATA_READ_WAIT() while (!(RF1AIFCTL1 & RFDOUTIFG)) ; + +#define MRFI_RIF_DEBUG +#ifdef MRFI_RIF_DEBUG +# define MRFI_RIF_ASSERT(x) BSP_ASSERT(x) +#else +# define MRFI_RIF_ASSERT(x) +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Local Prototypes + * ------------------------------------------------------------------------------------------------ + */ + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceInit + * + * @brief Initialize the Radio Interface + * + * @param none + * + * @return none + ************************************************************************************************** + */ + +void mrfiRadioInterfaceInit(void) +{ + /* Enable interrupt on interface error. + * The code behaves differently between different runs on the debugger, and seemingly fails + * due to error flags on the bench. The code does not fail, however, on functional tests. + * This points to problems with the debugger that need to be sorted through carefully. + * For the time being, remove the following line, since it will likely cause operational + * failures. + */ + // RF1AIFCTL1 |= RFERRIE; +} + +/************************************************************************************************** + * @fn mrfiRadioInterfaceCmdStrobe + * + * @brief Send command strobe to the radio. Returns status byte read during transfer + * of strobe command. + * + * @param addr - address of register to strobe + * + * @return status byte of radio + ************************************************************************************************** + */ + +uint8_t mrfiRadioInterfaceCmdStrobe(uint8_t addr) +{ + uint8_t statusByte, gdoState; + mrfiRIFIState_t s; + + /* Check for invalid address. + * 0xBD is for SNOP with MSP set to read the bytes available in RX FIFO. + */ + MRFI_RIF_ASSERT((addr == 0xBD) || (addr >= RF_SRES) && (addr <= RF_SNOP)); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Clear the Status read flag */ + MRFI_RADIO_STATUS_READ_CLEAR(); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + if ((addr > RF_SRES) && (addr < RF_SNOP)) + { + /* buffer IOCFG2 state */ + gdoState = MRFI_RADIO_REG_READ(IOCFG2); + + /* c-ready to GDO2 */ + MRFI_RADIO_REG_WRITE(IOCFG2, 0x29); + + RF1AINSTRB = addr; + + /* chip at sleep mode */ + if ((RF1AIN & 0x04) == 0x04) + { + if ((addr == RF_SXOFF) || (addr == RF_SPWD) || (addr == RF_SWOR)) + { + /* Do nothing */ + } + else + { + /* c-ready */ + while ((RF1AIN & 0x04) == 0x04) ; + + /* Delay should be 760us */ + Mrfi_DelayUsec(760); + } + } + + /* restore IOCFG2 setting */ + MRFI_RADIO_REG_WRITE(IOCFG2, gdoState); + } + else + { + /* chip active mode */ + RF1AINSTRB = addr; + } + + /* Read status byte */ + statusByte = RF1ASTAT0B; + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); + + /* return the status byte */ + return statusByte; +} + +/************************************************************************************************** + * @fn mrfiRadioInterfaceReadReg + * + * @brief Read value from radio register. + * + * @param addr - address of register + * + * @return register value + ************************************************************************************************** + */ + +uint8_t mrfiRadioInterfaceReadReg(uint8_t addr) +{ + mrfiRIFIState_t s; + uint8_t regValue; + + /* Check for valid range. 0x3E is for PATABLE access */ + MRFI_RIF_ASSERT((addr <= 0x3B) || (addr == 0x3E)); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + if ((addr <= 0x2E) || (addr == 0x3E)) + { + /* Write cmd: read the Configuration register */ + RF1AINSTR1B = (0x80 | addr); + } + else + { + /* Write cmd: read the Status register */ + RF1AINSTR1B = (0xC0 | addr); + } + + /* Read out the register value */ + regValue = RF1ADOUT1B; //auto read + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); + + return (regValue); +} + +/************************************************************************************************** + * @fn mrfiRadioInterfaceWriteReg + * + * @brief Write value to radio register. + * + * @param addr - address of register + * @param value - register value to write + * + * @return none + ************************************************************************************************** + */ + +void mrfiRadioInterfaceWriteReg(uint8_t addr, uint8_t value) +{ + mrfiRIFIState_t s; + + /* Check for valid range. 0x3E is for PATABLE access */ + MRFI_RIF_ASSERT((addr <= 0x2E) || (addr == 0x3E)); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: 'write to register' */ + RF1AINSTRB = (0x00 | addr); + + /* Wait for radio to be ready to accept the data */ + MRFI_RADIO_DATA_WRITE_WAIT(); + + /* Write the register value */ + RF1ADINB = value; /* value to be written to the radio register */ + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + +/************************************************************************************************** + * @fn mrfiRadioInterfaceWriteTxFifo + * + * @brief Write data to radio transmit FIFO. + * + * @param pData - pointer for storing write data + * @param len - length of data in bytes + * + * @return none + ************************************************************************************************** + */ + +void mrfiRadioInterfaceWriteTxFifo(uint8_t * pData, uint8_t len) +{ + mrfiRIFIState_t s; + + MRFI_RIF_ASSERT(len != 0); /* zero length is not allowed */ + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: TXFIFOWR */ + RF1AINSTRB = 0x7F; + + do + { + /* Wait for radio to be ready to accept the data */ + MRFI_RADIO_DATA_WRITE_WAIT(); + + /* Write one byte to FIFO */ + RF1ADINB = *pData; + + pData++; + len--; + + } while (len); + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + +/************************************************************************************************** + * @fn mrfiRadioInterfaceReadRxFifo + * + * @brief Read data from radio receive FIFO. + * + * @param pData - pointer for storing read data + * @param len - length of data in bytes + * + * @return none + ************************************************************************************************** + */ +uint8_t method = 2; +void mrfiRadioInterfaceReadRxFifo(uint8_t * pData, uint8_t len) +{ + mrfiRIFIState_t s; + + MRFI_RIF_ASSERT(len != 0); /* zero length is not allowed */ + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + if (method == 1) + { + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: RXFIFORD */ + RF1AINSTRB = 0xFF; + + do + { + /* dummy write */ + RF1ADINB = 0; + + /* Wait for data to be available for reading */ + MRFI_RADIO_DATA_READ_WAIT(); + + /* Read one byte from FIFO */ + *pData = RF1ADOUT0B; + + pData++; + len--; + + } while (len); + } + + if (method == 2) + { + do + { + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: SNGLRXRD */ + RF1AINSTR1B = 0xBF; + + /* Read byte from FIFO */ + *pData = RF1ADOUT1B; //auto read register + + pData++; + len--; + + } while (len); + } + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h new file mode 100755 index 0000000..ae46724 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h @@ -0,0 +1,151 @@ +/************************************************************************************************** +* Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ +* Revision: $Revision: 13579 $ +* +* Copyright 2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radio interface code for CC430 + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_RADIO_INTERFACE_H +#define MRFI_RADIO_INTERFACE_H + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + +/* configuration registers */ +#define IOCFG2 0x00 /* IOCFG2 - GDO2 output pin configuration */ +#define IOCFG1 0x01 /* IOCFG1 - GDO1 output pin configuration */ +#define IOCFG0 0x02 /* IOCFG1 - GDO0 output pin configuration */ +#define FIFOTHR 0x03 /* FIFOTHR - RX FIFO and TX FIFO thresholds */ +#define SYNC1 0x04 /* SYNC1 - Sync word, high byte */ +#define SYNC0 0x05 /* SYNC0 - Sync word, low byte */ +#define PKTLEN 0x06 /* PKTLEN - Packet length */ +#define PKTCTRL1 0x07 /* PKTCTRL1 - Packet automation control */ +#define PKTCTRL0 0x08 /* PKTCTRL0 - Packet automation control */ +#define ADDR 0x09 /* ADDR - Device address */ +#define CHANNR 0x0A /* CHANNR - Channel number */ +#define FSCTRL1 0x0B /* FSCTRL1 - Frequency synthesizer control */ +#define FSCTRL0 0x0C /* FSCTRL0 - Frequency synthesizer control */ +#define FREQ2 0x0D /* FREQ2 - Frequency control word, high byte */ +#define FREQ1 0x0E /* FREQ1 - Frequency control word, middle byte */ +#define FREQ0 0x0F /* FREQ0 - Frequency control word, low byte */ +#define MDMCFG4 0x10 /* MDMCFG4 - Modem configuration */ +#define MDMCFG3 0x11 /* MDMCFG3 - Modem configuration */ +#define MDMCFG2 0x12 /* MDMCFG2 - Modem configuration */ +#define MDMCFG1 0x13 /* MDMCFG1 - Modem configuration */ +#define MDMCFG0 0x14 /* MDMCFG0 - Modem configuration */ +#define DEVIATN 0x15 /* DEVIATN - Modem deviation setting */ +#define MCSM2 0x16 /* MCSM2 - Main Radio Control State Machine configuration */ +#define MCSM1 0x17 /* MCSM1 - Main Radio Control State Machine configuration */ +#define MCSM0 0x18 /* MCSM0 - Main Radio Control State Machine configuration */ +#define FOCCFG 0x19 /* FOCCFG - Frequency Offset Compensation configuration */ +#define BSCFG 0x1A /* BSCFG - Bit Synchronization configuration */ +#define AGCCTRL2 0x1B /* AGCCTRL2 - AGC control */ +#define AGCCTRL1 0x1C /* AGCCTRL1 - AGC control */ +#define AGCCTRL0 0x1D /* AGCCTRL0 - AGC control */ +#define WOREVT1 0x1E /* WOREVT1 - High byte Event0 timeout */ +#define WOREVT0 0x1F /* WOREVT0 - Low byte Event0 timeout */ +#define WORCTRL 0x20 /* WORCTRL - Wake On Radio control */ +#define FREND1 0x21 /* FREND1 - Front end RX configuration */ +#define FREND0 0x22 /* FREDN0 - Front end TX configuration */ +#define FSCAL3 0x23 /* FSCAL3 - Frequency synthesizer calibration */ +#define FSCAL2 0x24 /* FSCAL2 - Frequency synthesizer calibration */ +#define FSCAL1 0x25 /* FSCAL1 - Frequency synthesizer calibration */ +#define FSCAL0 0x26 /* FSCAL0 - Frequency synthesizer calibration */ +#define RCCTRL1 0x27 /* RCCTRL1 - RC oscillator configuration */ +#define RCCTRL0 0x28 /* RCCTRL0 - RC oscillator configuration */ +#define FSTEST 0x29 /* FSTEST - Frequency synthesizer calibration control */ +#define PTEST 0x2A /* PTEST - Production test */ +#define AGCTEST 0x2B /* AGCTEST - AGC test */ +#define TEST2 0x2C /* TEST2 - Various test settings */ +#define TEST1 0x2D /* TEST1 - Various test settings */ +#define TEST0 0x2E /* TEST0 - Various test settings */ + +/* status registers */ +#define PARTNUM 0x30 /* PARTNUM - Chip ID */ +#define VERSION 0x31 /* VERSION - Chip ID */ +#define FREQEST 0x32 /* FREQEST – Frequency Offset Estimate from demodulator */ +#define LQI 0x33 /* LQI – Demodulator estimate for Link Quality */ +#define RSSI 0x34 /* RSSI – Received signal strength indication */ +#define MARCSTATE 0x35 /* MARCSTATE – Main Radio Control State Machine state */ +#define WORTIME1 0x36 /* WORTIME1 – High byte of WOR time */ +#define WORTIME0 0x37 /* WORTIME0 – Low byte of WOR time */ +#define PKTSTATUS 0x38 /* PKTSTATUS – Current GDOx status and packet status */ +#define VCO_VC_DAC 0x39 /* VCO_VC_DAC – Current setting from PLL calibration module */ +#define TXBYTES 0x3A /* TXBYTES – Underflow and number of bytes */ +#define RXBYTES 0x3B /* RXBYTES – Overflow and number of bytes */ + +/* burst write registers */ +#define PATABLE 0x3E /* PATABLE - PA control settings table */ + +/* command strobe registers */ +#define SRES 0x30 /* SRES - Reset chip. */ +#define SFSTXON 0x31 /* SFSTXON - Enable and calibrate frequency synthesizer. */ +#define SXOFF 0x32 /* SXOFF - Turn off crystal oscillator. */ +#define SCAL 0x33 /* SCAL - Calibrate frequency synthesizer and turn it off. */ +#define SRX 0x34 /* SRX - Enable RX. Perform calibration if enabled. */ +#define STX 0x35 /* STX - Enable TX. If in RX state, only enable TX if CCA passes. + **/ +#define SIDLE 0x36 /* SIDLE - Exit RX / TX, turn off frequency synthesizer. */ +#define SRSVD 0x37 /* SRVSD - Reserved. Do not use. */ +#define SWOR 0x38 /* SWOR - Start automatic RX polling sequence (Wake-on-Radio) */ +#define SPWD 0x39 /* SPWD - Enter power down mode when CSn goes high. */ +#define SFRX 0x3A /* SFRX - Flush the RX FIFO buffer. */ +#define SFTX 0x3B /* SFTX - Flush the TX FIFO buffer. */ +#define SWORRST 0x3C /* SWORRST - Reset real time clock. */ +#define SNOP 0x3D /* SNOP - No operation. Returns status byte. */ + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void mrfiRadioInterfaceInit(void); +void mrfiRadioInterfaceWriteReg(uint8_t addr, uint8_t value); +void mrfiRadioInterfaceWriteTxFifo(uint8_t * pWriteData, uint8_t len); +void mrfiRadioInterfaceReadRxFifo(uint8_t * pReadData, uint8_t len); + +uint8_t mrfiRadioInterfaceCmdStrobe(uint8_t addr); +uint8_t mrfiRadioInterfaceReadReg(uint8_t addr); + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h new file mode 100755 index 0000000..e699f6c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h @@ -0,0 +1,170 @@ +/*************************************************************** +* SmartRF Studio(tm) Export +* +* Radio register settings specifed with C-code +* compatible #define statements. +* +***************************************************************/ + +#ifndef SMARTRF_CC430_H +#define SMARTRF_CC430_H + +// [BM] Modified radio settings for 433MHz, 868MHz, 915MHz + +// ISM_LF configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 433.92 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first +// received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at +// the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_EU configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 869.524963 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first +// received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at +// the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_US configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 905.998993 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first +// received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at +// the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +#define SMARTRF_RADIO_CC430 + +#define SMARTRF_SETTING_FSCTRL1 0x08 +#define SMARTRF_SETTING_FSCTRL0 0x00 +#ifdef ISM_EU +// 869.525MHz +# define SMARTRF_SETTING_FREQ2 0x21 +# define SMARTRF_SETTING_FREQ1 0x71 +# define SMARTRF_SETTING_FREQ0 0x7A +#else +# ifdef ISM_US +// 902MHz (CHANNR=20->906MHz) +# define SMARTRF_SETTING_FREQ2 0x22 +# define SMARTRF_SETTING_FREQ1 0xB1 +# define SMARTRF_SETTING_FREQ0 0x3B +# else +# ifdef ISM_LF +// 433.92MHz +# define SMARTRF_SETTING_FREQ2 0x10 +# define SMARTRF_SETTING_FREQ1 0xB0 +# define SMARTRF_SETTING_FREQ0 0x71 +# else +# error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" +# endif // ISM_LF +# endif // ISM_US +#endif // ISM_EU +#define SMARTRF_SETTING_MDMCFG4 0x7B +#define SMARTRF_SETTING_MDMCFG3 0x83 +#define SMARTRF_SETTING_MDMCFG2 0x13 +#define SMARTRF_SETTING_MDMCFG1 0x22 +#define SMARTRF_SETTING_MDMCFG0 0xF8 +#define SMARTRF_SETTING_CHANNR 0x00 +#define SMARTRF_SETTING_DEVIATN 0x42 +#define SMARTRF_SETTING_FREND1 0xB6 +#define SMARTRF_SETTING_FREND0 0x10 +#define SMARTRF_SETTING_MCSM0 0x18 +#define SMARTRF_SETTING_FOCCFG 0x1D +#define SMARTRF_SETTING_BSCFG 0x1C +#define SMARTRF_SETTING_AGCCTRL2 0xC7 +#define SMARTRF_SETTING_AGCCTRL1 0x00 +#define SMARTRF_SETTING_AGCCTRL0 0xB2 +#define SMARTRF_SETTING_FSCAL3 0xEA +#define SMARTRF_SETTING_FSCAL2 0x2A +#define SMARTRF_SETTING_FSCAL1 0x00 +#define SMARTRF_SETTING_FSCAL0 0x1F +#define SMARTRF_SETTING_FSTEST 0x59 +#define SMARTRF_SETTING_TEST2 0x81 +#define SMARTRF_SETTING_TEST1 0x35 +#define SMARTRF_SETTING_TEST0 0x09 +#define SMARTRF_SETTING_FIFOTHR 0x47 +#define SMARTRF_SETTING_IOCFG2 0x29 +#define SMARTRF_SETTING_IOCFG0D 0x06 +#define SMARTRF_SETTING_PKTCTRL1 0x04 +#define SMARTRF_SETTING_PKTCTRL0 0x05 +#define SMARTRF_SETTING_ADDR 0x00 +#define SMARTRF_SETTING_PKTLEN 0xFF + +#endif // SMARTRF_CC430_H diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk.c new file mode 100755 index 0000000..526df8d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk.c @@ -0,0 +1,1112 @@ +/************************************************************************************************** +* Filename: nwk.c +* Revised: $Date: 2009-03-11 15:29:07 -0700 (Wed, 11 Mar 2009) $ +* Revision: $Revision: 19382 $ +* Author $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI network layer. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "nwk_globals.h" +#include "nwk_QMgmt.h" + +/****************************************************************************** + * MACROS + */ +/************************* NETWORK MANIFEST CONSTANT SANITY CHECKS ****************************/ +#if !defined(ACCESS_POINT) && !defined(RANGE_EXTENDER) && !defined(END_DEVICE) +# error ERROR: No SimpliciTI device type defined +#endif + +#if defined(END_DEVICE) && !defined(RX_POLLS) +# define RX_USER +#endif + +#ifndef MAX_HOPS +# define MAX_HOPS 3 +#elif MAX_HOPS > 4 +# error ERROR: MAX_HOPS must be 4 or fewer +#endif + +#ifndef MAX_APP_PAYLOAD +# error ERROR: MAX_APP_PAYLOAD must be defined +#endif + +#if (MAX_PAYLOAD < MAX_FREQ_APP_FRAME) +# error ERROR: Application payload size too small for Frequency frame +#endif + +#if (MAX_PAYLOAD < MAX_JOIN_APP_FRAME) +# error ERROR: Application payload size too small for Join frame +#endif + +#if (MAX_PAYLOAD < MAX_LINK_APP_FRAME) +# error ERROR: Application payload size too small for Link frame +#endif + +#if (MAX_PAYLOAD < MAX_MGMT_APP_FRAME) +# error ERROR: Application payload size too small for Management frame +#endif + +#if (MAX_PAYLOAD < MAX_SEC_APP_FRAME) +# error ERROR: Application payload size too small for Security frame +#endif + +#if (MAX_PAYLOAD < MAX_PING_APP_FRAME) +# error ERROR: Application payload size too small for Ping frame +#endif + +#if NWK_FREQ_TBL_SIZE < 1 +# error ERROR: NWK_FREQ_TBL_SIZE must be > 0 +#endif + +/************************* END NETWORK MANIFEST CONSTANT SANITY CHECKS ************************/ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ +#define SYS_NUM_CONNECTIONS (NUM_CONNECTIONS + 1) + +/* Increment this if the persistentContext_t structure is changed. It will help + * detect the upgrade context: any saved values will have a version with a + * lower number. + */ +#define CONNTABLEINFO_STRUCTURE_VERSION 1 + +#define SIZEOF_NV_OBJ sizeof(sPersistInfo) + +/****************************************************************************** + * TYPEDEFS + */ + +/* This structure aggregates eveything necessary to save if we want to restore + * the connection information later. + */ +typedef struct +{ + const uint8_t structureVersion; /* to dectect upgrades... */ + uint8_t numConnections; /* count includes the UUD port/link ID */ + + /* The next two are used to detect overlapping port assignments. When _sending_ a + * link frame the local port is assigned from the top down. When sending a _reply_ + * the assignment is bottom up. Overlapping assignments are rejected. That said it + * is extremely unlikely that this will ever happen. If it does the test implemented + * here is overly cautious (it will reject assignments when it needn't). But we leave + * it that way on the assumption that it will never happen anyway. + */ + uint8_t curNextLinkPort; + uint8_t curMaxReplyPort; + linkID_t nextLinkID; +#ifdef ACCESS_POINT + sfInfo_t sSandFContext; +#endif + /* Connection table entries last... */ + connInfo_t connStruct[SYS_NUM_CONNECTIONS]; +} persistentContext_t; + +/****************************************************************************** + * LOCAL VARIABLES + */ + +/* This will be overwritten if we restore the structure from NV for example. + * Note that restoring will not permit overwriting the version element as it + * is declared 'const'. + */ +static persistentContext_t sPersistInfo = {CONNTABLEINFO_STRUCTURE_VERSION}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static uint8_t map_lid2idx(linkID_t, uint8_t *); +static void initializeConnection(connInfo_t *); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_nwkInit + * + * @brief Initialize NWK conext. + * + * input parameters + * + * output parameters + * + * @return Status of operation. + */ + +smplStatus_t nwk_nwkInit(uint8_t (*f)(linkID_t)) +{ + // [BM] Added variable + uint8_t i; + + /* Truly ugly initialization because CCE won't initialize properly. Must + * skip first const element. Yuk. + */ + memset((((uint8_t *)&sPersistInfo) + 1), 0x0, (sizeof(sPersistInfo) - 1)); + /* OK. The zeroed elements are set. Now go back and do fixups... */ + + sPersistInfo.numConnections = SYS_NUM_CONNECTIONS; + sPersistInfo.curNextLinkPort = SMPL_PORT_USER_MAX; + sPersistInfo.curMaxReplyPort = PORT_BASE_NUMBER; + sPersistInfo.nextLinkID = 1; + + /* initialize globals */ + nwk_globalsInit(); + + /* initialize frame processing */ + nwk_frameInit(f); + + /* initialize queue manager */ + nwk_QInit(); + + /* initialize each network application. */ + nwk_freqInit(); + nwk_pingInit(); + nwk_joinInit(f); + nwk_mgmtInit(); + nwk_linkInit(); + nwk_securityInit(); + + // [BM] Workaround to enable stack restarting + for (i = 0; i < SYS_NUM_CONNECTIONS; ++i) + { + sPersistInfo.connStruct[i].connState = CONNSTATE_FREE; + } + + /* set up the last connection as the broadcast port mapped to the broadcast Link ID */ + if (CONNSTATE_FREE == sPersistInfo.connStruct[NUM_CONNECTIONS].connState) + { + sPersistInfo.connStruct[NUM_CONNECTIONS].connState = CONNSTATE_CONNECTED; + sPersistInfo.connStruct[NUM_CONNECTIONS].hops2target = MAX_HOPS; + sPersistInfo.connStruct[NUM_CONNECTIONS].portRx = SMPL_PORT_USER_BCAST; + sPersistInfo.connStruct[NUM_CONNECTIONS].portTx = SMPL_PORT_USER_BCAST; + sPersistInfo.connStruct[NUM_CONNECTIONS].thisLinkID = SMPL_LINKID_USER_UUD; + /* set peer address to broadcast so it is used when Application sends to the broadcast Link + *ID */ + memcpy(sPersistInfo.connStruct[NUM_CONNECTIONS].peerAddr, + nwk_getBCastAddress(), NET_ADDR_SIZE); + } + + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_getNextConnection + * + * @brief Return the next free connection structure if on is available. + * + * input parameters + * + * output parameters + * The returned structure has the Rx port number populated based on the + * free strucure found. This is the port queried when the app wants to + * do a receive. + * + * @return pointer to the new connInfo_t structure. NULL if there is + * no room in connection structure array. + */ + +connInfo_t *nwk_getNextConnection() +{ + uint8_t i; + + for (i = 0; i < SYS_NUM_CONNECTIONS; ++i) + { + if (sPersistInfo.connStruct[i].connState == CONNSTATE_CONNECTED) + { + continue; + } + break; + } + + if (SYS_NUM_CONNECTIONS == i) + { + return (connInfo_t *)0; + } + + initializeConnection(&sPersistInfo.connStruct[i]); + + return &sPersistInfo.connStruct[i]; +} + +/************************************************************************************ + * @fn initializeConnection + * + * @brief Initialize some elements of a Connection table entry. + * + * input parameters + * @param pCInfo - pointer to Connection Table entry to initialize. The file + * scope variable holding the next link ID value is also updated. + * + * output parameters + * @param pCInfo - certain elements are set to specific values. + * + * + * @return void + */ + +static void initializeConnection(connInfo_t *pCInfo) +{ + linkID_t *locLID = &sPersistInfo.nextLinkID; + uint8_t tmp; + + /* this element will be populated during the exchange with the peer. */ + pCInfo->portTx = 0; + + pCInfo->connState = CONNSTATE_CONNECTED; + pCInfo->thisLinkID = *locLID; + + /* Generate the next Link ID. This isn't foolproof. If the count wraps + * we can end up with confusing duplicates. We can protect aginst using + * one that is already in use but we can't protect against a stale Link ID + * remembered by an application that doesn't know its connection has been + * torn down. The test for 0 will hopefully never be true (indicating a wrap). + */ + (*locLID)++; + + while (!*locLID || (*locLID == SMPL_LINKID_USER_UUD) || map_lid2idx(*locLID, &tmp)) + { + (*locLID)++; + } + + return; +} + +/****************************************************************************** + * @fn nwk_freeConnection + * + * @brief Return the connection structure to the free pool. Currently + * this routine is only called when a link freame is sent and + * no reply is received so the freeing steps are pretty simple. + * But eventually this will be more complex so this place-holder + * is introduced. + * + * input parameters + * @param pCInfo - pointer to entry to be freed + * + * output parameters + * + * @return None. + */ + +void nwk_freeConnection(connInfo_t *pCInfo) +{ +#if NUM_CONNECTIONS > 0 + pCInfo->connState = CONNSTATE_FREE; +#endif +} + +/****************************************************************************** + * @fn nwk_getConnInfo + * + * @brief Return the connection info structure to which the input Link ID maps. + * + * input parameters + * @param port - port for which mapping desired + * + * output parameters + * + * @return pointer to connInfo_t structure found. NULL if no mapping + * found or entry not valid. + */ + +connInfo_t *nwk_getConnInfo(linkID_t linkID) +{ + uint8_t idx, rc; + + rc = map_lid2idx(linkID, &idx); + + return (rc && + (CONNSTATE_CONNECTED == + sPersistInfo.connStruct[idx].connState)) ? &sPersistInfo.connStruct[idx] : (connInfo_t *)0; +} + +/****************************************************************************** + * @fn nwk_isLinkDuplicate + * + * @brief Help determine if the link has already been established.. Defense + * against duplicate link frames. This file owns the data structure + * so the comparison is done here. + * + * input parameters + * @param addr - pointer to address of linker in question + * @param remotePort - remote port number provided by linker + * + * output parameters + * + * @return Returns pointer to connection entry if the address and remote Port + * match an existing entry, otherwise 0. + */ + +connInfo_t *nwk_isLinkDuplicate(uint8_t *addr, uint8_t remotePort) +{ +#if NUM_CONNECTIONS > 0 + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < NUM_CONNECTIONS; ++i, ++ptr) + { + if (CONNSTATE_CONNECTED == ptr->connState) + { + if (!(memcmp(ptr->peerAddr, addr, NET_ADDR_SIZE)) && + (ptr->portTx == remotePort)) + { + return ptr; + } + } + } +#endif + + return (connInfo_t *)NULL; +} + +/****************************************************************************** + * @fn nwk_findAddressMatch + * + * @brief Used to look for an address match in the Connection table. + * Match is based on source address in frame. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns non-zero if a match is found, otherwise 0. + */ + +uint8_t nwk_findAddressMatch(mrfiPacket_t *frame) +{ +#if NUM_CONNECTIONS > 0 + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < NUM_CONNECTIONS; ++i, ++ptr) + { + + if (CONNSTATE_CONNECTED == ptr->connState) + { + if (!(memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + return 1; + } + } + } +#endif + + return 0; +} + +#ifdef ACCESS_POINT + +/****************************************************************************** + * @fn nwk_getSFInfoPtr + * + * @brief Get pointer to store-and-forward information object kept in the + * NV object aggregate. + * + * input parameters + * + * output parameters + * + * @return Returns pointer to the store-nad-forward object. + */ + +sfInfo_t *nwk_getSFInfoPtr(void) +{ + return &sPersistInfo.sSandFContext; +} + +# if defined(AP_IS_DATA_HUB) + +/*************************************************************************************** + * @fn nwk_saveJoinedDevice + * + * @brief Save the address of a joining device on the Connection Table expecting + * a Link frame to follow. Only for when AP is a data hub. We want to + * use the space already allocated for a connection able entry instead + * of having redundant arrays for alread-joined devices in the data hub + * case. + * + * input parameters + * @param frame - pointer to frame containing address or joining device. + * + * output parameters + * + * @return Returns non-zero if this is a new device and it is saved. Returns + * 0 if device already there or there is no room in the Connection + * Table. + */ + +uint8_t nwk_saveJoinedDevice(mrfiPacket_t *frame) +{ + uint8_t i; + connInfo_t *avail = 0; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < NUM_CONNECTIONS; ++i, ++ptr) + { + if ((ptr->connState == CONNSTATE_CONNECTED) || (ptr->connState == CONNSTATE_JOINED)) + { + if (!memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + return 0; + } + } + else + { + avail = ptr; + } + } + + if (!avail) + { + return 0; + } + + avail->connState = CONNSTATE_JOINED; + memcpy(avail->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + return 1; +} + +/*********************************************************************************** + * @fn nwk_findAlreadyJoined + * + * @brief Used when AP is a data hub to look for an address match in the + * Connection table for a device that is already enterd in the joined + * state. This means that the Connection Table resource is already + * allocated so the link-listen doesn't have to do it again. Match is + * based on source address in frame. Thsi shoudl only be called from + * the Link-listen context during the link frame reply. + * + * If found the Connection Table entry is initialized as if it were + * found using the nwk_getNextConnection() method. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns pointer to Connection Table entry if match is found, otherwise + * 0. This call will only fail if the Connection Table was full when the + * device tried to join initially. + */ + +connInfo_t *nwk_findAlreadyJoined(mrfiPacket_t *frame) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < NUM_CONNECTIONS; ++i, ++ptr) + { + /* Look for an entry in the JOINED state */ + if (CONNSTATE_JOINED == ptr->connState) + { + /* Is this it? */ + if (!(memcmp(&ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + /* Yes. Initilize tabel entry and return the pointer. */ + initializeConnection(ptr); + return ptr; + } + } + } + + /* Nothing found... */ + return (connInfo_t *)NULL; +} + +# endif /* AP_IS_DATA_HUB */ +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_checkConnInfo + * + * @brief Do a sanity/validity check on the connection info + * + * input parameters + * @param ptr - pointer to a valid connection info structure to validate + * @param which - Tx or Rx port checked + * + * output parameters + * + * @return Status of operation. + */ + +smplStatus_t nwk_checkConnInfo(connInfo_t *ptr, uint8_t which) +{ + uint8_t port; + + /* make sure port isn't null and that the entry is active */ + port = (CHK_RX == which) ? ptr->portRx : ptr->portTx; + if (!port || (CONNSTATE_FREE == ptr->connState)) + { + return SMPL_BAD_PARAM; + } + + /* validate port number */ + if (port < PORT_BASE_NUMBER) + { + return SMPL_BAD_PARAM; + } + + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_isConnectionValid + * + * @brief Do a sanity/validity check on the frame target address by + * validating frame against connection info + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * @param lid - link ID of found connection + * + * @return 0 if connection specified in frame is not valid, otherwise non-zero. + */ + +uint8_t nwk_isConnectionValid(mrfiPacket_t *frame, linkID_t *lid) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + uint8_t port = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_PORT_OS); + + for (i = 0; i < SYS_NUM_CONNECTIONS; ++i, ++ptr) + { + if (CONNSTATE_CONNECTED == ptr->connState) + { + /* check port first since we're done if the port is the user bcast port. */ + if (port == ptr->portRx) + { + /* yep...ports match. */ + if ((SMPL_PORT_USER_BCAST == port) || + !(memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + uint8_t rc = 1; + + /* we're done. */ + *lid = ptr->thisLinkID; +#ifdef APP_AUTO_ACK + /* can't ack the broadcast port... */ + if (!(SMPL_PORT_USER_BCAST == port)) + { + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_ACK_REQ)) + { + /* Ack requested. Send ack now */ + nwk_sendAckReply(frame, ptr->portTx); + } + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_ACK_RPLY)) + { + /* This is a reply. Signal that it was received by resetting the + * saved transaction ID in the connection object if they match. The + * main thread is polling this value. The setting here is in the + * Rx ISR thread. + */ + if (ptr->ackTID == GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS)) + { + ptr->ackTID = 0; + } + + /* This causes the frame to be dropped. All ack frames are + * dropped. + */ + rc = 0; + } + } +#endif /* APP_AUTO_ACK */ + + /* Unconditionally kill the reply delay semaphore. This used to be done + * unconditionally in the calling routine. + */ + MRFI_PostKillSem(); + return rc; + } + } + } + } + + /* no matches */ + return 0; +} + +/****************************************************************************** + * @fn nwk_allocateLocalRxPort + * + * @brief Allocate a local port on which to receive frames from a peer. + * + * Allocation differs depending on whether the allocation is for + * a link reply frame or a link frame. In the former case we + * know the address of the peer so we can ensure allocating a + * unique port number for that address. The same port number can be + * used mulitple times for distinct peers. Allocations are done from + * the bottom of the namespace upward. + * + * If allocation is for a link frame we do not yet know the peer + * address so we must ensure the port number is unique now. + * Allocations are done from the top of the namespace downward. + * + * The two allocation methods track the extreme values used in each + * case to detect overlap, i.e., exhausted namespace. This can only + * happen if the number of connections supported is greater than the + * total namespace available. + * + * input parameters + * @param which - Sending a link frame or a link reply frame + * @param newPtr - pointer to connection info structure to be populated + * + * output parameters + * @param newPtr->portRx - element is populated with port number. + * + * @return Non-zero if port number assigned. 0 if no port available. + */ + +uint8_t nwk_allocateLocalRxPort(uint8_t which, connInfo_t *newPtr) +{ +#if NUM_CONNECTIONS > 0 + uint8_t num, i; + uint8_t marker[NUM_CONNECTIONS]; + connInfo_t *ptr = sPersistInfo.connStruct; + + memset(&marker, 0x0, sizeof(marker)); + + for (i = 0; i < NUM_CONNECTIONS; ++i, ++ptr) + { + /* Mark the port number as used unless it's a statically allocated port */ + if ((ptr != newPtr) && (CONNSTATE_CONNECTED == ptr->connState) && + (ptr->portRx <= SMPL_PORT_USER_MAX)) + { + if (LINK_SEND == which) + { + if (ptr->portRx > sPersistInfo.curNextLinkPort) + { + marker[SMPL_PORT_USER_MAX - ptr->portRx] = 1; + } + } + else if (!memcmp(ptr->peerAddr, newPtr->peerAddr, NET_ADDR_SIZE)) + { + marker[ptr->portRx - PORT_BASE_NUMBER] = 1; + } + } + } + + num = 0; + for (i = 0; i < NUM_CONNECTIONS; ++i) + { + if (!marker[i]) + { + if (LINK_REPLY == which) + { + num = PORT_BASE_NUMBER + i; + } + else + { + num = SMPL_PORT_USER_MAX - i; + } + break; + } + } + + if (LINK_REPLY == which) + { + /* if the number we have doesn't overlap the assignment of ports used + * for sending link frames, use it. + */ + if (num <= sPersistInfo.curNextLinkPort) + { + if (num > sPersistInfo.curMaxReplyPort) + { + /* remember maximum port number used */ + sPersistInfo.curMaxReplyPort = num; + } + } + else + { + /* the port number we need has already been used in the other context. It may or + * may not have been used for the same address but we don't bother to check...we + * just reject the asignment. This is the overly cautious part but is extermely + * unlikely to ever occur. + */ + num = 0; + } + } + else + { + /* if the number we have doesn't overlap the assignment of ports used + * for sending link frame replies, use it. + */ + if (num >= sPersistInfo.curMaxReplyPort) + { + if (num == sPersistInfo.curNextLinkPort) + { + sPersistInfo.curNextLinkPort--; + } + } + else + { + /* the port number we need has already been used in the other context. It may or + * may not have been used for the same address but we don't bother to check...we + * just reject the asignment. This is the overly cautious part but is extermely + * unlikely to ever occur. + */ + num = 0; + } + } + + newPtr->portRx = num; + + return num; +#else + return 0; +#endif /* NUM_CONNECTIONS > 0 */ + +} + +/******************************************************************************* + * @fn nwk_isValidReply + * + * @brief Examine a frame to see if it is a valid reply when compared with + * expected parameters. + * + * input parameters + * @param frame - pointer to frmae being examined + * @param tid - expected transaction ID in application payload + * @param infoOffset - offset to payload information containing reply hint + * @param tidOffset - offset to transaction ID in payload + * + * output parameters + * + * @return reply category: + * SMPL_NOT_REPLY: not a reply + * SMPL_MY_REPLY : a reply that matches input parameters + * SMPL_A_REPLY : a reply but does not match input parameters + */ + +uint8_t nwk_isValidReply(mrfiPacket_t *frame, uint8_t tid, uint8_t infoOffset, uint8_t tidOffset) +{ + uint8_t rc = SMPL_NOT_REPLY; + + if ((*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + infoOffset) & NWK_APP_REPLY_BIT)) + { + if ((*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + tidOffset) == tid) && + !memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + rc = SMPL_MY_REPLY; + } + else + { + rc = SMPL_A_REPLY; + } + } + + return rc; +} + +/****************************************************************************** + * @fn map_lid2idx + * + * @brief Map link ID to index into connection table. + * + * input parameters + * @param lid - Link ID to be matched + * + * output parameters + * @param idx - populated with index into connection table + * + * @return Non-zero if Link ID found and output is valid else 0. + */ + +static uint8_t map_lid2idx(linkID_t lid, uint8_t *idx) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < SYS_NUM_CONNECTIONS; ++i, ++ptr) + { + if ((CONNSTATE_CONNECTED == ptr->connState) && (ptr->thisLinkID == lid)) + { + *idx = i; + return 1; + } + } + + return 0; +} + +/****************************************************************************** + * @fn nwk_findPeer + * + * @brief Find connection entry for a peer + * + * input parameters + * @param peerAddr - address of peer + * @param peerPort - port on which this device was sending to peer. + * + * output parameters + * + * @return Pointer to matching connection table entry else 0. + */ + +connInfo_t *nwk_findPeer(addr_t *peerAddr, uint8_t peerPort) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i = 0; i < SYS_NUM_CONNECTIONS; ++i, ++ptr) + { + if (CONNSTATE_CONNECTED == ptr->connState) + { + if (!memcmp(peerAddr, ptr->peerAddr, NET_ADDR_SIZE)) + { + if (peerPort == ptr->portTx) + { + return ptr; + } + } + } + } + + return (connInfo_t *)NULL; +} + +/****************************************************************************** + * @fn nwk_checkAppMsgTID + * + * @brief Compare received TID to last-seen TID to decide whether the + * received message is a duplicate or we missed some. + * + * input parameters + * @param lastTID - last-seen TID + * @param appMsgTID - TID from current application payload. + * + * output parameters + * + * @return Returns zero if message with supplied TID should be discarded. + * Otherwise returns non-zero. In this case the message should be + * processed. The last-seen TID should be updated with the current + * application payload TID. + * + */ + +uint8_t nwk_checkAppMsgTID(appPTid_t lastTID, appPTid_t appMsgTID) +{ + uint8_t rc = 0; + + /* If the values are equal this is a duplicate. We're done. */ + if (lastTID != appMsgTID) + { + /* Is the new TID bigger? */ + if (appMsgTID > lastTID) + { + /* In this case the current payload is OK unless we've received a late + * (duplicate) message that occurred just before the TID wrapped. This is + * considered a duplicate and we should discard it. + */ + if (!(DUP_TID_AFTER_WRAP(lastTID, appMsgTID))) + { + rc = 1; + } + } + else + { + /* New TID is smaller. Accept the payload if this is the wrap case or we missed + * the specific wrap frame but are still within the range in which we assume + * we missed it. Otherwise is a genuine late frame so we should ignore it. + */ + if (CHECK_TID_WRAP(lastTID, appMsgTID)) + { + rc = 1; + } + } + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_getNumObjectFromMsg + * + * @brief Get a numeric object from a message buffer. Take care of + * alignment and endianess issues. + * + * input parameters + * @param src - pointer to object location in message buffer + * @param objSize - size of numeric object + * + * output parameters + * @param dest - pointer to numeric type variable receiving the object + * contains aligned number in correct endian order on return. + * + * @return void. There is no warning if there is no case for the supplied + * object size. A simple copy is then done. Alignment is + * guaranteed only for object size cases defined (and + * vacuously size 1). + * + */ + +void nwk_getNumObjectFromMsg(void *src, void *dest, uint8_t objSize) +{ + /* Take care of alignment */ + memmove(dest, src, objSize); + + /* Take care of endianess */ + switch (objSize) + { + case 2: + *((uint16_t *)dest) = ntohs(*((uint16_t *)dest)); + break; + + case 4: + *((uint32_t *)dest) = ntohl(*((uint32_t *)dest)); + break; + } + + return; +} + +/****************************************************************************** + * @fn nwk_putNumObjectIntoMsg + * + * @brief Put a numeric object into a message buffer. Take care of + * alignment and endianess issues. + * + * input parameters + * @param src - pointer to numeric type variable providing the object + * @param objSize - size of numeric object. Fuction works for object size 1. + * + * output parameters + * @param dest - pointer to object location in message buffer where the + * correct endian order representation will be placed. + * + * @return void. There is no warning if there is no case for the supplied + * object size. A simple copy is then done. + * + */ + +void nwk_putNumObjectIntoMsg(void *src, void *dest, uint8_t objSize) +{ + + uint8_t *ptr; + uint16_t u16; + uint32_t u32; + + /* Take care of endianess */ + switch (objSize) + { + case 1: + ptr = (uint8_t *)src; + break; + + case 2: + u16 = htons(*((uint16_t *)src)); + ptr = (uint8_t *)&u16; + break; + + case 4: + u32 = htonl(*((uint32_t *)src)); + ptr = (uint8_t *)&u32; + break; + + default: + ptr = (uint8_t *)src; + break; + } + + /* Take care of alignment */ + memmove(dest, ptr, objSize); + + return; +} + +/****************************************************************************** + * @fn nwk_NVObj + * + * @brief GET and SET support for NV object (connection context). + * + * input parameters + * @param action - GET or SET + * @param val - (GET/SET) pointer to NV IOCTL object. + * (SET) NV length and version values to be used for sanity + * checks. + * + * output parameters + * @param val - (GET) Version number of NV object, size of NV object and + * pointer to the connection context memory. + * - (SET) Pointer to the connection context memory. + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Object version or size do not conform on a SET call + * or illegal action specified. + */ + +smplStatus_t nwk_NVObj(ioctlAction_t action, ioctlNVObj_t *val) +{ +#ifdef NVOBJECT_SUPPORT + smplStatus_t rc = SMPL_SUCCESS; + + if (IOCTL_ACT_GET == action) + { + /* Populate helper objects */ + val->objLen = SIZEOF_NV_OBJ; + val->objVersion = sPersistInfo.structureVersion; + /* Set pointer to connection context if address of pointer is not null */ + if (val->objPtr) + { + *(val->objPtr) = (uint8_t *)&sPersistInfo; + } + } + else + { + rc = SMPL_BAD_PARAM; + } + + return rc; +#else /* NVOBJECT_SUPPORT */ + return SMPL_BAD_PARAM; +#endif +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk.h new file mode 100755 index 0000000..4fffc01 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk.h @@ -0,0 +1,164 @@ +/************************************************************************************************** +* Filename: nwk.h +* Revised: $Date: 2008-12-01 11:58:33 -0800 (Mon, 01 Dec 2008) $ +* Revision: $Revision: 18551 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI network layer. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_H +#define NWK_H + + +/* well known ports*/ +#define SMPL_PORT_PING 0x01 +#define SMPL_PORT_LINK 0x02 +#define SMPL_PORT_JOIN 0x03 +#define SMPL_PORT_SECURITY 0x04 +#define SMPL_PORT_FREQ 0x05 +#define SMPL_PORT_MGMT 0x06 + +#define SMPL_PORT_NWK_BCAST 0x1F +#define SMPL_PORT_USER_BCAST 0x3F + +/* Unconnected User Datagram Link ID */ +#define SMPL_LINKID_USER_UUD ((linkID_t) ~0) + +#define PORT_BASE_NUMBER 0x20 + +/* Reserve the top of the User port namespace below the broadcast + * address for static allocation. + */ +#define PORT_USER_STATIC_NUM 1 +#define SMPL_PORT_STATIC_MAX 0x3E +#define SMPL_PORT_USER_MAX (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM) + + +/* to check connection info sanity */ +#define CHK_RX 0 +#define CHK_TX 1 + +/* return types for validating a reply frame */ +#define SMPL_MY_REPLY 0 +#define SMPL_A_REPLY 1 +#define SMPL_NOT_REPLY 2 + +/* when allocating local Rx port it depends on whether the allocation + * is being done as a result of a link or a link reply + */ +#define LINK_SEND 1 +#define LINK_REPLY 2 + +#define CONNSTATE_FREE (0x00) +#define CONNSTATE_JOINED (0x01) +#define CONNSTATE_CONNECTED (0x02) + +typedef struct +{ + volatile uint8_t connState; + uint8_t hops2target; +#ifdef APP_AUTO_ACK + volatile uint8_t ackTID; +#endif + uint8_t peerAddr[NET_ADDR_SIZE]; + rxMetrics_t sigInfo; + uint8_t portRx; + uint8_t portTx; + linkID_t thisLinkID; +#ifdef SMPL_SECURE + uint32_t connTxCTR; + uint32_t connRxCTR; +#endif +} connInfo_t; + +/**************************************************************************************** + * Application Payload TID support + * + * Sometimes the receiving application uses a payload TID to determine if either it + * missed frames (received TID > (last-seen TID+1)) or is seeing a duplicate (received + * TID <= last-seen TID). Typically the TID simply increments for each successive frame. + * But when the count wraps there is a problem. The received TID should always be one + * more than the last TID. If it's equal, it's a duplicate. If it's less it's late. If + * it's one more it's the one we expect. If it's more than 1 more then we missed frames. + * Simple increments work for the wrap arithmetically. If the received TID is 0 and the last + * seen ID is the biggest number in the world -- 0xFF... depending on type we can detect + * the wrap. But if the receiver misses the 0 TID value for any reason or the biggest + * number in the world TID is missed then susbequent testing for missed or duplicate + * frames can get confused. We resolve this by allowing some leeway in the wrap testing. + * this testing is assisted by the following macros. Setting TID_VALID_WINDOW to 0 + * will enforce a no leniency policy. In this case you'd better not miss either the + * biggest number or the 0. The CHECK_TID_WRAP macro is only needed if the received + * TID is less than the last-seen TID. The DUP_TID_AFTER_WRAP macro is only needed if the + * received TID is greater than 1 more than the last-seen TID. + ***************************************************************************************/ +#define MAX_APT ((appPTid_t) ~0) /* max value of application payload TID type */ +#define TID_VALID_WINDOW 2 /* window around max and 0 */ + +#define CHECK_TID_WRAP(lastTID, newTID) ((lastTID >= (MAX_APT - TID_VALID_WINDOW)) && \ + (newTID <= TID_VALID_WINDOW) \ + ) +#define DUP_TID_AFTER_WRAP(lastTID, newTID) ((newTID >= (MAX_APT - TID_VALID_WINDOW)) && \ + (lastTID <= TID_VALID_WINDOW) \ + ) + +/* prototypes */ +smplStatus_t nwk_nwkInit(uint8_t (*)(linkID_t)); +connInfo_t *nwk_getNextConnection(void); +void nwk_freeConnection(connInfo_t *); +uint8_t nwk_getNextClientPort(void); +connInfo_t *nwk_getConnInfo(linkID_t port); + +connInfo_t *nwk_isLinkDuplicate(uint8_t *, uint8_t); +uint8_t nwk_findAddressMatch(mrfiPacket_t *); + +smplStatus_t nwk_checkConnInfo(connInfo_t *, uint8_t); +uint8_t nwk_isConnectionValid(mrfiPacket_t *, linkID_t *); + +uint8_t nwk_allocateLocalRxPort(uint8_t, connInfo_t *); +uint8_t nwk_isValidReply(mrfiPacket_t *, uint8_t, uint8_t, uint8_t); +connInfo_t *nwk_findPeer(addr_t *, uint8_t); +smplStatus_t nwk_NVObj(ioctlAction_t, ioctlNVObj_t *); + + +uint8_t nwk_checkAppMsgTID(appPTid_t, appPTid_t); +void nwk_getNumObjectFromMsg(void *, void *, uint8_t); +void nwk_putNumObjectIntoMsg(void *, void *, uint8_t); +#ifdef ACCESS_POINT +sfInfo_t *nwk_getSFInfoPtr(void); + +# ifdef AP_IS_DATA_HUB +uint8_t nwk_saveJoinedDevice(mrfiPacket_t *); +connInfo_t *nwk_findAlreadyJoined(mrfiPacket_t *); + +# endif +#endif + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.c new file mode 100755 index 0000000..721cad7 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.c @@ -0,0 +1,422 @@ +/************************************************************************************************** +* Filename: nwk_QMgmt.c +* Revised: $Date: 2009-03-10 17:01:56 -0700 (Tue, 10 Mar 2009) $ +* Revision: $Revision: 19372 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI input and output frame queues +* +* Copyright 2007-2008 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk.h" +#include "nwk_frame.h" +#include "nwk_QMgmt.h" +#include "nwk_mgmt.h" /* need offsets for poll frames */ + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +#if SIZE_INFRAME_Q > 0 +static frameInfo_t sInFrameQ[SIZE_INFRAME_Q]; +#else +static frameInfo_t *sInFrameQ = NULL; +#endif /* SIZE_INFRAME_Q > 0 */ + +static frameInfo_t sOutFrameQ[SIZE_OUTFRAME_Q]; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_QInit + * + * @brief Initialize the input and output frame queues to hold no packets. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_QInit(void) +{ +#if SIZE_INFRAME_Q > 0 + memset(sInFrameQ, 0, sizeof(sInFrameQ)); +#endif // SIZE_INFRAME_Q > 0 + memset(sOutFrameQ, 0, sizeof(sOutFrameQ)); +} + +/****************************************************************************** + * @fn nwk_QfindSlot + * + * @brief Finds a slot to use to retrieve the frame from the radio. It + * uses a LRU cast-out scheme. It is possible that this routine + * finds no slot. This can happen if the queue is of size 1 or 2 + * and the Rx interrupt occurs during a retrieval call from an + * application. There are meta-states for frames as the application + * looks for the oldest frame on the port being requested. + * + * This routine is running in interrupt context. + * + * input parameters + * @param which - INQ or OUTQ to search + * + * output parameters + * + * @return Pointer to oldest available frame in the queue + */ + +frameInfo_t *nwk_QfindSlot(uint8_t which) +{ + frameInfo_t *pFI, *oldest = 0, *newFI = 0; + uint8_t i, num, newOrder = 0, orderTest; + + if (INQ == which) + { + pFI = sInFrameQ; + num = SIZE_INFRAME_Q; + } + else + { + pFI = sOutFrameQ; + num = SIZE_OUTFRAME_Q; + } + + orderTest = num + 1; + + for (i = 0; i < num; ++i, ++pFI) + { + /* if frame is available it's a candidate. */ + if (pFI->fi_usage != FI_AVAILABLE) + { + if (INQ == which) /* TODO: do cast-out for Tx as well */ + { + + /* need to know the number of occupied slots so we know the age value + * for the unoccupied slot (if there is one). + */ + newOrder++; + + /* make sure nwk_retrieveFrame() is not processing this frame */ + if (FI_INUSE_TRANSITION == pFI->fi_usage) + { + continue; + } + /* is this frame older than any we've seen? */ + if (orderTest > pFI->orderStamp) + { + /* yes. */ + oldest = pFI; + orderTest = pFI->orderStamp; + } + } + } + else + { + if (OUTQ == which) /* TODO: do cast-out for Tx as well */ + { + return pFI; + } + newFI = pFI; + } + } + + /* did we find anything? */ + if (!newFI) + { + /* queue was full. cast-out happens here...unless... */ + if (!oldest) + { + /* This can happen if the queue is only of size 1 or 2 and all + * the frames are in transition when the Rx interrupt occurs. + */ + return (frameInfo_t *)0; + } + newFI = oldest; + nwk_QadjustOrder(which, newFI->orderStamp); + newFI->orderStamp = i; + } + else + { + /* mark the available slot. */ + newFI->orderStamp = ++newOrder; + } + + return newFI; +} + +/****************************************************************************** + * @fn nwk_QadjustOrder + * + * @brief Adjusts the age of everyone in the queue newer than the frame + * being removed. + * + * input parameters + * @param which - INQ or OUTQ to adjust + * @param stamp - value of frame being removed + * + * output parameters + * + * @return void + */ + +void nwk_QadjustOrder(uint8_t which, uint8_t stamp) +{ + frameInfo_t *pFI; + uint8_t i, num; + bspIState_t intState; + + if (INQ == which) + { + pFI = sInFrameQ; + num = SIZE_INFRAME_Q; + } + else + { + /* pFI = sOutFrameQ; + * num = SIZE_OUTFRAME_Q; */ + return; + } + + BSP_ENTER_CRITICAL_SECTION(intState); + + for (i = 0; i < num; ++i, ++pFI) + { + if ((pFI->fi_usage != FI_AVAILABLE) && (pFI->orderStamp > stamp)) + { + pFI->orderStamp--; + } + } + + BSP_EXIT_CRITICAL_SECTION(intState); + + return; +} + +/****************************************************************************** + * @fn nwk_QfindOldest + * + * @brief Look through frame queue and find the oldest available frame + * in the context in question. Supports connection-based (user), + * non-connection based (NWK applications), and the special case + * of store-and-forward. + * + * input parameters + * @param which - INQ or OUTQ to adjust + * @param rcvContext - context information for finding the oldest + * @param usage - normal usage or store-and-forward usage + * + * output parameters + * + * @return Pointer to frame that is the oldsest on the requested port, or + * 0 if there are none. + */ + +frameInfo_t *nwk_QfindOldest(uint8_t which, rcvContext_t *rcv, uint8_t fi_usage) +{ + uint8_t i, oldest, num, port; + uint8_t uType, addr12Compare; + bspIState_t intState; + frameInfo_t *fPtr = 0, *wPtr; + connInfo_t *pCInfo = 0; + uint8_t *pAddr1, *pAddr2, *pAddr3 = 0; + + if (INQ == which) + { + wPtr = sInFrameQ; + num = SIZE_INFRAME_Q; + oldest = SIZE_INFRAME_Q + 1; + } + else + { + /* pFI = sOutFrameQ; + * num = SIZE_OUTFRAME_Q; */ + return 0; + } + + if (RCV_APP_LID == rcv->type) + { + pCInfo = nwk_getConnInfo(rcv->t.lid); + if (!pCInfo) + { + return (frameInfo_t *)0; + } + port = pCInfo->portRx; + pAddr2 = pCInfo->peerAddr; + } + else if (RCV_NWK_PORT == rcv->type) + { + port = rcv->t.port; + } +#ifdef ACCESS_POINT + else if (RCV_RAW_POLL_FRAME == rcv->type) + { + port = *(MRFI_P_PAYLOAD(rcv->t.pkt) + F_APP_PAYLOAD_OS + M_POLL_PORT_OS); + pAddr2 = MRFI_P_SRC_ADDR(rcv->t.pkt); + pAddr3 = MRFI_P_PAYLOAD(rcv->t.pkt) + F_APP_PAYLOAD_OS + M_POLL_ADDR_OS; + } +#endif + else + { + return (frameInfo_t *)0; + } + + uType = (USAGE_NORMAL == fi_usage) ? FI_INUSE_UNTIL_DEL : FI_INUSE_UNTIL_FWD; + + for (i = 0; i < num; ++i, ++wPtr) + { + + BSP_ENTER_CRITICAL_SECTION(intState); /* protect the frame states */ + + /* only check entries in use and waiting for this port */ + if (uType == wPtr->fi_usage) + { + wPtr->fi_usage = FI_INUSE_TRANSITION; + + BSP_EXIT_CRITICAL_SECTION(intState); /* release hold */ + /* message sent to this device? */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&wPtr->mrfiPkt), F_PORT_OS) == port) + { + /* Port matches. If the port of interest is a NWK applicaiton we're a + * match...the NWK applications are not connection-based. If it is a + * NWK application we need to check the source address for disambiguation. + * Also need to check source address if it's a raw frame lookup (S&F frame) + */ + if (RCV_APP_LID == rcv->type) + { + if (SMPL_PORT_USER_BCAST == port) + { + /* guarantee a match... */ + pAddr1 = pCInfo->peerAddr; + } + else + { + pAddr1 = MRFI_P_SRC_ADDR(&wPtr->mrfiPkt); + } + } +#ifdef ACCESS_POINT + else if (RCV_RAW_POLL_FRAME == rcv->type) + { + pAddr1 = MRFI_P_DST_ADDR(&wPtr->mrfiPkt); + } +#endif + + addr12Compare = memcmp(pAddr1, pAddr2, NET_ADDR_SIZE); + if ((RCV_NWK_PORT == rcv->type) || + (!pAddr3 && !addr12Compare) || + (pAddr3 && !memcmp(pAddr3, MRFI_P_SRC_ADDR(&wPtr->mrfiPkt), NET_ADDR_SIZE)) + ) + { + if (wPtr->orderStamp < oldest) + { + if (fPtr) + { + /* restore previous oldest one */ + fPtr->fi_usage = uType; + } + oldest = wPtr->orderStamp; + fPtr = wPtr; + continue; + } + else + { + /* not oldest. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + /* not a match. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + /* wrong port. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + BSP_EXIT_CRITICAL_SECTION(intState); + } + } + + return fPtr; +} + +/****************************************************************************** + * @fn nwk_getQ + * + * @brief Get location of teh specified frame queue. + * + * input parameters + * @param which - INQ or OUTQ to get + * + * output parameters + * + * @return Pointer to frame queue + */ + +frameInfo_t *nwk_getQ(uint8_t which) +{ + return (INQ == which) ? sInFrameQ : sOutFrameQ; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.h new file mode 100755 index 0000000..c66e141 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.h @@ -0,0 +1,54 @@ +/************************************************************************************************** +* Filename: nwk_QMgmt.h +* Revised: $Date: 2009-01-17 15:14:16 -0800 (Sat, 17 Jan 2009) $ +* Revision: $Revision: 18788 $ +* Author: $Author: rlord $ +* +* Description: This header file supports the SimpliciTI input and output frame queues. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_QMGMT_H +#define NWK_QMGMT_H + + +#define INQ 1 +#define OUTQ 2 + +#define USAGE_NORMAL 1 +#define USAGE_FWD 2 + +/* prototypes */ +void nwk_QInit(void); + +frameInfo_t *nwk_QfindSlot(uint8_t); +void nwk_QadjustOrder(uint8_t, uint8_t); +frameInfo_t *nwk_QfindOldest(uint8_t, rcvContext_t *, uint8_t); +frameInfo_t *nwk_getQ(uint8_t); + +#endif /* NWK_QMGMT_H */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_api.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_api.c new file mode 100755 index 0000000..caa6093 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_api.c @@ -0,0 +1,876 @@ +/************************************************************************************************** +* Filename: nwk_api.c +* Revised: $Date: 2009-01-28 18:27:38 -0800 (Wed, 28 Jan 2009) $ +* Revision: $Revision: 18875 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI appliction layer API. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "mrfi.h" +#include "nwk_globals.h" +#include "nwk_freq.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/* These defines are in support an application listening for a link frame to + * terminate after some amount of time. The intention is that this guard be + * the exception. The intention of the SimpliciTI design is that the + * temporal contiguity between the listen and the reception of the link frame + * from the peer be very tight. The SMPL_LinkListen() should be termninated + * by the reception of the link frame. But in case it does not receive the frame + * the support below allows intervention by the application. + */ + +/* The intention is for user to modify just the following single value */ +#define LINKLISTEN_MILLISECONDS_2_WAIT (5000) + +#define LINKLISTEN_POLL_PERIOD_MS (10) +#define LINKLISTEN_POLL_COUNT ((LINKLISTEN_MILLISECONDS_2_WAIT) / \ + (LINKLISTEN_POLL_PERIOD_MS)) + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +// [BM] Workaround to enable multiple stack restarts +// static uint8_t sInit_done = 0; +uint8_t sInit_done = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static uint8_t ioctlPreInitAccessIsOK(ioctlObject_t); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/*********************************************************************************** + * @fn SMPL_Init + * + * @brief Initialize the SimpliciTI stack. + * + * input parameters + * @param f - Pointer to call back function. Function called by NWK when + * user application frame received. The callback is done in the + * ISR thread. Argument is Link ID associated with frame. Function + * returns 0 if frame is to be kept by NWK, otherwise 1. Frame + * should be kept if application will do a SMPL_Receive() in the + * user thread (recommended). Pointer may be NULL. + * + * output parameters + * + * @return Status of operation: + * SMPL_SUCCESS + * SMPL_NO_JOIN No Join reply. AP possibly not yet up. + * SMPL_NO_CHANNEL Only if Frequency Agility enabled. Channel scan + * failed. AP possibly not yet up. + */ + +smplStatus_t SMPL_Init(uint8_t (*f)(linkID_t)) +{ + smplStatus_t rc; + + if (!sInit_done) + { + /* set up radio. */ + MRFI_Init(); + + /* initialize network */ + if ((rc = nwk_nwkInit(f)) != SMPL_SUCCESS) + { + return rc; + } + + MRFI_WakeUp(); +#if defined(FREQUENCY_AGILITY) + { + freqEntry_t chan; + + chan.logicalChan = 0; + /* ok to set default channel explicitly now that MRFI initialized. */ + nwk_setChannel(&chan); + } +#endif + /* don't turn Rx on if we're an end device that isn't always on. */ +#if !defined(END_DEVICE) + MRFI_RxOn(); +#endif + +#if defined(END_DEVICE) + /* All except End Devices are in promiscuous mode */ + MRFI_SetRxAddrFilter((uint8_t *)nwk_getMyAddress()); + MRFI_EnableRxAddrFilter(); +#endif + } + sInit_done = 1; + + /* Join. if no AP or Join fails that status is returned. */ + rc = nwk_join(); + + return rc; +} + +/****************************************************************************** + * @fn SMPL_LinkListen + * + * @brief Listen for a link frame from a 'client' device. + * + * input parameters + * + * output parameters + * @param linkID - pointer to Link ID to be used by application to + * read and write to the linked peer. + * + * @return status of operation. + * SMPL_SUCCESS + * SMPL_TIMEOUT No link frame received during listen interval. + * Interval set in #defines above. linkID not valid. + * + */ + +smplStatus_t SMPL_LinkListen(linkID_t *linkID) +{ + uint8_t radioState = MRFI_GetRadioState(); + uint16_t i; + linkID_t locLinkID; + + /* Set the context. We want to reject any link frames received if + * we're not listening. For example if we're an AP we are in + * promiscuous mode and we'll see any broadcast link frames. + */ + nwk_setListenContext(LINK_LISTEN_ON); + + NWK_CHECK_FOR_SETRX(radioState); + + for (i = 0; i < LINKLISTEN_POLL_COUNT; ++i) + { + /* check the semaphore. local port is assigned when the reply is sent. */ + if ((locLinkID = nwk_getLocalLinkID())) + { + break; + } + NWK_DELAY(LINKLISTEN_POLL_PERIOD_MS); + } + + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + /* If the listen is terminated without hearing a message and setting a + * link ID the listen context must be explicitly turned off. + */ + if (!(locLinkID)) + { + nwk_setListenContext(LINK_LISTEN_OFF); + return SMPL_TIMEOUT; + } + + *linkID = locLinkID; + + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn SMPL_Send + * + * @brief Send a message to a peer application. Old API kept for + * backward compatibility. Calls the new SMPL_SendOpt() with + * no options. + * + * input parameters + * @param lid - Link ID (port) from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * + * output parameters + * + * @return Status of operation. On a filaure the frame buffer is discarded + * and the Send call must be redone by the app. + * SMPL_SUCCESS + * SMPL_BAD_PARAM No valid Connection Table entry for Link ID + * Data in Connection Table entry bad + * No message or message too long + * SMPL_NOMEM No room in output frame queue + * SMPL_TX_CCA_FAIL CCA failure. + */ + +smplStatus_t SMPL_Send(linkID_t lid, uint8_t *msg, uint8_t len) +{ + return SMPL_SendOpt(lid, msg, len, SMPL_TXOPTION_NONE); +} + +/****************************************************************************** + * @fn SMPL_SendOpt + * + * @brief Send a message to a peer application. + * + * input parameters + * @param lid - Link ID (port) from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param options - Transmit options (bit map) + * + * output parameters + * + * @return Status of operation. On a filaure the frame buffer is discarded + * and the Send call must be redone by the app. + * SMPL_SUCCESS + * SMPL_BAD_PARAM No valid Connection Table entry for Link ID + * Data in Connection Table entry bad + * No message or message too long + * SMPL_NOMEM No room in output frame queue + * SMPL_TX_CCA_FAIL CCA failure. + * SMPL_NO_ACK If application auto acknowledgement enabled + * and no acknowledgement is received + */ + +smplStatus_t SMPL_SendOpt(linkID_t lid, uint8_t *msg, uint8_t len, txOpt_t options) +{ + frameInfo_t *pFrameInfo; + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + uint8_t radioState = MRFI_GetRadioState(); + uint8_t ackreq = 0; + +#if defined(ACCESS_POINT) + uint8_t loc; +#endif + + /* we have the connection info for this Link ID. make sure it is valid. */ + if (!pCInfo || ((rc = nwk_checkConnInfo(pCInfo, CHK_TX)) != SMPL_SUCCESS)) + { + return rc; + } + + /* parameter sanity check... */ + if (!msg || (len > MAX_APP_PAYLOAD)) + { + return rc; + } + + /* Build an outgoing message frame destined for the port from the + * connection info using the destination address also from the + * connection info. + */ + if (SMPL_TXOPTION_NONE == options) + { + pFrameInfo = nwk_buildFrame(pCInfo->portTx, msg, len, pCInfo->hops2target); + } +#if defined(APP_AUTO_ACK) + else if (options & SMPL_TXOPTION_ACKREQ) + { + if (SMPL_LINKID_USER_UUD != lid) + { + pFrameInfo = nwk_buildAckReqFrame(pCInfo->portTx, msg, len, pCInfo->hops2target, + &pCInfo->ackTID); + ackreq = 1; + } + else + { + /* can't request an ack on the UUD link ID */ + return SMPL_BAD_PARAM; + } + } +#endif /* APP_AUTO_ACK */ + else + { + return SMPL_BAD_PARAM; + } + + if (!pFrameInfo) + { + return SMPL_NOMEM; + } + memcpy(MRFI_P_DST_ADDR(&pFrameInfo->mrfiPkt), pCInfo->peerAddr, NET_ADDR_SIZE); + +#if defined(SMPL_SECURE) + { + uint32_t *pUL = 0; + + if (pCInfo->thisLinkID != SMPL_LINKID_USER_UUD) + { + pUL = &pCInfo->connTxCTR; + } + nwk_setSecureFrame(&pFrameInfo->mrfiPkt, len, pUL); + } +#endif /* SMPL_SECURE */ + +#if defined(ACCESS_POINT) + + /* If we are an AP trying to send to a polling device, don't do it. + * See if the target is a store-and-forward client. + */ + if (nwk_isSandFClient(MRFI_P_DST_ADDR(&pFrameInfo->mrfiPkt), &loc)) + { + pFrameInfo->fi_usage = FI_INUSE_UNTIL_FWD; + return SMPL_SUCCESS; + } + else +#endif /* ACCESS_POINT */ + { + rc = nwk_sendFrame(pFrameInfo, MRFI_TX_TYPE_CCA); + } + +#if !defined(APP_AUTO_ACK) + /* save a little code space with this #if */ + (void) ackreq; /* keep compiler happy */ + return rc; +#else + /* we're done if the send failed or no ack requested. */ + if (SMPL_SUCCESS != rc || !ackreq) + { + return rc; + } + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + { + bspIState_t intState; + + /* If the saved TID hasn't been reset then we never got the ack. */ + BSP_ENTER_CRITICAL_SECTION(intState); + if (pCInfo->ackTID) + { + pCInfo->ackTID = 0; + rc = SMPL_NO_ACK; + } + BSP_EXIT_CRITICAL_SECTION(intState); + } + + return rc; +#endif /* APP_AUTO_ACK */ +} + +/************************************************************************************** + * @fn SMPL_Receive + * + * @brief Receive a message from a peer application. + * + * input parameters + * @param lid - Link ID (port) from application + * + * + * output parameters + * @param msg - pointer to where received message should be copied. + * buffer should be of size == MAX_APP_PAYLOAD + * @param len - pointer to receive length of received message + * + * @return Status of operation. + * Caller should not use the value returned in 'len' to decide + * whether there is a frame or not. It could be useful to the + * Caller to distinguish between no frame and a frame with no data. + * For example, in the polling case a frame with no application payload + * is the way the AP conveys that there are no frames waiting. + * + * SMPL_SUCCESS + * + * SMPL_BAD_PARAM No valid Connection Table entry for Link ID + * Data in Connection Table entry bad + * SMPL_NO_FRAME No frame received. + * SMPL_NO_PAYLOAD Frame received with no payload (not necessarily + * an error and could be deduced by application + * because the returned length will be 0) + * + * Polling device only: + * + * SMPL_TIMEOUT No response from Access Point + * SMPL_NO_AP_ADDRESS Access Point address unknown + * SMPL_TX_CCA_FAIL Could not send poll frame + * SMPL_NOMEM No memory in output frame queue + * SMPL_NO_CHANNEL Frequency Agility enabled and could not find channel + */ + +smplStatus_t SMPL_Receive(linkID_t lid, uint8_t *msg, uint8_t *len) +{ + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + rcvContext_t rcv; + + if (!pCInfo || ((rc = nwk_checkConnInfo(pCInfo, CHK_RX)) != SMPL_SUCCESS)) + { + return rc; + } + + rcv.type = RCV_APP_LID; + rcv.t.lid = lid; + +#if defined(RX_POLLS) + { + uint8_t numChans = 1; +# if defined(FREQUENCY_AGILITY) + freqEntry_t chans[NWK_FREQ_TBL_SIZE]; + uint8_t scannedB4 = 0; +# endif + + do + { + uint8_t radioState = MRFI_GetRadioState(); + + /* I'm polling. Do the poll to stimulate the sending of a frame. If the + * frame has application length of 0 it means there were no frames. If + * no reply is received infer that the channel is changed. We then need + * to scan and then retry the poll on each channel returned. + */ + if (SMPL_SUCCESS != (rc = nwk_poll(pCInfo->portRx, pCInfo->peerAddr))) + { + /* for some reason couldn't send the poll out. */ + return rc; + } + + /* do this before code block below which may reset it. */ + numChans--; + + /* Wait until there's a frame. if the len is 0 then return SMPL_NO_FRAME + * to the caller. In the poll case the AP always sends something. + */ + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + /* TODO: deal with pending */ + rc = nwk_retrieveFrame(&rcv, msg, len, 0, 0); + +# if defined(FREQUENCY_AGILITY) + if (SMPL_SUCCESS == rc) + { + /* we received something... */ + return (*len) ? SMPL_SUCCESS : SMPL_NO_PAYLOAD; + } + + /* No reply. scan for other channel(s) if we haven't already. Then set + * one and try again. + */ + if (!scannedB4) + { + numChans = nwk_scanForChannels(chans); + scannedB4 = 1; + } + if (numChans) + { + nwk_setChannel(&chans[numChans - 1]); + } +# else /* FREQUENCY_AGILITY */ + return (*len) ? rc : ((SMPL_SUCCESS == rc) ? SMPL_NO_PAYLOAD : SMPL_TIMEOUT); +# endif + } while (numChans); + } + +# if defined(FREQUENCY_AGILITY) + return SMPL_NO_CHANNEL; +# endif + +#else /* RX_POLLS */ + return nwk_retrieveFrame(&rcv, msg, len, 0, 0); +#endif /* RX_POLLS */ +} + +/****************************************************************************** + * @fn SMPL_Link + * + * @brief Link to a peer. + * + * input parameters + * + * output parameters + * @param lid - pointer to where we should write the link ID to which the + * application will read and write. + * + * @return Status of operation. + * SMPL_SUCCESS + * SMPL_NOMEM No room to allocate local Rx port, no more + * room in Connection Table, or no room in + * output frame queue. + * SMPL_NO_LINK No reply frame during wait window. + * SMPL_TX_CCA_FAIL Could not send Link frame. + */ + +smplStatus_t SMPL_Link(linkID_t *lid) +{ + return nwk_link(lid); +} + +#if defined(EXTENDED_API) + +/************************************************************************************** + * @fn SMPL_Unlink + * + * @brief Tear down connection to a peer. + * + * input parameters + * @param lid - Link ID whose connection is to be terminated. + * + * output parameters + * + * @return Status of operation. The Connection Table entry for the Link ID + * is always freed successfuly. The returned status value is the + * status of the _peer's_ connection tear-down as a result of the + * message sent here. + * SMPL_SUCCESS Local and remote connection destroyed. + * SMPL_BAD_PARAM No local connection table entry for this Link ID + * SMPL_TIMEOUT No reply from peer. + * SMPL_NO_PEER_UNLINK Peer did not have a Connection Table entry for me. + */ + +smplStatus_t SMPL_Unlink(linkID_t lid) +{ + return nwk_unlink(lid); +} + +/************************************************************************************** + * @fn SMPL_Ping + * + * @brief Ping a peer. Synchronous call. Although a link ID is used it is the + * NWK Ping application that is pinged, not the peer of this Link ID. The + * peer is not expected to be the responder to the frame sent from here. + * This API is a proxy for a real ping since the application doesn't + * have direct access to SimpliciTI device addresses. Kind of hokey but a + * useful keep-alive mechanism without having to support it with + * user application service. + * + * input parameters + * @param lid - The link ID whose peer device address is used to direct the NWK Ping + * + * output parameters + * + * @return Status of operation. + */ + +smplStatus_t SMPL_Ping(linkID_t lid) +{ + return nwk_ping(lid); +} + +/************************************************************************************** + * @fn SMPL_Commission + * + * @brief Commission a connection. + * + * input parameters + * @param peerAddr - Pointer to address of the peer for this connection + * @param locPort - Port on which to listen for messages from the peer + * @param rmtPort - Port on which to send messages to the peer. + * @param lid - Pointer to Link ID object. If content of location is + * non-zero on input the value is placed in the Connection + * object. + * + * output parameters + * @param lid - Pointer to Link ID object. If content of location is zero + * on input the value in the Connection object is stored there. + * + * @return SMPL_SUCCESS + * SMPL_NOMEM - No room left in Connection table. + * SMPL_BAD_PARAM - A pointer to a Link object was not supplied. + */ + +smplStatus_t SMPL_Commission(addr_t *peerAddr, uint8_t locPort, uint8_t rmtPort, linkID_t *lid) +{ + connInfo_t *pCInfo = nwk_getNextConnection(); + smplStatus_t rc = SMPL_BAD_PARAM; + + do { + if (pCInfo) + { + /* sanity checks... */ + + /* Check port info. */ + if ((locPort > SMPL_PORT_STATIC_MAX) || + (locPort < (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM + 1))) + { + continue; + } + + if ((rmtPort > SMPL_PORT_STATIC_MAX) || + (rmtPort < (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM + 1))) + { + continue; + } + + /* Must supply a pointer to the Link ID object */ + if (!lid) + { + /* No Link ID pointer supplied */ + continue; + } + + /* we're sane */ + + /* Use the value generated at connection object assign time. */ + *lid = pCInfo->thisLinkID; + + /* store peer's address */ + memcpy(pCInfo->peerAddr, peerAddr, NET_ADDR_SIZE); + + /* store port info */ + pCInfo->portRx = locPort; + pCInfo->portTx = rmtPort; + + pCInfo->hops2target = MAX_HOPS; + + rc = SMPL_SUCCESS; + } + else + { + /* No room in Connection table */ + rc = SMPL_NOMEM; + } + } while (0); + + if ((SMPL_SUCCESS != rc) && pCInfo) + { + nwk_freeConnection(pCInfo); + } + + return rc; +} + +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn SMPL_Ioctl + * + * @brief This routine supplies the SimpliciTI IOCTL support. + * + * input parameters + * @param object - The IOCTL target object + * @param action - The IOCTL target action on the object + * @param val - pointer to value. exact forn depends on object type. + * + * output parameters + * + * @return Status of action. Value depends on object, action, and result. + * + * SMPL_BAD_PARAM is returned if this API is called before + * initialization and the object is not one of + * the valid exceptions. + */ + +smplStatus_t SMPL_Ioctl(ioctlObject_t object, ioctlAction_t action, void *val) +{ + smplStatus_t rc; + + /* if init hasn't occurred see if access is still valid */ + if (!sInit_done && !ioctlPreInitAccessIsOK(object)) + { + return SMPL_BAD_PARAM; + } + + switch (object) + { +#if defined(EXTENDED_API) + case IOCTL_OBJ_TOKEN: + { + ioctlToken_t *t = (ioctlToken_t *)val; + + rc = SMPL_SUCCESS; + if (TT_LINK == t->tokenType) + { + if (IOCTL_ACT_SET == action) + { + nwk_setLinkToken(t->token.linkToken); + } + else if (IOCTL_ACT_GET == action) + { + nwk_getLinkToken(&t->token.linkToken); + } + else + { + rc = SMPL_BAD_PARAM; + } + } + else if (TT_JOIN == t->tokenType) + { + if (IOCTL_ACT_SET == action) + { + nwk_setJoinToken(t->token.joinToken); + } + else if (IOCTL_ACT_GET == action) + { + nwk_getJoinToken(&t->token.joinToken); + } + else + { + rc = SMPL_BAD_PARAM; + } + } + else + { + rc = SMPL_BAD_PARAM; + } + } + break; + + case IOCTL_OBJ_NVOBJ: + rc = nwk_NVObj(action, (ioctlNVObj_t *)val); + break; +#endif /* EXTENDED_API */ + + case IOCTL_OBJ_CONNOBJ: + rc = nwk_connectionControl(action, val); + break; + + case IOCTL_OBJ_ADDR: + if ((IOCTL_ACT_GET == action) || (IOCTL_ACT_SET == action)) + { + rc = nwk_deviceAddress(action, (addr_t *)val); + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_RAW_IO: + if (IOCTL_ACT_WRITE == action) + { + rc = nwk_rawSend((ioctlRawSend_t *)val); + } + else if (IOCTL_ACT_READ == action) + { + rc = nwk_rawReceive((ioctlRawReceive_t *)val); + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_RADIO: + rc = nwk_radioControl(action, val); + break; + +#if defined(ACCESS_POINT) + case IOCTL_OBJ_AP_JOIN: + rc = nwk_joinContext(action); + break; +#endif +#if defined(FREQUENCY_AGILITY) + case IOCTL_OBJ_FREQ: + rc = nwk_freqControl(action, val); + break; +#endif + case IOCTL_OBJ_FWVER: + if (IOCTL_ACT_GET == action) + { + memcpy(val, nwk_getFWVersion(), SMPL_FWVERSION_SIZE); + rc = SMPL_SUCCESS; + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_PROTOVER: + if (IOCTL_ACT_GET == action) + { + *((uint8_t *)val) = nwk_getProtocolVersion(); + rc = SMPL_SUCCESS; + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + default: + rc = SMPL_BAD_PARAM; + break; + } + + return rc; +} + +/****************************************************************************** + * @fn ioctlPreInitAccessIsOK + * + * @brief Is the request legal yet? Most requests are not legal before + * SMPL_Init(). + * + * input parameters + * @param object - The IOCTL target object + * + * output parameters + * + * @return Returns non-zero if request should be honored for further + * processing, otherwise returns 0. This function does not + * determine of the object-action pair are valid. It only knows + * about exceptions, i.e., those that are valid before the + * SMPL_Init() call. + * + */ + +static uint8_t ioctlPreInitAccessIsOK(ioctlObject_t object) +{ + uint8_t rc; + + /* Currently the only legal pre-init accesses are the address and + * the token objects. + */ + switch (object) + { + case IOCTL_OBJ_ADDR: + case IOCTL_OBJ_TOKEN: + rc = 1; /* legal */ + break; + + default: + rc = 0; /* not legal when init not done */ + break; + } + + return rc; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_api.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_api.h new file mode 100755 index 0000000..104f031 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_api.h @@ -0,0 +1,58 @@ +/************************************************************************************************** +* Filename: nwk_api.h +* Revised: $Date: 2008-11-24 12:09:31 -0800 (Mon, 24 Nov 2008) $ +* Revision: $Revision: 18508 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI appliction layer API. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_API_H +#define NWK_API_H + +/* Tx options (bit map) */ +#define SMPL_TXOPTION_NONE ((txOpt_t)0x00) +#define SMPL_TXOPTION_ACKREQ ((txOpt_t)0x01) + +smplStatus_t SMPL_Init(uint8_t (*)(linkID_t)); +smplStatus_t SMPL_Link(linkID_t *); +smplStatus_t SMPL_LinkListen(linkID_t *); +smplStatus_t SMPL_Send(linkID_t lid, uint8_t *msg, uint8_t len); + +smplStatus_t SMPL_SendOpt(linkID_t lid, uint8_t * msg, uint8_t len, txOpt_t); +smplStatus_t SMPL_Receive(linkID_t lid, uint8_t *msg, uint8_t *len); + +smplStatus_t SMPL_Ioctl(ioctlObject_t, ioctlAction_t, void *); +#ifdef EXTENDED_API +smplStatus_t SMPL_Ping(linkID_t); +smplStatus_t SMPL_Unlink(linkID_t); +smplStatus_t SMPL_Commission(addr_t *, uint8_t, uint8_t, linkID_t *); +#endif /* EXTENDED_API */ + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_app.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_app.h new file mode 100755 index 0000000..4aa942b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_app.h @@ -0,0 +1,53 @@ + +/************************************************************************************************** +* Filename: nwk_app.h +* Revised: $Date: 2007-07-10 11:21:35 -0700 (Tue, 10 Jul 2007) $ +* Revision: $Revision: 14865 $ +* Author: $Author: lfriedman $ +* +* Description: This header file is for convenience and includes the headers for all the +* network applications. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + + + +#ifndef NWK_APP_H +#define NWK_APP_H + +#include "nwk_freq.h" +#include "nwk_ping.h" +#include "nwk_link.h" +#include "nwk_mgmt.h" +#include "nwk_join.h" +#include "nwk_security.h" +#include "nwk_ioctl.h" + +#endif + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_frame.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_frame.c new file mode 100755 index 0000000..1726d13 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_frame.c @@ -0,0 +1,984 @@ +/************************************************************************************************** +* Filename: nwk_frame.c +* Revised: $Date: 2009-03-10 16:21:40 -0700 (Tue, 10 Mar 2009) $ +* Revision: $Revision: 19368 $ +* Author $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI frame handling functions. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "nwk_QMgmt.h" +#include "nwk_globals.h" +#include "nwk_mgmt.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +#if SIZE_INFRAME_Q > 0 +/* array of function pointers to handle NWK application frames */ +static fhStatus_t(*const func[]) (mrfiPacket_t *) = { nwk_processPing, + nwk_processLink, + nwk_processJoin, + nwk_processSecurity, + nwk_processFreq, + nwk_processMgmt}; +#endif /* SIZE_INFRAME_Q > 0 */ + +static uint8_t sTRACTID = 0; + +static addr_t const *sMyAddr = NULL; + +static uint8_t sMyRxType = 0, sMyTxType = 0; + +#if !defined(RX_POLLS) +static uint8_t (*spCallback)(linkID_t) = NULL; +#endif + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +#if SIZE_INFRAME_Q > 0 +/* local helper functions for Rx devices */ +static void dispatchFrame(frameInfo_t *); + +# if !defined(END_DEVICE) +# if defined(ACCESS_POINT) +/* only Access Points need to worry about duplicate S&F frames */ +uint8_t isDupSandFFrame(mrfiPacket_t *); + +# endif /* ACCESS_POINT */ +# endif /* !END_DEVICE */ +#endif /* SIZE_INFRAME_Q > 0 */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_frameInit + * + * @brief Initialize network context. + * + * input parameters + * pF - Pointer to callback function. If none intended should be NULL. + * + * output parameters + * + * @return void + */ + +void nwk_frameInit(uint8_t (*pF)(linkID_t)) +{ + + /****** Fill static values for the DEVICEINFO byte that will go in each frame ***** + * Rx type when frame originates from this device. Set in nwk_buildFrame() + * Tx type when frame sent from this device. Set in nwk_sendframe() */ +#if !defined(END_DEVICE) + sMyRxType = F_RX_TYPE_USER_CTL; +# if defined(ACCESS_POINT) + sMyTxType = F_TX_DEVICE_AP; +# else + sMyTxType = F_TX_DEVICE_RE; +# endif +#else + sMyTxType = F_TX_DEVICE_ED; +# if defined(RX_POLLS) + sMyRxType = F_RX_TYPE_POLLS; +# endif +# if defined(RX_USER) + sMyRxType = F_RX_TYPE_USER_CTL; +# endif +#endif + /****** DONE fill static values for the DEVICEINFO byte that will go in each frame ******/ + +#if !defined(RX_POLLS) + spCallback = pF; +#else + (void) pF; +#endif + + sMyAddr = nwk_getMyAddress(); + + while (!(sTRACTID = MRFI_RandomByte())) ; + + return; +} + +/****************************************************************************** + * @fn nwk_buildFrame + * + * @brief Builds an output frame for the port and message enclosed. + * This routine prepends the frame header and populates the + * frame in the output queue. + * + * input parameters + * @param port - port from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param hops - number of hops allowed. this is less than MAX_HOPS + * whenever the frame is being sent to the AP. this is to + * help mitigate the (short) broadcast storms + * + * output parameters + * + * @return pointer to frameInfo_t structure created. NULL if there is + * no room in output queue. + */ + +frameInfo_t *nwk_buildFrame(uint8_t port, uint8_t *msg, uint8_t len, uint8_t hops) +{ + frameInfo_t *fInfoPtr; + + if (!(fInfoPtr = nwk_QfindSlot(OUTQ))) + { + return (frameInfo_t *)NULL; + } + + MRFI_SET_PAYLOAD_LEN(&fInfoPtr->mrfiPkt, len + F_APP_PAYLOAD_OS); + + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ENCRYPT_OS, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_PORT_OS, port); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_TRACTID_OS, sTRACTID); + while (!(++sTRACTID)) ; /* transaction ID can't be 0 */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_RX_TYPE, sMyRxType); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_HOP_COUNT, hops); + + /* reset ack-relevant bits */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_REQ, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_RPLY, 0); + + /* reset forwarding bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_FWD_FRAME, 0); + + memcpy(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt) + F_APP_PAYLOAD_OS, msg, len); + memcpy(MRFI_P_SRC_ADDR(&fInfoPtr->mrfiPkt), sMyAddr, NET_ADDR_SIZE); + + return fInfoPtr; +} + +#if defined(APP_AUTO_ACK) + +/****************************************************************************** + * @fn nwk_buildAckReqFrame + * + * @brief Builds an output frame for the port and message enclosed. + * This routine prepends the frame header and populates the + * frame in the output queue. The frame is set to request that + * an ack frame be sent by the peer. + * + * input parameters + * @param port - port from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param hops - number of hops allowed. this is less than MAX_HOPS + * whenever the frame is being sent to the AP. this is to + * help mitigate the (short) broadcast storms + * @param tid - Transaction ID to insert in NWK header used to match + * the ack reply. + * + * output parameters + * + * @return pointer to frameInfo_t structure created. NULL if there is + * no room in output queue. + */ + +frameInfo_t *nwk_buildAckReqFrame(uint8_t port, uint8_t *msg, uint8_t len, uint8_t hops, + volatile uint8_t *tid) +{ + frameInfo_t *fInfoPtr; + + /* Build a normal frame first. */ + if (!(fInfoPtr = nwk_buildFrame(port, msg, len, hops))) + { + return (frameInfo_t *)NULL; + } + + /* save TID */ + *tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_TRACTID_OS); + /* Set REQ_ACK bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_REQ, F_ACK_REQ_TYPE); + + return fInfoPtr; +} + +#endif /* APP_AUTO_ACK */ + +#if SIZE_INFRAME_Q > 0 + +/****************************************************************************** + * @fn MRFI_RxCompleteISR + * + * @brief Here on Rx interrupt from radio. Process received frame from the + * radio Rx FIFO. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void MRFI_RxCompleteISR() +{ + frameInfo_t *fInfoPtr; + + /* room for more? */ + if (fInfoPtr = nwk_QfindSlot(INQ)) + { + MRFI_Receive(&fInfoPtr->mrfiPkt); + + dispatchFrame(fInfoPtr); + } + + return; +} + +/****************************************************************************** + * @fn nwk_retrieveFrame + * + * @brief Retrieve frame from Rx frame queue. Invoked by application-level + * code either app through SMPL_Receive() or IOCTL through raw Rx. This + * should run in a user thread, not an ISR thread. + * + * input parameters + * @param port - port on which to get a frame + * + * output parameters + * @param msg - pointer to where app payload should be copied. Buffer + * allocated should be == MAX_APP_PAYLOAD. + * + * @param len - pointer to where payload length should be stored. Caller + * can check for non-zero when polling the port. initialized + * to 0 even if no frame is retrieved. + * @param srcAddr - if non-NULL, a pointer to where to copy the source address + * of the retrieved message. + * @param hopCount - if non-NULL, a pointer to where to copy the hop count + * of the retrieved message. + * + * @return SMPL_SUCCESS + * SMPL_NO_FRAME - no frame found for specified destination + * SMPL_BAD_PARAM - no valid connection info for the Link ID + * + */ + +smplStatus_t nwk_retrieveFrame(rcvContext_t *rcv, uint8_t *msg, uint8_t *len, addr_t *srcAddr, + uint8_t *hopCount) +{ + frameInfo_t *fPtr; + uint8_t done; + + do { + /* look for a frame on requested port. */ + *len = 0; + done = 1; + + fPtr = nwk_QfindOldest(INQ, rcv, USAGE_NORMAL); + if (fPtr) + { + connInfo_t *pCInfo = 0; + + if (RCV_APP_LID == rcv->type) + { + pCInfo = nwk_getConnInfo(rcv->t.lid); + if (!pCInfo) + { + return SMPL_BAD_PARAM; + } +# if defined(SMPL_SECURE) + /* decrypt here...we have all the context we need. */ + { + uint32_t ctr = pCInfo->connRxCTR; + uint32_t *pctr = &ctr; + uint8_t len = MRFI_GET_PAYLOAD_LEN(&fPtr->mrfiPkt) - F_SEC_CTR_OS; + + if (pCInfo->thisLinkID == SMPL_LINKID_USER_UUD) + { + pctr = NULL; + } +# if defined(RX_POLLS) + else if ((F_APP_PAYLOAD_OS - F_SEC_CTR_OS) == len) + { + /* This was an empty poll reply frame generated by the AP. + * It uses the single-byte CTR value like network applications. + * We do not want to use the application layer counter in this case. + */ + pctr = NULL; + } +# endif + if (nwk_getSecureFrame(&fPtr->mrfiPkt, len, pctr)) + { + if (pctr) + { + /* Update connection's counter. */ + pCInfo->connRxCTR = ctr; + } + } + else + { + /* Frame bogus. Check for another frame. */ + done = 0; + continue; + } + } +# endif /* SMPL_SECURE */ + } + + /* it's on the requested port. */ + *len = MRFI_GET_PAYLOAD_LEN(&fPtr->mrfiPkt) - F_APP_PAYLOAD_OS; + memcpy(msg, MRFI_P_PAYLOAD(&fPtr->mrfiPkt) + F_APP_PAYLOAD_OS, *len); + /* save signal info */ + if (pCInfo) + { + /* Save Rx metrics... */ + pCInfo->sigInfo.rssi = fPtr->mrfiPkt.rxMetrics[MRFI_RX_METRICS_RSSI_OFS]; + pCInfo->sigInfo.lqi = fPtr->mrfiPkt.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS]; + } + if (srcAddr) + { + /* copy source address if requested */ + memcpy(srcAddr, MRFI_P_SRC_ADDR(&fPtr->mrfiPkt), NET_ADDR_SIZE); + } + if (hopCount) + { + /* copy hop count if requested */ + *hopCount = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fPtr->mrfiPkt), F_HOP_COUNT); + } + /* input frame no longer needed. free it. */ + nwk_QadjustOrder(INQ, fPtr->orderStamp); + + fPtr->fi_usage = FI_AVAILABLE; + return SMPL_SUCCESS; + } + } while (!done); + + return SMPL_NO_FRAME; +} + +/****************************************************************************** + * @fn dispatchFrame + * + * @brief Received frame looks OK so far. Dispatch to either NWK app by + * invoking the handler or the user's app by simply leaving the + * frame in the queue and letting the app poll the port. + * + * input parameters + * @param fiPtr - frameInfo_t pointer to received frame + * + * output parameters + * + * @return void + */ + +static void dispatchFrame(frameInfo_t *fiPtr) +{ + uint8_t port = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_PORT_OS); + uint8_t nwkAppSize = sizeof(func) / sizeof(func[0]); + fhStatus_t rc; + linkID_t lid; + +# if defined(ACCESS_POINT) + uint8_t loc; +# endif +# if !defined(END_DEVICE) + uint8_t isForMe; +# endif + + /* be sure it's not an echo... */ + if (!memcmp(MRFI_P_SRC_ADDR(&fiPtr->mrfiPkt), sMyAddr, NET_ADDR_SIZE)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + + /* Make sure encyrption bit conforms to our security support context. */ +# if defined(SMPL_SECURE) + if (!(GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ENCRYPT_OS))) + { + /* Encyrption bit is not on when when it should be */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +# else + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ENCRYPT_OS)) + { + /* Encyrption bit is on when when it should not be */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +# endif /* SMPL_SECURE */ + + /* If it's a network application port dispatch to service routine. Dispose + * of frame depending on return code. + */ + if (port && (port <= nwkAppSize)) + { +# if defined(SMPL_SECURE) + /* Non-connection-based frame. We can decode here if it was encrypted */ + if (!nwk_getSecureFrame(&fiPtr->mrfiPkt, MRFI_GET_PAYLOAD_LEN(&fiPtr->mrfiPkt) - + F_SEC_CTR_OS, 0)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +# endif + rc = func[port - 1](&fiPtr->mrfiPkt); + if (FHS_KEEP == rc) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + } +# if !defined(END_DEVICE) + else if (FHS_REPLAY == rc) + { + /* an AP or an RE could be relaying a NWK application frame... */ + nwk_replayFrame(fiPtr); + } +# endif + else /* rc == FHS_RELEASE (default...) */ + { + fiPtr->fi_usage = FI_AVAILABLE; + } + return; + } + /* sanity check */ + else if ((port != SMPL_PORT_USER_BCAST) && + ((port < PORT_BASE_NUMBER) || (port > SMPL_PORT_STATIC_MAX))) + { + /* bogus port. drop frame */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + + /* At this point we know the target is a user app. If this is an end device + * and we got this far save the frame and we're done. If we're an AP there + * are 3 cases: it's for us, it's for s store-and-forward client, or we need + * to replay the frame. If we're and RE and the frame didn't come from an RE + * and it's not for us, replay the frame. + */ + +# if defined(END_DEVICE) + + /* If we're s polling end device we only accept application frames from + * the AP. This prevents duplicate reception if we happen to be on when + * a linked peer sends. + */ +# if defined(RX_POLLS) + if (F_TX_DEVICE_ED != GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE)) + { + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } +# else + /* it's destined for a user app. */ + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + if (spCallback && spCallback(lid)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } +# endif /* RX_POLLS */ + +# else /* END_DEVICE */ + + /* We have an issue if the frame is broadcast to the UUD port. The AP (or RE) must + * handle this frame as if it were the target in case there is an application + * running that is listening on that port. But if it's a broadcast it must also be + * replayed. It isn't enough just to test for the UUD port because it could be a + * directed frame to another device. We must check explicitly for broadcast + * destination address. + */ + isForMe = !memcmp(sMyAddr, MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), NET_ADDR_SIZE); + if (isForMe || + ((port == SMPL_PORT_USER_BCAST) && + !memcmp(nwk_getBCastAddress(), MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), NET_ADDR_SIZE))) + { + /* The folllowing test will succeed for the UUD port regardless of the + * source address. + */ + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + /* If this is for the UUD port and we are here then the device is either + * an AP or an RE. In either case it must replay the UUD port frame if the + * frame is not "for me". But it also must handle it since it could have a + * UUD-listening application. Do the reply first and let the subsequent code + * correctly set the frame usage state. Note that the routine return can be + * from this code block. If not it will drop through to the bottom without + * doing a replay. + */ + /* Do I need to replay it? */ + if (!isForMe) + { + /* must be a broadcast for the UUD port */ + nwk_replayFrame(fiPtr); + } + /* OK. Now I handle it... */ + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + if (spCallback && spCallback(lid)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } +# if defined(ACCESS_POINT) + + /* Check to see if we need to save this for a S and F client. Otherwise, + * if it's not for us, get rid of it. + */ + else if (nwk_isSandFClient(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), &loc)) + { + /* Don't bother if it is a duplicate frame or if it's a forwarded frame + * echoed back from an RE. + */ + if (!isDupSandFFrame(&fiPtr->mrfiPkt) && + !(GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_FWD_FRAME)) + ) + { +# if defined(APP_AUTO_ACK) + /* Make sure ack request bit is off. Sender will have gone away. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ACK_REQ, 0); +# endif + fiPtr->fi_usage = FI_INUSE_UNTIL_FWD; + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE) == F_TX_DEVICE_AP) + { + /* I'm an AP and this frame came from an AP. Don't replay. */ + fiPtr->fi_usage = FI_AVAILABLE; + } +# elif defined(RANGE_EXTENDER) + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE) == F_TX_DEVICE_RE) + { + /* I'm an RE and this frame came from an RE. Don't replay. */ + fiPtr->fi_usage = FI_AVAILABLE; + } +# endif + else + { + /* It's not for me and I'm either an AP or I'm an RE and the frame + * didn't come from an RE. Replay the frame. + */ + nwk_replayFrame(fiPtr); + } +# endif /* !END_DEVICE */ + return; +} + +#endif /* SIZE_INFRAME_Q > 0 */ + +/****************************************************************************** + * @fn nwk_sendFrame + * + * @brief Send a frame by copying it to the radio Tx FIFO. + * + * input parameters + * @param pFrameInfo - pointer to frame to be sent + * @param txOption - do CCA or force frame out. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_TX_CCA_FAIL Tx failed because of CCA failure. + * Tx FIFO flushed in this case. + */ + +smplStatus_t nwk_sendFrame(frameInfo_t *pFrameInfo, uint8_t txOption) +{ + smplStatus_t rc; + + /* set the type of device sending the frame in the header */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_TX_DEVICE, sMyTxType); + + if (MRFI_TX_RESULT_SUCCESS == MRFI_Transmit(&pFrameInfo->mrfiPkt, txOption)) + { + rc = SMPL_SUCCESS; + } + else + { + /* Tx failed -- probably CCA. free up frame buffer. We do not have NWK + * level retries. Let application do it. + */ + rc = SMPL_TX_CCA_FAIL; + } + + /* TX is done. free up the frame buffer */ + pFrameInfo->fi_usage = FI_AVAILABLE; + + return rc; +} + +/****************************************************************************** + * @fn nwk_getMyRxType + * + * @brief Get my Rx type. Used to help populate the hops count in the + * frame header to try and limit the broadcast storm. Info is + * exchanged when linking. + * + * input parameters + * + * output parameters + * + * @return The address LSB. + */ + +uint8_t nwk_getMyRxType(void) +{ + return sMyRxType; +} + +#if defined(APP_AUTO_ACK) + +/****************************************************************************** + * @fn nwk_sendAckReply + * + * @brief Send an acknowledgement reply frame. + * + * input parameters + * @param frame - pointer to frame with ack request. + * @param port - port on whcih reply expected. + * + * output parameters + * + * @return void + */ + +void nwk_sendAckReply(mrfiPacket_t *frame, uint8_t port) +{ + mrfiPacket_t dFrame; + uint8_t tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS); + + /* set the type of device sending the frame in the header */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, sMyTxType); + + /* set the listen type of device sending the frame in the header. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); + + /* destination address from received frame */ + memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + /* source address */ + memcpy(MRFI_P_SRC_ADDR(&dFrame), sMyAddr, NET_ADDR_SIZE); + + /* port is the source the Tx port from the connection object */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); + + /* frame length... */ + MRFI_SET_PAYLOAD_LEN(&dFrame, F_APP_PAYLOAD_OS); + + /* transaction ID taken from source frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, tid); + + /* hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS); + + /* set ACK field */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, F_ACK_RPLY_TYPE); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); + + /* This is not a forwarded frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, 0); + + /* Encryption state */ +# if !defined(SMPL_SECURE) + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); +# else + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + nwk_setSecureFrame(&dFrame, 0, 0); +# endif + + MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +#endif /* APP_AUTO_ACK */ + +#if !defined(END_DEVICE) + +/****************************************************************************** + * @fn nwk_replayFrame + * + * @brief Deal with hop count on a Range Extender or Access Point replay. + * Queue entry usage always left as available when done. + * + * input parameters + * @param pFrameInfo - pointer to frame information structure + * + * output parameters + * + * @return void + */ + +void nwk_replayFrame(frameInfo_t *pFrameInfo) +{ + uint8_t hops = GET_FROM_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_HOP_COUNT); + + /* if hops are zero, drop frame. othewise send it. */ + if (hops--) + { + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_HOP_COUNT, hops); + + /* Don't care if the Tx fails because of TO. Either someone else + * will retransmit or the application itself will recover. + */ +# if defined(SMPL_SECURE) + + /* If the frame was targeted to a NWK port it was decrypted on spec in + * the 'dispatchFrame()' method. It must be re-encypted in this case. + */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_PORT_OS) <= SMPL_PORT_NWK_BCAST) + { + nwk_setSecureFrame(&pFrameInfo->mrfiPkt, MRFI_GET_PAYLOAD_LEN( + &pFrameInfo->mrfiPkt) - F_APP_PAYLOAD_OS, 0); + } +# endif + MRFI_DelayMs(1); + nwk_sendFrame(pFrameInfo, MRFI_TX_TYPE_CCA); + } + else + { + pFrameInfo->fi_usage = FI_AVAILABLE; + } + return; +} + +# if defined(ACCESS_POINT) + +/****************************************************************************** + * @fn nwk_getSandFFrame + * + * @brief Get any frame waiting for the client on the port supplied in + * the frame payload. + * TODO: support returning NWK application frames always. the + * port requested in the call should be an user application port. + * NWK app ports will never be in the called frame. + * TODO: deal with broadcast NWK frames from AP. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return pointer to frame if there is one, otherwise 0. + */ + +frameInfo_t *nwk_getSandFFrame(mrfiPacket_t *frame, uint8_t osPort) +{ + uint8_t i, port = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + osPort); + frameInfo_t *fiPtr; + rcvContext_t rcv; + + rcv.type = RCV_RAW_POLL_FRAME; + rcv.t.pkt = frame; + /* check the input queue for messages sent by others. */ + if (fiPtr = nwk_QfindOldest(INQ, &rcv, USAGE_FWD)) + { + return fiPtr; + } + + /* Check the output queue to see if we ourselves need to send anything. + * TODO: use the cast-out scheme for output queue so this routine finds + * the oldest in either queue. + */ + fiPtr = nwk_getQ(OUTQ); + for (i = 0; i < SIZE_OUTFRAME_Q; ++i, fiPtr++) + { + if (FI_INUSE_UNTIL_FWD == fiPtr->fi_usage) + { + if (!memcmp(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_PORT_OS) == port) + { + return fiPtr; + } + } + } + } + return 0; +} + +/****************************************************************************** + * @fn nwk_SendEmptyPollRspFrame + * + * @brief There are no frames waiting for the requester on the specified + * port. Send a frame back to that port with no payload. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return void + */ + +void nwk_SendEmptyPollRspFrame(mrfiPacket_t *frame) +{ + mrfiPacket_t dFrame; + uint8_t port = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + M_POLL_PORT_OS); + + /* set the type of device sending the frame in the header. we know it's an AP */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, F_TX_DEVICE_AP); + + /* set the listen type of device sending the frame in the header. we know it's + * an AP is is probably always on...but use the static variable anyway. + */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); + /* destination address from received frame (polling device) */ + memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + /* source address */ + memcpy(MRFI_P_SRC_ADDR(&dFrame), MRFI_P_PAYLOAD( + frame) + F_APP_PAYLOAD_OS + M_POLL_ADDR_OS, NET_ADDR_SIZE); + /* port is the port requested */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); + /* frame length... */ + MRFI_SET_PAYLOAD_LEN(&dFrame, F_APP_PAYLOAD_OS); + /* transaction ID... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, sTRACTID); + sTRACTID++; + /* hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS_FROM_AP); + + /* Ack fields */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); + + /* This is logically a forwarded frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, F_FRAME_FWD_TYPE); + + /* Encryption state */ +# if !defined(SMPL_SECURE) + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); +# else + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + nwk_setSecureFrame(&dFrame, 0, 0); +# endif + + MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +/****************************************************************************** + * @fn isDupSandFFrame + * + * @brief Have we already stored this frame on behalf of a client? + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns 1 if the frame is a duplicate, otherwise 0. + */ + +uint8_t isDupSandFFrame(mrfiPacket_t *frame) +{ + uint8_t i, plLen = MRFI_GET_PAYLOAD_LEN(frame); + frameInfo_t *fiPtr; + + /* check the input queue for duplicate S&F frame. */ + fiPtr = nwk_getQ(INQ); + for (i = 0; i < SIZE_INFRAME_Q; ++i, fiPtr++) + { + if (FI_INUSE_UNTIL_FWD == fiPtr->fi_usage) + { + /* compare everything except the DEVICE INFO byte. */ + if (MRFI_GET_PAYLOAD_LEN(&fiPtr->mrfiPkt) == plLen && + !memcmp(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), MRFI_P_DST_ADDR(frame), NET_ADDR_SIZE) && + !memcmp(MRFI_P_SRC_ADDR(&fiPtr->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE) && + !memcmp(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), MRFI_P_PAYLOAD(frame), 1) && + !memcmp(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt) + F_TRACTID_OS, MRFI_P_PAYLOAD(frame) + + F_TRACTID_OS, plLen - F_TRACTID_OS) + ) + { + return 1; + } + } + } + return 0; +} + +# endif /* ACCESS_POINT */ + +#endif /* !END_DEVICE */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_frame.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_frame.h new file mode 100755 index 0000000..f169911 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_frame.h @@ -0,0 +1,155 @@ +/************************************************************************************************** +* Filename: nwk_frame.h +* Revised: $Date: 2008-12-23 13:49:41 -0800 (Tue, 23 Dec 2008) $ +* Revision: $Revision: 18651 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI frame handling functions. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_FRAME_H +#define NWK_FRAME_H + +/* Frame field defines and masks. Mask name must be field name with '_MSK' appended + * so the GET and PUT macros work correctly -- they use token pasting. Offset values + * are with respect to the MRFI payload and not the entire frame. + */ +#define F_PORT_OS 0 +#define F_PORT_OS_MSK (0x3F) +#define F_ENCRYPT_OS 0 +#define F_ENCRYPT_OS_MSK (0x40) +#define F_FWD_FRAME 0 +#define F_FWD_FRAME_MSK (0x80) +#define F_RX_TYPE 1 +#define F_RX_TYPE_MSK (0x40) +#define F_ACK_REQ 1 +#define F_ACK_REQ_MSK (0x80) +#define F_ACK_RPLY 1 +#define F_ACK_RPLY_MSK (0x08) +#define F_TX_DEVICE 1 +#define F_TX_DEVICE_MSK (0x30) +#define F_HOP_COUNT 1 +#define F_HOP_COUNT_MSK (0x07) +#define F_TRACTID_OS 2 +#define F_TRACTID_OS_MSK (0xFF) +#define SMPL_NWK_HDR_SIZE 3 + +#ifdef SMPL_SECURE + +# define F_SECURE_OS 3 + +# define F_SEC_CTR_OS 3 /* counter hint */ +# define F_SEC_CTR_OS_MSK (0xFF) +# define F_SEC_ICHK_OS 4 /* Message integrity check */ +# define F_SEC_ICHK_OS_MSK (0xFF) +# define F_SEC_MAC_OS 5 /* Message authentication code */ +# define F_SEC_MAC_OS_MSK (0xFF) + +#else + +# define F_SECURE_OS 0 + +#endif /* SMPL_SECURE */ + +#define F_APP_PAYLOAD_OS (SMPL_NWK_HDR_SIZE + F_SECURE_OS) + +/* sub field details. they are in the correct bit locations (already shifted) */ +#define F_RX_TYPE_USER_CTL 0x00 /* does not poll... */ +#define F_RX_TYPE_POLLS 0x40 /* polls for held messages */ + +#define F_ACK_REQ_TYPE 0x80 +#define F_ACK_RPLY_TYPE 0x08 +#define F_FRAME_FWD_TYPE 0x80 +#define F_FRAME_ENCRYPT_TYPE 0x40 + +/* device type fields */ +#define F_TX_DEVICE_ED 0x00 /* End Device */ +#define F_TX_DEVICE_RE 0x10 /* Range Extender */ +#define F_TX_DEVICE_AP 0x20 /* Access Point */ + +/* macro to get a field from a frame buffer */ +#define GET_FROM_FRAME(b, f) ((b)[f] & (f##_MSK)) + +/* Macro to put a value 'v' into a frame buffer 'b'. 'v' value must already be shifted + * if necessary. 'b' is a byte array + */ +#define PUT_INTO_FRAME(b, f, v) do {(b)[f] = ((b)[f] & ~(f##_MSK)) | (v); } while (0) + + +/* **** frame information objects + * info kept on each frame object + */ +#define FI_AVAILABLE 0 /* entry available for use */ +#define FI_INUSE_UNTIL_DEL 1 /* in use. will be explicitly reclaimed */ +#define FI_INUSE_UNTIL_TX 2 /* in use. will be reclaimed after Tx */ +#define FI_INUSE_UNTIL_FWD 3 /* in use until forwarded by AP */ +#define FI_INUSE_TRANSITION 4 /* being retrieved. do not delete in Rx ISR thread. */ + +typedef struct +{ + uint8_t rssi; + uint8_t lqi; +} sigInfo_t; + +typedef struct +{ + volatile uint8_t fi_usage; + uint8_t orderStamp; + mrfiPacket_t mrfiPkt; +} frameInfo_t; + + +/* prototypes */ +frameInfo_t *nwk_buildFrame(uint8_t, uint8_t * msg, uint8_t len, uint8_t hops); +#ifdef APP_AUTO_ACK +frameInfo_t *nwk_buildAckReqFrame(uint8_t, uint8_t *, uint8_t, uint8_t, volatile uint8_t *); +#endif +void nwk_receiveFrame(void); + +void nwk_frameInit(uint8_t (*)(linkID_t)); +smplStatus_t nwk_retrieveFrame(rcvContext_t *, uint8_t *, uint8_t *, addr_t *, uint8_t *); +smplStatus_t nwk_sendFrame(frameInfo_t *, uint8_t txOption); + +frameInfo_t *nwk_getSandFFrame(mrfiPacket_t *, uint8_t); +uint8_t nwk_getMyRxType(void); +void nwk_SendEmptyPollRspFrame(mrfiPacket_t *); + +#ifdef APP_AUTO_ACK +void nwk_sendAckReply(mrfiPacket_t *, uint8_t); +#endif + +#ifndef END_DEVICE +/* only APs and REs repeat frames */ +void nwk_replayFrame(frameInfo_t *); + +#endif + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_globals.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_globals.c new file mode 100755 index 0000000..b63cf67 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_globals.c @@ -0,0 +1,267 @@ +/************************************************************************************************** +* Filename: nwk_globals.c +* Revised: $Date: 2009-10-27 20:48:11 -0700 (Tue, 27 Oct 2009) $ +* Revision: $Revision: 20995 $ +* +* Description: This file manages global NWK data. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_globals.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static const addr_t sMyROMAddress = THIS_DEVICE_ADDRESS; +static addr_t sAPAddress; +static addr_t sMyRAMAddress; +static uint8_t sRAMAddressIsSet = 0; + +/* Version number set as a 4 byte quantity. Each byte is a revision number + * in the form w.x.y.z. The subfields are each limited to values 0x0-0xFF. + */ +static const smplVersionInfo_t sVersionInfo = { + 0x02, /* protocol version */ + 0x01, /* major revision number */ + 0x01, /* minor revision number */ + 0x01, /* maintenance release number */ + 0x00 /* special release */ +}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_globalsInit + * + * @brief Initialization of global symbols + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_globalsInit(void) +{ + + memset(&sAPAddress, 0x00, sizeof(addr_t)); + + /* populate RAM address from ROM default if it hasn't laready been set + * using the IOCTL interface. + */ + if (!sRAMAddressIsSet) + { + memcpy(&sMyRAMAddress, &sMyROMAddress, sizeof(addr_t)); + sRAMAddressIsSet = 1; /* RAM address is now valid */ + } + + return; +} + +/****************************************************************************** + * @fn nwk_getMyAddress + * + * @brief Return a pointer to my address. It comes either from ROM as + * set in the configuration file or it was set using the IOCTL + * interface -- probably from random bytes. + * + * input parameters + * + * output parameters + * + * @return pointer to a constant address type object. + */ + +addr_t const *nwk_getMyAddress(void) +{ + /* This call supports returning a valid pointer before either the + * initialization or external setting of the address. But caller needs + * to be careful -- if this routine is called immediately it will return + * the ROM address. If the application then sets the address using the + * IOCTL before doing the SMPL_Init() the original pointer is no longer + * valid as it points to the wrong address. + */ + return sRAMAddressIsSet ? &sMyRAMAddress : &sMyROMAddress; +} + +/****************************************************************************** + * @fn nwk_getFWVersion + * + * @brief Return a pointer to the current firmware version string. + * + * input parameters + * + * output parameters + * + * @return pointer to a constant uint16_t object. + */ + +uint8_t const *nwk_getFWVersion() +{ + return sVersionInfo.fwVerString; +} + +/****************************************************************************** + * @fn nwk_getProtocolVersion + * + * @brief Return the current protocol version. + * + * input parameters + * + * output parameters + * + * @return Protocol version. + */ + +uint8_t nwk_getProtocolVersion(void) +{ + return sVersionInfo.protocolVersion; +} + +/****************************************************************************** + * @fn nwk_setMyAddress + * + * @brief Set my address object if it hasn't already been set. This call + * is referenced by the IOCTL support used to change the device + * address. It is effective only if the address has not already + * been set. + * + * input parameters + * + * @param addr - pointer to the address object to be used to set my address. + * + * output parameters + * + * @return Returns non-zero if request is respected, otherwise returns 0. + */ + +uint8_t nwk_setMyAddress(addr_t *addr) +{ + uint8_t rc = 0; + + if (!sRAMAddressIsSet) + { + memcpy(&sMyRAMAddress, addr, sizeof(addr_t)); + sRAMAddressIsSet = 1; /* RAM address is now valid */ + rc = 1; + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_setAPAddress + * + * @brief Set the AP's address. Called after the AP address is gleaned + * from the Join reply. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_setAPAddress(addr_t *addr) +{ + + memcpy((void *)&sAPAddress, (void *)addr, NET_ADDR_SIZE); + + return; +} + +/****************************************************************************** + * @fn nwk_getAPAddress + * + * @brief Get the AP's address. + * + * input parameters + * + * output parameters + * + * @return Pointer to a constant address object or null if the address has not + * yet been set. + */ + +addr_t const *nwk_getAPAddress(void) +{ + addr_t addr; + + memset(&addr, 0x0, sizeof(addr)); + + return !memcmp(&sAPAddress, &addr, NET_ADDR_SIZE) ? 0 : &sAPAddress; +} + +/****************************************************************************** + * @fn nwk_getBCastAddress + * + * @brief Get the network broadcast address. + * + * input parameters + * + * output parameters + * + * @return Pointer to a constant address object. + */ + +addr_t const *nwk_getBCastAddress(void) +{ + return (addr_t const *)mrfiBroadcastAddr; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_globals.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_globals.h new file mode 100755 index 0000000..7f349c7 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_globals.h @@ -0,0 +1,51 @@ +/************************************************************************************************** +* Filename: nwk_globals.h +* Revised: $Date: 2008-07-30 11:22:21 -0700 (Wed, 30 Jul 2008) $ +* Revision: $Revision: 17655 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the management of NWK global symbols. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_GLOBALS_H +#define NWK_GLOBALS_H + + +/* Prototypes */ +void nwk_globalsInit(void); +addr_t const *nwk_getMyAddress(void); +uint8_t nwk_setMyAddress(addr_t *addr); +void nwk_setAPAddress(addr_t *addr); +addr_t const *nwk_getAPAddress(void); +addr_t const *nwk_getBCastAddress(void); +uint8_t const *nwk_getFWVersion(void); +uint8_t nwk_getProtocolVersion(void); + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_types.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_types.h new file mode 100755 index 0000000..79d4e03 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk/nwk_types.h @@ -0,0 +1,344 @@ +/************************************************************************************************** +* Filename: nwk_types.h +* Revised: $Date: 2009-01-13 11:31:14 -0800 (Tue, 13 Jan 2009) $ +* Revision: $Revision: 18744 $ +* Author: $Author: lfriedman $ +* +* Description: This header file defines the SimpliciTI typedefs. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_TYPES_H +#define NWK_TYPES_H + +#define NWK_TX_RETRY_COUNT 10 +#define NWK_RX_RETRY_COUNT 10 + +#define NWK_APP_REPLY_BIT (0x80) + +#define NET_ADDR_SIZE MRFI_ADDR_SIZE /* size of address in bytes */ + +#ifdef FREQUENCY_AGILITY +# define NWK_FREQ_TBL_SIZE MRFI_NUM_LOGICAL_CHANS +#else +# define NWK_FREQ_TBL_SIZE 1 +#endif + +typedef struct +{ + uint8_t addr[NET_ADDR_SIZE]; +} addr_t; + +typedef uint8_t linkID_t; +typedef uint8_t ccRadioStatus_t; + + +/* *********************************************** + * Begin IOCTL Support + * *********************************************** + */ +enum ioctlObject { + IOCTL_OBJ_FREQ, + IOCTL_OBJ_CRYPTKEY, + IOCTL_OBJ_RAW_IO, + IOCTL_OBJ_RADIO, + IOCTL_OBJ_AP_JOIN, + IOCTL_OBJ_ADDR, + IOCTL_OBJ_CONNOBJ, + IOCTL_OBJ_FWVER, + IOCTL_OBJ_PROTOVER, + IOCTL_OBJ_NVOBJ, + IOCTL_OBJ_TOKEN +}; + +enum ioctlAction { + IOCTL_ACT_SET, + IOCTL_ACT_GET, + IOCTL_ACT_READ, + IOCTL_ACT_WRITE, + IOCTL_ACT_RADIO_SLEEP, + IOCTL_ACT_RADIO_AWAKE, + IOCTL_ACT_RADIO_SIGINFO, + IOCTL_ACT_RADIO_RSSI, + IOCTL_ACT_RADIO_RXON, + IOCTL_ACT_RADIO_RXIDLE, + IOCTL_ACT_RADIO_SETPWR, + IOCTL_ACT_ON, + IOCTL_ACT_OFF, + IOCTL_ACT_SCAN, + IOCTL_ACT_DELETE +}; + +typedef enum ioctlObject ioctlObject_t; +typedef enum ioctlAction ioctlAction_t; + +enum ioctlLevel +{ + IOCTL_LEVEL_0, + IOCTL_LEVEL_1, + IOCTL_LEVEL_2 +}; + +typedef enum ioctlLevel ioctlLevel_t; + +typedef struct +{ + addr_t *addr; + uint8_t *msg; + uint8_t len; + uint8_t port; +} ioctlRawSend_t; + +typedef struct +{ + addr_t *addr; + uint8_t *msg; + uint8_t len; + uint8_t port; + uint8_t hopCount; +} ioctlRawReceive_t; + +/* + * Signal information support + */ +typedef int8_t rssi_t; + +typedef struct +{ + rssi_t rssi; + uint8_t lqi; +} rxMetrics_t; + +typedef struct +{ + linkID_t lid; /* input: Link ID for which signal info desired */ + rxMetrics_t sigInfo; +} ioctlRadioSiginfo_t; + + +/* *** Begin SET/GET token support *** */ +enum tokenType +{ + TT_LINK, /* Token Type is Link */ + TT_JOIN /* Token Type is Join */ +}; + +typedef enum tokenType tokenType_t; + +/* Create a union. If either token ever changes type it will make things easier. */ +typedef union +{ + uint32_t linkToken; + uint32_t joinToken; +} token_t; + +typedef struct +{ + tokenType_t tokenType; + token_t token; +} ioctlToken_t; +/* *** End SET/GET token support *** */ + + +/* + * Frequency Agility support + */ +typedef struct +{ + uint8_t logicalChan; +} freqEntry_t; + +typedef struct +{ + uint8_t numChan; + freqEntry_t *freq; +} ioctlScanChan_t; + +/* Security typedefs to make things easier if they change types */ +typedef uint8_t secMAC_t; +typedef uint8_t secFCS_t; + +/*************************************************************************************** + * ** NV Object support ** + * + * The following object supports saving and restoring the information + * necessary to save and restore a device connection context. + * + * On a GET interface populates the IOCTL object with the version and length (in bytes) + * of the current static connection iformation area. In addition it populates the address + * pointed to by 'objPtr' with the base address of the connection context. At this point + * the caller can either copy to or from the address. Note that this is a dangerous + * interface, as the caller is provided with direct access to the connection context. + * + * When restoring the connection context some sanity checks are possible. If the + * version or length elements of the saved context do not match those of the current + * static object the static object should not be populated. If this sanity fails the + * caller is not provided with the pointer to the conneciton ocntext. + * + * This interface is fairly simple and it is possible to get the address of the + * connection context to do a restore by simply doing a GET call. This avoids the + * sanity checks. However, this is not recommended because there may be other side + * effects of doing a SET that are necessary when restoring a context and are done + * only when the proper option is used to restore the connection context. + * + *************************************************************************************/ +typedef struct +{ + uint8_t objVersion; + uint16_t objLen; + uint8_t **objPtr; +} ioctlNVObj_t; + +/* *********************************************** + * End IOCTL Support + * *********************************************** + */ + +enum smplStatus { + SMPL_SUCCESS, + SMPL_TIMEOUT, + SMPL_BAD_PARAM, + SMPL_NOMEM, + SMPL_NO_FRAME, + SMPL_NO_LINK, + SMPL_NO_JOIN, + SMPL_NO_CHANNEL, + SMPL_NO_PEER_UNLINK, + SMPL_TX_CCA_FAIL, + SMPL_NO_PAYLOAD, + SMPL_NO_AP_ADDRESS, + SMPL_NO_ACK +}; + +typedef enum smplStatus smplStatus_t; + +/* NWK application frame handling status codes */ +enum fhStatus +{ + FHS_RELEASE, /* handled in interrupt thread */ + FHS_KEEP, /* handled by background application */ + FHS_REPLAY /* non-ED case: NWK frame not for me that should be replayed */ +}; + +typedef enum fhStatus fhStatus_t; + +/******** BEGIN: Object support for parameter context in queue management *********/ +enum rcvType +{ + RCV_NWK_PORT, + RCV_APP_LID, + RCV_RAW_POLL_FRAME +}; + +typedef enum rcvType rcvType_t; + +/* Tx options type */ +typedef uint16_t txOpt_t; + +typedef struct +{ + rcvType_t type; + union + { + linkID_t lid; + uint8_t port; + mrfiPacket_t *pkt; + } t; +} rcvContext_t; +/******** END: Object support for parameter context in queue management *********/ + +#define SMPL_FWVERSION_SIZE 4 + +typedef struct +{ + uint8_t protocolVersion; + uint8_t fwVerString[SMPL_FWVERSION_SIZE]; +} smplVersionInfo_t; + +/* The following typedef is used to standardize the application Transaction ID field. + * This field can be used for detection of out-of-order application payloads if this + * is an issue. There is no real reason to use more than a byte for this support. But + * if this typedef is anything other than uint8_t be sure to attend to alignment and + * endian issues. + */ +typedef uint8_t appPTid_t; + +#ifdef ACCESS_POINT +/* Store-and-forward client info object */ +typedef struct +{ + addr_t clientAddr; + appPTid_t lastTID; +} sfClientInfo_t; + +typedef struct +{ + uint8_t curNumSFClients; + sfClientInfo_t sfClients[NUM_STORE_AND_FWD_CLIENTS]; +} sfInfo_t; +#endif + +/**************************************************************************************** +* SOME USEFUL MACROS +****************************************************************************************/ + +/* Delay loop support. Requires mrfi.h */ +#define NWK_DELAY(spin) MRFI_DelayMs(spin) +#define NWK_REPLY_DELAY() MRFI_ReplyDelay(); + +/* Network applications may need to remember radio state because the user + * application may choose to turn Rx off. These macros help get and restore + * the radio Rx state. The macros should be in the same code block at the same level. + * The argument 's' is the 'current' radio state and should be set in the code block + * with a call to MRFI_GetRadioState() _before_ using the macros. + * + * Used extensively by NWK but user applications may use them as well. But it is + * much more liekly that an application will know the radio state since it likely + * will have set it with IOCTL calls. Requires mrfi.h. + */ +#define NWK_CHECK_FOR_SETRX(s) if (MRFI_RADIO_STATE_RX != s) \ + { \ + if (MRFI_RADIO_STATE_OFF == s) \ + { \ + MRFI_WakeUp(); \ + } \ + MRFI_RxOn(); \ + } + +#define NWK_CHECK_FOR_RESTORE_STATE(s) if (MRFI_RADIO_STATE_RX != s) \ + { \ + if (MRFI_RADIO_STATE_OFF == s) \ + { \ + MRFI_Sleep(); \ + } \ + else \ + { \ + MRFI_RxIdle(); \ + } \ + } +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.c new file mode 100755 index 0000000..ed18428 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.c @@ -0,0 +1,649 @@ +/************************************************************************************************** +* Filename: nwk_freq.c +* Revised: $Date: 2008-12-10 13:50:46 -0800 (Wed, 10 Dec 2008) $ +* Revision: $Revision: 18594 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Freq network application. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk.h" +#include "nwk_frame.h" +#include "nwk_freq.h" +#include "nwk_globals.h" +#include "nwk_api.h" +#include "nwk_security.h" + +#if defined(FREQUENCY_AGILITY) + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static freqEntry_t sCurLogicalChan; +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +static fhStatus_t handle_freq_cmd(mrfiPacket_t *); +static fhStatus_t send_ping_reply(mrfiPacket_t *); + +# ifndef ACCESS_POINT +static uint8_t change_channel_cmd_is_valid(mrfiPacket_t *); + +# endif +# ifdef RANGE_EXTENDER +/* REs must replay frame before changing channels */ +static void replayFirst(mrfiPacket_t *); + +# endif +# ifdef ACCESS_POINT +/* only the AP can broadcast this command */ +static void broadcast_channel_change(uint8_t); + +# else +/* APs do not process this frame */ +static void change_channel_cmd(mrfiPacket_t *); + +# endif + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_freqInit + * + * @brief Initialize NWK Frequency application. + * + * @return none. + */ + +void nwk_freqInit(void) +{ + + memset(&sCurLogicalChan, 0x0, sizeof(sCurLogicalChan)); + + /* pick a random value to start the transaction ID for this app. */ + sTid = MRFI_RandomByte(); + + return; +} + +/*************************************************************************** + * @fn nwk_setChannel + * + * @brief Set requested logical channel. Accessed by application + * through IOCTL interface + * + * input parameters + * @param chan - pointer to channel object of requested channel + * + * @return status of operation: + * SMPL_SUCCESS if channel set + * SMPL_BAD_PARAM if requested channel is out of range + */ + +smplStatus_t nwk_setChannel(freqEntry_t *chan) +{ + smplStatus_t rc = SMPL_BAD_PARAM; + + if (chan->logicalChan < NWK_FREQ_TBL_SIZE) + { + MRFI_SetLogicalChannel(chan->logicalChan); + sCurLogicalChan = *chan; + rc = SMPL_SUCCESS; + } + return rc; +} + +/****************************************************************************** + * @fn nwk_getChannel + * + * @brief Get current logical channel. Accessed by application through + * IOCTL interface + * + * input parameters + * @param chan - pointer to channel object of requested channel + * + * output parameters + * @param chan - populated channel object + * + * @return none. + */ + +void nwk_getChannel(freqEntry_t *chan) +{ + *chan = sCurLogicalChan; + + return; +} + +/****************************************************************************** + * @fn handle_freq_cmd + * + * @brief Handle a Frequency application command. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return Return FHS_RELEASE if caller should release frame otherwise + * return FHS_REPLAY. + */ + +static fhStatus_t handle_freq_cmd(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + + switch (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS)) + { + case FREQ_REQ_PING: + rc = send_ping_reply(frame); + break; + +# ifndef ACCESS_POINT + case FREQ_REQ_MOVE: +# ifdef RANGE_EXTENDER + replayFirst(frame); +# endif + + /* Make sure the change channel Freq command came from + * a valid source before obeying. + */ + if (change_channel_cmd_is_valid(frame)) + { + change_channel_cmd(frame); + } + break; +# endif + +# ifdef ACCESS_POINT + case FREQ_REQ_REQ_MOVE: + break; +# endif + default: + break; + } + + return rc; +} + +# ifndef ACCESS_POINT + +/****************************************************************************** + * @fn change_channel_cmd_is_valid + * + * @brief Check validity of a change channel command frame. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return Returns non-zero if command is valid, otherwise returns 0. + * Command is valid if either: + * - frame is directed + * - frame is from an AP and we know about that AP + * + * It is possible that either we don't know about an AP or that + * we do but this frame comes from another AP in range. + */ + +static uint8_t change_channel_cmd_is_valid(mrfiPacket_t *frame) +{ + uint8_t rc = 0; + addr_t const *apAddr; + + /* If this was a directed frame obey the command. */ + if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + rc = 1; + } + else + { + /* Do we know about an AP? If not assume frame bogus. */ + apAddr = nwk_getAPAddress(); + if (apAddr) + { + /* Yes, we know about an AP. Is that who sent it? */ + if (!memcmp(apAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + /* OK. We obey. */ + rc = 1; + } + } + } + + return rc; +} + +# endif /* !ACCESS_POINT */ + +# ifdef RANGE_EXTENDER + +/****************************************************************************** + * @fn replayFirst + * + * @brief Range Extenders must replay the change-channel boradcast + * frame before actually changing its own channel. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return void + */ + +/* This routine takes care of some awkwardness. From the dispatch thread all + * we have is a pointer to the mrfiPacket_t element in the frame buffer into + * which the frame was retrieved. But to call the replay routine we need the + * entire frame information structure frameInfo_t. This routine regenerates + * the frame information structure pointer and then calls the replay routine. + * + * This approach requires that the disptach thread guarantee that it will + * always pass a pointer to the mrfiPacket_t structure in the frame + * information structure and not a copy of the mrfipacket_t element. It is + * either the approach here or change all the NWK application dispatch routine + * argument types. This latter has the downside of interfering with any + * user-implemented NWK applications. It also needlessly complicates the argument + * handling: except for this instance all any routine needs is the mrfiPacket_t + * pointer. + */ + +static void replayFirst(mrfiPacket_t *frame) +{ + frameInfo_t *fiptr; + uint16_t offset = (uint16_t)&(((frameInfo_t *)0)->mrfiPkt); + + fiptr = (frameInfo_t *)(((uint8_t *)frame) - ((uint8_t *)offset)); + + nwk_replayFrame(fiptr); + + return; +} + +# endif /* RANGE_EXTENDER */ + +# ifndef ACCESS_POINT + +/******************************************************************************** + * @fn change_channel_cmd + * + * @brief Change to channel specified in received frame. Polling devices + * might be awake when the broadcast occurs but we want the channel + * change recovery to occur in a disciplined manner using the + * polling code. Also, with certain Test sceanrios in which a + * sleeping device is emulated we want to emulate 'missing' the + * broadcast change-channel command. + * + * input parameters + * @param frame - pointer to frame containing target logical channel. + * + * @return none. + */ + +static void change_channel_cmd(mrfiPacket_t *frame) +{ +# if !defined(RX_POLLS) + freqEntry_t chan; + + chan.logicalChan = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + F_CHAN_OS); + + nwk_setChannel(&chan); +# endif + return; +} + +# endif /* !ACCESS_POINT */ + +/****************************************************************************** + * @fn send_ping_reply + * + * @brief Send Frequency application ping reply. + * + * input parameters + * @param frame - pointer to frame from pinger. + * + * @return FHS_RELEASE unless this isn't an Access Point. In this case for + * flow to et this far it is a Range Extender, so replay the frame + * by returning FHW_REPLAY + */ + +static fhStatus_t send_ping_reply(mrfiPacket_t *frame) +{ +# ifdef ACCESS_POINT + uint8_t msg[FREQ_REQ_PING_FRAME_SIZE]; + frameInfo_t *pOutFrame; + + /* original request with reply bit on */ + msg[FB_APP_INFO_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS) | NWK_APP_REPLY_BIT; + msg[FB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + FB_TID_OS); + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_FREQ, msg, sizeof(msg), MAX_HOPS_FROM_AP)) + { + /* destination address is the source address of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + /* must use transaction ID of source frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_TRACTID_OS, + (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS))); +# ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +# endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + + return FHS_RELEASE; +# else + return FHS_REPLAY; +# endif /* ACCESS_POINT */ +} + +/**************************************************************************************** + * @fn nwk_processFreq + * + * @brief Process a Frequency application frame. + * + * input parameters + * @param frame - pointer to frame + * + * @return Disposition for frame: either release (FHS_RELEASE) or replay (FHS_REPLAY). + */ + +fhStatus_t nwk_processFreq(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + uint8_t replyType; + + /* Make sure this is a reply and see if we sent this. Validate the + * packet for reception by client app. + */ + if (SMPL_MY_REPLY == (replyType = nwk_isValidReply(frame, sTid, FB_APP_INFO_OS, FB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +# if !defined(END_DEVICE) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +# endif /* !END_DEVICE */ + else if (SMPL_NOT_REPLY == replyType) + { + rc = handle_freq_cmd(frame); + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_scanForChannels + * + * @brief Scan for channels by sending a ping frame on each channel in the + * channel table and listen for a reply. + * + * input parameters + * @param channels - pointer to area to receive list of channels from which + * ping replies were received. + * + * output parameters + * @param channels - populated list of channels. + * + * @return statuis of operation.. + */ + +uint8_t nwk_scanForChannels(freqEntry_t *channels) +{ + uint8_t msg[FREQ_REQ_PING_FRAME_SIZE], i, num = 0, notBcast = 1; + addr_t *apAddr, retAddr; + uint8_t radioState = MRFI_GetRadioState(); + freqEntry_t chan; + freqEntry_t curChan; + + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + nwk_getChannel(&curChan); + + /* send to AP. If we don't know AP address, broadcast. */ + apAddr = (addr_t *)nwk_getAPAddress(); + if (!apAddr) + { + apAddr = (addr_t *)nwk_getBCastAddress(); + notBcast = 0; + } + + for (i = 0; i < NWK_FREQ_TBL_SIZE; ++i) + { + chan.logicalChan = i; + + nwk_setChannel(&chan); + + ioctl_info.send.addr = apAddr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_FREQ; + + msg[FB_APP_INFO_OS] = FREQ_REQ_PING; + msg[FB_TID_OS] = sTid; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + ioctl_info.recv.port = SMPL_PORT_FREQ; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = &retAddr; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + /* Once we know the Access Point we're related to we only accept + * ping replies from that one. + */ + if (!notBcast || (notBcast && !memcmp(&retAddr, apAddr, NET_ADDR_SIZE))) + { + channels[num++].logicalChan = i; + } + } + + sTid++; + if (num && notBcast) + { + /* we're done...only one possible channel if we know the AP address. */ + break; + } + /* TODO: process encryption stuff */ + } + + /* reset original channel */ + nwk_setChannel(&curChan); + + return num; +} + +/****************************************************************************** + * @fn nwk_freqControl + * + * @brief Handle application requests received through IOCTL interface. + * + * input parameters + * @param action - requested action + * @param val - pointer to parameters required/returned for action + * + * output parameters + * @param val - populated values if action was a retrieval action. + * + * @return status of operation. + */ + +smplStatus_t nwk_freqControl(ioctlAction_t action, void *val) +{ + smplStatus_t rc; + + switch (action) + { + case IOCTL_ACT_SET: +# ifdef ACCESS_POINT + broadcast_channel_change(((freqEntry_t *)val)->logicalChan); +# endif /* ACCESS_POINT */ + rc = nwk_setChannel((freqEntry_t *)val); + break; + + case IOCTL_ACT_GET: + nwk_getChannel((freqEntry_t *)val); + rc = SMPL_SUCCESS; + break; + + case IOCTL_ACT_SCAN: + { + ioctlScanChan_t *sc = (ioctlScanChan_t *)val; + + sc->numChan = nwk_scanForChannels(sc->freq); + rc = SMPL_SUCCESS; + } + break; + + default: + rc = SMPL_BAD_PARAM; + break; + } + + return rc; +} + +/****************************************************************************** + * @fn broadcast_channel_change + * + * @brief For Access Point only: broadcast a channel change frame. + * + * input parameters + * @param idx - index into channel table of new (logical) channel + * + * @return none. + */ +# ifdef ACCESS_POINT +# define CC_REDUNDANCY 1 /* Change-channel redundancy count */ +static void broadcast_channel_change(uint8_t idx) +{ + ioctlRawSend_t send; + uint8_t msg[FREQ_REQ_MOVE_FRAME_SIZE]; + uint8_t repeat = CC_REDUNDANCY; + + if (idx >= NWK_FREQ_TBL_SIZE) + { + return; + } + + msg[FB_APP_INFO_OS] = FREQ_REQ_MOVE; + msg[F_CHAN_OS] = idx; + + send.addr = (addr_t *)nwk_getBCastAddress(); + send.msg = msg; + send.len = sizeof(msg); + send.port = SMPL_PORT_FREQ; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); + + /* Redundancy addresses the fact that an RE (or any always-listening + * device) might miss the command + */ + while (repeat--) + { + NWK_DELAY(250); + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); + } +} + +# endif /* ACCESS_POINT */ + +#else /* FREQUENCY_AGILITY */ + +/********************************************************************************** + * @fn nwk_freqInit + * + * @brief Initialize NWK Frequency application. Stub when Frequency Agility + * not supported. + * + * @return none. + */ + +void nwk_freqInit(void) +{ + return; +} + +/**************************************************************************************** + * @fn nwk_processFreq + * + * @brief Process a Frequency application frame. Stub when Frequency Agility + * not supported. + * + * input parameters + * @param frame - pointer to frame + * + * @return Disposition for frame: either release (FHS_RELEASE) or replay (FHS_REPLAY). + */ + +fhStatus_t nwk_processFreq(mrfiPacket_t *frame) +{ + return FHS_RELEASE; +} + +#endif /* FREQUENCY_AGILITY */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.h new file mode 100755 index 0000000..05c9b41 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.h @@ -0,0 +1,74 @@ +/************************************************************************************************** +* Filename: nwk_freq.h +* Revised: $Date: 2008-05-06 16:48:33 -0700 (Tue, 06 May 2008) $ +* Revision: $Revision: 17025 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI Freq network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_FREQ_H +#define NWK_FREQ_H + +/* application payload offsets + * both */ +#define FB_APP_INFO_OS 0 +#define FB_TID_OS 1 + +/* Logical channel number for MOVE request. Frame brodcast so no TID + * is used. Channel number can occupy the TID location. Same offset + * used for channel change request. No reply to that frame. + */ +#define F_CHAN_OS 1 + +/* MGMT frame application requests */ +#define FREQ_REQ_MOVE 0x01 +#define FREQ_REQ_PING 0x02 +#define FREQ_REQ_REQ_MOVE 0x03 + +/* change the following as protocol developed */ +#define MAX_FREQ_APP_FRAME 2 + +/* set the out frame sizes */ +#define FREQ_REQ_MOVE_FRAME_SIZE 2 +#define FREQ_REQ_PING_FRAME_SIZE 2 + +/* prototypes */ +void nwk_freqInit(void); +fhStatus_t nwk_processFreq(mrfiPacket_t *); + +#if defined(FREQUENCY_AGILITY) +smplStatus_t nwk_setChannel(freqEntry_t *); +void nwk_getChannel(freqEntry_t *); +uint8_t nwk_scanForChannels(freqEntry_t *); + +smplStatus_t nwk_freqControl(ioctlAction_t, void *); +#endif + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.c new file mode 100755 index 0000000..9d88be2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.c @@ -0,0 +1,356 @@ + +/************************************************************************************************** +* Filename: nwk_ioctl.c +* Revised: $Date: 2009-01-13 11:31:14 -0800 (Tue, 13 Jan 2009) $ +* Revision: $Revision: 18744 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI IOCTL implmentation. This interface +* gives applications access to the "driver" network level functions +* when necessary. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_ioctl.h" +#include "nwk_globals.h" +#include "nwk_security.h" +#ifdef ACCESS_POINT +# include "nwk_join.h" +#endif + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + + +/****************************************************************************** + * @fn nwk_rawSend + * + * @brief Builds an outut frame based on information provided by the + * caller. This function allows a raw transmission to the target + * if the network address is known. this function is used a lot + * to support NWK applications. + * + * input parameters + * @param info - pointer to strcuture containing info on how to build + * the outgoing frame. + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_NOMEM - no room in output frame queue + * SMPL_TX_CCA_FAIL - CCA failure + */ + +smplStatus_t nwk_rawSend(ioctlRawSend_t *info) +{ + frameInfo_t *pOutFrame; + uint8_t hops; + + /* If we know frame is going to or from the AP then we can reduce the hop + * count. + */ + switch (info->port) + { + case SMPL_PORT_JOIN: + case SMPL_PORT_FREQ: + case SMPL_PORT_MGMT: + hops = MAX_HOPS_FROM_AP; + break; + + default: + hops = MAX_HOPS; + break; + } + + if (pOutFrame = nwk_buildFrame(info->port, info->msg, info->len, hops)) + { + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), info->addr, NET_ADDR_SIZE); +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, info->len, 0); +#endif /* SMPL_SECURE */ + return nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_CCA); + } + return SMPL_NOMEM; +} + +/****************************************************************************** + * @fn nwk_rawReceive + * + * @brief Retriievs specified from from the input frame queue. Additional + * information such as source address and hop count may also be + * retrieved + * + * input parameters + * @param info - pointer to structure containing info on what to retrieve + * + * output parameters - actually populated by nwk_retrieveFrame() + * info->msg - application payload copied here + * info->len - length of received application payload + * info->addr - if non-NULL points to memory to be populated with + * source address of retrieved frame. + * info->hopCount - if non-NULL points to memory to be populated with + * hop count of retrieved frame. + * + * @return Status of operation. + */ + +smplStatus_t nwk_rawReceive(ioctlRawReceive_t *info) +{ + rcvContext_t rcv; + + rcv.type = RCV_NWK_PORT; + rcv.t.port = info->port; + + return nwk_retrieveFrame(&rcv, info->msg, &info->len, info->addr, &info->hopCount); +} + +/****************************************************************************** + * @fn nwk_radioControl + * + * @brief Handle radio control functions. + * + * input parameters + * @param action - radio operation to perform. currently suppoerted: + * sleep/unsleep + * output parameters + * + * @return Status of operation. + */ + +smplStatus_t nwk_radioControl(ioctlAction_t action, void *val) +{ + smplStatus_t rc = SMPL_SUCCESS; + + if (IOCTL_ACT_RADIO_SLEEP == action) + { + /* go to sleep mode. */ + MRFI_RxIdle(); + MRFI_Sleep(); + } + else if (IOCTL_ACT_RADIO_AWAKE == action) + { + MRFI_WakeUp(); + +#if !defined(END_DEVICE) + MRFI_RxOn(); +#endif + + } + else if (IOCTL_ACT_RADIO_SIGINFO == action) + { + ioctlRadioSiginfo_t *pSigInfo = (ioctlRadioSiginfo_t *)val; + connInfo_t *pCInfo = nwk_getConnInfo(pSigInfo->lid); + + if (!pCInfo) + { + return SMPL_BAD_PARAM; + } + memcpy(&pSigInfo->sigInfo, &pCInfo->sigInfo, sizeof(pCInfo->sigInfo)); + } + else if (IOCTL_ACT_RADIO_RSSI == action) + { + *((rssi_t *)val) = MRFI_Rssi(); + } + else if (IOCTL_ACT_RADIO_RXON == action) + { + MRFI_RxOn(); + } + else if (IOCTL_ACT_RADIO_RXIDLE == action) + { + MRFI_RxIdle(); + } +#ifdef EXTENDED_API + else if (IOCTL_ACT_RADIO_SETPWR == action) + { + uint8_t idx; + + switch (*(ioctlLevel_t *)val) + { + case IOCTL_LEVEL_2: + idx = 2; + break; + + case IOCTL_LEVEL_1: + idx = 1; + break; + + case IOCTL_LEVEL_0: + idx = 0; + break; + + default: + return SMPL_BAD_PARAM; + } + MRFI_SetRFPwr(idx); + return SMPL_SUCCESS; + } +#endif /* EXTENDED_API */ + else + { + rc = SMPL_BAD_PARAM; + } + return rc; +} + +/****************************************************************************** + * @fn nwk_joinContext + * + * @brief For Access Points we need a way to support changing the Join + * context. This will allow arbitration bewteen potentially nearby + * Access Points when a new device is joining. + * + * input parameters + * @param action - Join context is either on or off. + * + * output parameters + * + * @return Status of operation. Currently always succeeds. + */ +#ifdef ACCESS_POINT +smplStatus_t nwk_joinContext(ioctlAction_t action) +{ + nwk_setJoinContext((IOCTL_ACT_ON == action) ? JOIN_CONTEXT_ON : JOIN_CONTEXT_OFF); + + return SMPL_SUCCESS; +} + +#endif + +/****************************************************************************** + * @fn nwk_deviceAddress + * + * @brief Set or Get this device address. The Set must be done before + * SMPL_Init() for it to take effect. The Get is always legal but + * the value could be invalid if it is called before a valid set + * call is made. + * + * input parameters + * @param action - Gte or Set + * @param addr - pointer to address object containing value on Set + * + * output parameters + * @param addr - pointer to address object to receive value on Get. + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Action request illegal or a Set request + * was not respected. + */ + +smplStatus_t nwk_deviceAddress(ioctlAction_t action, addr_t *addr) +{ + smplStatus_t rc = SMPL_BAD_PARAM; + + if (IOCTL_ACT_GET == action) + { + memcpy(addr, nwk_getMyAddress(), sizeof(addr_t)); + rc = SMPL_SUCCESS; + } + else if (IOCTL_ACT_SET == action) + { + if (nwk_setMyAddress(addr)) + { + rc = SMPL_SUCCESS; + } + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_connectionControl + * + * @brief Access to connection table. Currently supports only deleting + * a connection from the table. + * + * input parameters + * @param action - Connection control action (only delete is curently valid). + * @param val - pointer to Link ID of connection on which to operate. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Action is not delete + * Link ID is the UUD Link ID + * No connection table info for Link ID + */ + +smplStatus_t nwk_connectionControl(ioctlAction_t action, void *val) +{ + connInfo_t *pCInfo; + linkID_t lid = *((linkID_t *)val); + + if (IOCTL_ACT_DELETE != action) + { + return SMPL_BAD_PARAM; + } + + if ((SMPL_LINKID_USER_UUD == lid) || + (!(pCInfo = nwk_getConnInfo(lid)))) + { + return SMPL_BAD_PARAM; + } + + nwk_freeConnection(pCInfo); + + return SMPL_SUCCESS; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.h new file mode 100755 index 0000000..3b583a9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.h @@ -0,0 +1,54 @@ +/************************************************************************************************** +* Filename: nwk_ioctl.h +* Revised: $Date: 2008-04-29 15:47:05 -0700 (Tue, 29 Apr 2008) $ +* Revision: $Revision: 16972 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI IOCTL implmentation. This interface +* gives applications access to the "driver" network level functions +* when necessary. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + + +#ifndef NWK_IOCTL_H +#define NWK_IOCTL_H + +/* prototypes */ +smplStatus_t nwk_rawSend(ioctlRawSend_t *); +smplStatus_t nwk_rawReceive(ioctlRawReceive_t *); + +smplStatus_t nwk_radioControl(ioctlAction_t, void *); +smplStatus_t nwk_deviceAddress(ioctlAction_t, addr_t *); +smplStatus_t nwk_connectionControl(ioctlAction_t, void *); +#ifdef ACCESS_POINT +smplStatus_t nwk_joinContext(ioctlAction_t); +#endif + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_join.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_join.c new file mode 100755 index 0000000..039bddd --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_join.c @@ -0,0 +1,599 @@ +/************************************************************************************************** +* Filename: nwk_join.c +* Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ +* Revision: $Revision: 18697 $ +* +* Description: This file supports the SimpliciTI Join network application. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_link.h" +#include "nwk_join.h" +#include "nwk_globals.h" +#include "nwk_freq.h" +#include "nwk_security.h" +#include "nwk_mgmt.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +static uint32_t sJoinToken = 0; +static uint8_t (*spCallback)(linkID_t) = NULL; +static volatile uint8_t sTid = 0; + +#ifdef ACCESS_POINT +static sfInfo_t *spSandFContext = NULL; +static uint8_t sJoinOK = 0; +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +#ifdef ACCESS_POINT +static void smpl_send_join_reply(mrfiPacket_t *frame); +static uint32_t generateLinkToken(void); +static void handleJoinRequest(mrfiPacket_t *); + +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_joinInit + * + * @brief Initialize Join application. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_joinInit(uint8_t (*pf)(linkID_t)) +{ + if (!sJoinToken) + { + sJoinToken = DEFAULT_JOIN_TOKEN; + } + + spCallback = pf; + (void) spCallback; /* keep compiler happy if we don't use this */ + + sTid = MRFI_RandomByte(); + +#ifdef ACCESS_POINT + /* set link token to something other than deafult if desired */ + nwk_setLinkToken(generateLinkToken()); +# if defined(STARTUP_JOINCONTEXT_ON) + sJoinOK = 1; +# elif defined(STARTUP_JOINCONTEXT_OFF) + sJoinOK = 0; +# else +# error ERROR: Must define either STARTUP_JOINCONTEXT_ON or STARTUP_JOINCONTEXT_OFF +# endif + spSandFContext = nwk_getSFInfoPtr(); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_setJoinToken + * + * @brief Sets the join token. + * + * input parameters + * @param token - join token to be used on this network. + * + * output parameters + * no room in output queue. + * + * @return void + */ + +void nwk_setJoinToken(uint32_t token) +{ + /* only set if the supplied token is non-zero. */ + if (token) + { + sJoinToken = token; + } + + return; +} + +/****************************************************************************** + * @fn nwk_getJoinToken + * + * @brief Gets the current join token. + * + * input parameters + * + * output parameters + * @param pToken - pointer to the returned value. + * + * @return Current link token + */ + +void nwk_getJoinToken(uint32_t *pToken) +{ + /* only set if the supplied token is non-zero. */ + if (pToken) + { + *pToken = sJoinToken; + } + + return; +} + +/****************************************************************************** + * @fn generateLinkToken + * + * @brief Generate the link token to be used for the network controlled + * by this Access Point. + * + * input parameters + * + * output parameters + * + * @return void + */ +#ifdef ACCESS_POINT +static uint32_t generateLinkToken(void) +{ + return 0xDEADBEEF; +} + +/****************************************************************************** + * @fn smpl_send_join_reply + * + * @brief Send the Join reply. Include the Link token. If the device is + * a polling sleeper put it into the list of store-and-forward + * clients. + * + * input parameters + * @param frame - join frame for which a reply is needed...maybe + * + * output parameters + * + * @return void + */ + +static void smpl_send_join_reply(mrfiPacket_t *frame) +{ + frameInfo_t *pOutFrame; + uint8_t msg[JOIN_REPLY_FRAME_SIZE]; + + /* Is this a legacy frame? If so continue. Otherwise check verion.*/ + if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > JOIN_LEGACY_MSG_LENGTH) + { + /* see if protocol version is correct... */ + if (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + J_PROTOCOL_VERSION_OS) != + nwk_getProtocolVersion()) + { + /* Accommodation of protocol version differences can be noted or accomplished here. + * Otherwise, no match and the board goes back + */ + return; + } + } + + + /* see if join token is correct */ + { + uint32_t jt; + + nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD( + frame) + F_APP_PAYLOAD_OS + J_JOIN_TOKEN_OS, &jt, sizeof(jt)); + if (jt != sJoinToken) + { + return; + } + } + + /* send reply with tid, the link token, and the encryption context */ + { + uint32_t linkToken; + + nwk_getLinkToken(&linkToken); + nwk_putNumObjectIntoMsg((void *)&linkToken, msg + JR_LINK_TOKEN_OS, sizeof(linkToken)); + } + msg[JR_CRYPTKEY_SIZE_OS] = SEC_CRYPT_KEY_SIZE; + msg[JB_REQ_OS] = JOIN_REQ_JOIN | NWK_APP_REPLY_BIT; + /* sender's tid... */ + msg[JB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + JB_TID_OS); + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_JOIN, msg, sizeof(msg), MAX_HOPS_FROM_AP)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + +# ifdef AP_IS_DATA_HUB + /* if source device supports ED objects save source address to detect duplicate joins */ + if (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + J_NUMCONN_OS)) + { + if (nwk_saveJoinedDevice(frame) && spCallback) + { + spCallback(0); + } + } +# endif + } + else + { + /* oops -- no room left for Tx frame. Don't send reply. */ + return; + } + + /* If this device polls we need to provide store-and-forward support */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_RX_TYPE) == F_RX_TYPE_POLLS) + { + uint8_t loc; + + /* Check duplicate status */ + if (!nwk_isSandFClient(MRFI_P_SRC_ADDR(frame), &loc)) + { + uint8_t *pNumc = &spSandFContext->curNumSFClients; + sfClientInfo_t *pClient = &spSandFContext->sfClients[*pNumc]; + + /* It's not a duplicate. Save it if there's room */ + if (*pNumc < NUM_STORE_AND_FWD_CLIENTS) + { + memcpy(pClient->clientAddr.addr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + *pNumc = *pNumc + 1; + } + else + { + /* No room left. Just return and don't send reply. */ + return; + } + } + else + { + /* We get here if it's a duplicate. We drop through and send reply. + * Reset the S&F marker in the Management application -- we should + * assume that the Client reset so the TID will be random. If this is + * simply a duplicate frame it causes no harm. + */ + nwk_resetSFMarker(loc); + } + } + +# ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +# endif /* SMPL_SECURE */ + + /* It's not S&F or it is but we're OK to send reply. */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +/****************************************************************************** + * @fn nwk_join + * + * @brief Stub Join function for Access Points. + * + * input parameters + * + * output parameters + * + * @return Always returns SMPL_SUCCESS. + */ + +smplStatus_t nwk_join(void) +{ + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_isSandFClient + * + * @brief Helper function to see if the destination of a frame we have is + * one of AP's store-and-forward clients. + * + * input parameters + * @param fPtr - pointer to address in frame in question + * + * output parameters + * @param entLoc - pointer to receive entry location in array of clients. + * + * @return Returns client info structure pointer if the destination is a + * store-and-forward client, else 0. + */ + +sfClientInfo_t *nwk_isSandFClient(uint8_t *pAddr, uint8_t *entLoc) +{ + uint8_t i; + sfClientInfo_t *pSFClient = spSandFContext->sfClients; + + for (i = 0; i < spSandFContext->curNumSFClients; ++i, ++pSFClient) + { + if (!memcmp(&pSFClient->clientAddr.addr, pAddr, NET_ADDR_SIZE)) + { + *entLoc = i; + return pSFClient; + } + } + + return 0; +} + +/****************************************************************************** + * @fn nwk_setJoinContext + * + * @brief Helper function to set Join context for Access Point. This will + * allow arbitration bewteen potentially nearby Access Points when + * a new device is joining. + * + * input parameters + * @param which - Join context is either off or on + * + * output parameters + * + * @return void + */ + +void nwk_setJoinContext(uint8_t which) +{ + sJoinOK = (JOIN_CONTEXT_ON == which) ? 1 : 0; + + return; +} + +/****************************************************************************** + * @fn handleJoinRequest + * + * @brief Dispatches handler for specfic join request + * + * input parameters + * + * @param frame - Join frame received + * + * output parameters + * + * @return void + */ + +static void handleJoinRequest(mrfiPacket_t *frame) +{ + if (JOIN_LEGACY_MSG_LENGTH == (MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS)) + { + /* Legacy frame. Spoof a join request */ + *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS) = JOIN_REQ_JOIN; + } + + switch (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS)) + { + case JOIN_REQ_JOIN: + smpl_send_join_reply(frame); + break; + + default: + break; + } + + return; +} + +#else /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_join + * + * @brief Join functioanlity for non-AP devices. Send the Join token + * and wait for the reply. + * + * input parameters + * + * output parameters + * + * @return Status of operation. + */ + +smplStatus_t nwk_join(void) +{ + uint8_t msg[JOIN_FRAME_SIZE]; + uint32_t linkToken; + addr_t apAddr; + uint8_t radioState = MRFI_GetRadioState(); + smplStatus_t rc = SMPL_NO_JOIN; + + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + +# if defined(FREQUENCY_AGILITY) + uint8_t i, numChan; + freqEntry_t channels[NWK_FREQ_TBL_SIZE]; + + if (!(numChan = nwk_scanForChannels(channels))) + { + return SMPL_NO_CHANNEL; + } + + for (i = 0; i < numChan; ++i) + { + nwk_setChannel(&channels[i]); +# else + { +# endif + + ioctl_info.send.addr = (addr_t *)nwk_getBCastAddress(); + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_JOIN; + + /* Put join token in */ + nwk_putNumObjectIntoMsg((void *)&sJoinToken, msg + J_JOIN_TOKEN_OS, sizeof(sJoinToken)); + /* set app info byte */ + msg[JB_REQ_OS] = JOIN_REQ_JOIN; + msg[JB_TID_OS] = sTid; + + /* Set number of connections supported. Used only by AP if it is + * a data hub. + */ + msg[J_NUMCONN_OS] = NUM_CONNECTIONS; + /* protocol version number */ + msg[J_PROTOCOL_VERSION_OS] = nwk_getProtocolVersion(); + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + ioctl_info.recv.port = SMPL_PORT_JOIN; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = &apAddr; /* save AP address from reply */ + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + uint8_t firstByte = msg[JB_REQ_OS] & (~NWK_APP_REPLY_BIT); + + /* Sanity check for correct reply frame. Older version + * has the length instead of the request as the first byte. + */ + if ((firstByte == JOIN_REQ_JOIN) || + (firstByte == JOIN_REPLY_LEGACY_MSG_LENGTH) + ) + { + /* join reply returns link token */ + memcpy(&linkToken, msg + JR_LINK_TOKEN_OS, sizeof(linkToken)); + + nwk_setLinkToken(linkToken); + /* save AP address */ + nwk_setAPAddress(&apAddr); + sTid++; /* guard against duplicates */ + rc = SMPL_SUCCESS; +# if defined(FREQUENCY_AGILITY) + break; +# endif + } + } + /* TODO: process encryption stuff */ + } + + return rc; + +} + +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_processJoin + * + * @brief Processes a Join frame. If this is a reply let it go to the + * application. Otherwise generate and send the reply. + * + * input parameters + * @param frame - Pointer to Join frame + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ + +fhStatus_t nwk_processJoin(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + uint8_t replyType; + + /* Make sure this is a reply and see if we sent this. Validate the + * packet for reception by client app. + */ + if (SMPL_MY_REPLY == (replyType = nwk_isValidReply(frame, sTid, JB_REQ_OS, JB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if defined(ACCESS_POINT) + else if (SMPL_A_REPLY == replyType) + { + /* No match. If I'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } + else + { + /* Send reply if we're an Access Point otherwise ignore the frame. */ + if ((SMPL_NOT_REPLY == replyType) && sJoinOK) + { + handleJoinRequest(frame); + } + } +#elif defined(RANGE_EXTENDER) + else + { + /* Either a reply that has to be replayed or a request that + * also must be replayed. + */ + rc = FHS_REPLAY; + } +#endif /* not END_DEVICE */ + + (void) replyType; /* keep compiler happy */ + + return rc; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_join.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_join.h new file mode 100755 index 0000000..63ff2c4 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_join.h @@ -0,0 +1,94 @@ +/************************************************************************************************** +* Filename: nwk_join.h +* Revised: $Date: 2009-01-06 12:26:02 -0800 (Tue, 06 Jan 2009) $ +* Revision: $Revision: 18693 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI Join network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_JOIN_H +#define NWK_JOIN_H + +#define JOIN_CONTEXT_ON (0x01) +#define JOIN_CONTEXT_OFF (0x02) + +/* Macros needed for protocol backward compatibility */ +#define JOIN_LEGACY_MSG_LENGTH 7 +#define JOIN_REPLY_LEGACY_MSG_LENGTH 6 + +/* place holder... */ +#define SEC_CRYPT_KEY_SIZE 0 + +/* application payload offsets + * both */ +#define JB_REQ_OS 0 +#define JB_TID_OS 1 +/* join frame */ +#define J_JOIN_TOKEN_OS 2 +#define J_NUMCONN_OS 6 +#define J_PROTOCOL_VERSION_OS 7 +/* join reply frame */ +#define JR_LINK_TOKEN_OS 2 +#define JR_CRYPTKEY_SIZE_OS 6 +#define JR_CRYPTKEY_OS 7 + +/* change the following as protocol developed */ +#define MAX_JOIN_APP_FRAME (JR_CRYPTKEY_OS + SEC_CRYPT_KEY_SIZE) + +/* set out frame size */ +#define JOIN_FRAME_SIZE 8 +#define JOIN_REPLY_FRAME_SIZE MAX_JOIN_APP_FRAME + +/* join requests + * NOTE: If aditional command codes are required do _not_ use the + * value JOIN_REPLY_LEGACY_MSG_LENGTH. This numeral is used + * to guarantee that legacy Join frames (from before release + * 1.0.6) work correctly. Don't ask. + */ +#define JOIN_REQ_JOIN 1 + +/* prototypes */ +void nwk_joinInit(uint8_t (*)(linkID_t)); +smplStatus_t nwk_join(void); +fhStatus_t nwk_processJoin(mrfiPacket_t *); +void nwk_getJoinToken(uint32_t *); + +void nwk_setJoinContext(uint8_t); +void nwk_setJoinToken(uint32_t); +void nwk_getJoinToken(uint32_t *); + +#ifdef ACCESS_POINT +sfClientInfo_t *nwk_isSandFClient(uint8_t *, uint8_t *); + +#endif + +#endif + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_link.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_link.c new file mode 100755 index 0000000..8188970 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_link.c @@ -0,0 +1,886 @@ +/************************************************************************************************** +* Filename: nwk_link.c +* Revised: $Date: 2008-12-23 13:54:27 -0800 (Tue, 23 Dec 2008) $ +* Revision: $Revision: 18652 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Link network application. +* +* Copyright 2007-2008 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_link.h" +#include "nwk_globals.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static uint32_t sLinkToken = 0; +static volatile uint8_t sListenActive = 0; +#if NUM_CONNECTIONS > 0 +static volatile linkID_t sServiceLinkID[NUM_CONNECTIONS]; +#endif +static volatile uint8_t sNumLinkers = 0; +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +#define SENT_REPLY 1 +#define SENT_NO_REPLY 2 +static uint8_t smpl_send_link_reply(mrfiPacket_t *); +static fhStatus_t handleLinkRequest(mrfiPacket_t *); + +#if defined(EXTENDED_API) +static void smpl_send_unlink_reply(mrfiPacket_t *); + +#endif + + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_linkInit + * + * @brief Initialize link app. Set link token to the default. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_linkInit(void) +{ + if (!sLinkToken) + { + /* if the link token has not been set externally by the time we get here + * (such as by the ioctl token-setting interface) assign the default + */ + sLinkToken = DEFAULT_LINK_TOKEN; + } + + /* set a non-zero TID. */ + while (!(sTid = MRFI_RandomByte())) ; + +#if NUM_CONNECTIONS > 0 + memset((void *)&sServiceLinkID, 0x0, sizeof(sServiceLinkID)); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_setLinkToken + * + * @brief Sets the link token received in a Join reply. + * + * input parameters + * @param token - Link token to be used on this network to link to any peer. + * + * output parameters + * + * @return void + */ + +void nwk_setLinkToken(uint32_t token) +{ + /* only set if the supplied token is non-zero. */ + if (token) + { + sLinkToken = token; + } + + return; +} + +/****************************************************************************** + * @fn nwk_getLinkToken + * + * @brief Gets the current link token. + * + * input parameters + * + * output parameters + * @param pToken - pointer to the returned value. + * + * @return Current link token + */ + +void nwk_getLinkToken(uint32_t *pToken) +{ + /* only set if the supplied token is non-zero. */ + if (pToken) + { + *pToken = sLinkToken; + } + + return; +} + +#if defined(EXTENDED_API) + +/****************************************************************************** + * @fn nwk_unlink + * + * @brief Called from the application level to tear down a link. + * + * input parameters + * + * output parameters + * @param lid - Link ID assigned for this link + * + * @return Status of the operation. + * SMPL_SUCCESS + * SMPL_BAD_PARAM No connection table entry for this Link ID; + * SMPL_LINKID_USER_UUD not valid since it is not + * connection-based. + * SMPL_TIMEOUT No reply from peer. + * SMPL_NO_PEER_UNLINK Peer did not have a Connection Table entry for me. + */ + +smplStatus_t nwk_unlink(linkID_t lid) +{ + uint8_t msg[UNLINK_FRAME_SIZE]; + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_SUCCESS; + addr_t addr; + + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + /* is there connection info? */ + if (!pCInfo || (lid == SMPL_LINKID_USER_UUD)) + { + return SMPL_BAD_PARAM; + } + + /* set request byte */ + msg[LB_REQ_OS] = LINK_REQ_UNLINK; + + /* set the transaction ID. this allows target to figure out duplicates */ + msg[LB_TID_OS] = sTid; + + /* remote port to be sent in message to help match connection */ + msg[UL_RMT_PORT_OS] = pCInfo->portRx; + + /* setup for ioctl raw I/O */ + memcpy(addr.addr, pCInfo->peerAddr, NET_ADDR_SIZE); + ioctl_info.send.addr = &addr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_LINK; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + { + uint8_t spin = NWK_RX_RETRY_COUNT; + uint8_t radioState = MRFI_GetRadioState(); + + ioctl_info.recv.port = SMPL_PORT_LINK; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = (addr_t *)0; + + do + { + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + if ((msg[LB_REQ_OS] & (~NWK_APP_REPLY_BIT)) == LINK_REQ_UNLINK) + { + rc = (smplStatus_t)msg[ULR_RESULT_OS]; + break; + } + } + if (!spin) + { + rc = SMPL_TIMEOUT; + break; + } + --spin; + } while (1); + + /* it's ok to unconditionally invalidate connection object */ + nwk_freeConnection(pCInfo); + } + return rc; +} + +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn nwk_link + * + * @brief Called from the application level to accomplish the link + * + * input parameters + * + * output parameters + * @param lid - pointer to Link ID (port) assigned for this link + * + * @return Status of the operation. + */ + +smplStatus_t nwk_link(linkID_t *lid) +{ + uint8_t msg[LINK_FRAME_SIZE]; + connInfo_t *pCInfo = nwk_getNextConnection(); + smplStatus_t rc; + + if (pCInfo) + { + addr_t addr; + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + if (!nwk_allocateLocalRxPort(LINK_SEND, pCInfo)) + { + nwk_freeConnection(pCInfo); + return SMPL_NOMEM; + } + + memcpy(addr.addr, nwk_getBCastAddress(), NET_ADDR_SIZE); + ioctl_info.send.addr = &addr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_LINK; + + /* Put link token in */ + nwk_putNumObjectIntoMsg((void *)&sLinkToken, msg + L_LINK_TOKEN_OS, sizeof(sLinkToken)); + + /* set port to which the remote device should send */ + msg[L_RMT_PORT_OS] = pCInfo->portRx; + + /* set the transaction ID. this allows target to figure out duplicates */ + msg[LB_TID_OS] = sTid; + + /* set my Rx type */ + msg[L_MY_RXTYPE_OS] = nwk_getMyRxType(); + + /* set request byte */ + msg[LB_REQ_OS] = LINK_REQ_LINK; + + /* protocol version number */ + msg[L_PROTOCOL_VERSION_OS] = nwk_getProtocolVersion(); + +#if defined(SMPL_SECURE) + pCInfo->connTxCTR = MRFI_RandomByte() | \ + ((uint32_t)(MRFI_RandomByte()) << 8) | \ + ((uint32_t)(MRFI_RandomByte()) << 16) | \ + ((uint32_t)(MRFI_RandomByte()) << 24); + + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[L_CTR_OS], 4); +#endif + + + if (SMPL_SUCCESS != (rc = SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send))) + { + return rc; + } + + { + uint8_t radioState = MRFI_GetRadioState(); + + ioctl_info.recv.port = SMPL_PORT_LINK; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = (addr_t *)pCInfo->peerAddr; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + uint8_t firstByte = msg[LB_REQ_OS] & (~NWK_APP_REPLY_BIT); + + /* Sanity check for correct reply frame. Older version + * has the length instead of the request as the first byte. + */ + if ((firstByte != LINK_REQ_LINK) && + (firstByte != LINK_REPLY_LEGACY_MSG_LENGTH) + ) + { + /* invalidate connection object */ + nwk_freeConnection(pCInfo); + return SMPL_NO_LINK; + + } + } + else + { + /* no successful receive */ + nwk_freeConnection(pCInfo); + return SMPL_TIMEOUT; + } + + pCInfo->connState = CONNSTATE_CONNECTED; + pCInfo->portTx = msg[LR_RMT_PORT_OS]; /* link reply returns remote port */ + *lid = pCInfo->thisLinkID; /* return our local port number */ + + /* Set hop count. If it's a polling device set the count to the + * distance to the AP. Otherwise, set it to the max less the remaining + * which will be the path taken for this frame. It will be no worse + * then tha max and probably will be better. + */ + if (F_RX_TYPE_POLLS == msg[LR_MY_RXTYPE_OS]) + { + pCInfo->hops2target = MAX_HOPS_FROM_AP; + } + else + { + /* Can't really use this trick because the device could move. If the + * devices are all static this may work unless the initial reception + * was marginal. + */ +#if defined(DEVICE_DOES_NOT_MOVE) + pCInfo->hops2target = MAX_HOPS - ioctl_info.recv.hopCount; +#else + pCInfo->hops2target = MAX_HOPS; +#endif + } + +#if defined(SMPL_SECURE) + nwk_getNumObjectFromMsg((void *)&msg[LR_CTR_OS], (void *)&pCInfo->connRxCTR, 4); +#endif + } + + /* guard against duplicates... */ + ++sTid; + if (!sTid) + { + sTid = 1; + } + return SMPL_SUCCESS; + } + + return SMPL_NOMEM; +} + +#if defined(EXTENDED_API) + +/****************************************************************************** + * @fn smpl_send_unlink_reply + * + * @brief Send the unlink reply to the device trying to unlink + * + * input parameters + * @param frame - frame received from linker + * + * output parameters + * + * @return void + */ + +static void smpl_send_unlink_reply(mrfiPacket_t *frame) +{ + connInfo_t *pCInfo; + frameInfo_t *pOutFrame; + uint8_t msg[UNLINK_REPLY_FRAME_SIZE]; + smplStatus_t rc = SMPL_NO_PEER_UNLINK; + + /* match the remote port and source address with a connection table entry */ + if (pCInfo = + nwk_findPeer((addr_t *)MRFI_P_SRC_ADDR(frame), + *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + UL_RMT_PORT_OS))) + { + /* Note we unconditionally free the connection resources */ + nwk_freeConnection(pCInfo); + rc = SMPL_SUCCESS; + } + + /* set reply bit */ + msg[LB_REQ_OS] = LINK_REQ_UNLINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + LB_TID_OS); + + /* result of freeing local connection */ + msg[ULR_RESULT_OS] = rc; + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +# if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +# endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } +} + +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn smpl_send_link_reply + * + * @brief Send the link reply to the device trying to link. This routine + * will handle duplicates. + * + * input parameters + * @param frame - frame received from linker + * + * output parameters + * + * @return Returns SENT_REPLY if reply sent, else SENT_NO_REPLY. + * The return value is used as this routine unwinds to know + * whether to replay the frame. An RE or AP can host an ED + * object in which case it might send a reply (possibly from + * a duplicate frame). If we do reply we do not want to replay. + */ + +static uint8_t smpl_send_link_reply(mrfiPacket_t *frame) +{ +#if NUM_CONNECTIONS > 0 + frameInfo_t *pOutFrame; + connInfo_t *pCInfo; + uint8_t remotePort; + uint8_t msg[LINK_REPLY_FRAME_SIZE]; + + /* Is this a legacy frame? If so continue. Otherwise check version.*/ + if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > LINK_LEGACY_MSG_LENGTH) + { + /* see if protocol version is correct... */ + if (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_PROTOCOL_VERSION_OS) != + nwk_getProtocolVersion()) + { + /* Accommodation of protocol version differences can be noted or accomplished here. + * This field was also checked in the join transaction but it is checked again here + * because that check may not have occurred if thre is no AP in this topology. + * Otherwise, no match and the board goes back + */ + return SENT_NO_REPLY; + } + } + + /* see if token is correct */ + { + uint32_t lt; + + nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD( + frame) + F_APP_PAYLOAD_OS + L_LINK_TOKEN_OS, <, sizeof(lt)); + if (lt != sLinkToken) + { + return SENT_NO_REPLY; + } + } + + /* if we get here the token matched. */ + + /* is this a duplicate request? */ + remotePort = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_RMT_PORT_OS); + if (pCInfo = nwk_isLinkDuplicate(MRFI_P_SRC_ADDR(frame), remotePort)) + { + /* resend reply */ + msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + LB_TID_OS); + + /* Send reply with the local port number so the remote device knows where to + * send packets. + */ + msg[LR_RMT_PORT_OS] = pCInfo->portRx; + + /* put my Rx type in there. used to know how to set hops when sending back. */ + msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); +# if defined(SMPL_SECURE) + /* Set the Tx counter value for peer's Rx counter object */ + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); + /* We also need to save the newly generated Rx counter value. */ + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_CTR_OS), + (void *)&pCInfo->connRxCTR, 4); +# endif + if (pOutFrame = + nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS - + (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT)))) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +# if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +# endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + return SENT_REPLY; + } + + if (!sListenActive) + { + /* We've checked for duplicate and resent reply. In that case we weren't listening + * so just go back`. + */ + return SENT_NO_REPLY; + } + + /* room to link? */ +# if defined(AP_IS_DATA_HUB) + pCInfo = nwk_findAlreadyJoined(frame); + + if (!pCInfo) +# endif + { + pCInfo = nwk_getNextConnection(); + } + + if (pCInfo) + { + /* yes there's room and it's not a dup. address. */ + memcpy(&pCInfo->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + if (!nwk_allocateLocalRxPort(LINK_REPLY, pCInfo)) + { + nwk_freeConnection(pCInfo); + /* we're done with the packet */ + return SENT_REPLY; + } + + /* The local Rx port is the one returned in the connection structure. The + * caller is waiting on this to be set. The code here is running in an ISR + * thread so the caller will see this change after RETI. + */ + if (NUM_CONNECTIONS == sNumLinkers) + { + /* Something is wrong -- no room to stack Link request */ + nwk_freeConnection(pCInfo); + /* we're done with the packet */ + return SENT_REPLY; + } + sServiceLinkID[sNumLinkers++] = pCInfo->thisLinkID; + + /* save the remote Tx port */ + pCInfo->portTx = remotePort; + + /* connection is valid... */ + pCInfo->connState = CONNSTATE_CONNECTED; + + /* Set hop count. If it's a polling device set the count to the + * distance to the AP. otherwise, set it to the max less the remaining + * which will be the path taken for this frame. It will be no worse + * then tha max and probably will be better. + */ + if (F_RX_TYPE_POLLS == *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_MY_RXTYPE_OS)) + { + /* It polls. so. we'll be sending to the AP which will store the + * frame. The AP is only MAX_HOPS_FROM_AP hops away from us. + */ + pCInfo->hops2target = MAX_HOPS_FROM_AP; + } + else + { + /* Can't really use this trick because the device could move. If the + * devices are all static this may work unless the initial reception + * was marginal. + */ +# if defined(DEVICE_DOES_NOT_MOVE) + pCInfo->hops2target = MAX_HOPS - GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT); +# else + pCInfo->hops2target = MAX_HOPS; +# endif + } + + /* Send reply with the local port number so the remote device knows where to + * send packets. + */ + msg[LR_RMT_PORT_OS] = pCInfo->portRx; + + /* put my Rx type in there. used to know how to set hops when sending back. */ + msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); + + msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + LB_TID_OS); +# if defined(SMPL_SECURE) + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + L_CTR_OS), + (void *)&pCInfo->connRxCTR, 4); + pCInfo->connTxCTR = MRFI_RandomByte() | \ + ((uint32_t)(MRFI_RandomByte()) << 8) | \ + ((uint32_t)(MRFI_RandomByte()) << 16) | \ + ((uint32_t)(MRFI_RandomByte()) << 24); + + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); +# endif + if (pOutFrame = + nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS - + (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT)))) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +# if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +# endif + if (SMPL_SUCCESS != nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED)) + { + /* better release the connection structure */ + nwk_freeConnection(pCInfo); + } + } + else + { + /* better release the connection structure */ + nwk_freeConnection(pCInfo); + } + } + /* we're done with the packet */ + return SENT_REPLY; +#else + return SENT_NO_REPLY; +#endif /* NUM_CONNECTIONS */ +} + +/****************************************************************************** + * @fn nwk_processLink + * + * @brief Process Link frame. Just save the frame for the Link app if it + * a reply. If it isn't a reply, send the reply in this thread. + * + * input parameters + * @param frame - pointer to frame to be processed + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame.. + */ + +fhStatus_t nwk_processLink(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. send the reply. + */ + if (SMPL_MY_REPLY == (replyType = nwk_isValidReply(frame, sTid, LB_REQ_OS, LB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined(END_DEVICE) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* No, we didn't send it. Process request assuming it's + * intended for us. + */ + rc = handleLinkRequest(frame); + } + + (void) replyType; /* keep compiler happy when ED built... */ + + return rc; +} + +/****************************************************************************** + * @fn nwk_getLocalLinkID + * + * @brief This routine checks to see if a service port has been assigned + * as a result of a link reply frame being received. It is the means + * by which the user thread knows that the waiting is over for the + * link listen. the value is set in an interrupt thread. + * + * input parameters + * + * output parameters + * + * @return Local port assigned when the link reply was received. + */ + +linkID_t nwk_getLocalLinkID(void) +{ + linkID_t lid = 0; + +#if NUM_CONNECTIONS > 0 + uint8_t i; + bspIState_t intState; + + + BSP_ENTER_CRITICAL_SECTION(intState); + if (sNumLinkers) + { + sNumLinkers--; + BSP_EXIT_CRITICAL_SECTION(intState); + + nwk_setListenContext(LINK_LISTEN_OFF); + lid = sServiceLinkID[0]; + + /* If more than one Link frame has been processed without an intervening + * Listen assume that there will be another Link Listen call that will + * poll for completion which has already occurred. Age any existing entries. + * This code was added to deal with the possibility of mulitple EDs being + * activated simultaneously in the AP-as-data-hub example. This opens a + * window of opportunity for a "typical" scenario to get hosed. But for + * a "typical" scenario to get hosed a number of improbable events have to + * occur. These are deemed far less likely than the multiple-ED-activation + * scenario in the AP-as-dat-hub case. + */ + for (i = 0; i < sNumLinkers; ++i) + { + sServiceLinkID[i] = sServiceLinkID[i + 1]; + } + } + else + { + BSP_EXIT_CRITICAL_SECTION(intState); + } +#endif /* NUM_CONNECTIONS */ + + return lid; +} + +/****************************************************************************** + * @fn nwk_setListenContext + * + * @brief Sets the context when a LinkListen is executed. This prevents + * processing other link frames from being confused with the real + * one. Without this semaphore other broadcast link messages + * could wait int the input queue and accidently be processed if + * a listen is done later. + * + * input parameters + * + * @param context - listen on or off + * + * output parameters + * + * @return void + */ + +void nwk_setListenContext(uint8_t context) +{ + sListenActive = (context == LINK_LISTEN_ON) ? 1 : 0; +} + +/****************************************************************************** + * @fn handleLinkRequest + * + * @brief Dispatches handler for specfic link request + * + * input parameters + * + * @param frame - Link frame received + * + * output parameters + * + * @return void + */ + +static fhStatus_t handleLinkRequest(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + uint8_t isReplySent; + + if (LINK_LEGACY_MSG_LENGTH == (MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS)) + { + /* Legacy frame. Spoof a link request */ + *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS) = LINK_REQ_LINK; + } + + switch (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS)) + { + case LINK_REQ_LINK: + isReplySent = smpl_send_link_reply(frame); +#if !defined(END_DEVICE) + + /* If I am an AP or RE and not listening I need to replay frame. + * The exception is if I am an AP or RE hosting an End Device + * object and I just sent a reply frame to a duplicate link frame + * for which I was not listening. In this case don't replay. + */ + if (!sListenActive && (SENT_REPLY != isReplySent)) + { + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + break; + +#if defined(EXTENDED_API) + case LINK_REQ_UNLINK: + smpl_send_unlink_reply(frame); + break; +#endif + + default: + break; + } + + /* keep compiler happy if I'm compiled as an End Device */ + (void) isReplySent; + + return rc; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_link.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_link.h new file mode 100755 index 0000000..64ed033 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_link.h @@ -0,0 +1,108 @@ +/************************************************************************************************** +* Filename: nwk_link.h +* Revised: $Date: 2008-12-10 16:52:14 -0800 (Wed, 10 Dec 2008) $ +* Revision: $Revision: 18596 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI Join network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_LINK_H +#define NWK_LINK_H + +/* Macros needed for protocol backward compatibility */ +#define LINK_LEGACY_MSG_LENGTH 8 +#define LINK_REPLY_LEGACY_MSG_LENGTH 3 + + +#define LINK_LISTEN_ON 0 +#define LINK_LISTEN_OFF 1 + +/* application payload offsets + * both */ +#define LB_REQ_OS 0 +#define LB_TID_OS 1 + +/* link frame */ +#define L_LINK_TOKEN_OS 2 +#define L_RMT_PORT_OS 6 +#define L_MY_RXTYPE_OS 7 +#define L_PROTOCOL_VERSION_OS 8 +#define L_CTR_OS 9 +/* link reply frame */ +#define LR_RMT_PORT_OS 2 +#define LR_MY_RXTYPE_OS 3 +#define LR_CTR_OS 4 + +/* unlink frame */ +#define UL_RMT_PORT_OS 2 +/* unlink reply frame */ +#define ULR_RESULT_OS 2 + +/* change the following as protocol developed */ +#ifndef SMPL_SECURE +# define MAX_LINK_APP_FRAME 9 +#else +# define MAX_LINK_APP_FRAME 13 +#endif + +/* frame sizes */ +#ifndef SMPL_SECURE +# define LINK_FRAME_SIZE 9 +# define LINK_REPLY_FRAME_SIZE 4 +#else +# define LINK_FRAME_SIZE 13 +# define LINK_REPLY_FRAME_SIZE 8 +#endif +#define UNLINK_FRAME_SIZE 3 +#define UNLINK_REPLY_FRAME_SIZE 3 + +/* link requests + * NOTE: If aditional command codes are required do _not_ use the + * value LINK_REPLY_LEGACY_MSG_LENGTH. This numeral is used + * to guarantee that legacy Link frames (from before release + * 1.0.6) work correctly. Don't ask. + */ + +#define LINK_REQ_LINK 1 +#define LINK_REQ_UNLINK 2 + +/* prototypes */ +fhStatus_t nwk_processLink(mrfiPacket_t *); +linkID_t nwk_getLocalLinkID(void); +void nwk_linkInit(void); +smplStatus_t nwk_link(linkID_t *); + +smplStatus_t nwk_unlink(linkID_t); +void nwk_setLinkToken(uint32_t); +void nwk_getLinkToken(uint32_t *); + +void nwk_setListenContext(uint8_t); + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_mgmt.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_mgmt.c new file mode 100755 index 0000000..51253ac --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_mgmt.c @@ -0,0 +1,357 @@ +/************************************************************************************************** +* Filename: nwk_mgmt.c +* Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ +* Revision: $Revision: 18697 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Mgmt network application. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_mgmt.h" +#include "nwk_join.h" +#include "nwk_globals.h" +#include "nwk_QMgmt.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +#ifndef ACCESS_POINT +static addr_t const *sAPAddr = NULL; +#else +static uint8_t sSFMarker[NUM_STORE_AND_FWD_CLIENTS] = {0}; +#endif + +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static void smpl_send_mgmt_reply(mrfiPacket_t *); + +#ifdef ACCESS_POINT +static void send_poll_reply(mrfiPacket_t *); + +#endif + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_mgmtInit + * + * @brief Initialize Management functions. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_mgmtInit(void) +{ + sTid = MRFI_RandomByte(); + +#ifdef ACCESS_POINT + memset(&sSFMarker, 0x0, sizeof(sSFMarker)); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_processMgmt + * + * @brief Process Management frame. Just save the frame for the Management + * app it it is a reply. If it isn't a reply, send the reply in this + * thread. + * + * input parameters + * @param frame - pointer to frame to be processed + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ + +fhStatus_t nwk_processMgmt(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. send the reply. + */ + if (SMPL_MY_REPLY == (replyType = nwk_isValidReply(frame, sTid, MB_APP_INFO_OS, MB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined(END_DEVICE) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* no, we didn't send it. send reply if it's intended for us */ + if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + smpl_send_mgmt_reply(frame); + + /* we're done with the frame. */ + rc = FHS_RELEASE; + } + else + { + rc = FHS_REPLAY; + } + } + + (void) replyType; /* keep compiler happy */ + + return rc; +} + +/****************************************************************************** + * @fn smpl_send_mgmt_reply + * + * @brief Send appropriate reply to Management frame. + * + * input parameters + * @param frame - Pointer to frame for which reply required. + * + * output parameters + * + * @return void + */ + +static void smpl_send_mgmt_reply(mrfiPacket_t *frame) +{ +#ifdef ACCESS_POINT + /* what kind of management frame is this? */ + switch (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + MB_APP_INFO_OS)) + { + case MGMT_REQ_POLL: + send_poll_reply(frame); + break; + + default: + break; + } +#endif /* ACCESS_POINT */ + return; +} + +#ifdef ACCESS_POINT + +/****************************************************************************** + * @fn send_poll_reply + * + * @brief Send reply to polling frame. + * + * input parameters + * @param frame - Pointer to frame for which reply required. + * + * output parameters + * + * @return void + */ + +static void send_poll_reply(mrfiPacket_t *frame) +{ + uint8_t msgtid = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + MB_TID_OS); + frameInfo_t *pOutFrame; + sfClientInfo_t *pClientInfo; + uint8_t loc; + + /* Make sure this guy is really a client. We can tell from the source address. */ + if (!(pClientInfo = nwk_isSandFClient(MRFI_P_SRC_ADDR(frame), &loc))) + { + /* TODO: maybe send an error frame? */ + return; + } + + /* If we have to resync the TID then do it based on the first + * poll frame we see + */ + if (!sSFMarker[loc]) + { + /* If the marker flag is null then it has been initialized, i.e., + * there has been a reset. In this case infer that we need to update + * a (probably) stale last TID. The test will always be true the first + * time through after a client is established even when an NV restore + * did not take place but this does no harm. + */ + pClientInfo->lastTID = msgtid; + sSFMarker[loc] = 1; + } + + /* If we've seen this poll frame before ignore it. Otherwise we + * may send a stored frame when we shouldn't. + */ + else if (nwk_checkAppMsgTID(pClientInfo->lastTID, msgtid)) + { + pClientInfo->lastTID = msgtid; + } + else + { + return; + } + + if (pOutFrame = nwk_getSandFFrame(frame, M_POLL_PORT_OS)) + { + /* We need to adjust the order in the queue in this case. Currently + * we know it is in the input queue and that this adjustment is safe + * because we're in an ISR thread. This is a fragile fix, though, and + * should be revisited when time permits. + */ + nwk_QadjustOrder(INQ, pOutFrame->orderStamp); + + /* reset hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_HOP_COUNT, MAX_HOPS_FROM_AP); + /* It's gonna be a forwarded frame. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_FWD_FRAME, 0x80); + + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + else + { + nwk_SendEmptyPollRspFrame(frame); + } + + return; +} + +/****************************************************************************** + * @fn nwk_resetSFMarker + * + * @brief Reset S&F cklient marker so the TIDs resync. + * + * input parameters + * @param idx - index of the client that should be reset. + * + * output parameters + * + * @return void + */ + +void nwk_resetSFMarker(uint8_t idx) +{ + sSFMarker[idx] = 0; + + return; +} + +#else /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_poll + * + * @brief Poll S&F server for any waiting frames. + * + * input parameters + * @param port - Port on peer. + * @param addr - SimpliciTI address of peer. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_NO_AP_ADDRESS - We don't know Access Point's address + * SMPL_NOMEM - no room in output frame queue + * SMPL_TX_CCA_FAIL - CCA failure + */ + +smplStatus_t nwk_poll(uint8_t port, uint8_t *addr) +{ + uint8_t msg[MGMT_POLL_FRAME_SIZE]; + ioctlRawSend_t send; + + msg[MB_APP_INFO_OS] = MGMT_REQ_POLL; + msg[MB_TID_OS] = sTid; + msg[M_POLL_PORT_OS] = port; + memcpy(msg + M_POLL_ADDR_OS, addr, NET_ADDR_SIZE); + + /* it's OK to increment the TID here because the reply will not be + * matched based on this number. The reply to the poll comes back + * to the client port, not the Management port. + */ + sTid++; + + if (!sAPAddr) + { + sAPAddr = nwk_getAPAddress(); + if (!sAPAddr) + { + return SMPL_NO_AP_ADDRESS; + } + } + send.addr = (addr_t *)sAPAddr; + send.msg = msg; + send.len = sizeof(msg); + send.port = SMPL_PORT_MGMT; + + return SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); +} + +#endif /* ACCESS_POINT */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_mgmt.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_mgmt.h new file mode 100755 index 0000000..13bff76 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_mgmt.h @@ -0,0 +1,68 @@ +/************************************************************************************************** +* Filename: nwk_mgmt.h +* Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ +* Revision: $Revision: 18697 $ +* Author: $Author: lfriedman $ +* +* Description: This header file supports the SimpliciTI Mgmt network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_MGMT_H +#define NWK_MGMT_H + +/* MGMT frame application requests */ +#define MGMT_REQ_POLL 0x01 + +/* change the following as protocol developed */ +#define MAX_MGMT_APP_FRAME 7 + +/* application payload offsets + * both */ +#define MB_APP_INFO_OS 0 +#define MB_TID_OS 1 + +/* Poll frame */ +#define M_POLL_PORT_OS 2 +#define M_POLL_ADDR_OS 3 + +/* change the following as protocol developed */ +#define MAX_MGMT_APP_FRAME 7 + +/* frame sizes */ +#define MGMT_POLL_FRAME_SIZE 7 + +/* prototypes */ +void nwk_mgmtInit(void); +fhStatus_t nwk_processMgmt(mrfiPacket_t *); + +smplStatus_t nwk_poll(uint8_t, uint8_t *); +void nwk_resetSFMarker(uint8_t); + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.c new file mode 100755 index 0000000..a257e62 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.c @@ -0,0 +1,323 @@ +/************************************************************************************************** +* Filename: nwk_ping.c +* Revised: $Date: 2009-01-18 16:01:08 -0800 (Sun, 18 Jan 2009) $ +* Revision: $Revision: 18796 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Ping network application. +* +* Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_ping.h" +#include "nwk_globals.h" +#include "nwk_api.h" +#include "nwk_freq.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static void smpl_send_ping_reply(mrfiPacket_t *); +static void handlePingRequest(mrfiPacket_t *); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_pingInit + * + * @brief Initialize Ping application. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_pingInit(void) +{ + sTid = MRFI_RandomByte(); + + return; +} + +/****************************************************************************** + * @fn nwk_ping + * + * @brief Called from the application level to ping a peer. A small + * payload is sent that includes a tid to detect correct reply. + * Caller does not supply payload. + * + * input parameters + * @param lid - Link ID representing peer to ping + * + * output parameters + * + * @return SMPL_SUCCESS valid reply received + * SMPL_TIMEOUT no valid reply received + * SMPL_NO_CHANNEL no channels returned on a scan + */ + +smplStatus_t nwk_ping(linkID_t lid) +{ + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + uint8_t done = 0; + uint8_t repeatIt = 2; + uint8_t msg[MAX_PING_APP_FRAME]; + uint8_t radioState = MRFI_GetRadioState(); + + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + if (!pCInfo || (SMPL_LINKID_USER_UUD == lid)) + { + /* either link ID bogus or tried to ping the unconnected user datagram link ID. */ + return rc; + } + + do + { +#if defined(FREQUENCY_AGILITY) && !defined(ACCESS_POINT) + uint8_t i, numChan; + freqEntry_t channels[NWK_FREQ_TBL_SIZE]; + + if (repeatIt == 2) + { + /* If FA enabled, first time through set up so that the 'for' + * loop checks the current channel. This saves time (no scan) + * and is very likely to succeed. Populate the proper strucure. + */ + SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_GET, channels); + numChan = 1; + } + else + { + /* If we get here we must scan for the channel we're now on */ + if (!(numChan = nwk_scanForChannels(channels))) + { + return SMPL_NO_CHANNEL; + } + } + /* Either we scan next time through or we're done */ + repeatIt--; + + /* this loop Pings on each channel (probably only 1) looking + * for peer. + */ + for (i = 0; i < numChan && !done; ++i) + { + nwk_setChannel(&channels[i]); +#else + { + repeatIt = 0; +#endif /* defined(FREQUENCY_AGILITY) && !defined(ACCESS_POINT) */ + + ioctl_info.send.addr = (addr_t *)pCInfo->peerAddr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_PING; + + /* fill in msg */ + msg[PB_REQ_OS] = PING_REQ_PING; + msg[PB_TID_OS] = sTid; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + ioctl_info.recv.port = SMPL_PORT_PING; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = 0; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + repeatIt = 0; + done = 1; + sTid++; /* guard against duplicates */ + } + } + } while (repeatIt); + + return done ? SMPL_SUCCESS : SMPL_TIMEOUT; + +} + +/****************************************************************************** + * @fn smpl_send_ping_reply + * + * @brief Send a reply to a ping request. + * + * input parameters + * @param frame - pointer to frame containing request + * + * output parameters + * + * @return void + */ + +static void smpl_send_ping_reply(mrfiPacket_t *frame) +{ + frameInfo_t *pOutFrame; + + /* Build the reply frame. The application payload is the one included in the + * received frame payload. + */ + if (pOutFrame = + nwk_buildFrame(SMPL_PORT_PING, MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS, + MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS, MAX_HOPS)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + /* turn on the reply bit in the application payload */ + *(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt) + F_APP_PAYLOAD_OS + PB_REQ_OS) |= NWK_APP_REPLY_BIT; +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS, 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } +} + +/****************************************************************************** + * @fn nwk_processPing + * + * @brief Ping network application frame handler. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ + +fhStatus_t nwk_processPing(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. Send the reply. + */ + replyType = nwk_isValidReply(frame, sTid, PB_REQ_OS, PB_TID_OS); + if (SMPL_MY_REPLY == replyType) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined(END_DEVICE) + else if (SMPL_A_REPLY == replyType) + { + /* no match. If I'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* No, we didn't send it. Send reply assuming it's a Ping intended for us. */ + handlePingRequest(frame); + + rc = FHS_RELEASE; + } + + return rc; +} + +/****************************************************************************** + * @fn handlePingRequest + * + * @brief Dispatches handler for specfic Ping request + * + * input parameters + * + * @param frame - Ping frame received + * + * output parameters + * + * @return void + */ + +static void handlePingRequest(mrfiPacket_t *frame) +{ + switch (*(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS)) + { + case PING_REQ_PING: + smpl_send_ping_reply(frame); + break; + + default: + break; + } + + return; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.h new file mode 100755 index 0000000..6f49bbf --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.h @@ -0,0 +1,59 @@ +/************************************************************************************************** +* Filename: nwk_ping.h +* Revised: $Date: 2008-05-14 14:22:31 -0700 (Wed, 14 May 2008) $ +* Revision: $Revision: 17075 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Ping network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_PING_H +#define NWK_PING_H + +/* change the following as protocol developed */ +#define MAX_PING_APP_FRAME 2 + +/* application payload offsets + * both */ +#define PB_REQ_OS 0 +#define PB_TID_OS 1 + + +/* ping requests */ +#define PING_REQ_PING 1 + +/* prototypes */ +fhStatus_t nwk_processPing(mrfiPacket_t *); +void nwk_pingInit(void); + +smplStatus_t nwk_ping(linkID_t); + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.c b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.c new file mode 100755 index 0000000..d53a558 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.c @@ -0,0 +1,565 @@ +/************************************************************************************************** +* Filename: nwk_security.c +* Revised: $Date: 2009-01-20 14:05:46 -0800 (Tue, 20 Jan 2009) $ +* Revision: $Revision: 18816 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Security network application. +* +* Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include /* needed for NULL */ +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_security.h" +#include "nwk_frame.h" +#include "nwk.h" + +#ifdef SMPL_SECURE + +/* *** GENERAL SECURITY OUTLINE *** + * + * We are using XTEA (eXtended Tiny Encryption Algorithm) with a fixed + * number of rounds (32). We have removed the parameters from the API + * we harvested from the public domain. + * + * We are using a CTR-like mode. We use the 64-bit block cipher function of the + * XTEA code to encipher a concatenation of the 32-bit initialization vector and + * a 32-bit counter that increments each block. We encrypt using a fixed 128-bit + * key. The resulting 64-bit output is XOR'ed with the message. If the message is + * longer than 64 bits we encipher the next block (incrementing the counter) and + * continue until the message is exhausted. If the last cipher block is longer + * than the message we simply discard the remaining cipher block. + */ + + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/* The counter can be off by quite a bit because the number of cipher + * blocks can easily be more than 1 per frame. Value limited to a + * maximum of 255. + */ +# define CTR_WINDOW 255 + +# if (CTR_WINDOW > 255) || (CTR_WINDOW < 0) +# error ERROR: 0 <= CTR_WINDOW < 256 +# endif + +/* Number of rounds for XTEA algorithm. A parameter in the public domain code + * but we fix it here at 32. + */ +# define NUM_ROUNDS 32 + +/* Key and cipher block size constants */ +# define SMPL_KEYSIZE_BYTES 16 +# define SMPL_KEYSIZE_LONGS 4 + +/****************************************************************************** + * TYPEDEFS + */ +/* Union used to access key as both a string and as unsigned longs */ +typedef union +{ + uint8_t keyS[SMPL_KEYSIZE_BYTES]; + uint32_t keyL[SMPL_KEYSIZE_LONGS]; +} key_t; + + +/****************************************************************************** + * LOCAL VARIABLES + */ +/* 32-bit Initialization vector */ +static uint32_t const sIV = 0x87654321; + +/* 128-bit (16 byte) key. Initialized as string but fetched and used in XTEA + * encryption as 4 unsigned longs. Endianess could count if the peers are on + * two different MCUs. Endianess is rectified in initialization code. + * + * Initialization _MUST_ be done as a string (or character array). Though it + * won't matter how the initialization is done if both peers are the same + * endianness, good prectice will initialize these as a string (or character + * array) so that the endianess reconciliation works properly for all cases. + */ +static key_t sKey = {"SimpliciTI's Key"}; + +/* Constant set as an authentication code. Note that since it is a + * fixed value as opposed to a hash of the message it does not provide + * an integrity check. It will only differentiate two message encryptions + * with the same LSB but different MSB components. Thus it helps guard + * against replays. + */ +static secMAC_t const sMAC = 0xA5; + +/* This is the 64-bit cipher block target. It is this 64-bit block that + * is XOR'ed with the actual message to be encrypted. + */ +static uint32_t sMsg[2] = {0, 0}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static secFCS_t calcFCS(uint8_t *, uint8_t); +static void msg_encipher(uint8_t *, uint8_t, uint32_t *); +static void msg_decipher(uint8_t *, uint8_t, uint32_t *); +static void xtea_encipher(void); + +#endif /* SMPL_SECURE */ + +/****************************************************************************** + * @fn nwk_securityInit + * + * @brief Initialize Security network application. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_securityInit(void) +{ +#ifdef SMPL_SECURE + uint8_t i; + + /* The key is set as a string. But the XTEA routines operate on 32-bit + * unsigned longs. Endianess should be taken into account and we do that + * here by treating the key as being an array of unsigned longs in + * network order. + */ + for (i = 0; i < sizeof(sKey.keyL) / sizeof(uint32_t); ++i) + { + sKey.keyL[i] = ntohl(sKey.keyL[i]); + } + +#endif /* SMPL_SECURE */ + return; +} + +/****************************************************************************** + * @fn nwk_processSecurity + * + * @brief Security network application frame handler. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ + +fhStatus_t nwk_processSecurity(mrfiPacket_t *frame) +{ + return FHS_RELEASE; +} + +/****************************************************************************** + * @fn msg_encipher + * + * @brief Encipher a message using the XTEA algorithm and the modified + * CTR mode method. + * + * input parameters + * @param msg - pointer to message to encipher + * @param len - length of message + * @param cntStart - pointer to the counter used in the cipher block. + * + * output parameters + * @param cntStart - counter is updated during encryption. + * + * @return void + */ +#ifdef SMPL_SECURE +static void msg_encipher(uint8_t *msg, uint8_t len, uint32_t *cntStart) +{ + uint8_t i, idx, done; + uint8_t *mptr = (uint8_t *)&sMsg[0]; + uint32_t ctr; + + if ((NULL == msg) || !len) + { + return; + } + + /* set local counter from input */ + ctr = *cntStart; + + idx = 0; + done = 0; + do + { + /* Set block to be enciphered. 1st 32 bits are the IV. The second + * 32 bits are the current CTR value. + */ + sMsg[0] = sIV; + sMsg[1] = ctr; + /* encrypt */ + xtea_encipher(); + /* increment counter for next time. */ + ctr++; + + /* XOR ciphered block with message to be sent. Only operate + * up to and including the last message byte which may not + * be on a cipher block boundary (64 bits == 8 bytes). + */ + for (i = 0; i < sizeof(sMsg) && idx < len; ++i, ++idx) + { + msg[idx] ^= mptr[i]; + } + + if (idx >= len) + { + /* we're done */ + done = 1; + } + } while (!done); + + /* return counter value start for next time */ + *cntStart = ctr; + + return; +} + +/****************************************************************************** + * @fn msg_decipher + * + * @brief Decipher a message using the XTEA algorithm and the modified + * CTR mode method. + * + * input parameters + * @param msg - pointer to message to decipher + * @param len - length of message + * @param cntStart - pointer to the counter used in the cipher block. + * + * output parameters + * @param cntStart - counter is updated during decryption. + * + * @return void + */ + +static void msg_decipher(uint8_t *msg, uint8_t len, uint32_t *cntStart) +{ + msg_encipher(msg, len, cntStart); + + return; +} + +/****************************************************************************** + * @fn xtea_encipher + * + * @brief XTEA encipher algorithm. Calling arguments removed from public + * domain code and static-scope values used instead. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void xtea_encipher(void) +{ + uint32_t v0 = sMsg[0], v1 = sMsg[1]; + uint16_t i; + uint32_t sum = 0, delta = 0x9E3779B9; + + for (i = 0; i < NUM_ROUNDS; i++) + { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + sKey.keyL[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + sKey.keyL[(sum >> 11) & 3]); + } + + sMsg[0] = v0; + sMsg[1] = v1; +} + +/****************************************************************************** + * @fn nwk_setSecureFrame + * + * @brief Called from NWK to secure a frame. + * + * input parameters + * @param frame - pointer to frame to secure + * @param msglen - length of message + * @param ctr - pointer to the counter used in the cipher block. This will + * be NULL if a network application is sending a frame. Since + * these are not connection-based there is no counter sync + * issue but we still need a counter value. A random value + * is used. + * + * output parameters + * @param cntStart - counter is updated during encryption. + * + * @return void + */ + +void nwk_setSecureFrame(mrfiPacket_t *frame, uint8_t msglen, uint32_t *ctr) +{ + uint32_t locCnt; + + /* If an encrypted frame is to be sent to a non-connection based port use a + * random number as the lsb counter value. In this case only the lsb is used + * for a counter value during decryption. Not as secure but there are still + * the 32 bits in the IV. + */ + locCnt = ctr ? *ctr : MRFI_RandomByte(); + + /* place counter value into frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(frame), F_SEC_CTR_OS, (uint8_t)(locCnt & 0xFF)); + + /* Put MAC value in */ + nwk_putNumObjectIntoMsg((void *)&sMAC, (void *)(MRFI_P_PAYLOAD(frame) + F_SEC_MAC_OS), + sizeof(secMAC_t)); + + /* Put FCS value in */ + { + secFCS_t fcs = calcFCS(MRFI_P_PAYLOAD(frame) + F_SEC_MAC_OS, msglen + sizeof(secMAC_t)); + + nwk_putNumObjectIntoMsg((void *)&fcs, (void *)(MRFI_P_PAYLOAD( + frame) + F_SEC_ICHK_OS), sizeof(secFCS_t)); + } + + /* Encrypt frame */ + msg_encipher(MRFI_P_PAYLOAD( + frame) + F_SEC_ICHK_OS, msglen + sizeof(secMAC_t) + sizeof(secFCS_t), &locCnt); + + /* Set the Encryption bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(frame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + + /* Update the counter if it was a "real" counter. */ + if (ctr) + { + *ctr = locCnt; + } + + return; +} + +/****************************************************************************** + * @fn calcFCS + * + * @brief Calculate the frame check sequence. Currently it's just a + * cumulative XOR of each byte starting with the MAC byte. The + * FCS is placed in front of the MAC after the counter hint and is + * included in the encryption. + * + * input parameters + * @param msg - pointer to message + * @param len - length of message + * + * output parameters + * + * @return Returns the FCS using the typedef. + */ + +static secFCS_t calcFCS(uint8_t *msg, uint8_t len) +{ + uint8_t i; + secFCS_t result = 0; + + for (i = 0; i < len; ++i) + { + result ^= *(msg + i); + } + + return result; +} + +/****************************************************************************** + * @fn nwk_getSecureFrame + * + * @brief Called from NWK to get a secure a frame and decrypt. + * + * input parameters + * @param frame - pointer to frame containing encrypted message + * @param msglen - length of message + * @param ctr - pointer to the counter used in the cipher block. This will + * be NULL if a network applicaiton is getting a frame. Since + * these are not connection-nbased there is no counter sync + * issue but we still need a counter value. + * + * output parameters + * @param cntStart - counter is updated during decryption. If decryption fails + * this value is not changed. + * + * @return Returns non-zero if frame decryption is valid, otherwise returns 0. + */ + +uint8_t nwk_getSecureFrame(mrfiPacket_t *frame, uint8_t msglen, uint32_t *ctr) +{ + uint8_t rc = 1; + uint8_t done = 0; + uint8_t cntHint = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_SEC_CTR_OS); + uint32_t locCnt, frameCnt; + + /* Construct proposed CTR values */ + + /* Just like encryption, we may be talking to a non-connection based + * peer in which case the counter value is represented by the lsb byte + * conveyed in the frame. + */ + locCnt = ctr ? *ctr : cntHint; + + frameCnt = (locCnt & 0xFFFFFF00) + cntHint; + + do + { + /* See if counters match */ + if (locCnt == frameCnt) + { + /* When the counters appear to match is the only time we actually decipher + * the message. It is the only time we can do so since out-of-sync lsb counter + * values guarantees that something is wrong somewhere. Decryption is successful + * only if the MAC and FCS values match. The message is left as-is after the + * decipher attempt. Either it appears valid or is doesn't and is discarded. + * There is no recovery attempt if the counters match but the MAC or FCS do + * not. It is considered a rogue message. + */ + msg_decipher(MRFI_P_PAYLOAD(frame) + F_SEC_ICHK_OS, msglen - 1, &locCnt); + + /* Get MAC and make sure it matches. A failure can occur if a replayed frame happens + * to have the correct counter sync value but was encoded with the wrong complete + * counter value. Otherwise the MAC values must match when the counter values are equal. + */ + { + secMAC_t mac; + + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD( + frame) + F_SEC_MAC_OS), (void *)&mac, + sizeof(secMAC_t)); + if (mac != sMAC) + { + rc = 0; + } + } + + /* FCS check... */ + { + secFCS_t fcs; + + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD( + frame) + F_SEC_ICHK_OS), (void *)&fcs, + sizeof(secFCS_t)); + if (fcs != + calcFCS(MRFI_P_PAYLOAD(frame) + F_SEC_MAC_OS, msglen - 1 - sizeof(secMAC_t))) + { + rc = 0; + } + } + + /* we're done. */ + done = 1; + } + else + { + /* Uh oh. Counters don't match. Try and resync. We need to distinguish among + * missed frames, duplicates and rogues plus account for counter wrap. + */ + if (frameCnt > locCnt) + { + /* frameCnt is bigger. Second part of test below takes care of + * the unlikely case of a complete counter wrap (msb's all 0) in + * which case the test will incorrectly fail when the count is + * actually within the (wrapped) window. #ifdef'ed to avoid compiler + * warning in case user sets CNT_WINDOW to 0 (pointless comparison of + * unsigned value). + */ + if (((frameCnt - CTR_WINDOW) <= locCnt) +# if CTR_WINDOW > 0 + || (frameCnt < CTR_WINDOW) +# endif + ) + { + /* Value within window. We probably missed something. Adjust and decipher. + * If locCnt is less because it wrapped and frameCnt didn't it means that + * it's a duplicate or late frame. In that case the following will lead to + * a decryption that fails sanity checks which is OK because the frame will + * be correctly rejected. + */ + locCnt = frameCnt; + } + else + { + /* It's either a rogue or a really old duplicate packet. In either case + * we dismiss the frame. + */ + rc = 0; + done = 1; + } + } + else + { + /* locCnt is bigger. The only way the frame can be valid is if the + * counter wrapped causing frameCnt to appear to be smaller. Wrap the + * counter and decrypt. If the frame isn't valid, i.e., it's late, + * a duplicate, or a rogue, the decryption will fail sanity checks and + * the frame will be correctly rejected. The following arithmetic works + * correctly without a special test for the complete counter wrap case. + */ + frameCnt += 0x100; /* wrap the hint-based counter */ + if (((frameCnt - CTR_WINDOW) <= locCnt)) + { + /* An lsb wrap but still within window. We probably missed something. + * Adjust (with wrap) and decrypt. + */ + locCnt = frameCnt; + } + else + { + /* rogue frame */ + rc = 0; + done = 1; + } + } + } + } while (!done); + + if (ctr && rc) + { + /* Only update the counter if the count was a "real" one and the + * decryption succeeded. + */ + *ctr = locCnt; + } + + return rc; +} + +#endif /* SMPL_SECURE */ diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.h new file mode 100755 index 0000000..ad8b087 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.h @@ -0,0 +1,49 @@ +/************************************************************************************************** +* Filename: nwk_security.h +* Revised: $Date: 2009-01-09 15:02:17 -0800 (Fri, 09 Jan 2009) $ +* Revision: $Revision: 18728 $ +* Author: $Author: lfriedman $ +* +* Description: This file supports the SimpliciTI Security network application. +* +* Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +* +* IMPORTANT: Your use of this Software is limited to those specific rights granted under +* the terms of a software license agreement between the user who downloaded the software, +* his/her employer (which must be your employer) and Texas Instruments Incorporated (the +* "License"). You may not use this Software unless you agree to abide by the terms of the +* License. The License limits your use, and you acknowledge, that the Software may not be +* modified, copied or distributed unless embedded on a Texas Instruments microcontroller +* or used solely and exclusively in conjunction with a Texas Instruments radio frequency +* transceiver, which is integrated into your product. Other than for the foregoing purpose, +* you may not use, reproduce, copy, prepare derivative works of, modify, distribute, +* perform, display or sell this Software and/or its documentation for any purpose. +* +* YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY +* WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. +* IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +* NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE +* THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY +* INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST +* DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY +* THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +* +* Should you have any questions regarding your right to use this Software, +* contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_SECURITY_H +#define NWK_SECURITY_H + +/* change the following as Security application is developed */ +#define MAX_SEC_APP_FRAME 0 + +/* prototypes */ +void nwk_securityInit(void); +fhStatus_t nwk_processSecurity(mrfiPacket_t *); + +void nwk_setSecureFrame(mrfiPacket_t *, uint8_t, uint32_t *); +uint8_t nwk_getSecureFrame(mrfiPacket_t *, uint8_t, uint32_t *); +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/simpliciti.h b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/simpliciti.h new file mode 100755 index 0000000..9881a61 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/simpliciti.h @@ -0,0 +1,163 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// +// SimpliciTI packet size (TX only mode) +// ------------------------------------- +// +// * packet rate (100/3) packets/second = 33.3 packets/second +// * packet length 28 bytes +// * packet structure 4 bytes preamble +// 4 bytes sync +// 1 bytes length +// 1 bytes address +// 16 bytes data +// 12 byte network data +// 4 byte user data +// 2 bytes crc +// +// SimpliciTI frequency overview +// ----------------------------- +// +// CC430_End_Device_433MHz.lib (433MHz ISM band) +// +// * base frequency 433.92 MHz +// * deviation 32 kHz +// * channel spacing 25 kHz +// * used channel number 0 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.4 dBm +// * duty 9,6% (TX only mode, 32 packets / second) +// +// CC430_End_Device_868MHz.lib (868MHz ISM band) +// +// * base frequency 869.525 MHz +// * deviation 32 kHz +// * channel spacing 25 kHz +// * used channel number 0 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.1 dBm +// * duty 9,6% (TX only mode, 32 packets / second) +// +// CC430_End_Device_915MHz.lib (915MHz ISM band) +// +// * base frequency 902.000 MHz +// * deviation 32 kHz +// * channel spacing 200 kHz +// * used channel number 20 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.3 dBm +// * duty 9.6% (TX only mode, 32 packets / second) +// +// ************************************************************************************************* + +// --------------------------------------------------------------- +// Generic defines and variables + +// Entry point into SimpliciTI library +extern unsigned char simpliciti_link(void); + +// 4 byte device address overrides device address set during compile time +extern unsigned char simpliciti_ed_address[4]; + +// Maximum data length +#define SIMPLICITI_MAX_PAYLOAD_LENGTH (32u) + +// Data to send / receive +extern unsigned char simpliciti_data[SIMPLICITI_MAX_PAYLOAD_LENGTH]; + +// Flag contains status information and triggers to send data or to exit SimpliciTI library +// Control is done from outside SimpliciTI library +extern unsigned char simpliciti_flag; +#define SIMPLICITI_STATUS_LINKING (BIT0) +#define SIMPLICITI_STATUS_LINKED (BIT1) +#define SIMPLICITI_STATUS_ERROR (BIT2) +#define SIMPLICITI_TRIGGER_SEND_DATA (BIT3) +#define SIMPLICITI_TRIGGER_RECEIVED_DATA (BIT4) +#define SIMPLICITI_TRIGGER_STOP (BIT5) + +// Radio frequency offset read from calibration memory +// Compensates crystal deviation from 26MHz nominal value +extern unsigned char rf_frequoffset; + +// Macros +#define getFlag(val, flag) ((val & flag) == flag) +#define setFlag(val, flag) (val |= flag) +#define clearFlag(val, flag) (val &= (~flag)) +#define toggleFlag(val, flag) (val ^= flag) + + +// --------------------------------------------------------------- +// SimpliciTI RX only + +// Entry point into SimpliciTI library +extern void simpliciti_main_tx_only(void); + +// Callback function to read data from acceleration sensor or buttons and trigger sending +extern void simpliciti_get_ed_data_callback(void); + + +// --------------------------------------------------------------- +// SimpliciTI Sync + +// Sync data length +#define BM_SYNC_DATA_LENGTH (19u) + +// Device data (0)TYPE (1) - (18) DATA +#define SYNC_ED_TYPE_R2R (1u) +#define SYNC_ED_TYPE_MEMORY (2u) +#define SYNC_ED_TYPE_STATUS (3u) + +// Host data (0)CMD (1) - (18) DATA +#define SYNC_AP_CMD_NOP (1u) +#define SYNC_AP_CMD_GET_STATUS (2u) +#define SYNC_AP_CMD_SET_WATCH (3u) +#define SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_1 (4u) +#define SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_2 (5u) +#define SYNC_AP_CMD_ERASE_MEMORY (6u) +#define SYNC_AP_CMD_EXIT (7u) + + +// Entry point into SimpliciTI library +extern void simpliciti_main_sync(void); + +// Callback function to decode access point command +extern void simpliciti_sync_decode_ap_cmd_callback(void); + +// Callback function to read data from application and trigger sending +extern void simpliciti_sync_get_data_callback(unsigned int index); + +// Send reply packets (>0), 0=no need to reply +extern unsigned char simpliciti_reply_count; + diff --git a/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/simpliciti_readme.txt b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/simpliciti_readme.txt new file mode 100755 index 0000000..d1ff81d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/CCS/Sports Watch/simpliciti/simpliciti_readme.txt @@ -0,0 +1,46 @@ +Some notes about the SimpliciTI configuration used in this project + +- The source code is based on the SimpliciTI 1.1.1 release. + +- A full SimpliciTI installation contains configurations for many targets and device types. To avoid confusion, + only the configuration (End Device) and target files (CC430EM) required for the eZ430-Chronos have been used. + +- All source code files have been copied into the project physically. Symbolic links have been replaced with + the real source code file. + +- Due to the indirect inclusion scheme of hardware-dependent source code, some source code files have been + excluded from build. However, they will be included through higher level source code. + +- Some modifications where required to the original source code. All these changes have been marked with [BM]. + + bsp_board.c/BSP_InitBoard(void) Changed from TA0 to TA1 for delay function, because TA0 is already occupied. + + bsp_msp430_defs.h/BSP_EarlyInit(void) Function removed, because SimpliciTI must run in watch context + + mrfi_radio_interface.c/mrfiRadioInterfaceCmdStrobe(uint8_t addr) + Added code to properly synchronize with radio interface. Otherwise + interface could get stuck. + + mrfi_radio.c Changed channel assignment (mrfiLogicalChanTable) for three ISM bands + Changed power output settings (mrfiRFPowerTable) for three ISM bands + + mrfi_radio.c/MRFI_Init(void) Added frequency offset correction to use calibrated frequency offset + when starting RF communication + + mrfi_radio.c/MRFI_RadioIsr(void) Changed radio ISR to normal function, since we have a shared radio ISR + + nwk_api.c Made variable sInit_done globally available to allow SimpliciTI to shutdown + and restart multiple times + + nwk.c/nwk_nwkInit Added workaround to allow allow SimpliciTI to shutdown + and restart multiple times + +- If you (for whatever reason) want to upgrade to a newer version of SimpliciTI, please bear in mind that + + a) the access point SimpliciTI version is 1.1.1 (and cannot be updated) + + b) the workarounds used here to enable SimpliciTI to shutdown and restart multiple times might not necessarily + work when used with later revisions + + + \ No newline at end of file diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_433MHz.r43 b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_433MHz.r43 new file mode 100755 index 0000000..6bc0263 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_433MHz.r43 differ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_868MHz.r43 b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_868MHz.r43 new file mode 100755 index 0000000..beb04a4 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_868MHz.r43 differ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_915MHz.r43 b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_915MHz.r43 new file mode 100755 index 0000000..17a47b4 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_915MHz.r43 differ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_API.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_API.h new file mode 100755 index 0000000..6cdbb8e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/BlueRobin_RX_API.h @@ -0,0 +1,161 @@ +// ************************************************************************************************* +// +// Copyright 2009 BM innovations GmbH (www.bm-innovations.com), all rights reserved. +// +// This trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC" may be used for non-profit non-commercial purposes only. If you want to use +// BlueRobin(TM) in a commercial project, please contact the copyright holder for a +// separate license agreement. +// +// By using this trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC", you implicitly agree that you will not modify, adapt, disassemble, decompile, +// reverse engineer, translate or otherwise attempt to discover the source code of the +// "BlueRobin(TM) receiver library for the Texas Instruments CC430 SoC". +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// +// Public header for eZ430-Chronos specific BlueRobin(TM) receiver library. +// +// The following BlueRobin(TM) profiles are supported by this build +// - heart rate (HR) transmitter +// +// The following number of channels is supported: 1 +// +// ************************************************************************************************* +// +// BlueRobin(TM) packet size +// ------------------------- +// +// * average packet rate 1 packet/875 msec = ~1.14 packets/second +// * payload per packet 5 bytes +// +// BlueRobin(TM) frequency overview +// (Please note: Settings apply for the transmitter side, i.e. the USB dongle) +// ---------------------------------------------------------------------- +// +// Bluerobin_RX_433MHz.lib (433MHz ISM band) +// +// * frequency 433.30 MHz - 434.00 MHz +// * deviation 95 kHz +// * channels 3 +// * data rate 250 kBaud +// +// Bluerobin_RX_868MHz.lib (868MHz ISM band) +// +// * frequency 868.25 MHz - 868.95 MHz +// * deviation 95 kHz +// * channels 3 +// * data rate 250 kBaud +// +// +// Bluerobin_RX_915MHz.lib (915MHz ISM band) +// +// * frequency 914.35 MHz - 917.75 MHz +// * deviation 95 kHz +// * channels 34 +// * data rate 250 kBaud +// +// ************************************************************************************************* + +#ifndef BRRX_API_H_ +#define BRRX_API_H_ + +// ************************************************************************************************* +// Include section + + +// ************************************************************************************************* +// Defines section + +// List of all possible channel states +typedef enum +{ + TX_OFF = 0, // Powerdown mode + TX_ACTIVE, // Active mode + TX_SEARCH // Search mode +} brtx_state_t; + +// Transmitter to channel assignment +#define HR_CHANNEL (0) + + +// ************************************************************************************************* +// API section + +// ---------------------------------------------------------- +// Functions for initializing and controlling the library + +// Initialize several global variables. +void BRRX_Init_v(void); + +// Set delay after which a channel will be switched off if no new data can be received. +// Param1: Powerdown delay in packet intervals (875 ms) +void BRRX_SetPowerdownDelay_v(u8 Delay_u8); + +// Set timeout when searching for a transmitter +// Param1: Search timeout in seconds +void BRRX_SetSearchTimeout_v(u8 Timeout_u8); + +// Set reduction of valid signal level in learn mode. +// Param1: Reduction of signal level +void BRRX_SetSignalLevelReduction_v(u8 Reduction_u8); + +// Set ID for a channel. To search for an unknown transmitter the ID has to be set to 0. +// Can be only executed on channels currently in powerdown mode. +// Param1: Channel index +// Param2: New ID +void BRRX_SetID_v(u8 Index_u8, u32 ID_u32); + +// Get current ID of channel. +// Return: Current ID of channel +// Param1: Channel index +u32 BRRX_GetID_u32(u8 Index_u8); + +// Start reception on one or all channels. +// Param1: Channel index (use 0xFF to start all channels) +void BRRX_Start_v(u8 Index_u8); + +// Stop reception on one or all channels. +// Param1: Channel index (0xFF for all channels) +void BRRX_Stop_v(u8 Index_u8); + +// Get current state of a channel +// Param1: Channel index +brtx_state_t BRRX_GetState_t(u8 Index_u8); + + +// ---------------------------------------------------------- +// eZ430-Chronos specific functions + +// Get current heart rate. +// Return: Heart rate in bpm +u8 BRRX_GetHeartRate_u8(void); + +// Get current distance. +// Return: Distance in 10m steps. +u16 BRRX_GetDistance_u16(void); + +// Get current speed. +// Return: Speed in 0.1km/h steps. Trial version is limited to 25.5km/h. +u8 BRRX_GetSpeed_u8(void); + +// ---------------------------------------------------------- +// Radio-related functions + +// RX packet end service function +// Must be called by CC1101_VECTOR ISR +void BlueRobin_RadioISR_v(void); + + +#endif /*BRRX_API_H_*/ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/bm.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/bm.h new file mode 100755 index 0000000..7e7db49 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/bluerobin/bm.h @@ -0,0 +1,445 @@ +// ************************************************************************************************* +// +// Copyright 2009 BM innovations GmbH (www.bm-innovations.com), all rights reserved. +// +// This trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC" may be used for non-profit non-commercial purposes only. If you want to use +// BlueRobin(TM) in a commercial project, please contact the copyright holder for a +// separate license agreement. +// +// By using this trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC", you implicitly agree that you will not modify, adapt, disassemble, decompile, +// reverse engineer, translate or otherwise attempt to discover the source code of the +// "BlueRobin(TM) receiver library for the Texas Instruments CC430 SoC". +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Standard definitions, have to be included in every source and header file. +// ************************************************************************************************* + +#ifndef __BM_H +#define __BM_H + + +#if (defined __IAR_SYSTEMS_ASM) || (defined __IAR_SYSTEMS_ASM__) + #define _ASSEMBLER_USED_ +#endif + +#ifndef _ASSEMBLER_USED_ + #include +#endif + +#ifndef FALSE + // the classic false + #define FALSE (0 == 1) +#endif + +#ifndef TRUE + // the classic true + #define TRUE (1 == 1) +#endif + +#ifndef USE_RAW_ATTR + // per default this feature is disabled + #define USE_RAW_ATTR FALSE +#endif + +// ************************************************************************************************* +// First Section: Basic Data Types +// ************************************************************************************************* + +// Fundamental #definitions +// CPU target idents are used for target dependent compilations + +// Texas Instruments MSP430 +#define _TI_MSP430_ (16) + + +// Find the currently running compiler +// and make the related #define's + +// _IAR_TID_ target ID from IAR compilers +// _CPU_TID_ remap to enum of processor target numbers +// _CPU_8BIT_INT_ type for 8 bit int +// _CPU_16BIT_INT_ type for 16 bit int +// _CPU_32BIT_INT_ type for 32 bit int +// _CPU_32BIT_FLOAT_ type for 32 bit float +// _CPU_64BIT_FLOAT_ type for 64 bit float +// INTERRUPT declares an interrupt service routine without an entry in the vector table +// ISR(vector) declares an interrupt service routine which is added in vector table at offset vector +// MONITOR declares a function atomic +// INTERRUPTS_ENABLE remap to the intrinsic for enable interrupts +// INTERRUPTS_DISABLE remap to the intrinsic for disable interrupts +// NO_OPERATION remap to the intrinsic for no operation +// _CPU_DIRECTION_OUT_1_ if TRUE the direction register indicates with an 1: direction is output +// _CPU_EDGE_HIGH_LOW_1_ if TRUE the edge select register indicates with an 1: trigger on high low +// NO_INIT declare a variable as not initialized +// INLINE_FUNC declare a function as inline for release builds + + +#if ((defined __IAR_SYSTEMS_ICC) || (defined __IAR_SYSTEMS_ASM)) && (__IAR_SYSTEMS_ICC__ < 2) + // Found IAR Compiler with classic IAR frontend + #ifndef _IAR_TID_ + #define _IAR_TID_ ((__TID__ >> 8) & 0x7f) + #endif + + #define INTERRUPT interrupt + #define ISR(vector) interrupt [(vector)] + #define MONITOR monitor + + #if ((_IAR_TID_) == 43) + // Found Texas Instruments MSP430 CPU + #define _CPU_TID_ _TI_MSP430_ + #define _CPU_DIRECTION_OUT_1_ TRUE + #define _CPU_EDGE_HIGH_LOW_1_ TRUE + #define INTERRUPTS_ENABLE() _EINT() + // WA for HW bug, add a NOP + #define INTERRUPTS_DISABLE() { _DINT(); _NOP(); } + #define NO_OPERATION() _NOP() + + #else + #error "Unknown IAR Compiler, the file bm.h has to be expanded !" + #endif + +#elif defined __IAR_SYSTEMS_ICC__ + // Found IAR Compiler with EDG frontend + #define _IAR_TID_ ((__TID__ >> 8) & 0x7f) + + #if USE_RAW_ATTR == TRUE + // Use the raw attribute in ISR's + #define _RAW __raw + #else + // Empty define RAW as it is not used + #define _RAW + #endif + #define INTERRUPT _RAW __interrupt + #define MONITOR __monitor + #define NO_INIT __no_init + #define INTERRUPTS_ENABLE() __enable_interrupt() + #define INTERRUPTS_DISABLE() __disable_interrupt() + #define NO_OPERATION() __no_operation() + + #ifndef DEBUG + // Force inlining of function in release builds + #define INLINE_FUNC PRAGMA(inline=forced) + #else + // Do not force inlining of function in debug builds + #define INLINE_FUNC + #endif + + #if (!defined CODECHECK) && (!defined __DA_C__) + // Define to a new way of using #pragmas in preprocessor + #define PRAGMA(x) _Pragma(#x) + #define ISR(x) PRAGMA(vector = (x)) INTERRUPT + #endif + + #if ((_IAR_TID_) == 43) + // Found Texas Instruments MSP430 CPU (V2) + #define _CPU_TID_ _TI_MSP430_ + #define _CPU_DIRECTION_OUT_1_ TRUE + #define _CPU_EDGE_HIGH_LOW_1_ TRUE + #define _CPU_64BIT_INT_ long long + #if __VER__ < 220 + // WA for HW bug, add a nop after DINT, Compiler has a bugfix since version 2.20 + #undef INTERRUPTS_DISABLE + #define INTERRUPTS_DISABLE() { __disable_interrupt(); __no_operation(); } + #endif + + #else + #error "Unknown new IAR Compiler, the file bm.h has to be expanded !" + #endif + + +#elif defined __CCE__ + // Found CCE Compiler + #define INTERRUPT __interrupt + #define MONITOR // __monitor + #define NO_INIT __no_init + #define INTERRUPTS_ENABLE() __enable_interrupt() + #define INTERRUPTS_DISABLE() __disable_interrupt() + #define NO_OPERATION() __no_operation() + + #ifndef DEBUG + // Force inlining of function in release builds + #define INLINE_FUNC PRAGMA(inline=forced) + #else + // Do not force inlining of function in debug builds + #define INLINE_FUNC + #endif + + // Found Texas Instruments MSP430 CPU (V2) + #define _CPU_TID_ _TI_MSP430_ + #define _CPU_DIRECTION_OUT_1_ TRUE + #define _CPU_EDGE_HIGH_LOW_1_ TRUE + //#define _CPU_64BIT_INT_ long long + +// #endif + +#else + #error "Unknown Compiler, the file bm.h has to be expanded !" +#endif + + +#ifndef _ASSEMBLER_USED_ + // Get the limits to autodetect the size of integral types + #include + // Get floats to autodetect the size of float types + #include + + // *********************************************************************************************** + // + // Common basic data types + // + // *********************************************************************************************** + #if UCHAR_MAX == 0xFFu + #define _CPU_8BIT_INT_ char + #else + #error "unable to get size of u8 automatically" + #endif + + #if USHRT_MAX == 0xFFFFu + #define _CPU_16BIT_INT_ short + #elif UINT_MAX == 0xFFFFu + #define _CPU_16BIT_INT_ int + #else + #error "unable to get size of u16 automatically" + #endif + + #if USHRT_MAX == 0xFFFFFFFFu + #define _CPU_32BIT_INT_ short + #elif UINT_MAX == 0xFFFFFFFFu + #define _CPU_32BIT_INT_ int + #elif ULONG_MAX == 0xFFFFFFFFu + #define _CPU_32BIT_INT_ long + #else + #error "unable to get size of u32 automatically" + #endif + + #ifdef __IAR_SYSTEMS_ICC__ + #if __IAR_SYSTEMS_ICC__ > 1 + #define _CPU_32BIT_FLOAT_ float + #if __DOUBLE_SIZE__ == 8 + #define _CPU_64BIT_FLOAT_ double + #endif + #endif + #endif + + #ifndef _CPU_32BIT_FLOAT_ + #if FLT_MANT_DIG == 24 + #define _CPU_32BIT_FLOAT_ float + #elif DBL_MANT_DIG == 24 + #define _CPU_32BIT_FLOAT_ double + #else + #error "unable to get size of f32 automatically" + #endif + + #if DBL_MANT_DIG == 53 + #define _CPU_64BIT_FLOAT_ double + #endif + #endif + + + // *********************************************************************************************** + // + // Following lines #typedef the basic data types in a compiler independent way. + // + // *********************************************************************************************** + + #ifdef _CPU_8BIT_INT_ + // unsigned 8 bit + typedef unsigned _CPU_8BIT_INT_ u8 ; + // unsigned 8 bit max value + #define U8_MAX (0xFFU) + // signed 8 bit max value + typedef signed _CPU_8BIT_INT_ s8 ; + // signed 8 bit min value + #define S8_MIN (-127 - 1) + // signed 8 bit max value + #define S8_MAX (127) + #endif + + #ifdef _CPU_16BIT_INT_ + // unsigned 16 bit + typedef unsigned _CPU_16BIT_INT_ u16 ; + // unsigned 16 bit max value + #define U16_MAX (0xFFFFU) + // signed 16 bit + typedef signed _CPU_16BIT_INT_ s16 ; + // signed 16 bit min value + #define S16_MIN (-32767 - 1) + // signed 16 bit max value + #define S16_MAX (32767) + #endif + + #ifdef _CPU_32BIT_INT_ + // unsigned 32 bit + typedef unsigned _CPU_32BIT_INT_ u32 ; + // unsigned 32 bit max value + #define U32_MAX (0xFFFFFFFFUL) + // signed 32 bit + typedef signed _CPU_32BIT_INT_ s32 ; + // signed 32 bit min value + #define S32_MIN (-2147483647L - 1L) + // signed 32 bit max value + #define S32_MAX (2147483647L) + #endif + + #ifdef _CPU_64BIT_INT_ + // unsigned 64 bit + typedef unsigned _CPU_64BIT_INT_ u64 ; + // signed 64 bit + typedef signed _CPU_64BIT_INT_ s64 ; + #endif + + #ifdef _CPU_32BIT_FLOAT_ + // float 32 bit + typedef _CPU_32BIT_FLOAT_ f32 ; + // number of digits in mantissa of f32 + #define F32_MANT_DIG (24) + // epsilon for f32 + #define F32_EPSILON (1.192092896e-07) + // number of digits of precision of f32 + #define F32_DIG (6) + // exponent min of f32 + #define F32_MIN_EXP (-125) + // min positive value of f32 + #define F32_MIN (1.175494351e-38) + // decimal exponent min of f32 + #define F32_MIN_10_EXP (-37) + // exponent max of f32 + #define F32_MAX_EXP (128) + // max value of f32 + #define F32_MAX (3.402823466e+38) + // decimal exponent max of f32 + #define F32_MAX_10_EXP (38) + #endif + + #ifdef _CPU_64BIT_FLOAT_ + // float 64 bit + typedef _CPU_64BIT_FLOAT_ f64 ; + // number of digits in mantissa of f64 + #define F64_MANT_DIG (53) + // epsilon for f64 + #define F64_EPSILON (2.2204460492503131e-016) + // number of digits of precision of f64 + #define F64_DIG (15) + // exponent min of f64 + #define F64_MIN_EXP (-1021) + // min positive value of f64 + #define F64_MIN (2.2250738585072014e-308) + // decimal exponent min of f64 + #define F64_MIN_10_EXP (-307) + // exponent max of f64 + #define F64_MAX_EXP (1024) + // max value of f64 + #define F64_MAX (1.7976931348623158e+308) + // decimal exponent max of f64 + #define F64_MAX_10_EXP (308) + #endif + + typedef unsigned char BYTE; + typedef unsigned int WORD; + typedef unsigned long DWORD; + +#endif // _ASSMEBLER_USED_ + +// A macro that calculates the number of bits of a given type +#ifndef BITSIZEOF +#define BITSIZEOF(type) (sizeof(type) * CHAR_BIT) +#endif + +/* A macro that generates a bit mask according to a given bit number. + * Example: + * - BIT(0) expands to 1 (== 0x01) + * - BIT(3) expands to 8 (== 0x08) + */ +#define BIT(x) (1uL << (x)) + +/* A macro that generates a bit mask according to a given bit number with a cast to type. + * The difference to BIT(X) is the additional type argument T that is used to cast the type of the + * constant 1 and the type of the result as well. + * Example: + * - BIT_T(u8,0) expands to (u8)1 (== 0x01) + * - BIT_T(u32,3) expands to (u32)8 (== 0x08L) + */ +#define BIT_T(t, x) ((t)((t)1 << (x))) + +/* A macro to calculate the position of the highest bit. + * The result is same as LOG2 in case only one bit is set. Use with constant values only because + * of code size. + */ +#define BIT_HIGHEST(Input_u32) ( \ + ( (Input_u32) & BIT(31) ) ? 31 : ( \ + ( (Input_u32) & BIT(30) ) ? 30 : ( \ + ( (Input_u32) & BIT(29) ) ? 29 : ( \ + ( (Input_u32) & BIT(28) ) ? 28 : ( \ + ( (Input_u32) & BIT(27) ) ? 27 : ( \ + ( (Input_u32) & BIT(26) ) ? 26 : ( \ + ( (Input_u32) & BIT(25) ) ? 25 : ( \ + ( (Input_u32) & BIT(24) ) ? 24 : ( \ + ( (Input_u32) & BIT(23) ) ? 23 : ( \ + ( (Input_u32) & BIT(22) ) ? 22 : ( \ + ( (Input_u32) & BIT(21) ) ? 21 : ( \ + ( (Input_u32) & BIT(20) ) ? 20 : ( \ + ( (Input_u32) & BIT(19) ) ? 19 : ( \ + ( (Input_u32) & BIT(18) ) ? 18 : ( \ + ( (Input_u32) & BIT(17) ) ? 17 : ( \ + ( (Input_u32) & BIT(16) ) ? 16 : ( \ + ( (Input_u32) & BIT(15) ) ? 15 : ( \ + ( (Input_u32) & BIT(14) ) ? 14 : ( \ + ( (Input_u32) & BIT(13) ) ? 13 : ( \ + ( (Input_u32) & BIT(12) ) ? 12 : ( \ + ( (Input_u32) & BIT(11) ) ? 11 : ( \ + ( (Input_u32) & BIT(10) ) ? 10 : ( \ + ( (Input_u32) & BIT( 9) ) ? 9 : ( \ + ( (Input_u32) & BIT( 8) ) ? 8 : ( \ + ( (Input_u32) & BIT( 7) ) ? 7 : ( \ + ( (Input_u32) & BIT( 6) ) ? 6 : ( \ + ( (Input_u32) & BIT( 5) ) ? 5 : ( \ + ( (Input_u32) & BIT( 4) ) ? 4 : ( \ + ( (Input_u32) & BIT( 3) ) ? 3 : ( \ + ( (Input_u32) & BIT( 2) ) ? 2 : ( \ + ( (Input_u32) & BIT( 1) ) ? 1 : ( \ + ( (Input_u32) & BIT( 0) ) ? 0 : -1uL )))))))))))))))))))))))))))))))) + + +#ifndef MONITOR + #define MONITOR +#endif + +#ifndef NO_INIT + #define NO_INIT +#endif + +#ifndef INTERRUPT + #define INTERRUPT +#endif + +#ifndef ISR + #define ISR(ignore) +#endif + +#ifndef INLINE_FUNC + #define INLINE_FUNC +#endif + +#ifndef INTERRUPTS_ENABLE + #define INTERRUPTS_ENABLE() +#endif + +#ifndef INTERRUPTS_DISABLE + #define INTERRUPTS_DISABLE() +#endif + + +#endif // __BM_H diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/change_record.txt b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/change_record.txt new file mode 100755 index 0000000..83d239d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/change_record.txt @@ -0,0 +1,35 @@ +V1.6 (21.11.2010) +Fixed following bugs +- rfsimpliciti.c/simpliciti_sync_decode_ap_cmd_callback(), +- timer.c/TIMER0_A0_ISR() LCD shows "done" after successfully received data +- main.c/wakeup_event(), +- rfbsl.c/sx_rfbsl() rfBSL requires two button presses in order to update watch +- timer.c/Timer0_A3_Start() Fixed register read (Asynchronous) +- timer.c/Timer0_A4_Delay() Fixed register read (Asynchronous) + Avoid unwanted flag changes caused by interrupt methods +- port.c/PORT2_ISR() and timer.c/TIMER0_A0_ISR() Changes the menu if the pressed time from STAR or NUM button are between "short(50ms)" and "long(3s)" + The backlight stays 3 seconds on +- display.c Removed file display1.c. The content is now in display.c +- display.h Fixed LCD_UNIT_L1_PER_S_MASK bit + +Other changes: +- DCO settling time Set to 375000 cycles + +__________________________________________________________________________________________________________________________________________________ +V1.5 (16.03.2010) +Fixed following bugs +- main.c/init_application() Changed XT1 drive level to highest to avoid ACLK noise when turning on backlight. +- main.c/wakeup_event(), timer.c/TIMER0_A0_ISR() Modified key lock procedure. +- vti_ps.c/ps_get_temp() Negative °C are now converted correctly to Kelvin + +Other changes +- main.c/read_calibration_values() Added range check for rf_frequoffset variable + Added bytes for altitude offset correction and s/w version +- altitude.h, altitude.c Added initial altitude offset correction +- SimpliciTI Added SimpliciTI sources to project. Upgraded to Version 1.1.1. +- RFBSL Added wireless update support +- Button names Changed button names from M1/M2/S1/S2/BL to STAR/NUM/UP/DOWN/BACKLIGHT + +__________________________________________________________________________________________________________________________________________________ +V1.4 (22.11.2009) +First version released to manufacturing. \ No newline at end of file diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/adc12.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/adc12.c new file mode 100755 index 0000000..07f13cc --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/adc12.c @@ -0,0 +1,164 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// ADC12 functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include + +// driver +#include "adc12.h" +#include "timer.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +u16 adc12_result; +u8 adc12_data_ready; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn adc12_single_conversion +// @brief Init ADC12. Do single conversion. Turn off ADC12. +// @param u16 ref Select reference +// u16 sht Sample-and-hold time +// u16 channel Channel of the conversion +// @return u16 adc12_result Return ADC result +// ************************************************************************************************* +u16 adc12_single_conversion(u16 ref, u16 sht, u16 channel) +{ + // Initialize the shared reference module + REFCTL0 |= REFMSTR + ref + REFON; // Enable internal reference (1.5V or 2.5V) + + // Initialize ADC12_A + ADC12CTL0 = sht + ADC12ON; // Set sample time + ADC12CTL1 = ADC12SHP; // Enable sample timer + ADC12MCTL0 = ADC12SREF_1 + channel; // ADC input channel + ADC12IE = 0x001; // ADC_IFG upon conv result-ADCMEMO + + // Wait 2 ticks (66us) to allow internal reference to settle + Timer0_A4_Delay(2); + + // Start ADC12 + ADC12CTL0 |= ADC12ENC; + + // Clear data ready flag + adc12_data_ready = 0; + + // Sampling and conversion start + ADC12CTL0 |= ADC12SC; + + // Delay to get next ADC value + Timer0_A4_Delay(5); + while (!adc12_data_ready) ; + + // Shut down ADC12 + ADC12CTL0 &= ~(ADC12ENC | ADC12SC | sht); + ADC12CTL0 &= ~ADC12ON; + + // Shut down reference voltage + REFCTL0 &= ~(REFMSTR + ref + REFON); + + ADC12IE = 0; + + // Return ADC result + return (adc12_result); +} + +// ************************************************************************************************* +// @fn ADC12ISR +// @brief Store ADC12 conversion result. Set flag to indicate data ready. +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=ADC12_VECTOR +__interrupt void ADC12ISR(void) +{ + switch (__even_in_range(ADC12IV, 34)) + { + case 0: + break; // Vector 0: No interrupt + case 2: + break; // Vector 2: ADC overflow + case 4: + break; // Vector 4: ADC timing overflow + case 6: // Vector 6: ADC12IFG0 + adc12_result = ADC12MEM0; // Move results, IFG is cleared + adc12_data_ready = 1; + _BIC_SR_IRQ(LPM3_bits); // Exit active CPU + break; + case 8: + break; // Vector 8: ADC12IFG1 + case 10: + break; // Vector 10: ADC12IFG2 + case 12: + break; // Vector 12: ADC12IFG3 + case 14: + break; // Vector 14: ADC12IFG4 + case 16: + break; // Vector 16: ADC12IFG5 + case 18: + break; // Vector 18: ADC12IFG6 + case 20: + break; // Vector 20: ADC12IFG7 + case 22: + break; // Vector 22: ADC12IFG8 + case 24: + break; // Vector 24: ADC12IFG9 + case 26: + break; // Vector 26: ADC12IFG10 + case 28: + break; // Vector 28: ADC12IFG11 + case 30: + break; // Vector 30: ADC12IFG12 + case 32: + break; // Vector 32: ADC12IFG13 + case 34: + break; // Vector 34: ADC12IFG14 + default: + break; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/adc12.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/adc12.h new file mode 100755 index 0000000..90fc327 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/adc12.h @@ -0,0 +1,57 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ADC12_H_ +#define ADC12_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern u16 adc12_single_conversion(u16 ref, u16 sht, u16 channel); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +extern u16 adc12_result; +extern u8 adc12_data_ready; + +// ************************************************************************************************* +// Extern section + +#endif /*ADC12_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/buzzer.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/buzzer.c new file mode 100755 index 0000000..ec5df8b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/buzzer.c @@ -0,0 +1,220 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Buzzer functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "buzzer.h" +#include "timer.h" +#include "display.h" + +// logic + +// ************************************************************************************************* +// Prototypes section +void toggle_buzzer(void); +void countdown_buzzer(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct buzzer sBuzzer; + +// ************************************************************************************************* +// Extern section +//extern u16 timer0_A3_ticks_g; + +// ************************************************************************************************* +// @fn reset_buzzer +// @brief Init buzzer variables +// @param none +// @return none +// ************************************************************************************************* +void reset_buzzer(void) +{ + sBuzzer.time = 0; + sBuzzer.state = BUZZER_OFF; +} + +// ************************************************************************************************* +// @fn start_buzzer +// @brief Start buzzer output for a number of cylces +// @param u8 cycles Keep buzzer output for number of cycles +// u16 on_time Output buzzer for "on_time" ACLK ticks +// u16 off_time Do not output buzzer for "off_time" ACLK ticks +// @return none +// ************************************************************************************************* +void start_buzzer(u8 cycles, u16 on_time, u16 off_time) +{ + // Store new buzzer duration while buzzer is off + if (sBuzzer.time == 0) + { + sBuzzer.time = cycles; + sBuzzer.on_time = on_time; + sBuzzer.off_time = off_time; + + // Need to init every time, because SimpliciTI claims same timer + + // Reset TA1R, set up mode, TA1 runs from 32768Hz ACLK + TA1CTL = TACLR | MC_1 | TASSEL__ACLK; + + // Set PWM frequency + TA1CCR0 = BUZZER_TIMER_STEPS; + + // Enable IRQ, set output mode "toggle" + TA1CCTL0 = OUTMOD_4; + + // Allow buzzer PWM output on P2.7 + P2SEL |= BIT7; + + // Activate Timer0_A3 periodic interrupts + fptr_Timer0_A3_function = toggle_buzzer; + Timer0_A3_Start(sBuzzer.on_time); + + // Preload timer advance variable + sTimer.timer0_A3_ticks = sBuzzer.off_time; + + // Start with buzzer output on + sBuzzer.state = BUZZER_ON_OUTPUT_ENABLED; + } +} + +// ************************************************************************************************* +// @fn toggle_buzzer +// @brief Keeps track of buzzer on/off duty cycle +// @param none +// @return none +// ************************************************************************************************* +void toggle_buzzer(void) +{ + // Turn off buzzer + if (sBuzzer.state == BUZZER_ON_OUTPUT_ENABLED) + { + // Stop PWM timer + TA1CTL &= ~(BIT4 | BIT5); + + // Reset and disable buzzer PWM output + P2OUT &= ~BIT7; + P2SEL &= ~BIT7; + + // Update buzzer state + sBuzzer.state = BUZZER_ON_OUTPUT_DISABLED; + + // Reload Timer0_A4 IRQ to restart output + sTimer.timer0_A3_ticks = sBuzzer.on_time; + } + else // Turn on buzzer + { + // Decrement buzzer total cycles + countdown_buzzer(); + + // Reload Timer0_A4 to stop output if sBuzzer.time > 0 + if (sBuzzer.state != BUZZER_OFF) + { + // Reset timer TA1 + TA1R = 0; + TA1CTL |= MC_1; + + // Enable buzzer PWM output + P2SEL |= BIT7; + + // Update buzzer state + sBuzzer.state = BUZZER_ON_OUTPUT_ENABLED; + + // Reload Timer0_A4 IRQ to turn off output + sTimer.timer0_A3_ticks = sBuzzer.off_time; + } + } +} + +// ************************************************************************************************* +// @fn stop_buzzer +// @brief Stop buzzer output +// @param none +// @return none +// ************************************************************************************************* +void stop_buzzer(void) +{ + // Stop PWM timer + TA1CTL &= ~(BIT4 | BIT5); + + // Disable buzzer PWM output + P2OUT &= ~BIT7; + P2SEL &= ~BIT7; + + // Clear PWM timer interrupt + TA1CCTL0 &= ~CCIE; + + // Disable periodic start/stop interrupts + Timer0_A3_Stop(); + + // Clear variables + reset_buzzer(); +} + +// ************************************************************************************************* +// @fn is_buzzer +// @brief Check if buzzer is operating +// @param none +// @return u8 1 = Buzzer is operating, 0 = Buzzer is off +// ************************************************************************************************* +u8 is_buzzer(void) +{ + return (sBuzzer.state != BUZZER_OFF); +} + +// ************************************************************************************************* +// @fn countdown_buzzer +// @brief Decrement active buzzer time. Turn off buzzer if cycle end reached. +// @param none +// @return none +// ************************************************************************************************* +void countdown_buzzer(void) +{ + // Stop buzzer when reaching 0 cycles + if (--sBuzzer.time == 0) + { + stop_buzzer(); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/buzzer.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/buzzer.h new file mode 100755 index 0000000..59fbba9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/buzzer.h @@ -0,0 +1,87 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BUZZER_H_ +#define BUZZER_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_buzzer(void); +extern void start_buzzer(u8 cycles, u16 on_time, u16 off_time); +extern void stop_buzzer(void); +extern void toggle_buzzer(void); +extern u8 is_buzzer(void); +extern void countdown_buzzer(void); + +// ************************************************************************************************* +// Defines section + +// Buzzer states +#define BUZZER_OFF (0u) +#define BUZZER_ON_OUTPUT_DISABLED (1u) +#define BUZZER_ON_OUTPUT_ENABLED (2u) + +// Buzzer output signal frequency = 32,768kHz/(BUZZER_TIMER_STEPS+1)/2 = 2.7kHz +#define BUZZER_TIMER_STEPS (5u) + +// Buzzer on time +#define BUZZER_ON_TICKS (CONV_MS_TO_TICKS(20)) + +// Buzzer off time +#define BUZZER_OFF_TICKS (CONV_MS_TO_TICKS(200)) + +// ************************************************************************************************* +// Global Variable section +struct buzzer +{ + // Keep output for "time" seconds + u8 time; + + // On/off duty + u16 on_time; + u16 off_time; + + // Current buzzer output state + u8 state; +}; +extern struct buzzer sBuzzer; + +// ************************************************************************************************* +// Extern section + +#endif /*BUZZER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/display.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/display.c new file mode 100755 index 0000000..c249f04 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/display.c @@ -0,0 +1,759 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Display functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include +#include + +// driver +#include "display.h" + +// logic +#include "clock.h" +#include "user.h" +#include "date.h" +#include "temperature.h" + +// ************************************************************************************************* +// Prototypes section +void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state); +void clear_line(u8 line); +void display_symbol(u8 symbol, u8 mode); +void display_char(u8 segment, u8 chr, u8 mode); +void display_chars(u8 segments, u8 * str, u8 mode); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// Table with memory bit assignment for digits "0" to "9" and characters "A" to "Z" +const u8 lcd_font[] = { + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F, // Displays "0" + SEG_B + SEG_C, // Displays "1" + SEG_A + SEG_B + SEG_D + SEG_E + SEG_G, // Displays "2" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_G, // Displays "3" + SEG_B + SEG_C + SEG_F + SEG_G, // Displays "4" + SEG_A + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "5" + SEG_A + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "6" + SEG_A + SEG_B + SEG_C, // Displays "7" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "8" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "9" + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + SEG_D + SEG_E + SEG_G, // Displays "c" + 0, // Displays " " + SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G, // Displays "A" + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "b" + SEG_A + SEG_D + SEG_E + SEG_F, // Displays "C" + SEG_B + SEG_C + SEG_D + SEG_E + SEG_G, // Displays "d" + SEG_A + +SEG_D + SEG_E + SEG_F + SEG_G, // Displays "E" + SEG_A + SEG_E + SEG_F + SEG_G, // Displays "F" + // SEG_A+ SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "G" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "g" + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G, // Displays "H" + SEG_E + SEG_F, // Displays "I" + SEG_A + SEG_B + SEG_C + SEG_D, // Displays "J" + // SEG_B+SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "k" + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "k" + SEG_D + SEG_E + SEG_F, // Displays "L" + SEG_A + SEG_B + SEG_C + SEG_E + SEG_F, // Displays "M" + SEG_C + SEG_E + SEG_G, // Displays "n" + SEG_C + SEG_D + SEG_E + SEG_G, // Displays "o" + SEG_A + SEG_B + SEG_E + SEG_F + SEG_G, // Displays "P" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F, // Displays "Q" + SEG_E + SEG_G, // Displays "r" + SEG_A + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "S" + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "t" + SEG_C + SEG_D + SEG_E, // Displays "u" + SEG_C + SEG_D + SEG_E, // Displays "u" + SEG_G, // Displays "-" + SEG_B + SEG_C + +SEG_E + SEG_F + SEG_G, // Displays "X" + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "Y" + SEG_A + SEG_B + SEG_D + SEG_E + SEG_G, // Displays "Z" +}; + +// Table with memory address for each display element +const u8 *segments_lcdmem[] = { + LCD_SYMB_AM_MEM, + LCD_SYMB_PM_MEM, + LCD_SYMB_ARROW_UP_MEM, + LCD_SYMB_ARROW_DOWN_MEM, + LCD_SYMB_PERCENT_MEM, + LCD_SYMB_TOTAL_MEM, + LCD_SYMB_AVERAGE_MEM, + LCD_SYMB_MAX_MEM, + LCD_SYMB_BATTERY_MEM, + LCD_UNIT_L1_FT_MEM, + LCD_UNIT_L1_K_MEM, + LCD_UNIT_L1_M_MEM, + LCD_UNIT_L1_I_MEM, + LCD_UNIT_L1_PER_S_MEM, + LCD_UNIT_L1_PER_H_MEM, + LCD_UNIT_L1_DEGREE_MEM, + LCD_UNIT_L2_KCAL_MEM, + LCD_UNIT_L2_KM_MEM, + LCD_UNIT_L2_MI_MEM, + LCD_ICON_HEART_MEM, + LCD_ICON_STOPWATCH_MEM, + LCD_ICON_RECORD_MEM, + LCD_ICON_ALARM_MEM, + LCD_ICON_BEEPER1_MEM, + LCD_ICON_BEEPER2_MEM, + LCD_ICON_BEEPER3_MEM, + LCD_SEG_L1_3_MEM, + LCD_SEG_L1_2_MEM, + LCD_SEG_L1_1_MEM, + LCD_SEG_L1_0_MEM, + LCD_SEG_L1_COL_MEM, + LCD_SEG_L1_DP1_MEM, + LCD_SEG_L1_DP0_MEM, + LCD_SEG_L2_5_MEM, + LCD_SEG_L2_4_MEM, + LCD_SEG_L2_3_MEM, + LCD_SEG_L2_2_MEM, + LCD_SEG_L2_1_MEM, + LCD_SEG_L2_0_MEM, + LCD_SEG_L2_COL1_MEM, + LCD_SEG_L2_COL0_MEM, + LCD_SEG_L2_DP_MEM, +}; + +// Table with bit mask for each display element +const u8 segments_bitmask[] = { + LCD_SYMB_AM_MASK, + LCD_SYMB_PM_MASK, + LCD_SYMB_ARROW_UP_MASK, + LCD_SYMB_ARROW_DOWN_MASK, + LCD_SYMB_PERCENT_MASK, + LCD_SYMB_TOTAL_MASK, + LCD_SYMB_AVERAGE_MASK, + LCD_SYMB_MAX_MASK, + LCD_SYMB_BATTERY_MASK, + LCD_UNIT_L1_FT_MASK, + LCD_UNIT_L1_K_MASK, + LCD_UNIT_L1_M_MASK, + LCD_UNIT_L1_I_MASK, + LCD_UNIT_L1_PER_S_MASK, + LCD_UNIT_L1_PER_H_MASK, + LCD_UNIT_L1_DEGREE_MASK, + LCD_UNIT_L2_KCAL_MASK, + LCD_UNIT_L2_KM_MASK, + LCD_UNIT_L2_MI_MASK, + LCD_ICON_HEART_MASK, + LCD_ICON_STOPWATCH_MASK, + LCD_ICON_RECORD_MASK, + LCD_ICON_ALARM_MASK, + LCD_ICON_BEEPER1_MASK, + LCD_ICON_BEEPER2_MASK, + LCD_ICON_BEEPER3_MASK, + LCD_SEG_L1_3_MASK, + LCD_SEG_L1_2_MASK, + LCD_SEG_L1_1_MASK, + LCD_SEG_L1_0_MASK, + LCD_SEG_L1_COL_MASK, + LCD_SEG_L1_DP1_MASK, + LCD_SEG_L1_DP0_MASK, + LCD_SEG_L2_5_MASK, + LCD_SEG_L2_4_MASK, + LCD_SEG_L2_3_MASK, + LCD_SEG_L2_2_MASK, + LCD_SEG_L2_1_MASK, + LCD_SEG_L2_0_MASK, + LCD_SEG_L2_COL1_MASK, + LCD_SEG_L2_COL0_MASK, + LCD_SEG_L2_DP_MASK, +}; + +// Quick integer to array conversion table for most common integer values +const u8 int_to_array_conversion_table[][3] = { + "000", "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", + "013", "014", "015", + "016", "017", "018", "019", "020", "021", "022", "023", "024", "025", "026", "027", "028", + "029", "030", "031", + "032", "033", "034", "035", "036", "037", "038", "039", "040", "041", "042", "043", "044", + "045", "046", "047", + "048", "049", "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", "060", + "061", "062", "063", + "064", "065", "066", "067", "068", "069", "070", "071", "072", "073", "074", "075", "076", + "077", "078", "079", + "080", "081", "082", "083", "084", "085", "086", "087", "088", "089", "090", "091", "092", + "093", "094", "095", + "096", "097", "098", "099", "100", "101", "102", "103", "104", "105", "106", "107", "108", + "109", "110", "111", + "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", + "125", "126", "127", + "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", + "141", "142", "143", + "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", + "157", "158", "159", + "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", + "173", "174", "175", + "176", "177", "178", "179", "180", +}; + +// Display flags +volatile s_display_flags display; + +// Global return string for int_to_array function +u8 int_to_array_str[8]; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); +extern void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn lcd_init +// @brief Erase LCD memory. Init LCD peripheral. +// @param none +// @return none +// ************************************************************************************************* +void lcd_init(void) +{ + // Clear entire display memory + LCDBMEMCTL |= LCDCLRBM + LCDCLRM; + + // LCD_FREQ = ACLK/16/8 = 256Hz + // Frame frequency = 256Hz/4 = 64Hz, LCD mux 4, LCD on + LCDBCTL0 = (LCDDIV0 + LCDDIV1 + LCDDIV2 + LCDDIV3) | (LCDPRE0 + LCDPRE1) | LCD4MUX | LCDON; + + // LCB_BLK_FREQ = ACLK/8/4096 = 1Hz + LCDBBLKCTL = LCDBLKPRE0 | LCDBLKPRE1 | LCDBLKDIV0 | LCDBLKDIV1 | LCDBLKDIV2 | LCDBLKMOD0; + + // I/O to COM outputs + P5SEL |= (BIT5 | BIT6 | BIT7); + P5DIR |= (BIT5 | BIT6 | BIT7); + + // Activate LCD output + LCDBPCTL0 = 0xFFFF; // Select LCD segments S0-S15 + LCDBPCTL1 = 0x00FF; // Select LCD segments S16-S22 + +#ifdef USE_LCD_CHARGE_PUMP + // Charge pump voltage generated internally, internal bias (V2-V4) generation + LCDBVCTL = LCDCPEN | VLCD_2_72; +#endif +} + +// ************************************************************************************************* +// @fn clear_display_all +// @brief Erase LINE1 and LINE2 segments. Clear also function-specific content. +// @param none +// @return none +// ************************************************************************************************* +void clear_display_all(void) +{ + // Clear generic content + clear_line(LINE1); + clear_line(LINE2); + + // Clean up function-specific content + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_CLEAR); + +} + +// ************************************************************************************************* +// @fn clear_display +// @brief Erase LINE1 and LINE2 segments. Keep icons. +// @param none +// @return none +// ************************************************************************************************* +void clear_display(void) +{ + clear_line(LINE1); + clear_line(LINE2); +} + +// ************************************************************************************************* +// @fn clear_line +// @brief Erase segments of a given line. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void clear_line(u8 line) +{ + display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_5_0), NULL, SEG_OFF); + if (line == LINE1) + { + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + display_symbol(LCD_SEG_L1_DP0, SEG_OFF); + display_symbol(LCD_SEG_L1_COL, SEG_OFF); + } + else // line == LINE2 + { + display_symbol(LCD_SEG_L2_DP, SEG_OFF); + display_symbol(LCD_SEG_L2_COL1, SEG_OFF); + display_symbol(LCD_SEG_L2_COL0, SEG_OFF); + } +} + +// ************************************************************************************************* +// @fn write_segment +// @brief Write to one or multiple LCD segments +// @param lcdmem Pointer to LCD byte memory +// bits Segments to address +// bitmask Bitmask for particular display item +// mode On, off or blink segments +// @return +// ************************************************************************************************* +void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state) +{ + if (state == SEG_ON) + { + // Clear segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (u8) (*lcdmem | bits); + } + else if (state == SEG_OFF) + { + // Clear segments + *lcdmem = (u8) (*lcdmem & ~bitmask); + } + else if (state == SEG_ON_BLINK_ON) + { + // Clear visible / blink segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + + // Set visible / blink segments + *lcdmem = (u8) (*lcdmem | bits); + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) | bits); + } + else if (state == SEG_ON_BLINK_OFF) + { + // Clear visible segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (u8) (*lcdmem | bits); + + // Clear blink segments + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + } + else if (state == SEG_OFF_BLINK_OFF) + { + // Clear segments + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Clear blink segments + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + } +} + +// ************************************************************************************************* +// @fn int_to_array +// @brief Generic integer to array routine. Converts integer n to string. +// Default conversion result has leading zeros, e.g. "00123" +// Option to convert leading '0' into whitespace (blanks) +// @param u32 n integer to convert +// u8 digits number of digits +// u8 blanks fill up result string with number of +// whitespaces instead of leading zeros +// @return u8 string +// ************************************************************************************************* +u8 *int_to_array(u32 n, u8 digits, u8 blanks) +{ + u8 i; + u8 digits1 = digits; + + // Preset result string + memcpy(int_to_array_str, "0000000", 7); + + // Return empty string if number of digits is invalid (valid range for digits: 1-7) + if ((digits == 0) || (digits > 7)) + return (int_to_array_str); + + // Numbers 0 .. 180 can be copied from int_to_array_conversion_table without conversion + if (n <= 180) + { + if (digits >= 3) + { + memcpy(int_to_array_str + (digits - 3), int_to_array_conversion_table[n], 3); + } + else // digits == 1 || 2 + { + memcpy(int_to_array_str, int_to_array_conversion_table[n] + (3 - digits), digits); + } + } + else // For n > 180 need to calculate string content + { + // Calculate digits from least to most significant number + do + { + int_to_array_str[digits - 1] = n % 10 + '0'; + n /= 10; + } + while (--digits > 0); + } + + // Remove specified number of leading '0', always keep last one + i = 0; + while ((int_to_array_str[i] == '0') && (i < digits1 - 1)) + { + if (blanks > 0) + { + // Convert only specified number of leading '0' + int_to_array_str[i] = ' '; + blanks--; + } + i++; + } + + return (int_to_array_str); +} + +// ************************************************************************************************* +// @fn display_value +// @brief Generic decimal display routine. Used exclusively by set_value function. +// @param u8 segments LCD segments where value is displayed +// u32 value Integer value to be displayed +// u8 digits Number of digits to convert +// u8 blanks Number of leadings blanks in +// int_to_array result string +// @return none +// ************************************************************************************************* +void display_value(u8 segments, u32 value, u8 digits, u8 blanks) +{ + u8 *str; + + str = int_to_array(value, digits, blanks); + + // Display string in blink mode + display_chars(segments, str, SEG_ON_BLINK_ON); +} + +// ************************************************************************************************* +// @fn display_hours +// @brief Display hours in 24H / 12H time format. +// @param u8 segments Segments where to display hour data +// u32 value Hour data +// u8 digits Must be "2" +// u8 blanks Must be "0" +// @return none +// ************************************************************************************************* +void display_hours(u8 segments, u32 value, u8 digits, u8 blanks) +{ + u8 hours; + + if (sys.flag.use_metric_units) + { + // Display hours in 24H time format + display_value(segments, (u16) value, digits, blanks); + } + else + { + // convert internal 24H time format to 12H time format + hours = convert_hour_to_12H_format(value); + + // display hours in 12H time format + display_value(segments, hours, digits, blanks); + display_am_pm_symbol(value); + } +} + +// ************************************************************************************************* +// @fn display_am_pm_symbol +// @brief Display AM or PM symbol. +// @param u8 hour 24H internal time format +// @return none +// ************************************************************************************************* +void display_am_pm_symbol(u8 hour) +{ + // Display AM/PM symbol + if (is_hour_am(hour)) + { + display_symbol(LCD_SYMB_AM, SEG_ON); + } + else + { + // Clear AM segments first - required when changing from AM to PM + display_symbol(LCD_SYMB_AM, SEG_OFF); + display_symbol(LCD_SYMB_PM, SEG_ON); + } +} + +// ************************************************************************************************* +// @fn display_symbol +// @brief Switch symbol on or off on LCD. +// @param u8 symbol A valid LCD symbol (index 0..42) +// u8 state SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_symbol(u8 symbol, u8 mode) +{ + u8 *lcdmem; + u8 bits; + u8 bitmask; + + if (symbol <= LCD_SEG_L2_DP) + { + // Get LCD memory address for symbol from table + lcdmem = (u8 *) segments_lcdmem[symbol]; + + // Get bits for symbol from table + bits = segments_bitmask[symbol]; + + // Bitmask for symbols equals bits + bitmask = bits; + + // Write LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + +// ************************************************************************************************* +// @fn display_char +// @brief Write to 7-segment characters. +// @param u8 segment A valid LCD segment +// u8 chr Character to display +// u8 mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_char(u8 segment, u8 chr, u8 mode) +{ + u8 *lcdmem; // Pointer to LCD memory + u8 bitmask; // Bitmask for character + u8 bits, bits1; // Bits to write + + // Write to single 7-segment character + if ((segment >= LCD_SEG_L1_3) && (segment <= LCD_SEG_L2_DP)) + { + // Get LCD memory address for segment from table + lcdmem = (u8 *) segments_lcdmem[segment]; + + // Get bitmask for character from table + bitmask = segments_bitmask[segment]; + + // Get bits from font set + if ((chr >= 0x30) && (chr <= 0x5A)) + { + // Use font set + bits = lcd_font[chr - 0x30]; + } + else if (chr == 0x2D) + { + // '-' not in font set + bits = BIT1; + } + else + { + // Other characters map to ' ' (blank) + bits = 0; + } + + // When addressing LINE2 7-segment characters need to swap high- and low-nibble, + // because LCD COM/SEG assignment is mirrored against LINE1 + if (segment >= LCD_SEG_L2_5) + { + bits1 = ((bits << 4) & 0xF0) | ((bits >> 4) & 0x0F); + bits = bits1; + + // When addressing LCD_SEG_L2_5, need to convert ASCII '1' and 'L' to 1 bit, + // because LCD COM/SEG assignment is special for this incomplete character + if (segment == LCD_SEG_L2_5) + { + if ((chr == '1') || (chr == 'L')) + bits = BIT7; + } + } + + // Physically write to LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + +// ************************************************************************************************* +// @fn display_chars +// @brief Write to consecutive 7-segment characters. +// @param u8 segments LCD segment array +// u8 * str Pointer to a string +// u8 mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_chars(u8 segments, u8 * str, u8 mode) +{ + u8 i; + u8 length = 0; // Write length + u8 char_start; // Starting point for consecutive write + + switch (segments) + { + // LINE1 + case LCD_SEG_L1_3_0: + length = 4; + char_start = LCD_SEG_L1_3; + break; + case LCD_SEG_L1_2_0: + length = 3; + char_start = LCD_SEG_L1_2; + break; + case LCD_SEG_L1_1_0: + length = 2; + char_start = LCD_SEG_L1_1; + break; + case LCD_SEG_L1_3_1: + length = 3; + char_start = LCD_SEG_L1_3; + break; + case LCD_SEG_L1_3_2: + length = 2; + char_start = LCD_SEG_L1_3; + break; + + // LINE2 + case LCD_SEG_L2_5_0: + length = 6; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_4_0: + length = 5; + char_start = LCD_SEG_L2_4; + break; + case LCD_SEG_L2_3_0: + length = 4; + char_start = LCD_SEG_L2_3; + break; + case LCD_SEG_L2_2_0: + length = 3; + char_start = LCD_SEG_L2_2; + break; + case LCD_SEG_L2_1_0: + length = 2; + char_start = LCD_SEG_L2_1; + break; + case LCD_SEG_L2_5_4: + length = 2; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_5_2: + length = 4; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_3_2: + length = 2; + char_start = LCD_SEG_L2_3; + break; + case LCD_SEG_L2_4_2: + length = 3; + char_start = LCD_SEG_L2_4; + break; + } + + // Write to consecutive digits + for (i = 0; i < length; i++) + { + // Use single character routine to write display memory + display_char(char_start + i, *(str + i), mode); + } +} + +// ************************************************************************************************* +// @fn switch_seg +// @brief Returns index of 7-segment character. Required for display routines that can draw +// information on both lines. +// @param u8 line LINE1 or LINE2 +// u8 index1 Index of LINE1 +// u8 index2 Index of LINE2 +// @return uint8 +// ************************************************************************************************* +u8 switch_seg(u8 line, u8 index1, u8 index2) +{ + if (line == LINE1) + { + return index1; + } + else // line == LINE2 + { + return index2; + } +} + +// ************************************************************************************************* +// @fn start_blink +// @brief Start blinking. +// @param none +// @return none +// ************************************************************************************************* +void start_blink(void) +{ + LCDBBLKCTL |= LCDBLKMOD0; +} + +// ************************************************************************************************* +// @fn stop_blink +// @brief Stop blinking. +// @param none +// @return none +// ************************************************************************************************* +void stop_blink(void) +{ + LCDBBLKCTL &= ~LCDBLKMOD0; +} + +// ************************************************************************************************* +// @fn stop_blink +// @brief Clear blinking memory. +// @param none +// @return none +// ************************************************************************************************* +void clear_blink_mem(void) +{ + LCDBMEMCTL |= LCDCLRBM; +} + +// ************************************************************************************************* +// @fn set_blink_rate +// @brief Set blink rate register bits. +// @param none +// @return none +// ************************************************************************************************* +void set_blink_rate(u8 bits) +{ + LCDBBLKCTL &= ~(BIT7 | BIT6 | BIT5); + LCDBBLKCTL |= bits; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/display.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/display.h new file mode 100755 index 0000000..044c3bd --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/display.h @@ -0,0 +1,338 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef __DISPLAY_H +#define __DISPLAY_H + +// ************************************************************************************************* +// Include section + +#include + +// ************************************************************************************************* +// Extern section + +// Constants defined in library +extern const u8 lcd_font[]; +extern const u8 *segments_lcdmem[]; +extern const u8 segments_bitmask[]; +extern const u8 int_to_array_conversion_table[][3]; + +// ************************************************************************************************* +// Global Variable section + +// Set of display flags +typedef union +{ + struct + { + // Line1 + Line2 + Icons + u16 full_update : 1; // 1 = Redraw all content + u16 partial_update : 1; // 1 = Update changes + + // Line only + u16 line1_full_update : 1; // 1 = Redraw Line1 content + u16 line2_full_update : 1; // 1 = Redraw Line2 content + + // Logic module data update flags + u16 update_time : 1; // 1 = Time was updated + u16 update_stopwatch : 1; // 1 = Stopwatch was updated + u16 update_temperature : 1; // 1 = Temperature was updated + u16 update_battery_voltage : 1; // 1 = Battery voltage was updated + u16 update_date : 1; // 1 = Date was updated + u16 update_alarm : 1; // 1 = Alarm time was updated + u16 update_acceleration : 1; // 1 = Acceleration data was updated + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_display_flags; +extern volatile s_display_flags display; + +// ************************************************************************************************* +// Defines section + +// Display function modes +#define DISPLAY_LINE_UPDATE_FULL (BIT0) +#define DISPLAY_LINE_UPDATE_PARTIAL (BIT1) +#define DISPLAY_LINE_CLEAR (BIT2) + +// Definitions for line view style +#define DISPLAY_DEFAULT_VIEW (0u) +#define DISPLAY_ALTERNATIVE_VIEW (1u) + +// Definitions for line access +#define LINE1 (1u) +#define LINE2 (2u) + +// LCD display modes +#define SEG_OFF (0u) +#define SEG_ON (1u) +#define SEG_ON_BLINK_ON (2u) +#define SEG_ON_BLINK_OFF (3u) +#define SEG_OFF_BLINK_OFF (4u) + +// 7-segment character bit assignments +#define SEG_A (BIT4) +#define SEG_B (BIT5) +#define SEG_C (BIT6) +#define SEG_D (BIT7) +#define SEG_E (BIT2) +#define SEG_F (BIT0) +#define SEG_G (BIT1) + +// ------------------------------------------ +// LCD symbols for easier access +// +// xxx_SEG_xxx = Seven-segment character (sequence 5-4-3-2-1-0) +// xxx_SYMB_xxx = Display symbol, e.g. "AM" for ante meridiem +// xxx_UNIT_xxx = Display unit, e.g. "km/h" for kilometers per hour +// xxx_ICON_xxx = Display icon, e.g. heart to indicate reception of heart rate data +// xxx_L1_xxx = Item is part of Line1 information +// xxx_L2_xxx = Item is part of Line2 information + +// Symbols for Line1 +#define LCD_SYMB_AM 0 +#define LCD_SYMB_PM 1 +#define LCD_SYMB_ARROW_UP 2 +#define LCD_SYMB_ARROW_DOWN 3 +#define LCD_SYMB_PERCENT 4 + +// Symbols for Line2 +#define LCD_SYMB_TOTAL 5 +#define LCD_SYMB_AVERAGE 6 +#define LCD_SYMB_MAX 7 +#define LCD_SYMB_BATTERY 8 + +// Units for Line1 +#define LCD_UNIT_L1_FT 9 +#define LCD_UNIT_L1_K 10 +#define LCD_UNIT_L1_M 11 +#define LCD_UNIT_L1_I 12 +#define LCD_UNIT_L1_PER_S 13 +#define LCD_UNIT_L1_PER_H 14 +#define LCD_UNIT_L1_DEGREE 15 + +// Units for Line2 +#define LCD_UNIT_L2_KCAL 16 +#define LCD_UNIT_L2_KM 17 +#define LCD_UNIT_L2_MI 18 + +// Icons +#define LCD_ICON_HEART 19 +#define LCD_ICON_STOPWATCH 20 +#define LCD_ICON_RECORD 21 +#define LCD_ICON_ALARM 22 +#define LCD_ICON_BEEPER1 23 +#define LCD_ICON_BEEPER2 24 +#define LCD_ICON_BEEPER3 25 + +// Line1 7-segments +#define LCD_SEG_L1_3 26 +#define LCD_SEG_L1_2 27 +#define LCD_SEG_L1_1 28 +#define LCD_SEG_L1_0 29 +#define LCD_SEG_L1_COL 30 +#define LCD_SEG_L1_DP1 31 +#define LCD_SEG_L1_DP0 32 + +// Line2 7-segments +#define LCD_SEG_L2_5 33 +#define LCD_SEG_L2_4 34 +#define LCD_SEG_L2_3 35 +#define LCD_SEG_L2_2 36 +#define LCD_SEG_L2_1 37 +#define LCD_SEG_L2_0 38 +#define LCD_SEG_L2_COL1 39 +#define LCD_SEG_L2_COL0 40 +#define LCD_SEG_L2_DP 41 + +// Line1 7-segment arrays +#define LCD_SEG_L1_3_0 70 +#define LCD_SEG_L1_2_0 71 +#define LCD_SEG_L1_1_0 72 +#define LCD_SEG_L1_3_1 73 +#define LCD_SEG_L1_3_2 74 + +// Line2 7-segment arrays +#define LCD_SEG_L2_5_0 90 +#define LCD_SEG_L2_4_0 91 +#define LCD_SEG_L2_3_0 92 +#define LCD_SEG_L2_2_0 93 +#define LCD_SEG_L2_1_0 94 +#define LCD_SEG_L2_5_2 95 +#define LCD_SEG_L2_3_2 96 +#define LCD_SEG_L2_5_4 97 +#define LCD_SEG_L2_4_2 98 + +// LCD controller memory map +#define LCD_MEM_1 ((u8*)0x0A20) +#define LCD_MEM_2 ((u8*)0x0A21) +#define LCD_MEM_3 ((u8*)0x0A22) +#define LCD_MEM_4 ((u8*)0x0A23) +#define LCD_MEM_5 ((u8*)0x0A24) +#define LCD_MEM_6 ((u8*)0x0A25) +#define LCD_MEM_7 ((u8*)0x0A26) +#define LCD_MEM_8 ((u8*)0x0A27) +#define LCD_MEM_9 ((u8*)0x0A28) +#define LCD_MEM_10 ((u8*)0x0A29) +#define LCD_MEM_11 ((u8*)0x0A2A) +#define LCD_MEM_12 ((u8*)0x0A2B) + +// Memory assignment +#define LCD_SEG_L1_0_MEM (LCD_MEM_6) +#define LCD_SEG_L1_1_MEM (LCD_MEM_4) +#define LCD_SEG_L1_2_MEM (LCD_MEM_3) +#define LCD_SEG_L1_3_MEM (LCD_MEM_2) +#define LCD_SEG_L1_COL_MEM (LCD_MEM_1) +#define LCD_SEG_L1_DP1_MEM (LCD_MEM_1) +#define LCD_SEG_L1_DP0_MEM (LCD_MEM_5) +#define LCD_SEG_L2_0_MEM (LCD_MEM_8) +#define LCD_SEG_L2_1_MEM (LCD_MEM_9) +#define LCD_SEG_L2_2_MEM (LCD_MEM_10) +#define LCD_SEG_L2_3_MEM (LCD_MEM_11) +#define LCD_SEG_L2_4_MEM (LCD_MEM_12) +#define LCD_SEG_L2_5_MEM (LCD_MEM_12) +#define LCD_SEG_L2_COL1_MEM (LCD_MEM_1) +#define LCD_SEG_L2_COL0_MEM (LCD_MEM_5) +#define LCD_SEG_L2_DP_MEM (LCD_MEM_9) +#define LCD_SYMB_AM_MEM (LCD_MEM_1) +#define LCD_SYMB_PM_MEM (LCD_MEM_1) +#define LCD_SYMB_ARROW_UP_MEM (LCD_MEM_1) +#define LCD_SYMB_ARROW_DOWN_MEM (LCD_MEM_1) +#define LCD_SYMB_PERCENT_MEM (LCD_MEM_5) +#define LCD_SYMB_TOTAL_MEM (LCD_MEM_11) +#define LCD_SYMB_AVERAGE_MEM (LCD_MEM_10) +#define LCD_SYMB_MAX_MEM (LCD_MEM_8) +#define LCD_SYMB_BATTERY_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_FT_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_K_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_M_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_I_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_PER_S_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_PER_H_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_DEGREE_MEM (LCD_MEM_5) +#define LCD_UNIT_L2_KCAL_MEM (LCD_MEM_7) +#define LCD_UNIT_L2_KM_MEM (LCD_MEM_7) +#define LCD_UNIT_L2_MI_MEM (LCD_MEM_7) +#define LCD_ICON_HEART_MEM (LCD_MEM_2) +#define LCD_ICON_STOPWATCH_MEM (LCD_MEM_3) +#define LCD_ICON_RECORD_MEM (LCD_MEM_1) +#define LCD_ICON_ALARM_MEM (LCD_MEM_4) +#define LCD_ICON_BEEPER1_MEM (LCD_MEM_5) +#define LCD_ICON_BEEPER2_MEM (LCD_MEM_6) +#define LCD_ICON_BEEPER3_MEM (LCD_MEM_7) + +// Bit masks for write access +#define LCD_SEG_L1_0_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_1_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_2_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_3_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_COL_MASK (BIT5) +#define LCD_SEG_L1_DP1_MASK (BIT6) +#define LCD_SEG_L1_DP0_MASK (BIT2) +#define LCD_SEG_L2_0_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_1_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_2_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_3_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_4_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_5_MASK (BIT7) +#define LCD_SEG_L2_COL1_MASK (BIT4) +#define LCD_SEG_L2_COL0_MASK (BIT0) +#define LCD_SEG_L2_DP_MASK (BIT7) +#define LCD_SYMB_AM_MASK (BIT1 + BIT0) +#define LCD_SYMB_PM_MASK (BIT0) +#define LCD_SYMB_ARROW_UP_MASK (BIT2) +#define LCD_SYMB_ARROW_DOWN_MASK (BIT3) +#define LCD_SYMB_PERCENT_MASK (BIT4) +#define LCD_SYMB_TOTAL_MASK (BIT7) +#define LCD_SYMB_AVERAGE_MASK (BIT7) +#define LCD_SYMB_MAX_MASK (BIT7) +#define LCD_SYMB_BATTERY_MASK (BIT7) +#define LCD_UNIT_L1_FT_MASK (BIT5) +#define LCD_UNIT_L1_K_MASK (BIT6) +#define LCD_UNIT_L1_M_MASK (BIT1) +#define LCD_UNIT_L1_I_MASK (BIT0) +#define LCD_UNIT_L1_PER_S_MASK (BIT7) +#define LCD_UNIT_L1_PER_H_MASK (BIT2) +#define LCD_UNIT_L1_DEGREE_MASK (BIT1) +#define LCD_UNIT_L2_KCAL_MASK (BIT4) +#define LCD_UNIT_L2_KM_MASK (BIT5) +#define LCD_UNIT_L2_MI_MASK (BIT6) +#define LCD_ICON_HEART_MASK (BIT3) +#define LCD_ICON_STOPWATCH_MASK (BIT3) +#define LCD_ICON_RECORD_MASK (BIT7) +#define LCD_ICON_ALARM_MASK (BIT3) +#define LCD_ICON_BEEPER1_MASK (BIT3) +#define LCD_ICON_BEEPER2_MASK (BIT3) +#define LCD_ICON_BEEPER3_MASK (BIT3) + +// ************************************************************************************************* +// API section + +// Physical LCD memory write +extern void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state); + +// Display init / clear +extern void lcd_init(void); +extern void clear_display(void); +extern void clear_display_all(void); +extern void clear_line(u8 line); + +// Blinking function +extern void start_blink(void); +extern void stop_blink(void); +extern void clear_blink_mem(void); +extern void set_blink_rate(u8 bits); + +// Character / symbol draw functions +extern void display_char(u8 segment, u8 chr, u8 mode); +extern void display_chars(u8 segments, u8 * str, u8 mode); +extern void display_symbol(u8 symbol, u8 mode); + +// Time display function +extern void DisplayTime(u8 updateMode); +extern void display_am_pm_symbol(u8 timeAM); + +// Set_value display functions +extern void display_value(u8 segments, u32 value, u8 digits, u8 blanks); +extern void display_hours(u8 segments, u32 value, u8 digits, u8 blanks); + +// Integer to string conversion +extern u8 *int_to_array(u32 n, u8 digits, u8 blanks); + +// Segment index helper function +extern u8 switch_seg(u8 line, u8 index1, u8 index2); + +#endif /*__DISPLAY_H*/ + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/ez430_chronos_datalogger_codesize_limited_drivers.r43 b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/ez430_chronos_datalogger_codesize_limited_drivers.r43 new file mode 100755 index 0000000..eaa660c Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/ez430_chronos_datalogger_codesize_limited_drivers.r43 differ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/flash.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/flash.c new file mode 100755 index 0000000..2247f4c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/flash.c @@ -0,0 +1,95 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Data logger routines. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// logic +#include "datalog.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Implementation + +void flash_erase_page(u8 page) +{ + // Convert page index to memory address + u16 *wptr = (u16 *) (page * 512); + + // Range check + if ((page < DATALOG_PAGE_START) || (page > DATALOG_PAGE_END)) + return; + + // Wait until not busy + while ((FCTL3 & BUSY) != 0) ; + + __disable_interrupt(); + FCTL3 = FWKEY; // Clear Lock bit + FCTL1 = FWKEY + ERASE; // Set Erase bit + *wptr = 0; // Dummy write to erase Flash seg + FCTL1 = FWKEY + WRT; // Set WRT bit for write operation + FCTL1 = FWKEY; // Clear WRT bit + FCTL3 = FWKEY + LOCK; // Set LOCK bit + __enable_interrupt(); +} + +void flash_write(u16 * wptr, u16 data) +{ + // Range check + //if ((page < DATALOG_MEMORY_START) || (page > DATALOG_MEMORY_END)) return; + + // Wait until not busy + while ((FCTL3 & BUSY) != 0) ; + + __disable_interrupt(); + FCTL3 = FWKEY; // Clear Lock bit + *wptr = 0; // Dummy write to erase Flash seg + FCTL1 = FWKEY + WRT; // Set WRT bit for write operation + *wptr = data; + FCTL1 = FWKEY; // Clear WRT bit + FCTL3 = FWKEY + LOCK; // Set LOCK bit + __enable_interrupt(); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/flash.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/flash.h new file mode 100755 index 0000000..b9cafa9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/flash.h @@ -0,0 +1,44 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef FLASH_H_ +#define FLASH_H_ + +// ************************************************************************************************* +// Extern section +extern void flash_erase_page(u8 page); +extern void flash_write(u16 * wptr, u16 data); + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/pmm.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/pmm.c new file mode 100755 index 0000000..3257e7a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/pmm.c @@ -0,0 +1,78 @@ +//****************************************************************************// +// Function Library for setting the PMM +// +// This file is used in conjunction with PMM.c to set the core +// voltage level of a device. To set a core voltage level, call +// SetVCore(level). See RF project(s) for example usage. +// +// Original programm Stefan Schauer +// Rev 1.1: changed VCoreUp to fit with recommended flow (09/04/2008) +// +//****************************************************************************// +#include "cc430x613x.h" +#include "pmm.h" + +//****************************************************************************// +// Set VCore level +// SetVCore level is called from the user API +//****************************************************************************// +void SetVCore(unsigned char level) // Note: change level by one + // step only +{ + unsigned char actLevel; + + do + { + actLevel = PMMCTL0_L & PMMCOREV_3; + if (actLevel < level) + SetVCoreUp(++actLevel); // Set VCore (step by step) + if (actLevel > level) + SetVCoreDown(--actLevel); // Set VCore (step by step) + } + while (actLevel != level); +} + +//****************************************************************************// +// Set VCore up +//****************************************************************************// +void SetVCoreUp(unsigned char level) // Note: change level by one + // step only +{ + PMMCTL0_H = 0xA5; // Open PMM module registers + // for write access + + SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; // Set SVS/M high side to new + // level + + SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; // Set SVM new Level + while ((PMMIFG & SVSMLDLYIFG) == 0) ; // Wait till SVM is settled + // (Delay) + PMMCTL0_L = PMMCOREV0 * level; // Set VCore to x + PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); // Clear already set flags + if ((PMMIFG & SVMLIFG)) + while ((PMMIFG & SVMLVLRIFG) == 0) ; // Wait till level is reached + + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Set SVS/M Low side to new + // level + PMMCTL0_H = 0x00; // Lock PMM module registers + // for write access +} + +//****************************************************************************// +// Set VCore down +//****************************************************************************// +void SetVCoreDown(unsigned char level) +{ + PMMCTL0_H = 0xA5; // Open PMM module registers + // for write access + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Set SVS/M Low side to new + // level + while ((PMMIFG & SVSMLDLYIFG) == 0) ; // Wait till SVM is settled + // (Delay) + PMMCTL0_L = (level * PMMCOREV0); // Set VCore to 1.85 V for Max + // Speed. + PMMCTL0_H = 0x00; // Lock PMM module registers + // for write access +} + +//****************************************************************************// diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/pmm.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/pmm.h new file mode 100755 index 0000000..170008f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/pmm.h @@ -0,0 +1,43 @@ +//==================================================================== +// File: PMM.h +// +// This file is used in conjunction with PMM.c to set the core +// voltage level of a device. To set a core voltage level, call +// SetVCore(level). See RF project(s) for example usage. +// +// Version 1.0 first +// 07/14/07 +// +//==================================================================== + +#ifndef __PMM +#define __PMM + +//==================================================================== + +/** + * Set the VCore to a new level + * + * \param level PMM level ID + */ +void SetVCore(unsigned char level); + +//==================================================================== + +/** + * Set the VCore to a new higher level + * + * \param level PMM level ID + */ +void SetVCoreUp(unsigned char level); + +//==================================================================== + +/** + * Set the VCore to a new Lower level + * + * \param level PMM level ID + */ +void SetVCoreDown(unsigned char level); + +#endif /* __PMM */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/ports.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/ports.c new file mode 100755 index 0000000..5a83a11 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/ports.c @@ -0,0 +1,440 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Button entry functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "ports.h" +#include "buzzer.h" +#include "vti_as.h" +#include "vti_ps.h" +#include "timer.h" +#include "display.h" + +// logic +#include "clock.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "altitude.h" + +// ************************************************************************************************* +// Prototypes section +void button_repeat_on(u16 msec); +void button_repeat_off(void); +void button_repeat_function(void); + +// ************************************************************************************************* +// Defines section + +// Macro for button IRQ +#define IRQ_TRIGGERED(flags, bit) ((flags & bit) == bit) + +// ************************************************************************************************* +// Global Variable section +volatile s_button_flags button; +volatile struct struct_button sButton; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// @fn init_buttons +// @brief Init and enable button interrupts. +// @param none +// @return none +// ************************************************************************************************* +void init_buttons(void) +{ + // Set button ports to input + BUTTONS_DIR &= ~ALL_BUTTONS; + + // Enable internal pull-downs + BUTTONS_OUT &= ~ALL_BUTTONS; + BUTTONS_REN |= ALL_BUTTONS; + + // IRQ triggers on rising edge + BUTTONS_IES &= ~ALL_BUTTONS; + + // Reset IRQ flags + BUTTONS_IFG &= ~ALL_BUTTONS; + + // Enable button interrupts + BUTTONS_IE |= ALL_BUTTONS; +} + +// ************************************************************************************************* +// @fn PORT2_ISR +// @brief Interrupt service routine for +// - buttons +// - acceleration sensor CMA_INT +// - pressure sensor DRDY +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=PORT2_VECTOR +__interrupt void PORT2_ISR(void) +{ + // Clear flags + u8 int_flag, int_enable; + u8 buzzer = 0; + u8 simpliciti_button_event = 0; + static u8 simpliciti_button_repeat = 0; + + // Remember interrupt enable bits + int_enable = BUTTONS_IE; + + if ((!button.flag.star_long) && (!button.flag.num_long)) + { + // Clear button flags + button.all_flags = 0; + + // Store valid button interrupt flag + int_flag = BUTTONS_IFG & int_enable; + + // --------------------------------------------------- + // While SimpliciTI stack is active, buttons behave differently: + // - Store button events in SimpliciTI packet data + // - Exit SimpliciTI when button DOWN was pressed + if (is_rf()) + { + // Erase previous button press after a number of resends (increase number if link + // quality is low) + // This will create a series of packets containing the same button press + // Necessary because we have no acknowledge + // Filtering (edge detection) will be done by receiver software + if (simpliciti_button_repeat++ > 6) + { + simpliciti_data[0] &= ~0xF0; + simpliciti_button_repeat = 0; + } + + if ((int_flag & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_STAR; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_NUM; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_UP_PIN) == BUTTON_UP_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_UP; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN) + { + simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; + } + + // Trigger packet sending inside SimpliciTI stack + if (simpliciti_button_event) + simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; + } + else // Normal operation + { + // Debounce buttons + if ((int_flag & ALL_BUTTONS) != 0) + { + // Disable PORT2 IRQ + __disable_interrupt(); + BUTTONS_IE = 0x00; + __enable_interrupt(); + + // Debounce delay 1 + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN)); + + // Reset inactivity detection + sTime.last_activity = sTime.system_time; + } + + // --------------------------------------------------- + // STAR button IRQ + if (IRQ_TRIGGERED(int_flag, BUTTON_STAR_PIN)) + { + // Filter bouncing noise + if (BUTTON_STAR_IS_PRESSED) + { + button.flag.star = 1; + button.flag.star_not_long = 0; + // Generate button click + buzzer = 1; + } + else if ((BUTTONS_IES & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) + { + button.flag.star = 1; + button.flag.star_not_long = 0; + BUTTONS_IES &= ~BUTTON_STAR_PIN; + } + } + // --------------------------------------------------- + // NUM button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN)) + { + // Filter bouncing noise + if (BUTTON_NUM_IS_PRESSED) + { + button.flag.num = 1; + button.flag.num_not_long = 0; + // Generate button click + buzzer = 1; + } + else if ((BUTTONS_IES & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) + { + button.flag.num = 1; + button.flag.num_not_long = 0; + BUTTONS_IES &= ~BUTTON_NUM_PIN; + } + } + // --------------------------------------------------- + // UP button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_UP_PIN)) + { + // Filter bouncing noise + if (BUTTON_UP_IS_PRESSED) + { + button.flag.up = 1; + + // Generate button click + buzzer = 1; + } + } + // --------------------------------------------------- + // DOWN button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_DOWN_PIN)) + { + // Filter bouncing noise + if (BUTTON_DOWN_IS_PRESSED) + { + button.flag.down = 1; + + // Generate button click + buzzer = 1; + } + } + // --------------------------------------------------- + // B/L button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_BACKLIGHT_PIN)) + { + // Filter bouncing noise + if (BUTTON_BACKLIGHT_IS_PRESSED) + { + sButton.backlight_status = 1; + sButton.backlight_timeout = 0; + P2OUT |= BUTTON_BACKLIGHT_PIN; + P2DIR |= BUTTON_BACKLIGHT_PIN; + } + } + } + + // Trying to lock/unlock buttons? + if (button.flag.num && button.flag.down) + { + // No buzzer output + buzzer = 0; + button.all_flags = 0; + } + + // Generate button click when button was activated + if (buzzer) + { + + if (!sys.flag.up_down_repeat_enabled) + { + start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150)); + } + + // Debounce delay 2 + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + } + + // --------------------------------------------------- + // Acceleration sensor IRQ + if (IRQ_TRIGGERED(int_flag, AS_INT_PIN)) + { + // Get data from sensor + request.flag.acceleration_measurement = 1; + } + + // --------------------------------------------------- + // Pressure sensor IRQ + if (IRQ_TRIGGERED(int_flag, PS_INT_PIN)) + { + // Get data from sensor + request.flag.altitude_measurement = 1; + } + + // --------------------------------------------------- + // Safe long button event detection + if (button.flag.star || button.flag.num) + { + // Additional debounce delay to enable safe high detection - 50ms + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT)); + + // Check if this button event is short enough + if (BUTTON_STAR_IS_PRESSED) + { + // Change interrupt edge to detect button release + BUTTONS_IES |= BUTTON_STAR_PIN; + button.flag.star = 0; + // This flag is used to detect if the user released the button before the + // time for a long button press (3s) + button.flag.star_not_long = 1; + } + if (BUTTON_NUM_IS_PRESSED) + { + // Change interrupt edge to detect button release + BUTTONS_IES |= BUTTON_NUM_PIN; + button.flag.num = 0; + // This flag is used to detect if the user released the button before the + // time for a long button press (3s) + button.flag.num_not_long = 1; + } + } + } + // Reenable PORT2 IRQ + __disable_interrupt(); + BUTTONS_IFG = 0x00; + BUTTONS_IE = int_enable; + __enable_interrupt(); + + // Exit from LPM3/LPM4 on RETI + __bic_SR_register_on_exit(LPM4_bits); +} + +// ************************************************************************************************* +// @fn button_repeat_on +// @brief Start button auto repeat timer. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_on(u16 msec) +{ + // Set button repeat flag + sys.flag.up_down_repeat_enabled = 1; + + // Set Timer0_A3 function pointer to button repeat function + fptr_Timer0_A3_function = button_repeat_function; + + // Timer0_A3 IRQ triggers every 200ms + Timer0_A3_Start(CONV_MS_TO_TICKS(msec)); +} + +// ************************************************************************************************* +// @fn button_repeat_off +// @brief Stop button auto repeat timer. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_off(void) +{ + // Clear button repeat flag + sys.flag.up_down_repeat_enabled = 0; + + // Timer0_A3 IRQ repeats with 4Hz + Timer0_A3_Stop(); +} + +// ************************************************************************************************* +// @fn button_repeat_function +// @brief Check at regular intervals if button is pushed continuously +// and trigger virtual button event. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_function(void) +{ + static u8 start_delay = 10; // Wait for 2 seconds before starting auto up/down + u8 repeat = 0; + + // If buttons UP or DOWN are continuously high, repeatedly set button flag + if (BUTTON_UP_IS_PRESSED) + { + if (start_delay == 0) + { + // Generate a virtual button event + button.flag.up = 1; + repeat = 1; + } + else + { + start_delay--; + } + } + else if (BUTTON_DOWN_IS_PRESSED) + { + if (start_delay == 0) + { + // Generate a virtual button event + button.flag.down = 1; + repeat = 1; + } + else + { + start_delay--; + } + } + else + { + // Reset repeat counter + sButton.repeats = 0; + start_delay = 10; + + // Enable blinking + start_blink(); + } + + // If virtual button event is generated, stop blinking and reset timeout counter + if (repeat) + { + // Increase repeat counter + sButton.repeats++; + + // Reset inactivity detection counter + sTime.last_activity = sTime.system_time; + + // Disable blinking + stop_blink(); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/ports.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/ports.h new file mode 100755 index 0000000..96c3fc2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/ports.h @@ -0,0 +1,130 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef PORTS_H_ +#define PORTS_H_ + +// ************************************************************************************************* +// Defines section + +// Port, pins and interrupt resources for buttons +#define BUTTONS_IN (P2IN) +#define BUTTONS_OUT (P2OUT) +#define BUTTONS_DIR (P2DIR) +#define BUTTONS_REN (P2REN) +#define BUTTONS_IE (P2IE) +#define BUTTONS_IES (P2IES) +#define BUTTONS_IFG (P2IFG) +#define BUTTONS_IRQ_VECT2 (PORT2_VECTOR) + +// Button ports +#define BUTTON_STAR_PIN (BIT2) +#define BUTTON_NUM_PIN (BIT1) +#define BUTTON_UP_PIN (BIT4) +#define BUTTON_DOWN_PIN (BIT0) +#define BUTTON_BACKLIGHT_PIN (BIT3) +#define ALL_BUTTONS (BUTTON_STAR_PIN + BUTTON_NUM_PIN + BUTTON_UP_PIN + \ + BUTTON_DOWN_PIN + BUTTON_BACKLIGHT_PIN) + +// Macros for button press detection +#define BUTTON_STAR_IS_PRESSED ((BUTTONS_IN & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) +#define BUTTON_NUM_IS_PRESSED ((BUTTONS_IN & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) +#define BUTTON_UP_IS_PRESSED ((BUTTONS_IN & BUTTON_UP_PIN) == BUTTON_UP_PIN) +#define BUTTON_DOWN_IS_PRESSED ((BUTTONS_IN & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN) +#define BUTTON_BACKLIGHT_IS_PRESSED ((BUTTONS_IN & BUTTON_BACKLIGHT_PIN) == \ + BUTTON_BACKLIGHT_PIN) +#define NO_BUTTON_IS_PRESSED ((BUTTONS_IN & ALL_BUTTONS) == 0) + +// Macros for button release detection +#define BUTTON_STAR_IS_RELEASED ((BUTTONS_IN & BUTTON_STAR_PIN) == 0) +#define BUTTON_NUM_IS_RELEASED ((BUTTONS_IN & BUTTON_NUM_PIN) == 0) +#define BUTTON_UP_IS_RELEASED (BUTTONS_IN & BUTTON_UP_PIN) == 0) +#define BUTTON_DOWN_IS_RELEASED ((BUTTONS_IN & BUTTON_DOWN_PIN) == 0) +#define BUTTON_BACKLIGHT_IS_RELEASED ((BUTTONS_IN & BUTTON_BACKLIGHT_PIN) == 0) + +// Button debounce time (msec) +#define BUTTONS_DEBOUNCE_TIME_IN (5u) +#define BUTTONS_DEBOUNCE_TIME_OUT (250u) +#define BUTTONS_DEBOUNCE_TIME_LEFT (50u) + +// Detect if STAR / NUM button is held low continuously +#define LEFT_BUTTON_LONG_TIME (2u) + +// Backlight time (sec) +#define BACKLIGHT_TIME_ON (3u) + +// Leave set_value() function after some seconds of user inactivity +#define INACTIVITY_TIME (30u) + +// Set of button flags +typedef union +{ + struct + { + // Manual button events + u16 star : 1; // Short STAR button press + u16 num : 1; // Short NUM button press + u16 up : 1; // Short UP button press + u16 down : 1; // Short DOWN button press + u16 backlight : 1; // Short BACKLIGHT button press + u16 star_long : 1; // Long STAR button press + u16 num_long : 1; // Long NUM button press + u16 star_not_long : 1; // Between short and long STAR button press + u16 num_not_long : 1; // Between short and long NUM button press + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_button_flags; +extern volatile s_button_flags button; + +struct struct_button +{ + u8 star_timeout; // This variable is incremented once per second if STAR button is + // still pressed + u8 num_timeout; // This variable is incremented once per second if NUM button is + // still pressed + u8 backlight_timeout; // controls the timeout for the backlight + u8 backlight_status; // 1 case backlight is on + s16 repeats; +}; +extern volatile struct struct_button sButton; + +// ************************************************************************************************* +// Extern section +extern void button_repeat_on(u16 msec); +extern void button_repeat_off(void); +extern void button_repeat_function(void); +extern void init_buttons(void); + +#endif /*PORTS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/radio.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/radio.c new file mode 100755 index 0000000..8e5a36b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/radio.c @@ -0,0 +1,187 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// system +#include "project.h" + +// driver +#include "rf1a.h" +#include "timer.h" + +// logic +#include "rfsimpliciti.h" +#include "bluerobin.h" + +// ************************************************************************************************* +// Extern section + +// SimpliciTI CC430 radio ISR - located in SimpliciTi library +extern void MRFI_RadioIsr(void); + +// BlueRobin CC430 radio ISR - located in BlueRobin library +extern void BlueRobin_RadioISR_v(void); + +// ************************************************************************************************* +// @fn radio_reset +// @brief Reset radio core. +// @param none +// @return none +// ************************************************************************************************* +void radio_reset(void) +{ + volatile u16 i; + u8 x; + + // Reset radio core + Strobe(RF_SRES); + // Wait before checking IDLE + for (i = 0; i < 100; i++) ; + do + { + x = Strobe(RF_SIDLE); + } + while ((x & 0x70) != 0x00); + + // Clear radio error register + RF1AIFERR = 0; +} + +// ************************************************************************************************* +// @fn radio_powerdown +// @brief Put radio to SLEEP mode. +// @param none +// @return none +// ************************************************************************************************* +void radio_powerdown(void) +{ + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + // Powerdown radio + Strobe(RF_SIDLE); + Strobe(RF_SPWD); +} + +// ************************************************************************************************* +// @fn radio_sxoff +// @brief Put radio to SLEEP mode (XTAL off only). +// @param none +// @return none +// ************************************************************************************************* +void radio_sxoff(void) +{ + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + // Powerdown radio + Strobe(RF_SIDLE); + Strobe(RF_SXOFF); +} + +// ************************************************************************************************* +// @fn open_radio +// @brief Prepare radio for RF communication. +// @param none +// @return none +// ************************************************************************************************* +void open_radio(void) +{ + // Reset radio core + radio_reset(); + + // Enable radio IRQ + RF1AIFG &= ~BIT4; // Clear a pending interrupt + RF1AIE |= BIT4; // Enable the interrupt +} + +// ************************************************************************************************* +// @fn close_radio +// @brief Shutdown radio for RF communication. +// @param none +// @return none +// ************************************************************************************************* +void close_radio(void) +{ + // Disable radio IRQ + RF1AIFG = 0; + RF1AIE = 0; + + // Reset radio core + radio_reset(); + + // Put radio to sleep + radio_powerdown(); +} + +// ************************************************************************************************* +// @fn GDOx_ISR +// @brief GDO0/2 ISR to detect received packet. +// In BlueRobin mode: capture packet end time and decode received +// packet +// In SimpliciTI mode: go to SimpliciTI handler +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=CC1101_VECTOR +__interrupt void radio_ISR(void) +{ + u8 rf1aivec = RF1AIV; + + // Forward to SimpliciTI interrupt service routine + if (is_rf()) + { + MRFI_RadioIsr(); + } + else // BlueRobin packet end interrupt service routine + { + if (rf1aivec == RF1AIV_RFIFG9) + { + if ((sBlueRobin.state == BLUEROBIN_SEARCHING) || + (sBlueRobin.state == BLUEROBIN_CONNECTED)) + { + BlueRobin_RadioISR_v(); + } + } + else if (rf1aivec == RF1AIV_NONE) // RF1A interface interrupt (error etc.) + { + asm (" nop"); // break here + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/radio.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/radio.h new file mode 100755 index 0000000..f4c1bb9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/radio.h @@ -0,0 +1,48 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RADIO_H_ +#define RADIO_H_ + +extern void radio_reset(void); +extern void radio_powerdown(void); +extern void radio_sxoff(void); +extern void radio_idle(void); +extern void open_radio(void); +extern void close_radio(void); +extern void pmm_set_high_current_mode(void); +extern void pmm_set_low_current_mode(void); + +#endif /*RADIO_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/rf1a.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/rf1a.c new file mode 100755 index 0000000..9f3b5be --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/rf1a.c @@ -0,0 +1,233 @@ +// ************************************************************************************************* +// +// Actual revision: $Revision: $ +// Revision label: $Name: $ +// Revision state: $State: $ +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include + +// driver +#include "rf1a.h" + +// ************************************************************************************************* +// Global section + +// ************************************************************************************************* +// Define section +#define st(x) do { x } while (__LINE__ == -1) +#define ENTER_CRITICAL_SECTION(x) st(x = __get_interrupt_state(); __disable_interrupt(); ) +#define EXIT_CRITICAL_SECTION(x) __set_interrupt_state(x) + +// ************************************************************************************************* +// @fn Strobe +// @brief Send command to radio. +// @param unsigned char strobe Command to radio +// @return statusByte Radio core status +// ************************************************************************************************* +unsigned char Strobe(unsigned char strobe) +{ + u8 statusByte = 0; + u16 int_state, gdo_state; + + // Check for valid strobe command + if ((strobe == 0xBD) || ((strobe > RF_SRES) && (strobe < RF_SNOP))) + { + ENTER_CRITICAL_SECTION(int_state); + + // Clear the Status read flag + RF1AIFCTL1 &= ~(RFSTATIFG); + + // Wait for radio to be ready for next instruction + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + + // Write the strobe instruction + if ((strobe > RF_SRES) && (strobe < RF_SNOP)) + { + + gdo_state = ReadSingleReg(IOCFG2); // buffer IOCFG2 state + WriteSingleReg(IOCFG2, 0x29); // c-ready to GDO2 + + RF1AINSTRB = strobe; + if ((RF1AIN & 0x04) == 0x04) // chip at sleep mode + { + if ((strobe == RF_SXOFF) || (strobe == RF_SPWD) || (strobe == RF_SWOR)) + { + } + else + { + while ((RF1AIN & 0x04) == 0x04) ; // c-ready ? + __delay_cycles(9800); // Delay for ~810usec at 12MHz CPU clock + } + } + WriteSingleReg(IOCFG2, gdo_state); // restore IOCFG2 setting + } + else // chip active mode + { + RF1AINSTRB = strobe; + } + statusByte = RF1ASTATB; + while (!(RF1AIFCTL1 & RFSTATIFG)) ; + EXIT_CRITICAL_SECTION(int_state); + } + return statusByte; +} + +// ************************************************************************************************* +// @fn ResetRadioCore +// @brief Software reset radio core. +// @param none +// @return none +// ************************************************************************************************* +void ResetRadioCore(void) +{ + Strobe(RF_SRES); // Reset the Radio Core + Strobe(RF_SNOP); // Reset Radio Pointer +} + +// ************************************************************************************************* +// @fn ReadSingleReg +// @brief Read byte from register. +// @param none +// @return none +// ************************************************************************************************* +unsigned char ReadSingleReg(unsigned char addr) +{ + unsigned char x; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + RF1AINSTR1B = (addr | RF_REGRD); + x = RF1ADOUT1B; + + EXIT_CRITICAL_SECTION(int_state); + + return x; +} + +// ************************************************************************************************* +// @fn WriteSingleReg +// @brief Write byte to register. +// @param none +// @return none +// ************************************************************************************************* +void WriteSingleReg(unsigned char addr, unsigned char value) +{ + volatile unsigned int i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for the next + // instruction + + RF1AINSTRW = ((addr | RF_REGWR) << 8) + value; // Send address + Instruction + while (!(RFDINIFG & RF1AIFCTL1)) ; + + i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status + // byte + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn ReadBurstReg +// @brief Read sequence of bytes from register. +// @param none +// @return none +// ************************************************************************************************* +void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) +{ + unsigned int i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for next instruction + RF1AINSTR1B = (addr | RF_REGRD); // Send address + Instruction + + for (i = 0; i < (count - 1); i++) + { + while (!(RFDOUTIFG & RF1AIFCTL1)) ; // Wait for the Radio Core to update the RF1ADOUTB reg + buffer[i] = RF1ADOUT1B; // Read DOUT from Radio Core + clears RFDOUTIFG + // Also initiates auo-read for next DOUT byte + } + buffer[count - 1] = RF1ADOUT0B; // Store the last DOUT from Radio Core + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn WriteBurstReg +// @brief Write sequence of bytes to register. +// @param none +// @return none +// ************************************************************************************************* +void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) +{ + // Write Burst works wordwise not bytewise - bug known already + unsigned char i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for next + // instruction + RF1AINSTRW = ((addr | RF_REGWR) << 8) + buffer[0]; // Send address + Instruction + + for (i = 1; i < count; i++) + { + RF1ADINB = buffer[i]; // Send data + while (!(RFDINIFG & RF1AIFCTL1)) ; // Wait for TX to finish + } + i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status + // byte + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn WritePATable +// @brief Write data to power table +// @param unsigned char value Value to write +// @return none +// ************************************************************************************************* +void WritePATable(unsigned char value) +{ + unsigned char readbackPATableValue = 0; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (readbackPATableValue != value) + { + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRW = 0x7E00 + value; // PA Table write (burst) + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; // reset pointer + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = 0xFE; // PA Table read (burst) + + while (!(RF1AIFCTL1 & RFDINIFG)) ; + RF1ADINB = 0x00; //dummy write + + while (!(RF1AIFCTL1 & RFDOUTIFG)) ; + readbackPATableValue = RF1ADOUT0B; + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; + } + + EXIT_CRITICAL_SECTION(int_state); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/rf1a.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/rf1a.h new file mode 100755 index 0000000..f1acd1c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/rf1a.h @@ -0,0 +1,20 @@ +// ************************************************************************************************* +// +// Actual revision: $Revision: $ +// Revision label: $Name: $ +// Revision state: $State: $ +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// ************************************************************************************************* +// Prototype section +unsigned char Strobe(unsigned char strobe); +unsigned char ReadSingleReg(unsigned char addr); +void WriteSingleReg(unsigned char addr, unsigned char value); +void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count); +void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count); +void ResetRadioCore(void); +void WritePATable(unsigned char value); +void WaitForXT2(void); diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/timer.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/timer.c new file mode 100755 index 0000000..428bb68 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/timer.c @@ -0,0 +1,485 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Timer service routines. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "timer.h" +#include "ports.h" +#include "buzzer.h" +#include "vti_ps.h" +#include "vti_as.h" + +// logic +#include "clock.h" +#include "battery.h" +#include "altitude.h" +#include "display.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "acceleration.h" +#include "bluerobin.h" +#include "temperature.h" +#include "datalog.h" + +// ************************************************************************************************* +// Prototypes section +void Timer0_Init(void); +void Timer0_Stop(void); +void Timer0_A1_Start(void); +void Timer0_A1_Stop(void); +void Timer0_A3_Start(u16 ticks); +void Timer0_A3_Stop(void); +void Timer0_A4_Delay(u16 ticks); + +void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct timer sTimer; + +// ************************************************************************************************* +// Extern section +extern void BRRX_TimerTask_v(void); +extern void to_lpm(void); + +// ************************************************************************************************* +// @fn Timer0_Init +// @brief Set Timer0 to a period of 1 or 2 sec. IRQ TACCR0 is asserted when timer overflows. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Init(void) +{ + // Set interrupt frequency to 1Hz + TA0CCR0 = 32768 - 1; + + // Enable timer interrupt + TA0CCTL0 |= CCIE; + + // Clear and start timer now + // Continuous mode: Count to 0xFFFF and restart from 0 again - 1sec timing will be generated by + // ISR + TA0CTL |= TASSEL0 + MC1 + TACLR; +} + +// ************************************************************************************************* +// @fn Timer0_Start +// @brief Start Timer0. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Start(void) +{ + // Start Timer0 in continuous mode + TA0CTL |= MC_2; +} + +// ************************************************************************************************* +// @fn Timer0_Stop +// @brief Stop and reset Timer0. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Stop(void) +{ + // Stop Timer0 + TA0CTL &= ~MC_2; + + // Set Timer0 count register to 0x0000 + TA0R = 0; +} + +// ************************************************************************************************* +// @fn Timer0_A3_Start +// @brief Trigger IRQ every "ticks" microseconds +// @param ticks (1 tick = 1/32768 sec) +// @return none +// ************************************************************************************************* +void Timer0_A3_Start(u16 ticks) +{ + u16 value = 0; + + // Store timer ticks in global variable + sTimer.timer0_A3_ticks = ticks; + + // Delay based on current counter value + // To make sure this value is correctly read + while (value != TA0R) + value = TA0R; + value += ticks; + + // Update CCR + TA0CCR3 = value; + + // Reset IRQ flag + TA0CCTL3 &= ~CCIFG; + + // Enable timer interrupt + TA0CCTL3 |= CCIE; +} + +// ************************************************************************************************* +// @fn Timer0_A3_Stop +// @brief Stop Timer0_A3. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_A3_Stop(void) +{ + // Clear timer interrupt + TA0CCTL3 &= ~CCIE; +} + +// ************************************************************************************************* +// @fn Timer0_A4_Delay +// @brief Wait for some microseconds +// @param ticks (1 tick = 1/32768 sec) +// @return none +// ************************************************************************************************* +void Timer0_A4_Delay(u16 ticks) +{ + u16 value = 0; + + // Exit immediately if Timer0 not running - otherwise we'll get stuck here + if ((TA0CTL & (BIT4 | BIT5)) == 0) + return; + + // Disable timer interrupt + TA0CCTL4 &= ~CCIE; + + // Clear delay_over flag + sys.flag.delay_over = 0; + + // Add delay to current timer value + // To make sure this value is correctly read + while (value != TA0R) + value = TA0R; + value += ticks; + + // Update CCR + TA0CCR4 = value; + + // Reset IRQ flag + TA0CCTL4 &= ~CCIFG; + + // Enable timer interrupt + TA0CCTL4 |= CCIE; + + // Wait for timer IRQ + while (1) + { + // Delay in LPM + to_lpm(); // will also set GIE again + +#ifdef USE_WATCHDOG + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; +#endif + + // Check stop condition + // disable interrupt to prevent flag's change caused by interrupt methods + __disable_interrupt(); + if (sys.flag.delay_over) + break; + } + __enable_interrupt(); +} + +// ************************************************************************************************* +// @fn TIMER0_A0_ISR +// @brief IRQ handler for TIMER0_A0 IRQ +// Timer0_A0 1/1sec clock tick (serviced by +// function TIMER0_A0_ISR) +// Timer0_A1 +// (serviced by function +// TIMER0_A1_5_ISR) +// Timer0_A2 1/100 sec Stopwatch (serviced by +// function TIMER0_A1_5_ISR) +// Timer0_A3 Configurable periodic IRQ (serviced by +// function TIMER0_A1_5_ISR) +// Timer0_A4 One-time delay (serviced by +// function TIMER0_A1_5_ISR) +// @param none +// @return none +// ************************************************************************************************* +#pragma vector = TIMER0_A0_VECTOR +__interrupt void TIMER0_A0_ISR(void) +{ + static u8 button_lock_counter = 0; + + // Disable IE + TA0CCTL0 &= ~CCIE; + // Reset IRQ flag + TA0CCTL0 &= ~CCIFG; + // Add 1 sec to TACCR0 register (IRQ will be asserted at 0x7FFF and 0xFFFF = 1 sec intervals) + TA0CCR0 += 32768; + // Enable IE + TA0CCTL0 |= CCIE; + + // Add 1 second to global time + clock_tick(); + + // Set clock update flag + display.flag.update_time = 1; + + // While BlueRobin searches freeze system state + if (is_bluerobin_searching()) + { + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); + return; + } + + if ((is_rf()) && (sRFsmpl.mode == SIMPLICITI_SYNC)) + { + if (sRFsmpl.display_sync_done == 0) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " SYNC", SEG_ON); + } + else + { + sRFsmpl.display_sync_done--; + } + } + + // ------------------------------------------------------------------- + // Service modules that require 1/min processing + if (sTime.drawFlag >= 2) + { + // Measure battery voltage + request.flag.voltage_measurement = 1; + } + + // ------------------------------------------------------------------- + // Service active modules that require 1/s processing + + // Request data logging + if (is_datalog()) + request.flag.datalog = 1; + + // Request temperature and pressure measurement + if (is_altitude_measurement()) + request.flag.altitude_measurement = 1; + + // Get BlueRobin data from API + if (is_bluerobin()) + get_bluerobin_data(); + + // If battery is low, count down display counter + if (sys.flag.low_battery) + { + if (sBatt.lobatt_display-- == 0) + { + message.flag.prepare = 1; + message.flag.type_lobatt = 1; + sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE; + } + } + + // If a message has to be displayed, set display flag + if (message.all_flags) + { + if (message.flag.prepare) + { + message.flag.prepare = 0; + message.flag.show = 1; + } + else if (message.flag.erase) // message cycle is over, so erase it + { + message.flag.erase = 0; + display.flag.full_update = 1; + } + } + + // ------------------------------------------------------------------- + // Check idle timeout, set timeout flag + if (sys.flag.idle_timeout_enabled) + { + if (sTime.system_time - sTime.last_activity > INACTIVITY_TIME) + sys.flag.idle_timeout = 1; //setFlag(sysFlag_g, SYS_TIMEOUT_IDLE); + } + + // ------------------------------------------------------------------- + // Turn the Backlight off after timeout + if (sButton.backlight_status == 1) + { + if (sButton.backlight_timeout > BACKLIGHT_TIME_ON) + { + //turn off Backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + sButton.backlight_timeout = 0; + sButton.backlight_status = 0; + } + else + { + sButton.backlight_timeout++; + } + } + + // ------------------------------------------------------------------- + // Detect continuous button high states + + // Trying to lock/unlock buttons? + if (BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED) + { + if (button_lock_counter++ > LEFT_BUTTON_LONG_TIME) + { + // Toggle lock / unlock buttons flag + sys.flag.lock_buttons = ~sys.flag.lock_buttons; + + // Show "buttons are locked/unlocked" message synchronously with next second tick + message.flag.prepare = 1; + if (sys.flag.lock_buttons) + message.flag.type_locked = 1; + else + message.flag.type_unlocked = 1; + + // Reset button lock counter + button_lock_counter = 0; + } + } + else // Trying to create a long button press? + { + // Reset button lock counter + button_lock_counter = 0; + + if (BUTTON_STAR_IS_PRESSED) + { + sButton.star_timeout++; + + // Check if button was held low for some seconds + if (sButton.star_timeout > LEFT_BUTTON_LONG_TIME) + { + button.flag.star_long = 1; + button.flag.star_not_long = 0; + sButton.star_timeout = 0; + // Return interrupt edge to normal value + BUTTONS_IES &= ~BUTTON_STAR_PIN; + } + } + else // there was a button press not long enough + { + sButton.star_timeout = 0; + } + + if (BUTTON_NUM_IS_PRESSED) + { + sButton.num_timeout++; + + // Check if button was held low for some seconds + if (sButton.num_timeout > LEFT_BUTTON_LONG_TIME) + { + button.flag.num_long = 1; + button.flag.num_not_long = 0; + sButton.num_timeout = 0; + // Return interrupt edge to normal value + BUTTONS_IES &= ~BUTTON_NUM_PIN; + } + } + else // there was a button press not long enough + { + sButton.num_timeout = 0; + } + } + + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); +} + +// ************************************************************************************************* +// @fn Timer0_A1_5_ISR +// @brief IRQ handler for timer IRQ. +// Timer0_A0 1/1sec clock tick (serviced by function +// TIMER0_A0_ISR) +// Timer0_A1 BlueRobin timer +// Timer0_A2 +// Timer0_A3 Configurable periodic IRQ (used by button_repeat and +// buzzer) +// Timer0_A4 One-time delay +// @param none +// @return none +// ************************************************************************************************* +#pragma vector = TIMER0_A1_VECTOR +__interrupt void TIMER0_A1_5_ISR(void) +{ + u16 value; + + switch (TA0IV) + { + // Timer0_A1 BlueRobin timer + case 0x02: // Timer0_A1 handler + BRRX_TimerTask_v(); + break; + + // Timer0_A3 Configurable periodic IRQ (used by button_repeat and buzzer) + case 0x06: // Disable IE + TA0CCTL3 &= ~CCIE; + // Reset IRQ flag + TA0CCTL3 &= ~CCIFG; + // Store new value in CCR + value = TA0R + sTimer.timer0_A3_ticks; //timer0_A3_ticks_g; + // Load CCR register with next capture point + TA0CCR3 = value; + // Enable timer interrupt + TA0CCTL3 |= CCIE; + // Call function handler + fptr_Timer0_A3_function(); + break; + + // Timer0_A4 One-time delay + case 0x08: // Disable IE + TA0CCTL4 &= ~CCIE; + // Reset IRQ flag + TA0CCTL4 &= ~CCIFG; + // Set delay over flag + sys.flag.delay_over = 1; + break; + } + + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/timer.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/timer.h new file mode 100755 index 0000000..a65bf92 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/timer.h @@ -0,0 +1,68 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef TIMER_H_ +#define TIMER_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void Timer0_Init(void); +extern void Timer0_Start(void); +extern void Timer0_Stop(void); +extern void Timer0_A3_Start(u16 ticks); +extern void Timer0_A3_Stop(void); +extern void Timer0_A4_Delay(u16 ticks); + +extern void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// Defines section +struct timer +{ + // Timer0_A3 periodic delay + u16 timer0_A3_ticks; +}; +extern struct timer sTimer; + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*TIMER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_as.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_as.c new file mode 100755 index 0000000..0bd4912 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_as.c @@ -0,0 +1,356 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// VTI CMA3000-D0x acceleration sensor driver functions +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// logic +#include "simpliciti.h" + +// driver +#include "vti_as.h" +#include "timer.h" +#include "display.h" + +// ************************************************************************************************* +// Prototypes section +void as_start(void); +void as_stop(void); +u8 as_read_register(u8 bAddress); +u8 as_write_register(u8 bAddress, u8 bData); + +// ************************************************************************************************* +// Defines section + +// ================================================================================================= +// CMA3000-D0x acceleration sensor configuration +// ================================================================================================= +// DCO frequency division factor determining speed of the acceleration sensor SPI interface +// Speed in Hz = 12MHz / AS_BR_DIVIDER (max. 500kHz) +#define AS_BR_DIVIDER (30u) + +// Acceleration measurement range in g +// Valid ranges are: 2 and 8 +#define AS_RANGE (2u) + +// Sample rate for acceleration values in Hz +// Valid sample rates for 2g range are: 100, 400 +// Valid sample rates for 8g range are: 40, 100, 400 +#define AS_SAMPLE_RATE (100u) + +// ************************************************************************************************* +// Global Variable section + +// Global flag for proper acceleration sensor operation +u8 as_ok; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn as_init +// @brief Setup acceleration sensor connection, do not power up yet +// @param none +// @return none +// ************************************************************************************************* +void as_init(void) +{ +#ifdef AS_DISCONNECT + // Deactivate connection to acceleration sensor + AS_PWR_OUT &= ~AS_PWR_PIN; // Power off + AS_INT_OUT &= ~AS_INT_PIN; // Pin to low to avoid floating pins + AS_SPI_OUT &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Pin to low to avoid floating pins + AS_CSN_OUT &= ~AS_CSN_PIN; // Pin to low to avoid floating pins + AS_INT_DIR |= AS_INT_PIN; // Pin to output to avoid floating pins + AS_SPI_DIR |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Pin to output to avoid floating pins + AS_CSN_DIR |= AS_CSN_PIN; // Pin to output to avoid floating pins + AS_PWR_DIR |= AS_PWR_PIN; // Power pin to output direction +#else + AS_INT_DIR &= ~AS_INT_PIN; // Input + AS_SPI_DIR &= ~AS_SDI_PIN; // Input + AS_SPI_DIR |= AS_SDO_PIN + AS_SCK_PIN; // Output + AS_SPI_SEL |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Port pins to SDO, SDI and SCK function + AS_CSN_OUT |= AS_CSN_PIN; // CSN=1 + AS_CSN_DIR |= AS_CSN_PIN; // + AS_PWR_OUT |= AS_PWR_PIN; // VDD=1 + AS_PWR_DIR |= AS_PWR_PIN; // +#endif + + // Reset global sensor flag + as_ok = 1; +} + +// ************************************************************************************************* +// @fn as_start +// @brief Power-up and initialize acceleration sensor +// @param none +// @return none +// ************************************************************************************************* +void as_start(void) +{ + volatile u16 Counter_u16; + u8 bConfig; //, bStatus; + + // Initialize SPI interface to acceleration sensor + AS_SPI_CTL0 |= UCSYNC | UCMST | UCMSB // SPI master, 8 data bits, MSB first, + | UCCKPH; // clock idle low, data output on falling + // edge + AS_SPI_CTL1 |= UCSSEL1; // SMCLK as clock source + AS_SPI_BR0 = AS_BR_DIVIDER; // Low byte of division factor for baud rate + AS_SPI_BR1 = 0x00; // High byte of division factor for baud + // rate + AS_SPI_CTL1 &= ~UCSWRST; // Start SPI hardware + + // Initialize interrupt pin for data read out from acceleration sensor + AS_INT_IES &= ~AS_INT_PIN; // Interrupt on rising edge + +#ifdef AS_DISCONNECT + // Enable interrupt + AS_INT_DIR &= ~AS_INT_PIN; // Switch INT pin to input + AS_SPI_DIR &= ~AS_SDI_PIN; // Switch SDI pin to input + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin + AS_SPI_SEL |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Port pins to SDO, SDI and SCK function + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_PWR_OUT |= AS_PWR_PIN; // Power on active high +#endif + + // Delay of >5ms required between switching on power and configuring sensor + Timer0_A4_Delay(CONV_MS_TO_TICKS(10)); + + // Initialize interrupt pin for data read out from acceleration sensor + AS_INT_IFG &= ~AS_INT_PIN; // Reset flag + AS_INT_IE |= AS_INT_PIN; // Enable interrupt + + // Configure sensor and start to sample data +#if (AS_RANGE == 2) + bConfig = 0x80; +# if (AS_SAMPLE_RATE == 100) + bConfig |= 0x02; +# elif (AS_SAMPLE_RATE == 400) + bConfig |= 0x04; +# else +# error "Sample rate not supported" +# endif +#elif (AS_RANGE == 8) + bConfig = 0x00; +# if (AS_SAMPLE_RATE == 40) + bConfig |= 0x06; +# elif (AS_SAMPLE_RATE == 100) + bConfig |= 0x02; +# elif (AS_SAMPLE_RATE == 400) + bConfig |= 0x04; +# else +# error "Sample rate not supported" +# endif +#else +# error "Measurement range not supported" +#endif + + // Reset sensor + as_write_register(0x04, 0x02); + as_write_register(0x04, 0x0A); + as_write_register(0x04, 0x04); + + // Wait 5 ms before starting sensor output + Timer0_A4_Delay(CONV_MS_TO_TICKS(5)); + + // Set 2g measurement range, start to output data with 100Hz rate + as_write_register(0x02, bConfig); +} + +// ************************************************************************************************* +// @fn as_stop +// @brief Power down acceleration sensor +// @param none +// @return none +// ************************************************************************************************* +void as_stop(void) +{ + // Disable interrupt + AS_INT_IE &= ~AS_INT_PIN; // Disable interrupt + +#ifdef AS_DISCONNECT + // Power-down sensor + AS_PWR_OUT &= ~AS_PWR_PIN; // Power off + AS_INT_OUT &= ~AS_INT_PIN; // Pin to low to avoid floating pins + AS_SPI_OUT &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Pins to low to avoid floating pins + AS_SPI_SEL &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Port pins to I/O function + AS_CSN_OUT &= ~AS_CSN_PIN; // Pin to low to avoid floating pins + AS_INT_DIR |= AS_INT_PIN; // Pin to output to avoid floating pins + AS_SPI_DIR |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Pins to output to avoid floating pins + AS_CSN_DIR |= AS_CSN_PIN; // Pin to output to avoid floating pins +#else + // Reset sensor -> sensor to powerdown + as_write_register(0x04, 0x02); + as_write_register(0x04, 0x0A); + as_write_register(0x04, 0x04); +#endif +} + +// ************************************************************************************************* +// @fn as_read_register +// @brief Read a byte from the acceleration sensor +// @param u8 bAddress Register address +// @return u8 Register content +// ************************************************************************************************* +u8 as_read_register(u8 bAddress) +{ + u8 bResult; + u16 timeout; + + // Exit function if an error was detected previously + if (!as_ok) + return (0); + + bAddress <<= 2; // Address to be shifted left by 2 and + // RW bit to be reset + + AS_SPI_REN &= ~AS_SDI_PIN; // Pulldown on SDI pin not required + AS_CSN_OUT &= ~AS_CSN_PIN; // Select acceleration sensor + + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bAddress; // Write address to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = 0; // Write dummy data to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer + + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin required again + + // Return new data from RX buffer + return bResult; +} + +// ************************************************************************************************* +// @fn as_write_register +// @brief Write a byte to the acceleration sensor +// @param u8 bAddress Register address +// u8 bData Data to write +// @return +// ************************************************************************************************* +u8 as_write_register(u8 bAddress, u8 bData) +{ + u8 bResult; + u16 timeout; + + // Exit function if an error was detected previously + if (!as_ok) + return (0); + + bAddress <<= 2; // Address to be shifted left by 1 + bAddress |= BIT1; // RW bit to be set + + AS_SPI_REN &= ~AS_SDI_PIN; // Pulldown on SDI pin not required + AS_CSN_OUT &= ~AS_CSN_PIN; // Select acceleration sensor + + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bAddress; // Write address to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bData; // Write data to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer + + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin required again + + return bResult; +} + +// ************************************************************************************************* +// @fn as_get_data +// @brief Service routine to read acceleration values. +// @param none +// @return none +// ************************************************************************************************* +void as_get_data(u8 * data) +{ + // Exit if sensor is not powered up + if ((AS_PWR_OUT & AS_PWR_PIN) != AS_PWR_PIN) + return; + + // Store X/Y/Z acceleration data in buffer + *(data + 0) = as_read_register(0x06); + *(data + 1) = as_read_register(0x07); + *(data + 2) = as_read_register(0x08); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_as.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_as.h new file mode 100755 index 0000000..178af33 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_as.h @@ -0,0 +1,106 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef VTI_AS_H_ +#define VTI_AS_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void as_init(void); +extern void as_start(void); +extern void as_stop(void); +extern u8 as_read_register(u8 bAddress); +extern u8 as_write_register(u8 bAddress, u8 bData); +extern void as_get_data(u8 * data); + +// ************************************************************************************************* +// Defines section + +// Disconnect power supply for acceleration sensor when not used +#define AS_DISCONNECT + +// Port and pin resource for SPI interface to acceleration sensor +// SDO=MOSI=P1.6, SDI=MISO=P1.5, SCK=P1.7 +#define AS_SPI_IN (P1IN) +#define AS_SPI_OUT (P1OUT) +#define AS_SPI_DIR (P1DIR) +#define AS_SPI_SEL (P1SEL) +#define AS_SPI_REN (P1REN) +#define AS_SDO_PIN (BIT6) +#define AS_SDI_PIN (BIT5) +#define AS_SCK_PIN (BIT7) + +// CSN=PJ.1 +#define AS_CSN_OUT (PJOUT) +#define AS_CSN_DIR (PJDIR) +#define AS_CSN_PIN (BIT1) + +#define AS_TX_BUFFER (UCA0TXBUF) +#define AS_RX_BUFFER (UCA0RXBUF) +#define AS_TX_IFG (UCTXIFG) +#define AS_RX_IFG (UCRXIFG) +#define AS_IRQ_REG (UCA0IFG) +#define AS_SPI_CTL0 (UCA0CTL0) +#define AS_SPI_CTL1 (UCA0CTL1) +#define AS_SPI_BR0 (UCA0BR0) +#define AS_SPI_BR1 (UCA0BR1) + +// Port and pin resource for power-up of acceleration sensor, VDD=PJ.0 +#define AS_PWR_OUT (PJOUT) +#define AS_PWR_DIR (PJDIR) +#define AS_PWR_PIN (BIT0) + +// Port, pin and interrupt resource for interrupt from acceleration sensor, CMA_INT=P2.5 +#define AS_INT_IN (P2IN) +#define AS_INT_OUT (P2OUT) +#define AS_INT_DIR (P2DIR) +#define AS_INT_IE (P2IE) +#define AS_INT_IES (P2IES) +#define AS_INT_IFG (P2IFG) +#define AS_INT_PIN (BIT5) + +// SPI timeout to detect sensor failure +#define SPI_TIMEOUT (1000u) + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*VTI_AS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_ps.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_ps.c new file mode 100755 index 0000000..fa2d493 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_ps.c @@ -0,0 +1,563 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// VTI SCP1000-D0x pressure sensor driver functions +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "vti_ps.h" +#include "timer.h" + +// ************************************************************************************************* +// Prototypes section +u16 ps_read_register(u8 address, u8 mode); +u8 ps_write_register(u8 address, u8 data); +u8 ps_twi_read(u8 ack); +void twi_delay(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// VTI pressure (hPa) to altitude (m) conversion tables +const s16 h0[17] = +{ -153, 0, 111, 540, 989, 1457, 1949, 2466, 3012, 3591, 4206, 4865, 5574, 6344, 7185, 8117, 9164 }; +const u16 p0[17] = +{ 1031, 1013, 1000, 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300 }; + +float p[17]; + +// Global flag for proper pressure sensor operation +u8 ps_ok; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn ps_init +// @brief Init pressure sensor I/O +// @param none +// @return none +// ************************************************************************************************* +void ps_init(void) +{ + volatile u8 success, status, eeprom, timeout; + + PS_INT_DIR &= ~PS_INT_PIN; // DRDY is input + PS_INT_IES &= ~PS_INT_PIN; // Interrupt on DRDY rising edge + PS_TWI_OUT |= PS_SCL_PIN + PS_SDA_PIN; // SCL and SDA are outputs by default + PS_TWI_DIR |= PS_SCL_PIN + PS_SDA_PIN; // SCL and SDA are outputs by default + + // Reset global ps_ok flag + ps_ok = 0; + + // 100msec delay to allow VDD stabilisation + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + + // Reset pressure sensor -> powerdown sensor + success = ps_write_register(0x06, 0x01); + + // 100msec delay + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + + // Check if STATUS register BIT0 is cleared + status = ps_read_register(0x07, PS_TWI_8BIT_ACCESS); + if (((status & BIT0) == 0) && (status != 0)) + { + // Check EEPROM checksum in DATARD8 register + eeprom = ps_read_register(0x7F, PS_TWI_8BIT_ACCESS); + if (eeprom == 0x01) + ps_ok = 1; + else + ps_ok = 0; + } +} + +// ************************************************************************************************* +// @fn ps_start +// @brief Init pressure sensor registers and start sampling +// @param none +// @return u8 1=Sensor started, 0=Sensor did not start +// ************************************************************************************************* +void ps_start(void) +{ + // Start sampling data in ultra low power mode + ps_write_register(0x03, 0x0B); +} + +// ************************************************************************************************* +// @fn ps_stop +// @brief Power down pressure sensor +// @param none +// @return none +// ************************************************************************************************* +void ps_stop(void) +{ + // Put sensor to standby + ps_write_register(0x03, 0x00); +} + +// ************************************************************************************************* +// @fn ps_twi_sda +// @brief Control SDA line +// @param u8 condition PS_TWI_SEND_START, PS_TWI_SEND_RESTART, PS_TWI_SEND_STOP +// PS_TWI_CHECK_ACK +// @return u8 1=ACK, 0=NACK +// ************************************************************************************************* +u8 ps_twi_sda(u8 condition) +{ + u8 sda = 0; + + if (condition == PS_TWI_SEND_START) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; // SCL 1-0 transition while SDA=0 + twi_delay(); + } + else if (condition == PS_TWI_SEND_RESTART) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SCL_LO; + PS_TWI_SDA_HI; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; + twi_delay(); + } + else if (condition == PS_TWI_SEND_STOP) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_HI; // SDA 0-1 transition while SCL=1 + twi_delay(); + } + else if (condition == PS_TWI_CHECK_ACK) + { + PS_TWI_SDA_IN; // SDA is input + PS_TWI_SCL_LO; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + sda = PS_TWI_IN & PS_SDA_PIN; + PS_TWI_SCL_LO; + } + + // Return value will only be evaluated when checking device ACK + return (sda == 0); +} + +// ************************************************************************************************* +// @fn twi_delay +// @brief Delay between TWI signal edges. +// @param none +// @return none +// ************************************************************************************************* +void twi_delay(void) +{ + asm (" nop"); +} + +// ************************************************************************************************* +// @fn ps_twi_write +// @brief Clock out bits through SDA. +// @param u8 data Byte to send +// @return none +// ************************************************************************************************* +void ps_twi_write(u8 data) +{ + u8 i, mask; + + // Set mask byte to 10000000b + mask = BIT0 << 7; + + PS_TWI_SDA_OUT; // SDA is output + + for (i = 8; i > 0; i--) + { + PS_TWI_SCL_LO; // SCL=0 + if ((data & mask) == mask) + { + PS_TWI_SDA_HI; // SDA=1 + } + else + { + PS_TWI_SDA_LO; // SDA=0 + } + mask = mask >> 1; + twi_delay(); + PS_TWI_SCL_HI; // SCL=1 + twi_delay(); + } + + PS_TWI_SCL_LO; // SCL=0 + PS_TWI_SDA_IN; // SDA is input +} + +// ************************************************************************************************* +// @fn ps_twi_read +// @brief Read bits from SDA +// @param u8 ack 1=Send ACK after read, 0=Send NACK after read +// @return u8 Bits read +// ************************************************************************************************* +u8 ps_twi_read(u8 ack) +{ + u8 i; + u8 data = 0; + + PS_TWI_SDA_IN; // SDA is input + + for (i = 0; i < 8; i++) + { + PS_TWI_SCL_LO; // SCL=0 + twi_delay(); + PS_TWI_SCL_HI; // SCL=0 + twi_delay(); + + // Shift captured bits to left + data = data << 1; + + // Capture new bit + if ((PS_TWI_IN & PS_SDA_PIN) == PS_SDA_PIN) + data |= BIT0; + } + + PS_TWI_SDA_OUT; // SDA is output + + // 1 aditional clock phase to generate master ACK + PS_TWI_SCL_LO; // SCL=0 + if (ack == 1) // Send ack -> continue read + { + PS_TWI_SDA_LO + } + else // Send nack -> stop read + { + PS_TWI_SDA_HI + } + twi_delay(); + PS_TWI_SCL_HI; // SCL=0 + twi_delay(); + PS_TWI_SCL_LO; + + return (data); +} + +// ************************************************************************************************* +// @fn as_write_register +// @brief Write a byte to the pressure sensor +// @param u8 address Register address +// u8 data Data to write +// @return u8 +// ************************************************************************************************* +u8 ps_write_register(u8 address, u8 data) +{ + volatile u8 success; + + ps_twi_sda(PS_TWI_SEND_START); // Generate start condition + + ps_twi_write((0x11 << 1) | PS_TWI_WRITE); // Send 7bit device address 0x11 + write bit '0' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(address); // Send 8bit register address + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(data); // Send 8bit data to register + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + // Slave does not send this ACK + // if (!success) return (0); + + ps_twi_sda(PS_TWI_SEND_STOP); // Generate stop condition + + return (1); +} + +// ************************************************************************************************* +// @fn ps_read_register +// @brief Read a byte from the pressure sensor +// @param u8 address Register address +// u8 mode PS_TWI_8BIT_ACCESS, PS_TWI_16BIT_ACCESS +// @return u16 Register content +// ************************************************************************************************* +u16 ps_read_register(u8 address, u8 mode) +{ + u8 success; + u16 data = 0; + + ps_twi_sda(PS_TWI_SEND_START); // Generate start condition + + ps_twi_write((0x11 << 1) | PS_TWI_WRITE); // Send 7bit device address 0x11 + write bit '0' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(address); // Send 8bit register address + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_sda(PS_TWI_SEND_RESTART); // Generate restart condition + + ps_twi_write((0x11 << 1) | PS_TWI_READ); // Send 7bit device address 0x11 + read bit '1' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + if (mode == PS_TWI_16BIT_ACCESS) + { + data = ps_twi_read(1) << 8; // Read MSB 8bit data from register + data |= ps_twi_read(0); // Read LSB 8bit data from register + } + else + { + data = ps_twi_read(0); // Read 8bit data from register + } + + ps_twi_sda(PS_TWI_SEND_STOP); // Generate stop condition + + return (data); +} + +// ************************************************************************************************* +// @fn ps_get_pa +// @brief Read out pressure. Format is Pa. Range is 30000 .. 120000 Pa. +// @param none +// @return u32 15-bit pressure sensor value (Pa) +// ************************************************************************************************* +u32 ps_get_pa(void) +{ + volatile u32 data = 0; + + // Get 3 MSB from DATARD8 register + data = ps_read_register(0x7F, PS_TWI_8BIT_ACCESS); + data = ((data & 0x07) << 8) << 8; + + // Get 16 LSB from DATARD16 register + data |= ps_read_register(0x80, PS_TWI_16BIT_ACCESS); + + // Convert decimal value to Pa + data = (data >> 2); + + return (data); +} + +// ************************************************************************************************* +// @fn ps_get_temp +// @brief Read out temperature. +// @param none +// @return u16 13-bit temperature value in xx.x K format +// ************************************************************************************************* +u16 ps_get_temp(void) +{ + volatile u16 data = 0; + u16 temp = 0; + u8 is_negative = 0; + u16 kelvin; + + // Get 13 bit from TEMPOUT register + data = ps_read_register(0x81, PS_TWI_16BIT_ACCESS); + + // Convert negative temperatures + if ((data & BIT(13)) == BIT(13)) + { + // Sign extend temperature + data |= 0xC000; + // Convert two's complement + data = ~data; + data += 1; + is_negative = 1; + } + + temp = data / 2; + + // Convert from °C to K + if (is_negative) + kelvin = 2732 - temp; + else + kelvin = temp + 2732; + + return (kelvin); +} + +// ************************************************************************************************* +// @fn init_pressure_table +// @brief Init pressure table with constants +// @param u32 p Pressure (Pa) +// @return u16 Altitude (m) +// ************************************************************************************************* +void init_pressure_table(void) +{ + u8 i; + + for (i = 0; i < 17; i++) + p[i] = p0[i]; +} + +// ************************************************************************************************* +// @fn update_pressure_table +// @brief Calculate pressure table for reference altitude. +// Implemented straight from VTI reference code. +// @param s16 href Reference height +// u32 p_meas Pressure (Pa) +// u16 t_meas Temperature (10*K) +// @return none +// ************************************************************************************************* +void update_pressure_table(s16 href, u32 p_meas, u16 t_meas) +{ + const float Invt00 = 0.003470415; + const float coefp = 0.00006; + volatile float p_fact; + volatile float p_noll; + volatile float hnoll; + volatile float h_low = 0; + volatile float t0; + u8 i; + + // Typecast arguments + volatile float fl_href = href; + volatile float fl_p_meas = (float)p_meas / 100; // Convert from Pa to hPa + volatile float fl_t_meas = (float)t_meas / 10; // Convert from 10 K to 1 K + + t0 = fl_t_meas + (0.0065 * fl_href); + + hnoll = fl_href / (t0 * Invt00); + + for (i = 0; i <= 15; i++) + { + if (h0[i] > hnoll) + break; + h_low = h0[i]; + } + + p_noll = + (float)(hnoll - + h_low) * + (1 - + (hnoll - + (float)h0[i]) * + coefp) * ((float)p0[i] - (float)p0[i - 1]) / ((float)h0[i] - h_low) + (float)p0[i - 1]; + + // Calculate multiplicator + p_fact = fl_p_meas / p_noll; + + // Apply correction factor to pressure table + for (i = 0; i <= 16; i++) + { + p[i] = p0[i] * p_fact; + } +} + +// ************************************************************************************************* +// @fn conv_pa_to_meter +// @brief Convert pressure (Pa) to altitude (m) using a conversion table +// Implemented straight from VTI reference code. +// @param u32 p_meas Pressure (Pa) +// u16 t_meas Temperature (10* K) +// @return s16 Altitude (m) +// ************************************************************************************************* +s16 conv_pa_to_meter(u32 p_meas, u16 t_meas) +{ + const float coef2 = 0.0007; + const float Invt00 = 0.003470415; + volatile float hnoll; + volatile float t0; + volatile float p_low; + volatile float fl_h; + volatile s16 h; + u8 i; + + // Typecast arguments + volatile float fl_p_meas = (float)p_meas / 100; // Convert from Pa to hPa + volatile float fl_t_meas = (float)t_meas / 10; // Convert from 10 K to 1 K + + for (i = 0; i <= 16; i++) + { + if (p[i] < fl_p_meas) + break; + p_low = p[i]; + } + + if (i == 0) + { + hnoll = (float)(fl_p_meas - p[0]) / (p[1] - p[0]) * ((float)(h0[1] - h0[0])); + } + else if (i < 15) + { + hnoll = + (float)(fl_p_meas - + p_low) * + (1 - + (fl_p_meas - + p[i]) * coef2) / (p[i] - p_low) * ((float)(h0[i] - h0[i - 1])) + h0[i - 1]; + } + else if (i == 15) + { + hnoll = + (float)(fl_p_meas - p_low) / (p[i] - p_low) * ((float)(h0[i] - h0[i - 1])) + h0[i - 1]; + } + else // i==16 + { + hnoll = (float)(fl_p_meas - p[16]) / (p[16] - p[15]) * ((float)(h0[16] - h0[15])) + h0[16]; + } + + // Compensate temperature error + t0 = fl_t_meas / (1 - hnoll * Invt00 * 0.0065); + fl_h = Invt00 * t0 * hnoll; + h = (u16) fl_h; + + return (h); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_ps.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_ps.h new file mode 100755 index 0000000..e044695 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/driver/vti_ps.h @@ -0,0 +1,99 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef VTI_PS_H_ +#define VTI_PS_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void ps_init(void); +extern void ps_start(void); +extern void ps_stop(void); +extern u32 ps_get_pa(void); +extern u16 ps_get_temp(void); +extern void init_pressure_table(void); +extern void update_pressure_table(s16 href, u32 p_meas, u16 t_meas); +extern s16 conv_pa_to_meter(u32 p_meas, u16 t_meas); + +// ************************************************************************************************* +// Defines section + +// Port and pin resource for TWI interface to pressure sensor +// SCL=PJ.3, SDA=PJ.2, DRDY=P2.6 +#define PS_TWI_IN (PJIN) +#define PS_TWI_OUT (PJOUT) +#define PS_TWI_DIR (PJDIR) +#define PS_TWI_REN (PJREN) +#define PS_SCL_PIN (BIT3) +#define PS_SDA_PIN (BIT2) + +// Port, pin and interrupt resource for interrupt from acceleration sensor, DRDY=P2.6 +#define PS_INT_IN (P2IN) +#define PS_INT_OUT (P2OUT) +#define PS_INT_DIR (P2DIR) +#define PS_INT_IE (P2IE) +#define PS_INT_IES (P2IES) +#define PS_INT_IFG (P2IFG) +#define PS_INT_PIN (BIT6) + +// TWI defines +#define PS_TWI_WRITE (0u) +#define PS_TWI_READ (1u) + +#define PS_TWI_SEND_START (0u) +#define PS_TWI_SEND_RESTART (1u) +#define PS_TWI_SEND_STOP (2u) +#define PS_TWI_CHECK_ACK (3u) + +#define PS_TWI_8BIT_ACCESS (0u) +#define PS_TWI_16BIT_ACCESS (1u) + +#define PS_TWI_SCL_HI { PS_TWI_OUT |= PS_SCL_PIN; } +#define PS_TWI_SCL_LO { PS_TWI_OUT &= ~PS_SCL_PIN; } +#define PS_TWI_SDA_HI { PS_TWI_OUT |= PS_SDA_PIN; } +#define PS_TWI_SDA_LO { PS_TWI_OUT &= ~PS_SDA_PIN; } +#define PS_TWI_SDA_IN { PS_TWI_OUT |= PS_SDA_PIN; PS_TWI_DIR &= ~PS_SDA_PIN; } +#define PS_TWI_SDA_OUT { PS_TWI_DIR |= PS_SDA_PIN; } + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*VTI_PS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/ez430_chronos_datalogger.ewd b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/ez430_chronos_datalogger.ewd new file mode 100755 index 0000000..1c1c244 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/ez430_chronos_datalogger.ewd @@ -0,0 +1,1963 @@ + + + + 2 + + 915MHz - Limited IAR Kickstart (USA) + + MSP430 + + 1 + + C-SPY + 4 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 868MHz - Limited IAR Kickstart (Europe) + + MSP430 + + 1 + + C-SPY + 4 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 433MHz - Limited IAR Kickstart (Other regions) + + MSP430 + + 1 + + C-SPY + 4 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 915MHz - Unrestricted IAR Workbench (USA) + + MSP430 + + 1 + + C-SPY + 4 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 868MHz - Unrestricted IAR Workbench (Europe) + + MSP430 + + 1 + + C-SPY + 4 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 433MHz - Unrestricted IAR Workbench (Other regions) + + MSP430 + + 1 + + C-SPY + 4 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/ez430_chronos_datalogger.ewp b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/ez430_chronos_datalogger.ewp new file mode 100755 index 0000000..44fe498 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/ez430_chronos_datalogger.ewp @@ -0,0 +1,6037 @@ + + + + 2 + + 915MHz - Limited IAR Kickstart (USA) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 868MHz - Limited IAR Kickstart (Europe) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 433MHz - Limited IAR Kickstart (Other regions) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 915MHz - Unrestricted IAR Workbench (USA) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 868MHz - Unrestricted IAR Workbench (Europe) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 433MHz - Unrestricted IAR Workbench (Other regions) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + bluerobin + + $PROJ_DIR$\bluerobin\BlueRobin_RX_433MHz.r43 + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + + + + $PROJ_DIR$\bluerobin\BlueRobin_RX_868MHz.r43 + + 915MHz - Limited IAR Kickstart (USA) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\bluerobin\BlueRobin_RX_915MHz.r43 + + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\bluerobin\BlueRobin_RX_API.h + + + $PROJ_DIR$\bluerobin\bm.h + + + + driver + + $PROJ_DIR$\driver\adc12.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\adc12.h + + + $PROJ_DIR$\driver\buzzer.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\buzzer.h + + + $PROJ_DIR$\driver\display.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\display.h + + + $PROJ_DIR$\driver\ez430_chronos_datalogger_codesize_limited_drivers.r43 + + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\driver\flash.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\flash.h + + + $PROJ_DIR$\driver\pmm.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\pmm.h + + + $PROJ_DIR$\driver\ports.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\ports.h + + + $PROJ_DIR$\driver\radio.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\radio.h + + + $PROJ_DIR$\driver\rf1a.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\rf1a.h + + + $PROJ_DIR$\driver\timer.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\timer.h + + + $PROJ_DIR$\driver\vti_as.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\vti_as.h + + + $PROJ_DIR$\driver\vti_ps.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\vti_ps.h + + + + include + + $PROJ_DIR$\include\project.h + + + + logic + + $PROJ_DIR$\logic\acceleration.c + + + $PROJ_DIR$\logic\acceleration.h + + + $PROJ_DIR$\logic\altitude.c + + + $PROJ_DIR$\logic\altitude.h + + + $PROJ_DIR$\logic\battery.c + + + $PROJ_DIR$\logic\battery.h + + + $PROJ_DIR$\logic\bluerobin.c + + + $PROJ_DIR$\logic\bluerobin.h + + + $PROJ_DIR$\logic\clock.c + + + $PROJ_DIR$\logic\clock.h + + + $PROJ_DIR$\logic\datalog.c + + + $PROJ_DIR$\logic\datalog.h + + + $PROJ_DIR$\logic\date.c + + + $PROJ_DIR$\logic\date.h + + + $PROJ_DIR$\logic\menu.c + + + $PROJ_DIR$\logic\menu.h + + + $PROJ_DIR$\logic\rfbsl.c + + + $PROJ_DIR$\logic\rfbsl.h + + + $PROJ_DIR$\logic\rfsimpliciti.c + + + $PROJ_DIR$\logic\rfsimpliciti.h + + + $PROJ_DIR$\logic\temperature.c + + + $PROJ_DIR$\logic\temperature.h + + + $PROJ_DIR$\logic\user.c + + + $PROJ_DIR$\logic\user.h + + + + simpliciti + + Applications + + application + + End Device + + $PROJ_DIR$\simpliciti\Applications\application\End Device\main_ED_BM.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + + + configuration + + End Device + + $PROJ_DIR$\simpliciti\Applications\configuration\End Device\smpl_config.dat + + + + $PROJ_DIR$\simpliciti\Applications\configuration\smpl_nwk_config.dat + + + + + Components + + bsp + + boards + + CC430EM + + bsp_external + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_external\mrfi_board_defs.h + + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_board.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_board_defs.h + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_button_defs.h + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_config.h + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_driver_defs.h + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_drivers.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_led_defs.h + + + + + drivers + + code + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_buttons.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_generic_buttons.h + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_generic_leds.h + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_leds.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\bsp_buttons.h + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\bsp_leds.h + + + + mcus + + $PROJ_DIR$\simpliciti\Components\bsp\mcus\bsp_msp430_defs.h + + + + $PROJ_DIR$\simpliciti\Components\bsp\bsp.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\bsp.h + + + $PROJ_DIR$\simpliciti\Components\bsp\bsp_macros.h + + + + mrfi + + radios + + family5 + + $PROJ_DIR$\simpliciti\Components\mrfi\radios\family5\mrfi_radio.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\mrfi\radios\family5\mrfi_radio_interface.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\mrfi\radios\family5\mrfi_radio_interface.h + + + + + smartrf + + CC1101 + + $PROJ_DIR$\simpliciti\Components\mrfi\smartrf\CC1101\smartrf_CC1101.h + + + + + $PROJ_DIR$\simpliciti\Components\mrfi\mrfi.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\mrfi\mrfi.h + + + $PROJ_DIR$\simpliciti\Components\mrfi\mrfi_defs.h + + + + nwk + + $PROJ_DIR$\simpliciti\Components\nwk\nwk.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_api.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_api.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_app.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_frame.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_frame.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_globals.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_globals.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_QMgmt.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_QMgmt.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_types.h + + + + nwk_applications + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_freq.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_freq.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ioctl.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ioctl.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_join.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_join.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_link.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_link.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_mgmt.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_mgmt.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ping.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ping.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_security.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_security.h + + + + + $PROJ_DIR$\simpliciti\CC430_End_Device_433MHz.r43 + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\CC430_End_Device_868MHz.r43 + + 915MHz - Limited IAR Kickstart (USA) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\CC430_End_Device_915MHz.r43 + + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\simpliciti.h + + + + $PROJ_DIR$\change_record.txt + + + $PROJ_DIR$\lnkCC430F6137.xcl + + + $PROJ_DIR$\main.c + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/ez430_chronos_datalogger.eww b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/ez430_chronos_datalogger.eww new file mode 100755 index 0000000..000c020 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/ez430_chronos_datalogger.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\ez430_chronos_datalogger.ewp + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/include/project.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/include/project.h new file mode 100755 index 0000000..5fa7ed2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/include/project.h @@ -0,0 +1,132 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef PROJECT_H_ +#define PROJECT_H_ + +// ************************************************************************************************* +// Include section +#include +#include + +// ************************************************************************************************* +// Defines section + +// Comment this to not use the LCD charge pump +//#define USE_LCD_CHARGE_PUMP + +// Uncomment this define to build the application without watchdog support +#define USE_WATCHDOG + +// Use/not use filter when measuring physical values +#define FILTER_OFF (0u) +#define FILTER_ON (1u) + +// Uncomment this define to build the application with BlueRobin heartrate support +#define INCLUDE_BLUEROBIN_SUPPORT + +// ************************************************************************************************* +// Macro section + +// Conversion from usec to ACLK timer ticks +#define CONV_US_TO_TICKS(usec) (((usec) * 32768) / 1000000) + +// Conversion from msec to ACLK timer ticks +#define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000) + +// ************************************************************************************************* +// Typedef section + +typedef enum +{ + MENU_ITEM_NOT_VISIBLE = 0, // Menu item is not visible + MENU_ITEM_VISIBLE // Menu item is visible +} menu_t; + +// Set of system flags +typedef union +{ + struct + { + u16 idle_timeout :1; // Timeout after inactivity + u16 idle_timeout_enabled :1; // When in set mode, timeout after a given period + u16 lock_buttons :1; // Lock buttons + u16 mask_buzzer :1; // Do not output buzz for next button event + u16 up_down_repeat_enabled :1; // While in set_value(), create virtual UP / DOWN button press + u16 low_battery :1; // 1 = Battery is low + u16 use_metric_units :1; // 1 = Use metric units, 0 = use English units + u16 delay_over :1; // 1 = Timer delay over + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_system_flags; +extern volatile s_system_flags sys; + +// Set of request flags +typedef union +{ + struct + { + u16 voltage_measurement :1; // 1 = Measure voltage + u16 altitude_measurement :1; // 1 = Measure air pressure + u16 acceleration_measurement :1; // 1 = Measure acceleration + u16 datalog :1; // 1 = Add data + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_request_flags; +extern volatile s_request_flags request; + +// Set of message flags +typedef union +{ + struct + { + u16 prepare :1; // 1 = Wait for clock tick, then set display.flag.show_message flag + u16 show :1; // 1 = Display message now + u16 erase :1; // 1 = Erase message + u16 type_locked :1; // 1 = Show "buttons are locked" in Line2 + u16 type_unlocked :1; // 1 = Show "buttons are unlocked" in Line2 + u16 type_lobatt :1; // 1 = Show "lobatt" text in Line2 + u16 type_on :1; // 1 = Show " on" text in Line1 + u16 type_off :1; // 1 = Show " off" text in Line1 + u16 type_nomem :1; // 1 = Show "nomem" text in Line2 + } flag; + u16 all_flags; // Shortcut to all message flags (for reset) +} s_message_flags; +extern volatile s_message_flags message; + +// ************************************************************************************************* +// Global Variable section + +#endif /*PROJECT_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/lnkcc430f6137.xcl b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/lnkcc430f6137.xcl new file mode 100755 index 0000000..f5c0401 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/lnkcc430f6137.xcl @@ -0,0 +1,138 @@ +//***************************************************************** +// +// XLINK command file for IAR Embedded Workbench for MSP430. +// +// This file should be used with the CC430F6137 microprocessor. +// +// Copyright 1996-2007 IAR Systems. All rights reserved. +// +// Usage: xlink your_file(s) -f lnkcc430f6137 library +// +// $Revision: 1.30 $ +// +//***************************************************************** + +//***************************************************************** +// +// The memory areas of the CC430F6137 microprocessor: +// +// Peripheral units: 0 - 01FF +// +// Information memory (FLASH): 1800 - 19FF +// +// Read-write memory (RAM): 1C00 - 23FD +// +// Read-only memory (FLASH): 8000 - FF7F +// +// +//***************************************************************** + +//***************************************************************** +// +// The following segments are defined in this linker command file: +// +// Data read/write segments (RAM) +// ============================== +// +// segment Restrictions Usage +// ------- ------------ -------------------------- +// DATA16_I < 10000 Data16 initialized variables +// DATA16_Z < 10000 Data16 zero initialized variables +// DATA16_N < 10000 Data16 uninitialized variables +// DATA16_HEAP < 10000 Data16 heap used by malloc and free +// DATA20_I Data20 initialized variables +// DATA20_Z Data20 zero initialized variables +// DATA20_N Data20 uninitialized variables +// DATA20_HEAP Data20 heap used by malloc and free +// CSTACK < 10000 Runtime stack +// +// +// Program and data read-only segments (FLASH) +// =========================================== +// +// segment Restrictions Usage +// ------- ------------ -------------------------- +// INFO Information memory +// CSTART < 10000 Program startup code +// CODE Program code +// ISR_CODE < 10000 Program code for interrupt service routines +// DATA16_C < 10000 Data16 constant data and string literals +// DATA16_ID < 10000 Data16 initializers for DATA16_I +// DATA20_C Data20 constant data and string literals +// DATA20_ID Data20 initializers for DATA20_I +// DIFUNCT < 10000 Dynamic initialization vector used by C++ +// CHECKSUM Checksum byte(s) generated by the -J option +// INTVEC FF80-FFFF Interrupt vectors +// RESET FFFE-FFFF The reset vector +// +//***************************************************************** + + +// --------------------------------------------------------- +// Stack and heap sizes. +// --------------------------------------------------------- + +// Uncomment for command line use +//-D_STACK_SIZE=80 +//-D_DATA16_HEAP_SIZE=80 + + +// --------------------------------------------------------- +// Define cpu. +// --------------------------------------------------------- + +-cmsp430 + + +// --------------------------------------------------------- +// Read-write memory. +// --------------------------------------------------------- + +-Z(DATA)DATA16_I,DATA16_Z,DATA16_N,DATA16_HEAP+_DATA16_HEAP_SIZE=1C00-23FD +-Z(DATA)CSTACK+_STACK_SIZE# + + +// --------------------------------------------------------- +// Read only memory + + +// --------------------------------------------------------- +// Information memory +// --------------------------------------------------------- + +-Z(CODE)INFO=1800-19FF +-Z(CODE)INFOA=1980-19FF +-Z(CODE)INFOB=1900-197F +-Z(CODE)INFOC=1880-18FF +-Z(CODE)INFOD=1800-187F + + + +// --------------------------------------------------------- +// Constant data +// --------------------------------------------------------- + +//-Z(CONST)DATA16_C,DATA16_ID,DIFUNCT=8000-FF7F +-Z(CONST)DATA16_C,DATA16_ID,DIFUNCT=9E00-FF7F + +// --------------------------------------------------------- +// Code +// --------------------------------------------------------- + +//-Z(CODE)CSTART,ISR_CODE=8000-FF7F +//-P(CODE)CODE=8000-FF7F +-Z(CODE)CSTART,ISR_CODE=9E00-FF7F +-P(CODE)CODE=9E00-FF7F + + +// --------------------------------------------------------- +// Interrupt vectors +// --------------------------------------------------------- + +-Z(CODE)INTVEC=FF80-FFFF +-Z(CODE)RESET=FFFE-FFFF + + +// --------------------------------------------------------- +// The end +// --------------------------------------------------------- diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/acceleration.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/acceleration.c new file mode 100755 index 0000000..c422496 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/acceleration.c @@ -0,0 +1,241 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Acceleration measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "vti_as.h" + +// logic +#include "acceleration.h" +#include "simpliciti.h" +#include "user.h" + +// ************************************************************************************************* +// Global Variable section +struct accel sAccel; + +// Conversion values from data to mgrav taken from CMA3000-D0x datasheet (rev 0.4, table 4) +const u16 mgrav_per_bit[7] = { 18, 36, 71, 143, 286, 571, 1142 }; + +// ************************************************************************************************* +// Extern section + +// Global flag for proper acceleration sensor operation +extern u8 as_ok; + +// ************************************************************************************************* +// @fn reset_acceleration +// @brief Reset acceleration variables. +// @param none +// @return none +// ************************************************************************************************* +void reset_acceleration(void) +{ +} + +// ************************************************************************************************* +// @fn acceleration_value_is_positive +// @brief Returns 1 if 2's complement number is positive +// @param u8 value 2's complement number +// @return u8 1 = number is positive, 0 = number is negavtive +// ************************************************************************************************* +u8 acceleration_value_is_positive(u8 value) +{ + return ((value & BIT7) == 0); +} + +// ************************************************************************************************* +// @fn convert_acceleration_value_to_mgrav +// @brief Converts measured value to mgrav units +// @param u8 value g data from sensor +// @return u16 Acceleration (mgrav) +// ************************************************************************************************* +u16 convert_acceleration_value_to_mgrav(u8 value) +{ + u16 result; + u8 i; + + if (!acceleration_value_is_positive(value)) + { + // Convert 2's complement negative number to positive number + value = ~value; + value += 1; + } + + result = 0; + for (i = 0; i < 7; i++) + { + result += ((value & (BIT(i))) >> i) * mgrav_per_bit[i]; + } + + return (result); +} + +// +//// +// ************************************************************************************************* +//// @fn display_acceleration +//// @brief Display routine. +//// @param u8 line LINE1 +//// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +//// @return none +//// +// ************************************************************************************************* +//void display_acceleration(u8 line, u8 update) +//{ +// u8 * str; +// u8 raw_data; +// u16 accel_data; +// +// // Show warning if acceleration sensor was not initialised properly +// if (!as_ok) +// { +// display_chars(LCD_SEG_L1_2_0, (u8*)"ERR", SEG_ON); +// } +// else +// { +// // Redraw whole screen +// if (update == DISPLAY_LINE_UPDATE_FULL) +// { +// { +// // Start acceleration sensor +// if (!is_acceleration_measurement()) +// { +// // Clear previous acceleration value +// sAccel.data = 0; +// +// // Start sensor +// as_start(); +// +// // Set timeout counter +// sAccel.timeout = ACCEL_MEASUREMENT_TIMEOUT; +// +// // Set mode +// sAccel.mode = ACCEL_MODE_ON; +// +// // Start with Y-axis values +// sAccel.view_style = DISPLAY_ACCEL_Y; +// } +// +// // Display decimal point +// display_symbol(LCD_SEG_L1_DP1, SEG_ON); +// } +// } +// else if (update == DISPLAY_LINE_UPDATE_PARTIAL) +// { +// // Convert X/Y/Z values to mg +// switch (sAccel.view_style) +// { +// case DISPLAY_ACCEL_X: raw_data = sAccel.xyz[0]; +// +// +// +// +// +// +// +// display_char(LCD_SEG_L1_3, +// 'X', SEG_ON); +// break; +// case DISPLAY_ACCEL_Y: raw_data = sAccel.xyz[1]; +// +// +// +// +// +// +// +// display_char(LCD_SEG_L1_3, +// 'Y', SEG_ON); +// break; +// default: raw_data = sAccel.xyz[2]; +// +// +// +// +// +// +// +// display_char(LCD_SEG_L1_3, +// 'Z', SEG_ON); +// break; +// } +// accel_data = convert_acceleration_value_to_mgrav(raw_data) / 10; +// +// // Filter acceleration +// accel_data = (u16)((accel_data * 0.2) + (sAccel.data * 0.8)); +// +// // Store average acceleration +// sAccel.data = accel_data; +// +// // Display acceleration in x.xx format +// str = int_to_array(accel_data, 3, 0); +// display_chars(LCD_SEG_L1_2_0, str, SEG_ON); +// +// // Display sign +// if (acceleration_value_is_positive(raw_data)) +// { +// display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); +// display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); +// } +// else +// { +// display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); +// display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); +// } +// } +// else if (update == DISPLAY_LINE_CLEAR) +// { +// // Stop acceleration sensor +// as_stop(); +// +// // Clear mode +// sAccel.mode = ACCEL_MODE_OFF; +// +// // Clean up display +// display_symbol(LCD_SEG_L1_DP1, SEG_OFF); +// display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); +// display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); +// } +// } +//} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/acceleration.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/acceleration.h new file mode 100755 index 0000000..7b39c2a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/acceleration.h @@ -0,0 +1,78 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ACCELERATION_H_ +#define ACCELERATION_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +//#define DISPLAY_ACCEL_X (0u) +//#define DISPLAY_ACCEL_Y (1u) +//#define DISPLAY_ACCEL_Z (2u) + +//#define ACCEL_MODE_OFF (0u) +//#define ACCEL_MODE_ON (1u) + +// Stop acceleration measurement after 60 minutes to save battery +//#define ACCEL_MEASUREMENT_TIMEOUT (60*60u) + +// ************************************************************************************************* +// Global Variable section +struct accel +{ + // u8 mode; // ACC_MODE_OFF, ACC_MODE_ON + u8 xyz[3]; // Sensor raw data + u16 data; // Acceleration data in 10 * mgrav + // u8 view_style; // Display X/Y/Z values + // u16 timeout; // Timeout +}; +extern struct accel sAccel; + +// ************************************************************************************************* +// Extern section +extern void reset_acceleration(void); +extern void sx_acceleration(u8 line); +extern void display_acceleration(u8 line, u8 update); +extern u8 is_acceleration_measurement(void); +extern void do_acceleration_measurement(void); + +#endif /*ACCELERATION_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/altitude.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/altitude.c new file mode 100755 index 0000000..b1cf98d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/altitude.c @@ -0,0 +1,342 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Altitude measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "altitude.h" +#include "display.h" +#include "vti_ps.h" +#include "ports.h" +#include "timer.h" + +// logic +#include "user.h" +#include "datalog.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct alt sAlt; + +// ************************************************************************************************* +// Extern section + +// Global flag for pressure sensor initialisation status +extern u8 ps_ok; + +// ************************************************************************************************* +// @fn reset_altitude_measurement +// @brief Reset altitude measurement. +// @param none +// @return none +// ************************************************************************************************* +void reset_altitude_measurement(void) +{ + // Set default values + sAlt.on = 0; + sAlt.altitude = 0; + sAlt.temperature_C = 0; + sAlt.temperature_C_offset = 0; + + // Pressure sensor ok? + if (ps_ok) + { + // Initialise pressure table + init_pressure_table(); + + // Do single conversion + start_altitude_measurement(); + stop_altitude_measurement(); + + // Apply calibration offset and recalculate pressure table + if (sAlt.altitude_offset != 0) + { + sAlt.altitude += sAlt.altitude_offset; + update_pressure_table(sAlt.altitude, sAlt.pressure, sAlt.temperature_K); + } + } +} + +// ************************************************************************************************* +// @fn conv_m_to_ft +// @brief Convert meters to feet +// @param u16 m Meters +// @return u16 Feet +// ************************************************************************************************* +s16 convert_m_to_ft(s16 m) +{ + return (((s32) 328 * m) / 100); +} + +// ************************************************************************************************* +// @fn conv_ft_to_m +// @brief Convert feet to meters +// @param u16 ft Feet +// @return u16 Meters +// ************************************************************************************************* +s16 convert_ft_to_m(s16 ft) +{ + return (((s32) ft * 61) / 200); +} + +// ************************************************************************************************* +// @fn start_altitude_measurement +// @brief Start altitude measurement +// @param none +// @return none +// ************************************************************************************************* +void start_altitude_measurement(void) +{ + u8 timeout = 15; + + // Already on? + if (sAlt.on) + return; + + // Show warning if pressure sensor was not initialised properly + if (!ps_ok) + { + display_chars(LCD_SEG_L1_2_0, (u8 *) "ERR", SEG_ON); + return; + } + + // Enable DRDY IRQ on rising edge + PS_INT_IFG &= ~PS_INT_PIN; + PS_INT_IE |= PS_INT_PIN; + + // Start pressure sensor + ps_start(); + + // Set altitude measurement flag + sAlt.on = 1; + + // Get updated altitude + while (((PS_INT_IN & PS_INT_PIN) == 0) && (timeout > 0)) + { + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + timeout--; + } + + // Failed to start? + if (timeout == 0) + { + sAlt.on = 0; + } + + do_altitude_measurement(FILTER_OFF); +} + +// ************************************************************************************************* +// @fn stop_altitude_measurement +// @brief Stop altitude measurement +// @param none +// @return none +// ************************************************************************************************* +void stop_altitude_measurement(void) +{ + // Return if pressure sensor was not initialised properly + if (!ps_ok) + return; + + // Not on? + if (!sAlt.on) + return; + + // Logging data? + if (is_datalog()) + return; + + // Stop pressure sensor + ps_stop(); + + // Clear on flag + sAlt.on = 0; + + // Disable DRDY IRQ + PS_INT_IE &= ~PS_INT_PIN; + PS_INT_IFG &= ~PS_INT_PIN; +} + +// ************************************************************************************************* +// @fn is_altitude_measurement +// @brief Altitude measurement check +// @param none +// @return u8 1=Measurement ongoing, 0=measurement off +// ************************************************************************************************* +u8 is_altitude_measurement(void) +{ + return (sAlt.on); +} + +// ************************************************************************************************* +// @fn do_altitude_measurement +// @brief Perform single altitude measurement +// @param u8 filter Filter option +// @return none +// ************************************************************************************************* +void do_altitude_measurement(u8 filter) +{ + volatile u32 pressure; + + // If sensor is not ready, skip data read + if ((PS_INT_IN & PS_INT_PIN) == 0) + return; + + // Get temperature (format is *10 K) from sensor + sAlt.temperature_K = ps_get_temp(); + sAlt.temperature_C = sAlt.temperature_K - 2721 + sAlt.temperature_C_offset; + + // Get pressure (format is 1Pa) from sensor + pressure = ps_get_pa(); + + // Store measured pressure value + if (filter == FILTER_OFF) + { + sAlt.pressure = pressure; + } + else + { + // Filter current pressure + pressure = (u32) ((pressure * 0.2) + (sAlt.pressure * 0.8)); + + // Store average pressure + sAlt.pressure = pressure; + } + + // Convert pressure (Pa) and temperature ( K) to altitude (m) + sAlt.altitude = conv_pa_to_meter(sAlt.pressure, sAlt.temperature_K); +} + +// ************************************************************************************************* +// @fn display_altitude +// @brief Display routine. Supports display in meters and feet. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_altitude(u8 line, u8 update) +{ + u8 *str; + s16 ft; + + // Start measurement + start_altitude_measurement(); + + // redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sys.flag.use_metric_units) + { + // Display "m" symbol + display_symbol(LCD_UNIT_L1_M, SEG_ON); + } + else + { + // Display "ft" symbol + display_symbol(LCD_UNIT_L1_FT, SEG_ON); + } + + // Display altitude + display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + if (sys.flag.use_metric_units) + { + // Display altitude in xxxx m format, allow 3 leading blank digits + if (sAlt.altitude >= 0) + { + str = int_to_array(sAlt.altitude, 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + else + { + str = int_to_array(sAlt.altitude * (-1), 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + } + else + { + // Convert from meters to feet + ft = convert_m_to_ft(sAlt.altitude); + + // Limit to 9999ft (3047m) + if (ft > 9999) + ft = 9999; + + // Display altitude in xxxx ft format, allow 3 leading blank digits + if (ft >= 0) + { + str = int_to_array(ft, 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + else + { + str = int_to_array(ft * (-1), 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + } + display_chars(LCD_SEG_L1_3_0, str, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Stop measurement + stop_altitude_measurement(); + + // Clean up function-specific segments before leaving function + display_symbol(LCD_UNIT_L1_M, SEG_OFF); + display_symbol(LCD_UNIT_L1_FT, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/altitude.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/altitude.h new file mode 100755 index 0000000..f9550d8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/altitude.h @@ -0,0 +1,73 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ALTITUDE_H_ +#define ALTITUDE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_altitude_measurement(void); +extern void start_altitude_measurement(void); +extern void stop_altitude_measurement(void); +extern u8 is_altitude_measurement(void); +extern void do_altitude_measurement(u8 filter); + +// menu functions +extern void display_altitude(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct alt +{ + u8 on; // 1 = Measurement started, 0 = measurement off + u32 pressure; // Pressure (Pa) + u16 temperature_K; // Temperature in K + s16 temperature_C; // Temperature in ºC + s16 temperature_C_offset; // Temperature ºC offset + s16 altitude; // Altitude (m) + s16 altitude_offset; // Altitude offset stored during calibration +}; +extern struct alt sAlt; + +// ************************************************************************************************* +// Extern section + +#endif /*ALTITUDE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/battery.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/battery.c new file mode 100755 index 0000000..d02a821 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/battery.c @@ -0,0 +1,135 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Battery voltage measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" +#include "adc12.h" + +// logic +#include "menu.h" +#include "battery.h" + +// ************************************************************************************************* +// Prototypes section +void reset_batt_measurement(void); +void battery_measurement(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct batt sBatt; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_batt_measurement +// @brief Reset battery measurement module. +// @param none +// @return none +// ************************************************************************************************* +void reset_batt_measurement(void) +{ + // Reset lobatt display counter + sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE; + + // Start with battery voltage of 3.00V + sBatt.voltage = 300; +} + +// ************************************************************************************************* +// @fn battery_measurement +// @brief Init ADC12. Do single conversion of AVCC voltage. Turn off ADC12. +// @param none +// @return none +// ************************************************************************************************* +void battery_measurement(void) +{ + u16 voltage; + + // Convert external battery voltage (ADC12INCH_11=AVCC-AVSS/2) + voltage = adc12_single_conversion(REFVSEL_1, ADC12SHT0_10, ADC12INCH_11); + + // Convert ADC value to "x.xx V" + // Ideally we have A11=0->AVCC=0V ... A11=4095(2^12-1)->AVCC=4V + // --> (A11/4095)*4V=AVCC --> AVCC=(A11*4)/4095 + voltage = (voltage * 2 * 2) / 41; + + // Correct measured voltage with calibration value + voltage += sBatt.offset; + + // Discard values that are clearly outside the measurement range + if (voltage > BATTERY_HIGH_THRESHOLD) + { + voltage = sBatt.voltage; + } + + // Filter battery voltage + sBatt.voltage = ((voltage * 2) + (sBatt.voltage * 8)) / 10; + + // If battery voltage falls below low battery threshold, set system flag and modify LINE2 + // display function pointer + if (sBatt.voltage < BATTERY_LOW_THRESHOLD) + { + sys.flag.low_battery = 1; + + // Set sticky battery icon + display_symbol(LCD_SYMB_BATTERY, SEG_ON); + } + else + { + sys.flag.low_battery = 0; + + // Clear sticky battery icon + display_symbol(LCD_SYMB_BATTERY, SEG_OFF); + } + // Update LINE2 + display.flag.line2_full_update = 1; + + // Indicate to display function that new value is available + display.flag.update_battery_voltage = 1; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/battery.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/battery.h new file mode 100755 index 0000000..ade8b8e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/battery.h @@ -0,0 +1,79 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BATTERY_H_ +#define BATTERY_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// Internal functions +extern void reset_batt_measurement(void); +extern void battery_measurement(void); + +// ************************************************************************************************* +// Defines section + +// Battery high voltage threshold +#define BATTERY_HIGH_THRESHOLD (360u) + +// Battery end of life voltage threshold -> disable radio, show "lobatt" message +#define BATTERY_LOW_THRESHOLD (240u) + +// Show "lobatt" message every n seconds +#define BATTERY_LOW_MESSAGE_CYCLE (15u) + +// ************************************************************************************************* +// Global Variable section +struct batt +{ + // Counter for alternating "lobatt" display + u8 lobatt_display; + + // Battery voltage + u16 voltage; + + // Battery voltage offset + s16 offset; +}; +extern struct batt sBatt; + +// ************************************************************************************************* +// Extern section + +#endif /*BATTERY_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/bluerobin.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/bluerobin.c new file mode 100755 index 0000000..f4460ef --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/bluerobin.c @@ -0,0 +1,396 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// BlueRobin functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "radio.h" +#include "ports.h" +#include "timer.h" +#include "rf1a.h" + +// logic +#include "BlueRobin_RX_API.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// Set to TRUE if transmitter ID should be remembered when reconnecting +// Transmitter ID can be cleared by pressing button STAR for more than 3 seconds +#define REMEMBER_TX_ID (FALSE) + +// ************************************************************************************************* +// Global Variable section +struct bluerobin sBlueRobin; + +// ************************************************************************************************* +// Extern section + +// Stop BlueRobin timer +extern void BRRX__StopTimer_v(void); + +// Calibration value for FSCTRL0 register (corrects deviation of 26MHz crystal) +extern u8 rf_frequoffset; + +// ************************************************************************************************* +// @fn reset_bluerobin +// @brief Reset BlueRobin data. +// @param none +// @return none +// ************************************************************************************************* +void reset_bluerobin(void) +{ + // Reset state is no connection + sBlueRobin.state = BLUEROBIN_OFF; + + // Reset value of chest strap ID is 0 --> connect to next best chest strap + sBlueRobin.cs_id = 0; + + // No new data available + sBlueRobin.update = BLUEROBIN_NO_UPDATE; + sBlueRobin.heartrate = 0; +} + +// ************************************************************************************************* +// @fn mx_rfblue +// @brief BlueRobin sub menu. Button STAR resets chest strap ID to 0. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void mx_bluerobin(u8 line) +{ +#if REMEMBER_TX_ID == TRUE + u8 i; + + // Reset chest strap ID + sBlueRobin.cs_id = 0; + + display_chars(LCD_SEG_L1_2_0, (u8 *) "CLR", SEG_ON); + for (i = 0; i < 4; i++) + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); +#endif + + // Clear simulated button event + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn sx_bluerobin +// @brief BlueRobin direct function. Button UP connects/disconnects with transmitter unit. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void sx_bluerobin(u8 line) +{ + u8 stop = 0; + + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if SimpliciTI stack is active + if (is_rf()) + return; + + // UP: connect / disconnect transmitter + if (button.flag.up) + { + if (sBlueRobin.state == BLUEROBIN_OFF) + { + // If no transmitter can be found, stop BlueRobin stack + if (!start_bluerobin()) + stop = 1; + } + else if (sBlueRobin.state == BLUEROBIN_CONNECTED) + { + // Shutdown connection + stop = 1; + } + } + + // Shutdown connection + if (stop) + { + stop_bluerobin(); + } +} + +// ************************************************************************************************* +// @fn display_heartrate +// @brief Heart rate display routine. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_heartrate(u8 line, u8 update) +{ + u8 *str; + + if (update != DISPLAY_LINE_CLEAR) + { + if (is_bluerobin()) + { + str = int_to_array(sBlueRobin.heartrate, 3, 2); + display_chars(LCD_SEG_L1_2_0, str, SEG_ON); + } + else + { + display_chars(LCD_SEG_L1_2_0, (u8 *) "---", SEG_ON); + } + } + + // Redraw whole screen + if (!is_bluerobin()) + { + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_symbol(LCD_ICON_HEART, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Clear heart when not connected + display_symbol(LCD_ICON_HEART, SEG_OFF); + } + } +} + +// ************************************************************************************************* +// @fn is_bluerobin +// @brief Returns TRUE if BlueRobin transmitter is connected. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_bluerobin(void) +{ + return (sBlueRobin.state == BLUEROBIN_CONNECTED); +} + +// ************************************************************************************************* +// @fn is_bluerobin_searching +// @brief Returns TRUE if BlueRobin is searching for a transmitter. +// @param none +// @return u8 1 if it is trying to connect +// ************************************************************************************************* +u8 is_bluerobin_searching(void) +{ + return (sBlueRobin.state == BLUEROBIN_SEARCHING); +} + +// ************************************************************************************************* +// @fn get_bluerobin_data +// @brief Read BlueRobin packet data from API. +// @param none +// @return none +// ************************************************************************************************* +void get_bluerobin_data(void) +{ + brtx_state_t bChannelState; + + // Check connection status + bChannelState = BRRX_GetState_t(HR_CHANNEL); + + switch (bChannelState) + { + case TX_ACTIVE: // Read heart rate data from BlueRobin API + sBlueRobin.heartrate = BRRX_GetHeartRate_u8(); + sBlueRobin.update = BLUEROBIN_NEW_DATA; + break; + + case TX_OFF: // Shutdown connection + stop_bluerobin(); + break; + + // BR_SEARCH, BR_LEARN, BR_PAUSE: Keep old values until we receive new data + default: + break; + } +} + +// ************************************************************************************************* +// @fn start_bluerobin +// @brief Start BlueRobin stack and search for a transmitter. +// @param none +// @return 0 = no transmitter found, 1 = connected to a transmitter +// ************************************************************************************************* +u8 start_bluerobin(void) +{ + u8 timeout, i; + + // Init BlueRobin timer and radio + // Enable high current mode + open_radio(); + + // Initialize BR library + BRRX_Init_v(); + + // Set BR data transmission properties + BRRX_SetPowerdownDelay_v(10); // Power down channel after 10 consecutive lost data packets (~9 + // seconds) + BRRX_SetSearchTimeout_v(6); // Stop searching after 8 seconds + + // Sensitivity in learn mode reduced --> connect only to close transmitters + // Skip this part if chest strap id was set in a previous learn mode run +#if REMEMBER_TX_ID == TRUE + if (sBlueRobin.cs_id == 0) + BRRX_SetSignalLevelReduction_v(5); +#else + // Forget previously learned transmitter ID and connect to next close transmitter + sBlueRobin.cs_id = 0; + BRRX_SetSignalLevelReduction_v(5); +#endif + + // Apply frequency offset compensation to radio register FSCTRL0 + // If calibration memory was erased, rf_frequoffset defaults to 0x00 and has no effect + WriteSingleReg(FSCTRL0, rf_frequoffset); + + // New state is SEARCH + sBlueRobin.state = BLUEROBIN_SEARCHING; + + // Blink RF icon to show searching + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + + // Turn on radio and establish connection if channel not already started + if (BRRX_GetState_t(HR_CHANNEL) == TX_OFF) + { + // Start in learn mode (connect to closest heart rate transmitter) + BRRX_SetID_v(HR_CHANNEL, sBlueRobin.cs_id); + BRRX_Start_v(HR_CHANNEL); + + // Wait until learning phase is over, additional timeout prevents race condition if hardware + // works incorrect + timeout = 40; + while ((BRRX_GetState_t(HR_CHANNEL) == TX_SEARCH) && (timeout-- > 0)) + { + Timer0_A4_Delay(CONV_MS_TO_TICKS(200)); + } + + // Timeout? + if (timeout == 0) + { + display_chars(LCD_SEG_L1_3_0, (u8 *) "FAIL", SEG_ON); + for (i = 0; i < 4; i++) + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); + } + } + + // Check if connection attempt was successful + if (BRRX_GetState_t(HR_CHANNEL) == TX_ACTIVE) + { + // Successfully connected to transmitter + sBlueRobin.state = BLUEROBIN_CONNECTED; + + // When in learn mode, copy chest strap ID + if (sBlueRobin.cs_id == 0) + sBlueRobin.cs_id = BRRX_GetID_u32(HR_CHANNEL); + + // Show steady RF icon to indicate established connection + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF); + + // Show blinking icon + display_symbol(LCD_ICON_HEART, SEG_ON_BLINK_ON); + + return (1); + } + else // Error -> Shutdown connection + { + // Clear RF icon + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); + + return (0); + } +} + +// ************************************************************************************************* +// @fn stop_bluerobin +// @brief Stop communication and put peripherals in power-down mode. +// @param none +// @return none +// ************************************************************************************************* +void stop_bluerobin(void) +{ + // Reset connection status byte + sBlueRobin.state = BLUEROBIN_OFF; + + // Stop channel + BRRX_Stop_v(HR_CHANNEL); + + // Powerdown radio + close_radio(); + + // Force full display update to clear heart rate and speed data + sBlueRobin.heartrate = 0; + display.flag.full_update = 1; + + // Clear heart and RF symbol + display_symbol(LCD_ICON_HEART, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); +} + +// ************************************************************************************************* +// @fn bluerobin_flash_write_window +// @brief Returns 1 if next BlueRobin ISR is more than 15msec away. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_bluerobin_flash_write_window(void) +{ + if (is_bluerobin()) + return ((TA0CCR1 - TA0R) > 500); + else + return (1); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/bluerobin.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/bluerobin.h new file mode 100755 index 0000000..7127c04 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/bluerobin.h @@ -0,0 +1,90 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BLUEROBIN_H_ +#define BLUEROBIN_H_ + +// ************************************************************************************************* +// Include section +#include + +// ************************************************************************************************* +// Prototypes section +extern void reset_bluerobin(void); +extern void mx_bluerobin(u8 line); +extern void sx_bluerobin(u8 line); +extern void display_heartrate(u8 line, u8 update); +extern u8 is_bluerobin(void); +extern u8 is_bluerobin_searching(void); +extern void get_bluerobin_data(void); +extern u8 start_bluerobin(void); +extern void stop_bluerobin(void); +extern u8 is_bluerobin_flash_write_window(void); + +// ************************************************************************************************* +// Defines section + +// BlueRobin connection states +typedef enum +{ + BLUEROBIN_OFF = 0, // Not connected + BLUEROBIN_SEARCHING, // Searching for transmitter + BLUEROBIN_CONNECTED, // Connected + BLUEROBIN_ERROR // Error occurred while trying to connect or while connected +} BlueRobin_state_t; + +// BlueRobin data update states +typedef enum +{ + BLUEROBIN_NO_UPDATE = 0, // No new data available + BLUEROBIN_NEW_DATA // New data arrived +} BlueRobin_update_t; + +// ************************************************************************************************* +// Global Variable section +struct bluerobin +{ + BlueRobin_state_t state; // BLUEROBIN_OFF, BLUEROBIN_SEARCHING, BLUEROBIN_CONNECTED, + // BLUEROBIN_ERROR + BlueRobin_update_t update; // BLUEROBIN_NO_UPDATE, BLUEROBIN_NEW_DATA + u32 cs_id; // BLUEROBIN_NO_UPDATE, BLUEROBIN_NEW_DATA + u8 heartrate; // Heart rate (1 bpm) +}; +extern struct bluerobin sBlueRobin; + +// ************************************************************************************************* +// Extern section + +#endif /*BLUEROBIN_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/clock.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/clock.c new file mode 100755 index 0000000..bc44675 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/clock.c @@ -0,0 +1,292 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Time functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "ports.h" +#include "display.h" +#include "timer.h" + +// logic +#include "menu.h" +#include "clock.h" +#include "user.h" +#include "bluerobin.h" +#include "date.h" + +// ************************************************************************************************* +// Prototypes section +void reset_clock(void); +void clock_tick(void); +void mx_time(u8 line); +void sx_time(u8 line); + +void calc_24H_to_12H(u8 * hours, u8 * timeAM); +void conv_24H_to_12H(u8 * hours24, u8 * hours12, u8 * timeAMorPM); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct time sTime; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_clock +// @brief Resets clock time to 00:00:00, 24H time format. +// @param none +// @return none +// ************************************************************************************************* +void reset_clock(void) +{ + // Set global system time to 0 + sTime.system_time = 0; + + // Set main 24H time to start value + sTime.hour = 4; + sTime.minute = 30; + sTime.second = 0; + + // Display style of both lines is default (HH:MM) + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; + + // Reset timeout detection + sTime.last_activity = 0; +} + +// ************************************************************************************************* +// @fn clock_tick +// @brief Add 1 second to system time and to display time +// @param none +// @return none +// ************************************************************************************************* +void clock_tick(void) +{ + // Use sTime.drawFlag to minimize display updates + // sTime.drawFlag = 1: second + // sTime.drawFlag = 2: minute, second + // sTime.drawFlag = 3: hour, minute + sTime.drawFlag = 1; + + // Increase global system time + sTime.system_time++; + + // Add 1 second + sTime.second++; + + // Add 1 minute + if (sTime.second == 60) + { + sTime.second = 0; + sTime.minute++; + sTime.drawFlag++; + + // Add 1 hour + if (sTime.minute == 60) + { + sTime.minute = 0; + sTime.hour++; + sTime.drawFlag++; + + // Add 1 day + if (sTime.hour == 24) + { + sTime.hour = 0; + add_day(); + } + } + } +} + +// ************************************************************************************************* +// @fn convert_hour_to_12H_format +// @brief Convert internal 24H time to 12H time. +// @param u8 hour Hour in 24H format +// @return u8 Hour in 12H format +// ************************************************************************************************* +u8 convert_hour_to_12H_format(u8 hour) +{ + // 00:00 .. 11:59 --> AM 12:00 .. 11:59 + if (hour == 0) + return (hour + 12); + else if (hour <= 12) + return (hour); + // 13:00 .. 23:59 --> PM 01:00 .. 11:59 + else + return (hour - 12); +} + +// ************************************************************************************************* +// @fn is_hour_am +// @brief Checks if internal 24H time is AM or PM +// @param u8 hour Hour in 24H format +// @return u8 1 = AM, 0 = PM +// ************************************************************************************************* +u8 is_hour_am(u8 hour) +{ + // 00:00 .. 11:59 --> AM 12:00 .. 11:59 + if (hour < 12) + return (1); + // 12:00 .. 23:59 --> PM 12:00 .. 11:59 + else + return (0); +} + +// ************************************************************************************************* +// @fn sx_time +// @brief Time user routine. Toggles view style between HH:MM and SS. +// @param line LINE1 +// @return none +// ************************************************************************************************* +void sx_time(u8 line) +{ + // Toggle display view style + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + sTime.line1ViewStyle = DISPLAY_ALTERNATIVE_VIEW; + else + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn display_time +// @brief Clock display routine. Supports 24H and 12H time format. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL +// @return none +// ************************************************************************************************* +void display_time(u8 line, u8 update) +{ + u8 hour12; + + // Partial update + if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + if (sTime.drawFlag != 0) + { + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + { + switch (sTime.drawFlag) + { + case 3: + if (sys.flag.use_metric_units) + { + // Display 24H time "HH" + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(sTime.hour, 2, + 0), SEG_ON); + } + else + { + // Display 12H time "HH" + AM/PM + hour12 = convert_hour_to_12H_format(sTime.hour); + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(hour12, 2, + 0), SEG_ON); + display_am_pm_symbol(sTime.hour); + } + + case 2: + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.minute, 2, + 0), SEG_ON); + } + } + else + { + // Seconds are always updated + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.second, 2, 0), SEG_ON); + } + } + } + else if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Full update + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + { + // Display 24H/12H time + if (sys.flag.use_metric_units) + { + // Display 24H time "HH" + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(sTime.hour, 2, 0), SEG_ON); + } + else + { + // Display 12H time "HH" + AM/PM information + hour12 = convert_hour_to_12H_format(sTime.hour); + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(hour12, 2, 0), SEG_ON); + // Display AM/PM information + if (line == LINE1) + { + display_am_pm_symbol(sTime.hour); + } + } + + // Display minute + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.minute, 2, 0), SEG_ON); + display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_ON_BLINK_ON); + } + else + { + // Display seconds + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.second, 2, 0), SEG_ON); + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_OFF_BLINK_OFF); + // Change display style to default (HH:MM) + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; + // Clean up AM/PM icon + display_symbol(LCD_SYMB_AM, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/clock.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/clock.h new file mode 100755 index 0000000..a4ad480 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/clock.h @@ -0,0 +1,74 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef CLOCK_H_ +#define CLOCK_H_ + +// ************************************************************************************************* +// Defines section + +// Definitions for time format +#define TIMEFORMAT_24H (0u) +#define TIMEFORMAT_12H (1u) + +// ************************************************************************************************* +// Prototypes section +extern void reset_clock(void); +extern void sx_time(u8 line); +extern void mx_time(u8 line); +extern void clock_tick(void); +extern void display_selection_Timeformat1(u8 segments, u32 index, u8 digits, u8 blanks); +extern void display_time(u8 line, u8 update); + +// English units support +extern void calc_24H_to_12H(u8 * hours, u8 * timeAM); +extern u8 convert_hour_to_12H_format(u8 hour); +extern u8 is_hour_am(u8 hour); + +// ************************************************************************************************* +// Global Variable section +struct time +{ + u32 system_time; // Global system time. Used to calculate last activity + u32 last_activity; // Inactivity detection (exits set_value() function) + u8 drawFlag; // Flag to minimize display updates + u8 line1ViewStyle; // Viewing style + u8 hour; // Time data + u8 minute; // Time data + u8 second; // Time data +}; +extern struct time sTime; + +#endif /*CLOCK_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/datalog.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/datalog.c new file mode 100755 index 0000000..6bd327b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/datalog.c @@ -0,0 +1,465 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Data logger routines. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "flash.h" +#include "ports.h" + +// logic +#include "datalog.h" +#include "date.h" +#include "clock.h" +#include "altitude.h" +#include "temperature.h" +#include "bluerobin.h" + +// ************************************************************************************************* +// Prototypes section +void start_datalog(void); +void stop_datalog(void); +void datalog_sm(u8 * data, u8 len, u8 cmd); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct datalog sDatalog; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_datalog +// @brief Reset data logger memory and init variables. +// @param none +// @return none +// ************************************************************************************************* +void reset_datalog(void) +{ + u8 i; + + // Clear data logger memory + for (i = DATALOG_PAGE_START; i <= DATALOG_PAGE_END; i++) + { + flash_erase_page(i); + } + + sDatalog.flags.all = 0; + sDatalog.mode = DATALOG_MODE_TEMPERATURE + DATALOG_MODE_ALTITUDE; + sDatalog.interval = DATALOG_INTERVAL; + sDatalog.delay = 0; + sDatalog.wptr = (u16 *) DATALOG_MEMORY_START; + sDatalog.idx = 0; +} + +// ************************************************************************************************* +// @fn sx_alarm +// @brief Sx button turns alarm on/off. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void sx_datalog(u8 line) +{ + // Turn off the backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + + // Toggle data logger state + if (!sDatalog.flags.flag.on) + { + if (!sDatalog.flags.flag.memory_full) + { + // Turn on data logger + start_datalog(); + } + else // Memory full + { + // Show "nomem" message + message.flag.prepare = 1; + message.flag.type_nomem = 1; + } + } + else + { + // Turn off data logger + stop_datalog(); + } +} + +// ************************************************************************************************* +// @fn start_datalog +// @brief Begin to log data. +// @param none +// @return none +// ************************************************************************************************* +void start_datalog(void) +{ + // Start BlueRobin RX + if ((sDatalog.mode & DATALOG_MODE_HEARTRATE) != 0) + { + // Keep existing connection + if (!is_bluerobin()) + { + // Start BlueRobin + if (!start_bluerobin()) + { + // No connection established? -> Close stack + stop_bluerobin(); + } + } + } + + // Start pressure measurement + if ((sDatalog.mode & (DATALOG_MODE_TEMPERATURE | DATALOG_MODE_ALTITUDE)) != 0) + { + // Start altitude measurement + start_altitude_measurement(); + } + + // Set datalogger icon + display_symbol(LCD_ICON_RECORD, SEG_ON_BLINK_OFF); + + // Start data logging + datalog_sm(NULL, 0, DATALOG_CMD_START); +} + +// ************************************************************************************************* +// @fn stop_datalog +// @brief Stop data logging. +// @param none +// @return none +// ************************************************************************************************* +void stop_datalog(void) +{ + if ((sDatalog.mode & DATALOG_MODE_HEARTRATE) != 0) + { + // Stop BlueRobin connection + if (is_bluerobin()) + stop_bluerobin(); + } + + // Stop data logging and write out buffer + datalog_sm(NULL, 0, DATALOG_CMD_CLOSE); + + if ((sDatalog.mode & (DATALOG_MODE_TEMPERATURE | DATALOG_MODE_ALTITUDE)) != 0) + { + // Stop altitude measurement + stop_altitude_measurement(); + } + + // Clear datalogger icon + display_symbol(LCD_ICON_RECORD, SEG_OFF_BLINK_OFF); +} + +u8 is_datalog(void) +{ + return (sDatalog.flags.flag.on); +} + +// ************************************************************************************************* +// @fn display_datalog +// @brief Display data logger information. +// @param u8 line LINE1, LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_datalog(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_chars(LCD_SEG_L2_4_0, (u8 *) " DLOG", SEG_ON); + } +} + +// ************************************************************************************************* +// @fn do_datalog +// @brief Add data to data logging buffer. Called by second tick. +// @param none +// @return none +// ************************************************************************************************* +void do_datalog(void) +{ + u8 temp[4]; + u8 count; + + // If logging delay is over, add new data + if (--sDatalog.delay == 0) + { + // Store data when possible compressed (heartrate = 8 bits, temperature/altitude = min. 12 + // bits) + if (sDatalog.mode == DATALOG_MODE_HEARTRATE) + { + temp[0] = sBlueRobin.heartrate; + count = 1; + } + else if (sDatalog.mode == DATALOG_MODE_TEMPERATURE) + { + temp[0] = (sAlt.temperature_C >> 8) & 0xFF; + temp[1] = sAlt.temperature_C & 0xFF; + count = 2; + } + else if (sDatalog.mode == DATALOG_MODE_ALTITUDE) + { + temp[0] = (sAlt.altitude >> 8) & 0xFF; + temp[1] = sAlt.altitude & 0xFF; + count = 2; + } + else if (sDatalog.mode == + (DATALOG_MODE_HEARTRATE | DATALOG_MODE_TEMPERATURE | DATALOG_MODE_ALTITUDE)) + { + temp[0] = sBlueRobin.heartrate; + temp[1] = (sAlt.temperature_C >> 4) & 0xFF; + temp[2] = ((sAlt.temperature_C << 4) & 0xF0) | ((sAlt.altitude >> 8) & 0x0F); + temp[3] = sAlt.altitude & 0xFF; + count = 4; + } + else if (sDatalog.mode == (DATALOG_MODE_HEARTRATE | DATALOG_MODE_TEMPERATURE)) + { + temp[0] = sBlueRobin.heartrate; + temp[1] = (sAlt.temperature_C >> 8) & 0xFF; + temp[2] = sAlt.temperature_C & 0xFF; + count = 3; + } + else if (sDatalog.mode == (DATALOG_MODE_HEARTRATE | DATALOG_MODE_ALTITUDE)) + { + temp[0] = sBlueRobin.heartrate; + temp[1] = (sAlt.altitude >> 8) & 0xFF; + temp[2] = sAlt.altitude & 0xFF; + count = 3; + } + else if (sDatalog.mode == (DATALOG_MODE_TEMPERATURE | DATALOG_MODE_ALTITUDE)) + { + temp[0] = (sAlt.temperature_C >> 4) & 0xFF; + temp[1] = ((sAlt.temperature_C << 4) & 0xF0) | ((sAlt.altitude >> 8) & 0x0F); + temp[2] = sAlt.altitude & 0xFF; + count = 3; + } + + // Add data to recording buffer + datalog_sm((u8 *) &temp, count, DATALOG_CMD_ADD_DATA); + + // Reset delay counter + sDatalog.delay = sDatalog.interval; + + // Write to flash if buffer is over write threshold and no BlueRobin event is close + datalog_sm(NULL, 0, DATALOG_CMD_WRITE_DATA); + } +} + +// ************************************************************************************************* +// @fn datalog_add_to_buffer +// @brief Add byte-data to data logging buffer +// @param u8 * data Pointer to byte-data +// u8 len Byte count +// @return none +// ************************************************************************************************* +void datalog_add_to_buffer(u8 * data, u8 len) +{ + u8 i; + + for (i = 0; i < len; i++) + { + // Copy values to buffer + if (sDatalog.idx < DATALOG_BUFFER_SIZE) + { + sDatalog.buffer[sDatalog.idx++] = *(data + i); + } + } +} + +// ************************************************************************************************* +// Write buffer content to flash +// ************************************************************************************************* +void datalog_write_buffer(void) +{ + u8 i = 0; + u16 data; + u8 eom = 0; + volatile u16 temp; + + // Check if we cross end of memory threshold with this buffer write + if (sDatalog.wptr >= (u16 *) (DATALOG_MEMORY_END - 1 - sDatalog.idx)) + { + // Correct index to only write to end of memory + // Leave 2 bytes for session end marker + temp = (u16) sDatalog.wptr; + sDatalog.idx = (u8) ((u16) DATALOG_MEMORY_END - 1 - temp); + eom = 1; + } + + // Write buffer content to flash + while (i < sDatalog.idx - 1) + { + // Keep array order when writing to flash memory + data = sDatalog.buffer[i++]; + data += (u16) (sDatalog.buffer[i++] << 8); + + // Write 16-bit word to flash + flash_write(sDatalog.wptr++, data); + } + + // Stop data logging and write session end marker + if (eom) + { + // Write end marker + flash_write((u16 *) (DATALOG_MEMORY_END - 1), 0xFFFE); + // Clear buffer index + sDatalog.idx = 0; + // Clear flags + sDatalog.flags.flag.on = 0; + sDatalog.flags.flag.memory_full = 1; + // Clear datalogger icon + display_symbol(LCD_ICON_RECORD, SEG_OFF_BLINK_OFF); + } + else + { + // If index was odd number, 1 byte remains in buffer and must be written next time + if ((sDatalog.idx & 0x01) == 0x01) + { + sDatalog.buffer[0] = sDatalog.buffer[sDatalog.idx - 1]; + sDatalog.idx = 1; + } + else // All bytes haven been written + { + sDatalog.idx = 0; + } + } +} + +// ************************************************************************************************* +// @fn datalog_sm +// @brief Data logging state machine +// @param u8 line LINE1, LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void datalog_sm(u8 * data, u8 len, u8 cmd) +{ + u8 i; + u16 temp; + + switch (cmd) + { + case DATALOG_CMD_START: + if (!sDatalog.flags.flag.on && !sDatalog.flags.flag.memory_full) + { + // Clear index + sDatalog.idx = 0; + sDatalog.delay = sDatalog.interval; + + // Add session begin marker to buffer (2 byte) + temp = 0xFFFB; + datalog_add_to_buffer((u8 *) &temp, 2); + + // Add recording mode to buffer (1 byte) + datalog_add_to_buffer((u8 *) &sDatalog.mode, 1); + + // Add recording interval to buffer (1 byte) + datalog_add_to_buffer((u8 *) &sDatalog.interval, 1); + + // Add date to buffer (DD.MM.YYYY) (4 bytes) + datalog_add_to_buffer((u8 *) &sDate.day, 1); + datalog_add_to_buffer((u8 *) &sDate.month, 1); + datalog_add_to_buffer((u8 *) &sDate.year, 2); + + // Add system time to buffer (HH.MM.SS) (3 bytes) + datalog_add_to_buffer((u8 *) &sTime.hour, 3); + + // Data logging has started + sDatalog.flags.flag.on = 1; + } + break; + + case DATALOG_CMD_CLOSE: + if (sDatalog.flags.flag.on && !sDatalog.flags.flag.memory_full) + { + // If index is odd, add a dummy byte before writing session end marker + if ((sDatalog.idx & 0x01) == 0x01) + { + temp = 0x00; + datalog_add_to_buffer((u8 *) &temp, 1); + } + // Add session end marker to buffer (2 byte) + temp = 0xFFFE; + datalog_add_to_buffer((u8 *) &temp, 2); + // Write buffer to flash + datalog_write_buffer(); + } + sDatalog.flags.flag.on = 0; + break; + + case DATALOG_CMD_ADD_DATA: + if (sDatalog.flags.flag.on && !sDatalog.flags.flag.memory_full) + { + datalog_add_to_buffer(data, len); + } + break; + + case DATALOG_CMD_WRITE_DATA: + if (sDatalog.flags.flag.on && !sDatalog.flags.flag.memory_full) + { + // Over write threshold? + if (sDatalog.idx > DATALOG_BUFFER_WRITE_THRESHOLD) + { + // BlueRobin ISR call more than ~13ms away? + if (is_bluerobin_flash_write_window()) + datalog_write_buffer(); + } + } + break; + + case DATALOG_CMD_ERASE: + if (!sDatalog.flags.flag.on) + { + for (i = DATALOG_PAGE_START; i <= DATALOG_PAGE_END; i++) + { + flash_erase_page(i); + } + } + break; + + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/datalog.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/datalog.h new file mode 100755 index 0000000..da3903f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/datalog.h @@ -0,0 +1,134 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef DATALOG_H_ +#define DATALOG_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// internal functions +extern void reset_datalog(void); +extern u8 is_datalog(void); +extern void do_datalog(void); +extern void display_datalog(u8 line, u8 update); +extern void stop_datalog(void); + +// menu functions +extern void sx_datalog(u8 line); + +// ************************************************************************************************* +// Defines section + +// Data logger state +#define DATALOG_OFF (0u) +#define DATALOG_ON (1u) + +// Data memory range: 0x8000 - 0x9DFF (7.5kB) +#define DATALOG_MEMORY_START (0x8000) +#define DATALOG_MEMORY_END (0x9DFF) +#define DATALOG_BYTES_PER_PAGE (512u) +#define DATALOG_PAGE_START (DATALOG_MEMORY_START / \ + DATALOG_BYTES_PER_PAGE) +#define DATALOG_PAGE_END (DATALOG_MEMORY_END / \ + DATALOG_BYTES_PER_PAGE) + +// Store data in buffer before writing to flash memory +#define DATALOG_BUFFER_SIZE (128u) +#define DATALOG_BUFFER_WRITE_THRESHOLD (100u) + +// Datalogging interval in seconds +#define DATALOG_INTERVAL (5u) + +// Datalogger state machine commands +#define DATALOG_CMD_START (BIT0) +#define DATALOG_CMD_CLOSE (BIT1) +#define DATALOG_CMD_ERASE (BIT2) +#define DATALOG_CMD_ADD_DATA (BIT3) +#define DATALOG_CMD_WRITE_DATA (BIT4) + +// Datalog modes +#define DATALOG_MODE_HEARTRATE (BIT0) +#define DATALOG_MODE_TEMPERATURE (BIT1) +#define DATALOG_MODE_ALTITUDE (BIT2) +#define DATALOG_MODE_ACCELERATION (BIT3) + +// ************************************************************************************************* +// Global Variable section + +// Flags +typedef union +{ + struct + { + u8 on : 1; // 1 = data logging has started + u8 memory_full : 1; // 1 = memory is full + u8 one_second : 1; // 1 = 1 second has elapsed + } flag; + u8 all; // Shortcut to all flags (for reset) +} datalog_flags; + +struct datalog +{ + // Flags + datalog_flags flags; + + // Data logging mode + u8 mode; + + // Data logging interval + u8 interval; + + // Data logging delay counter + u8 delay; + + // Datalog memory write pointer + u16 *wptr; + + // Datalogger write buffer index + u8 idx; + + // Datalogger write buffer + u8 buffer[DATALOG_BUFFER_SIZE]; +}; +extern struct datalog sDatalog; + +// ************************************************************************************************* +// Extern section + +#endif /*DATALOG_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/date.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/date.c new file mode 100755 index 0000000..1e34ec5 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/date.c @@ -0,0 +1,234 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Date functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" + +// logic +#include "date.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section +void reset_date(void); +u8 get_numberOfDays(u8 month, u16 year); +void add_day(void); +void mx_date(u8 line); +void sx_date(u8 line); +void display_date(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct date sDate; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_date +// @brief Reset date to start value. +// @param none +// @return none +// ************************************************************************************************* +void reset_date(void) +{ + // Set date + sDate.year = 2009; + sDate.month = 8; + sDate.day = 1; + + // Show day and month on display + sDate.display = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn get_NumberOfDays +// @brief Return number of days for a given month +// @param month month as char +// year year as int +// @return day count for given month +// ************************************************************************************************* +u8 get_numberOfDays(u8 month, u16 year) +{ + switch (month) + { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + return (31); + + case 4: + case 6: + case 9: + case 11: + return (30); + + // 1. A year that is divisible by 4 is a leap year. (Y % 4) == 0 + // 2. Exception to rule 1: a year that is divisible by 100 is not a leap year. (Y % 100) != + // 0 + // 3. Exception to rule 2: a year that is divisible by 400 is a leap year. (Y % 400) == 0 + + case 2: + if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))) + return (29); + else + return (28); + + default: + return (0); + } +} + +// ************************************************************************************************* +// @fn add_day +// @brief Add one day to current date. Called when clock changes from 23:59 to 00:00 +// @param none +// @return none +// ************************************************************************************************* +void add_day(void) +{ + // Add 1 day + sDate.day++; + + // Check if day overflows into next month + if (sDate.day > get_numberOfDays(sDate.month, sDate.year)) + { + // Add 1 month and reset to day to 1 + sDate.day = 1; + sDate.month++; + + // Check if month overflows into next year + if (sDate.month > 12) + { + // Add 1 year and reset month and day to 1 + sDate.day = 1; + sDate.month = 1; + sDate.year++; + } + } + + // Indicate to display function that new value is available + display.flag.full_update = 1; +} + +// ************************************************************************************************* +// @fn sx_date +// @brief Date user routine. Toggles view between DD.MM and YYYY. +// @param line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void sx_date(u8 line) +{ + // Toggle display items + if (sDate.display == DISPLAY_DEFAULT_VIEW) + sDate.display = DISPLAY_ALTERNATIVE_VIEW; + else + sDate.display = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn display_date +// @brief Display date in DD.MM format (metric units) or MM.DD (English units). +// @param u8 line LINE1, LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL +// @return none +// ************************************************************************************************* +void display_date(u8 line, u8 update) +{ + u8 *str; + + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sDate.display == DISPLAY_DEFAULT_VIEW) + { + // Convert day to string + str = int_to_array(sDate.day, 2, 0); + if (sys.flag.use_metric_units) + { + display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); + } + else + { + display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); + } + + // Convert month to string + str = int_to_array(sDate.month, 2, 0); + if (sys.flag.use_metric_units) + { + display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); + } + else + { + display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); + } + + // Display "." to separate day and month + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); + } + else + { + // Convert year to string + str = int_to_array(sDate.year, 4, 0); + display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_3_0), str, SEG_ON); + + // Clear "." + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_OFF); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Show day and month on display when coming around next time + sDate.display = DISPLAY_DEFAULT_VIEW; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/date.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/date.h new file mode 100755 index 0000000..f3a65b8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/date.h @@ -0,0 +1,68 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef DATE_H_ +#define DATE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_date(void); +extern void add_day(void); +extern void mx_date(u8 line); +extern void sx_date(u8 line); +extern void display_date(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct date +{ + u8 display; // Toggles view between DISPLAY_DEFAULT_VIEW = DD.MM and + // DISPLAY_ALTERNATIVE_VIEW = YYYY + u8 day; + u8 month; + u16 year; +}; +extern struct date sDate; + +// ************************************************************************************************* +// Extern section + +#endif /*DATE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/menu.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/menu.c new file mode 100755 index 0000000..f664cdf --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/menu.c @@ -0,0 +1,172 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Menu management functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" + +// logic +#include "menu.h" +#include "user.h" +#include "clock.h" +#include "date.h" +#include "temperature.h" +#include "altitude.h" +#include "battery.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "acceleration.h" +#include "datalog.h" +#include "rfbsl.h" + +// ************************************************************************************************* +// Defines section +#define FUNCTION(function) function + +// ************************************************************************************************* +// Global Variable section +const struct menu *ptrMenu_L1 = NULL; +const struct menu *ptrMenu_L2 = NULL; + +// ************************************************************************************************* +// Global Variable section + +void display_nothing(u8 line, u8 update) +{ +} + +u8 update_time(void) +{ + return (display.flag.update_time); +} + +u8 update_date(void) +{ + return (display.flag.update_date); +} + +u8 update_temperature(void) +{ + return (display.flag.update_temperature); +} + +// ************************************************************************************************* +// User navigation ( [____] = default menu item after reset ) +// +// LINE1: [Time] -> Temperature -> Altitude -> Heart rate +// +// LINE2: [Date] -> Datalog -> SYNC -> RFBSL +// ************************************************************************************************* + +// Line1 - Time +const struct menu menu_L1_Time = { + FUNCTION(sx_time), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_time), // display function + FUNCTION(update_time), // new display data + &menu_L1_Temperature, +}; + +// Line1 - Temperature +const struct menu menu_L1_Temperature = { + FUNCTION(dummy), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_temperature), // display function + FUNCTION(update_time), // new display data + &menu_L1_Altitude, +}; + +// Line1 - Altitude +const struct menu menu_L1_Altitude = { + FUNCTION(dummy), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_altitude), // display function + FUNCTION(update_time), // new display data +#ifdef INCLUDE_BLUEROBIN_SUPPORT + &menu_L1_Heartrate, +}; + +// Line1 - Heart Rate +const struct menu menu_L1_Heartrate = { + FUNCTION(sx_bluerobin), // direct function + FUNCTION(mx_bluerobin), // sub menu function + FUNCTION(display_heartrate), // display function + FUNCTION(update_time), // new display data +#endif + &menu_L1_Time, +}; + +// Line2 - Date +const struct menu menu_L2_Date = { + FUNCTION(sx_date), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_date), // display function + FUNCTION(update_date), // new display data + &menu_L2_DataLog, +}; + +// Line2 - DataLog (data recording on/off) +const struct menu menu_L2_DataLog = { + FUNCTION(sx_datalog), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_datalog), // display function + FUNCTION(update_time), // new display data + &menu_L2_Sync, +}; + +// Line2 - SYNC (synchronization/data download via SimpliciTI) +const struct menu menu_L2_Sync = { + FUNCTION(sx_sync), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_sync), // display function + FUNCTION(update_time), // new display data + &menu_L2_RFBSL, +}; + +// Line2 - RFBSL (software update) +const struct menu menu_L2_RFBSL = { + FUNCTION(sx_rfbsl), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_rfbsl), // display function + FUNCTION(update_time), // new display data + &menu_L2_Date, +}; diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/menu.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/menu.h new file mode 100755 index 0000000..6b543e1 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/menu.h @@ -0,0 +1,84 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef MENU_H_ +#define MENU_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +struct menu +{ + // Pointer to direct function (start, stop etc) + void (*sx_function)(u8 line); + // Pointer to sub menu function (change settings, reset counter etc) + void (*mx_function)(u8 line); + // Pointer to display function + void (*display_function)(u8 line, u8 mode); + // Display update trigger + u8 (*display_update)(void); + // Pointer to next menu item + const struct menu *next; +}; + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +// Line1 navigation +extern const struct menu menu_L1_Time; +extern const struct menu menu_L1_Temperature; +extern const struct menu menu_L1_Altitude; +extern const struct menu menu_L1_Heartrate; + +// Line2 navigation +extern const struct menu menu_L2_Date; +extern const struct menu menu_L2_DataLog; +extern const struct menu menu_L2_Sync; +extern const struct menu menu_L2_RFBSL; + +// Pointers to current menu item +extern const struct menu *ptrMenu_L1; +extern const struct menu *ptrMenu_L2; + +#endif /*MENU_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfbsl.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfbsl.c new file mode 100755 index 0000000..c32c980 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfbsl.c @@ -0,0 +1,118 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Wireless Update functions. +// ************************************************************************************************* + + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" + +// logic +#include "rfbsl.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" + +// ************************************************************************************************* +// Global Variable section +u8 rfBSL_button_confirmation; + +// ************************************************************************************************* +// @fn sx_rfbsl +// @brief This functions starts the RFBSL +// @param line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void sx_rfbsl(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Exit if SimpliciTI stack is active + if (is_rf()) + return; + + rfBSL_button_confirmation++; + + if (rfBSL_button_confirmation == 2) + { + // Before entering RFBSL clear the LINE1 Symbols + display_symbol(LCD_SYMB_AM, SEG_OFF); + + clear_line(LINE1); + + // Write RAM to indicate we will be downloading the RAM Updater first + display_chars(LCD_SEG_L2_5_0, (u8 *) " RFBSL", SEG_ON); + display_chars(LCD_SEG_L1_3_0, (u8 *) " RAM", SEG_ON); + + // Call RFBSL + CALL_RFSBL(); + } +} + +// ************************************************************************************************* +// @fn display_rfbsl +// @brief RFBSL display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_rfbsl(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (rfBSL_button_confirmation == 0) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " RFBSL", SEG_ON); + } + else if (rfBSL_button_confirmation < 2) + { + // Request one more button press to confirm rfBSL call + display_chars(LCD_SEG_L2_5_0, (u8 *) " CONF", SEG_ON); + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfbsl.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfbsl.h new file mode 100755 index 0000000..364749f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfbsl.h @@ -0,0 +1,55 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RFBSL_H_ +#define RFBSL_H_ + +// ************************************************************************************************* +// Prototypes section +extern void sx_rfbsl(u8 line); +extern void display_rfbsl(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// Entry point of of the Flash Updater in BSL memory +#define CALL_RFSBL() ((void (*)()) 0x1000)() + + +// ************************************************************************************************* +// Global Variable section +extern u8 rfBSL_button_confirmation; + +#endif /*RFBSL_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfsimpliciti.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfsimpliciti.c new file mode 100755 index 0000000..6887571 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfsimpliciti.c @@ -0,0 +1,403 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// SimpliciTI functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "vti_as.h" +#include "ports.h" +#include "timer.h" +#include "radio.h" +#include "flash.h" + +// logic +#include "acceleration.h" +#include "rfsimpliciti.h" +#include "bluerobin.h" +#include "simpliciti.h" +#include "clock.h" +#include "date.h" +#include "temperature.h" +#include "vti_ps.h" +#include "altitude.h" +#include "datalog.h" + +// ************************************************************************************************* +// Prototypes section +void simpliciti_get_data_callback(void); +void start_simpliciti_sync(void); + +// ************************************************************************************************* +// Defines section + +// Each packet index requires 2 bytes, so we can have 9 packet indizes in 18 bytes usable payload +#define BM_SYNC_BURST_PACKETS_IN_DATA (9u) + +// ************************************************************************************************* +// Global Variable section +struct RFsmpl sRFsmpl; + +// flag contains status information, trigger to send data and trigger to exit SimpliciTI +unsigned char simpliciti_flag; + +// 4 data bytes to send +unsigned char simpliciti_data[SIMPLICITI_MAX_PAYLOAD_LENGTH]; + +// 4 byte device address overrides SimpliciTI end device address set in "smpl_config.dat" +unsigned char simpliciti_ed_address[4]; + +// 1 = send one or more reply packets, 0 = no need to reply +//unsigned char simpliciti_reply; +unsigned char simpliciti_reply_count; + +// 1 = send packets sequentially from burst_start to burst_end, 2 = send packets addressed by their +// index +u8 burst_mode; + +// Start and end index of packets to send out +u16 burst_start, burst_end; + +// Array containing requested packets +u16 burst_packet[BM_SYNC_BURST_PACKETS_IN_DATA]; + +// Current packet index +u8 burst_packet_index; + +// Byte-Pointer to flash memory +u8 *flash_ptr; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn reset_rf +// @brief Reset SimpliciTI data. +// @param none +// @return none +// ************************************************************************************************* +void reset_rf(void) +{ + // No connection + sRFsmpl.mode = SIMPLICITI_OFF; +} + +// ************************************************************************************************* +// @fn sx_sync +// @brief Start SimpliciTI. Button DOWN connects/disconnects to access point. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_sync(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Turn off the backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + BUTTONS_IE &= ~BUTTON_BACKLIGHT_PIN; + + // Start SimpliciTI in sync mode + start_simpliciti_sync(); + + BUTTONS_IE |= BUTTON_BACKLIGHT_PIN; +} + +// ************************************************************************************************* +// @fn display_sync +// @brief SimpliciTI display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_sync(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " SYNC", SEG_ON); + } +} + +// ************************************************************************************************* +// @fn is_rf +// @brief Returns TRUE if SimpliciTI receiver is connected. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_rf(void) +{ + return (sRFsmpl.mode != SIMPLICITI_OFF); +} + +// ************************************************************************************************* +// @fn start_simpliciti_sync +// @brief Start SimpliciTI (sync mode). +// @param none +// @return none +// ************************************************************************************************* +void start_simpliciti_sync(void) +{ + // Clear LINE1 + clear_line(LINE1); + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + + // Stop data logging and close session + stop_datalog(); + + // Turn on beeper icon to show activity + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + + // Prepare radio for RF communication + open_radio(); + + // Set SimpliciTI mode + sRFsmpl.mode = SIMPLICITI_SYNC; + + // Set SimpliciTI timeout to save battery power + sRFsmpl.timeout = SIMPLICITI_TIMEOUT; + + // Start SimpliciTI stack. Try to link to access point. + // Exit with timeout or by a DOWN button press. + if (simpliciti_link()) + { + // Enter sync routine. This will send ready-to-receive packets at regular intervals to the + // access point. + // The access point always replies a command (NOP if no other command is set) + simpliciti_main_sync(); + } + + // Set SimpliciTI state to OFF + sRFsmpl.mode = SIMPLICITI_OFF; + + // Powerdown radio + close_radio(); + + // Clear last button events + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + BUTTONS_IFG = 0x00; + button.all_flags = 0; + + // Clear icons + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); + + // Force full display update + display.flag.full_update = 1; +} + +// ************************************************************************************************* +// @fn simpliciti_sync_decode_ap_cmd_callback +// @brief For SYNC mode only: Decode command from access point and trigger actions. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_sync_decode_ap_cmd_callback(void) +{ + u8 i; + s16 t1, offset; + + // Default behaviour is to send no reply packets + simpliciti_reply_count = 0; + + switch (simpliciti_data[0]) + { + case SYNC_AP_CMD_NOP: + break; + + case SYNC_AP_CMD_GET_STATUS: // Send watch parameters + simpliciti_data[0] = SYNC_ED_TYPE_STATUS; + // Send single reply packet + simpliciti_reply_count = 1; + break; + + case SYNC_AP_CMD_SET_WATCH: // Set watch parameters + sys.flag.use_metric_units = (simpliciti_data[1] >> 7) & 0x01; + sTime.hour = simpliciti_data[1] & 0x7F; + sTime.minute = simpliciti_data[2]; + sTime.second = simpliciti_data[3]; + sDate.year = (simpliciti_data[4] << 8) + simpliciti_data[5]; + sDate.month = simpliciti_data[6]; + sDate.day = simpliciti_data[7]; + // Set temperature and temperature offset + t1 = (s16) ((simpliciti_data[10] << 8) + simpliciti_data[11]); + offset = t1 - (sAlt.temperature_C - sAlt.temperature_C_offset); + sAlt.temperature_C_offset = offset; + sAlt.temperature_C = t1; + // Set altitude + sAlt.altitude = (s16) ((simpliciti_data[12] << 8) + simpliciti_data[13]); + update_pressure_table(sAlt.altitude, sAlt.pressure, sAlt.temperature_K); + // Data logging mode + sDatalog.mode = simpliciti_data[14]; + // Data logging interval + sDatalog.interval = simpliciti_data[15]; + + display_chars(LCD_SEG_L2_5_0, (u8 *) " DONE", SEG_ON); + sRFsmpl.display_sync_done = 1; + break; + + case SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_1: + // Send sequential packets out in a burst + simpliciti_data[0] = SYNC_ED_TYPE_MEMORY; + // Get burst start and end packet + burst_start = (simpliciti_data[1] << 8) + simpliciti_data[2]; + burst_end = (simpliciti_data[3] << 8) + simpliciti_data[4]; + // Set burst mode + burst_mode = 1; + // Number of packets to send + simpliciti_reply_count = burst_end - burst_start + 1; + break; + + case SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_2: + // Send specified packets out in a burst + simpliciti_data[0] = SYNC_ED_TYPE_MEMORY; + // Store the requested packets + for (i = 0; i < BM_SYNC_BURST_PACKETS_IN_DATA; i++) + { + burst_packet[i] = (simpliciti_data[i * 2 + 1] << 8) + simpliciti_data[i * 2 + 2]; + } + // Set burst mode + burst_mode = 2; + // Number of packets to send + simpliciti_reply_count = BM_SYNC_BURST_PACKETS_IN_DATA; + break; + + case SYNC_AP_CMD_ERASE_MEMORY: // Erase data logger memory + for (i = DATALOG_PAGE_START; i <= DATALOG_PAGE_END; i++) + { + flash_erase_page(i); + } + sDatalog.wptr = (u16 *) DATALOG_MEMORY_START; + sDatalog.flags.flag.memory_full = 0; + break; + + case SYNC_AP_CMD_EXIT: // Exit sync mode + simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; + break; + } + +} + +// ************************************************************************************************* +// @fn simpliciti_sync_get_data_callback +// @brief For SYNC mode only: Access point has requested data. Copy this data into the TX +// buffer now. +// @param u16 index Index used for memory requests +// @return none +// ************************************************************************************************* +void simpliciti_sync_get_data_callback(unsigned int index) +{ + u8 i; + u16 bytes_ready; + + volatile u16 addr, mem; + + // Calculate bytes ready for sync + bytes_ready = (sDatalog.wptr - (u16 *) DATALOG_MEMORY_START) * 2; + + // simpliciti_data[0] contains data type and needs to be returned to AP + switch (simpliciti_data[0]) + { + case SYNC_ED_TYPE_STATUS: // Status packet + // Time + simpliciti_data[1] = (sys.flag.use_metric_units << 7) | (sTime.hour & 0x7F); + simpliciti_data[2] = sTime.minute; + simpliciti_data[3] = sTime.second; + // Date + simpliciti_data[4] = sDate.year >> 8; + simpliciti_data[5] = sDate.year & 0xFF; + simpliciti_data[6] = sDate.month; + simpliciti_data[7] = sDate.day; + // Unused + simpliciti_data[8] = 0; + simpliciti_data[9] = 0; + // Temperature + simpliciti_data[10] = sAlt.temperature_C >> 8; + simpliciti_data[11] = sAlt.temperature_C & 0xFF; + // Altitude + simpliciti_data[12] = sAlt.altitude >> 8; + simpliciti_data[13] = sAlt.altitude & 0xFF; + // Data logging mode + simpliciti_data[14] = sDatalog.mode; + // Data logging interval + simpliciti_data[15] = sDatalog.interval; + // Bytes ready for download + simpliciti_data[16] = bytes_ready >> 8; + simpliciti_data[17] = bytes_ready & 0xFF; + // Unused + simpliciti_data[18] = 0; + + break; + + case SYNC_ED_TYPE_MEMORY: + if (burst_mode == 1) + { + // Set burst packet address + simpliciti_data[1] = ((burst_start + index) >> 8) & 0xFF; + simpliciti_data[2] = (burst_start + index) & 0xFF; + // Assemble payload + flash_ptr = (u8 *) (DATALOG_MEMORY_START + (burst_start + index) * 16); + for (i = 3; i < BM_SYNC_DATA_LENGTH; i++) + simpliciti_data[i] = *flash_ptr++; + } + else if (burst_mode == 2) + { + // Set burst packet address + simpliciti_data[1] = (burst_packet[index] >> 8) & 0xFF; + simpliciti_data[2] = burst_packet[index] & 0xFF; + // Assemble payload + flash_ptr = (u8 *) (DATALOG_MEMORY_START + burst_packet[index] * 16); + for (i = 3; i < BM_SYNC_DATA_LENGTH; i++) + simpliciti_data[i] = *flash_ptr++; + } + break; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfsimpliciti.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfsimpliciti.h new file mode 100755 index 0000000..3cf7902 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/rfsimpliciti.h @@ -0,0 +1,98 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RFSIMPLICITI_H_ +#define RFSIMPLICITI_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_rf(void); +extern void sx_rf(u8 line); +extern void sx_ppt(u8 line); +extern void sx_sync(u8 line); +extern void display_rf(u8 line, u8 update); +extern void display_ppt(u8 line, u8 update); +extern void display_sync(u8 line, u8 update); +extern void send_smpl_data(u16 data); +extern u8 is_rf(void); + +// ************************************************************************************************* +// Defines section + +// SimpliciTI connection states +typedef enum +{ + SIMPLICITI_OFF = 0, // Not connected + SIMPLICITI_ACCELERATION, // Transmitting acceleration data and button events + SIMPLICITI_BUTTONS, // Transmitting button events + SIMPLICITI_SYNC // Syncing +} simpliciti_mode_t; + +// Stop SimpliciTI transmission after 60 minutes to save power +#define SIMPLICITI_TIMEOUT (60 * 60u) + +// Button flags for SimpliciTI data +#define SIMPLICITI_BUTTON_STAR (0x10) +#define SIMPLICITI_BUTTON_NUM (0x20) +#define SIMPLICITI_BUTTON_UP (0x30) + +// SimpliciTI mode flag +#define SIMPLICITI_MOUSE_EVENTS (0x01) +#define SIMPLICITI_KEY_EVENTS (0x02) + +// ************************************************************************************************* +// Global Variable section +struct RFsmpl +{ + // SIMPLICITI_OFF, SIMPLICITI_ACCELERATION, SIMPLICITI_BUTTONS + simpliciti_mode_t mode; + + // Timeout until SimpliciTI transmission is automatically stopped + u16 timeout; + + // Variable to display + u8 display_sync_done; +}; +extern struct RFsmpl sRFsmpl; + +extern unsigned char simpliciti_flag; + +// ************************************************************************************************* +// Extern section + +#endif /*RFSIMPLICITI_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/temperature.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/temperature.c new file mode 100755 index 0000000..5a4f897 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/temperature.c @@ -0,0 +1,170 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Temperature measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "temperature.h" +#include "display.h" + +// logic +#include "altitude.h" + +// ************************************************************************************************* +// Prototypes section +s16 convert_C_to_F(s16 value); +s16 convert_F_to_C(s16 value); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn convert_C_to_F +// @brief Convert °C to °F +// @param s16 value Temperature in °C +// @return s16 Temperature in °F +// ************************************************************************************************* +s16 convert_C_to_F(s16 value) +{ + s16 DegF; + + // Celsius in Fahrenheit = (( TCelsius × 9 ) / 5 ) + 32 + DegF = ((value * 9 * 10) / 5 / 10) + 32 * 10; + + return (DegF); +} + +// ************************************************************************************************* +// @fn convert_F_to_C +// @brief Convert °F to °C +// @param s16 value Temperature in 2.1 °F +// @return s16 Temperature in 2.1 °C +// ************************************************************************************************* +s16 convert_F_to_C(s16 value) +{ + s16 DegC; + + // TCelsius =( TFahrenheit - 32 ) × 5 / 9 + DegC = (((value - 320) * 5)) / 9; + + return (DegC); +} + +// ************************************************************************************************* +// @fn display_temperature +// @brief Common display routine for metric and English units. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_temperature(u8 line, u8 update) +{ + u8 *str; + s16 temperature; + + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Start measurement + start_altitude_measurement(); + + // Display °C / °F + display_symbol(LCD_SEG_L1_DP1, SEG_ON); + display_symbol(LCD_UNIT_L1_DEGREE, SEG_ON); + if (sys.flag.use_metric_units) + display_char(LCD_SEG_L1_0, 'C', SEG_ON); + else + display_char(LCD_SEG_L1_0, 'F', SEG_ON); + + // Display temperature + display_temperature(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + // When using English units, convert °C to °F (temp*1.8+32) + if (!sys.flag.use_metric_units) + { + temperature = convert_C_to_F(sAlt.temperature_C); + } + else + { + temperature = sAlt.temperature_C; + } + + // Indicate temperature sign through arrow up/down icon + if (temperature < 0) + { + // Convert negative to positive number + temperature = ~temperature; + temperature += 1; + + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + else // Temperature is >= 0 + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + + // Display result in xx.x format + str = int_to_array(temperature, 3, 1); + display_chars(LCD_SEG_L1_3_1, str, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Stop measurement + stop_altitude_measurement(); + + // Clean up function-specific segments before leaving function + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + display_symbol(LCD_UNIT_L1_DEGREE, SEG_OFF); + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/temperature.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/temperature.h new file mode 100755 index 0000000..81121ac --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/temperature.h @@ -0,0 +1,55 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef TEMPERATURE_H_ +#define TEMPERATURE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void display_temperature(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*TEMPERATURE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/user.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/user.c new file mode 100755 index 0000000..6410d0b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/user.c @@ -0,0 +1,282 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Several user functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "buzzer.h" +#include "ports.h" + +// logic +#include "menu.h" +#include "date.h" +#include "clock.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section +extern void idle_loop(void); + +// ************************************************************************************************* +// @fn dummy +// @brief Dummy direct function. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void dummy(u8 line) +{ +} + +// ************************************************************************************************* +// @fn set_value +// @brief Generic value setting routine +// @param s32 * value Pointer to value to +// set +// u8digits +// Number of digits +// u8 blanks +// Number of whitespaces before first valid +// digit +// s32 limitLow Lower limit +// of value +// s32 limitHigh Upper limit +// of value +// u16 mode +// u8 segments +// Segments where value should be drawn +// fptr_setValue_display_function1 Value-specific display +// routine +// @return none +// ************************************************************************************************* +void set_value(s32 * value, u8 digits, u8 blanks, s32 limitLow, s32 limitHigh, u16 mode, + u8 segments, + void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, + u8 blanks)) +{ + u8 update; + s16 stepValue = 1; + u8 doRound = 0; + u32 val; + + // Clear button flags + button.all_flags = 0; + + // Clear blink memory + clear_blink_mem(); + + // For safety only - buzzer on/off and button_repeat share same IRQ + stop_buzzer(); + + // Init step size and repeat counter + sButton.repeats = 0; + + // Initial display update + update = 1; + + // Turn on 200ms button repeat function + button_repeat_on(200); + + // Start blinking with with 2Hz + set_blink_rate(BIT6 + BIT5); + + // Value set loop + while (1) + { + // Idle timeout: exit function + if (sys.flag.idle_timeout) + break; + + // STAR (short) button: exit function + if (button.flag.star) + break; + + // NUM button: exit function and goto to next value (if available) + if (button.flag.num) + { + if ((mode & SETVALUE_NEXT_VALUE) == SETVALUE_NEXT_VALUE) + break; + } + + // UP button: increase value + if (button.flag.up) + { + // Increase value + *value = *value + stepValue; + + // Check value limits + if (*value > limitHigh) + { + // Check if value can roll over, else stick to limit + if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) + *value = limitLow; + else + *value = limitHigh; + + // Reset step size to default + stepValue = 1; + } + + // Trigger display update + update = 1; + + // Clear button flag + button.flag.up = 0; + } + + // DOWN button: decrease value + if (button.flag.down) + { + // Decrease value + *value = *value - stepValue; + + // Check value limits + if (*value < limitLow) + { + // Check if value can roll over, else stick to limit + if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) + *value = limitHigh; + else + *value = limitLow; + + // Reset step size to default + stepValue = 1; + } + + // Trigger display update + update = 1; + + // Clear button flag + button.flag.down = 0; + } + + // When fast mode is enabled, increase step size if Sx button is continuously + if ((mode & SETVALUE_FAST_MODE) == SETVALUE_FAST_MODE) + { + switch (sButton.repeats) + { + case 0: + stepValue = 1; + doRound = 0; + break; + case 10: + case -10: + stepValue = 10; + doRound = 1; + break; + case 20: + case -20: + stepValue = 100; + doRound = 1; + break; + case 30: + case -30: + stepValue = 1000; + doRound = 1; + break; + } + + // Round value to avoid odd numbers on display + if (stepValue != 1 && doRound == 1) + { + *value -= *value % stepValue; + doRound = 0; + } + } + + // Update display when there is new data + if (update) + { + // Display up or down arrow according to sign of value + if ((mode & SETVALUE_DISPLAY_ARROWS) == SETVALUE_DISPLAY_ARROWS) + { + if (*value >= 0) + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + val = *value; + } + else + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + val = *value * (-1); + } + } + else + { + val = *value; + } + + // Display function can either display value directly, modify value before displaying + // or display a string referenced by the value + fptr_setValue_display_function1(segments, val, digits, blanks); + + // Clear update flag + update = 0; + } + + // Call idle loop to serve background tasks + idle_loop(); + + } + + // Clear up and down arrows + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + + // Set blinking rate to 1Hz and stop + set_blink_rate(BIT7 + BIT6 + BIT5); + clear_blink_mem(); + + // Turn off button repeat function + button_repeat_off(); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/user.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/user.h new file mode 100755 index 0000000..f48cea4 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/logic/user.h @@ -0,0 +1,59 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef USER_H_ +#define USER_H_ + +// ************************************************************************************************* +// Defines section +#define SETVALUE_ROLLOVER_VALUE BIT0 +#define SETVALUE_DISPLAY_VALUE BIT1 +#define SETVALUE_DISPLAY_ARROWS BIT2 +#define SETVALUE_DISPLAY_SELECTION BIT3 +#define SETVALUE_FAST_MODE BIT4 +#define SETVALUE_NEXT_VALUE BIT5 + +// ************************************************************************************************* +// Prototypes section +extern u8 *select_view_style(u8 line, u8 * view1, u8 * view2); + +extern void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, u8 blanks); +extern void set_value(s32 * value, u8 digits, u8 blanks, s32 limitLow, s32 limitHigh, u16 mode, + u8 segments, + void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, + u8 blanks)); +extern void dummy(u8 line); + +#endif /*USER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/main.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/main.c new file mode 100755 index 0000000..7c96545 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/main.c @@ -0,0 +1,707 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// +//****************************************************************************** +// eZ430-Chronos +// +// Description: Software for the eZ430-Chronos Datalogger +// +// P.Francisco +// Version 1.6 +// Texas Instruments, Inc +// November 2010 +// Known working builds: +// IAR Embedded Workbench (Version: 5.10.4) +// Code Composer Studio (Version 4.2.0.10012) +//****************************************************************************** +//Change Log (More detailed information can be found in change_record.txt): +//****************************************************************************** +//Version: 1.6 +//Comments: Several bugs were fixed. +// LCD shows "done" after successfully received data +// rfBSL requires two button presses in order to update watch +// New method detects a long button press +// Removed file display1.c. The content is now in display.c +// Backlight of Chronos stays on for 3 sec after backlight button was pushed. +// +//Version: 1.5 +//Comments: Changed XT1 drive level to highest +// Modified key lock procedure. +// Negative °C are now converted correctly to Kelvin +// Enabled fast mode when changing altitude offset +// Disabled stopwatch stop when watch buttons are locked +// Added SimpliciTI sources to project. Upgraded to Version 1.1.1. +// Changed button names from M1/M2/S1/S2/BL to STAR/NUM/UP/DOWN/BACKLIGHT +// +//Version: 1.4 +//Comments: Initial Release Version +//********************************************************************************** + +// ************************************************************************************************* +// Initialization and control of application. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" +#include + +// driver +#include "clock.h" +#include "display.h" +#include "vti_as.h" +#include "vti_ps.h" +#include "radio.h" +#include "buzzer.h" +#include "ports.h" +#include "timer.h" +#include "pmm.h" + +// logic +#include "menu.h" +#include "date.h" +#include "battery.h" +#include "temperature.h" +#include "altitude.h" +#include "battery.h" +#include "acceleration.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "datalog.h" +#include "rfbsl.h" + +// ************************************************************************************************* +// Prototypes section +void init_application(void); +void init_global_variables(void); +void wakeup_event(void); +void process_requests(void); +void display_update(void); +void idle_loop(void); +void configure_ports(void); +void read_calibration_values(void); + +// ************************************************************************************************* +// Defines section + +// Number of calibration data bytes in INFOA memory +#define CALIBRATION_DATA_LENGTH (13u) + +// ************************************************************************************************* +// Global Variable section + +// Variable holding system internal flags +volatile s_system_flags sys; + +// Variable holding flags set by logic modules +volatile s_request_flags request; + +// Variable holding message flags +volatile s_message_flags message; + +// Global radio frequency offset taken from calibration memory +// Compensates crystal deviation from 26MHz nominal value +u8 rf_frequoffset; + +// Function pointers for LINE1 and LINE2 display function +void (*fptr_lcd_function_line1)(u8 line, u8 update); +void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn main +// @brief Main routine +// @param none +// @return none +// ************************************************************************************************* +int main(void) +{ + // Init MCU + init_application(); + + // Assign initial value to global variables + init_global_variables(); + + // Main control loop: wait in low power mode until some event needs to be processed + while (1) + { + // When idle go to LPM3 + idle_loop(); + + // Process wake-up events + if (button.all_flags || sys.all_flags) + wakeup_event(); + + // Process actions requested by logic modules + if (request.all_flags) + process_requests(); + + // Before going to LPM3, update display + if (display.all_flags) + display_update(); + } +} + +// ************************************************************************************************* +// @fn init_application +// @brief Initialize the microcontroller. +// @param none +// @return none +// ************************************************************************************************* +void init_application(void) +{ + volatile unsigned char *ptr; + + // --------------------------------------------------------------------- + // Enable watchdog + + // Watchdog triggers after 16 seconds when not cleared +#ifdef USE_WATCHDOG + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK; +#else + WDTCTL = WDTPW + WDTHOLD; +#endif + + // --------------------------------------------------------------------- + // Configure PMM + SetVCore(3); + + // Set global high power request enable + PMMCTL0_H = 0xA5; + PMMCTL0_L |= PMMHPMRE; + PMMCTL0_H = 0x00; + + // --------------------------------------------------------------------- + // Enable 32kHz ACLK + P5SEL |= 0x03; // Select XIN, XOUT on P5.0 and P5.1 + UCSCTL6 &= ~XT1OFF; // XT1 On, Highest drive strength + UCSCTL6 |= XCAP_3; // Internal load cap + UCSCTL3 = SELA__XT1CLK; // Select XT1 as FLL reference + UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; + + // --------------------------------------------------------------------- + // Configure CPU clock for 12MHz + _BIS_SR(SCG0); // Disable the FLL control loop + UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx + UCSCTL1 = DCORSEL_5; // Select suitable range + UCSCTL2 = FLLD_1 + 0x16E; // Set DCO Multiplier + _BIC_SR(SCG0); // Enable the FLL control loop + + // Worst-case settling time for the DCO when the DCO range bits have been + // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx + // UG for optimization. + // 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle + __delay_cycles(375000); + + // Loop until XT1 & DCO stabilizes, use do-while to insure that + // body is executed at least once + do + { + UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); + SFRIFG1 &= ~OFIFG; // Clear fault flags + } + while ((SFRIFG1 & OFIFG)); + + // --------------------------------------------------------------------- + // Configure port mapping + + // Disable all interrupts + __disable_interrupt(); + // Get write-access to port mapping registers: + PMAPPWD = 0x02D52; + // Allow reconfiguration during runtime: + PMAPCTL = PMAPRECFG; + + // P2.7 = TA0CCR1A or TA1CCR0A output (buzzer output) + ptr = &P2MAP0; + *(ptr + 7) = PM_TA1CCR0A; + P2OUT &= ~BIT7; + P2DIR |= BIT7; + + // P1.5 = SPI MISO input + ptr = &P1MAP0; + *(ptr + 5) = PM_UCA0SOMI; + // P1.6 = SPI MOSI output + *(ptr + 6) = PM_UCA0SIMO; + // P1.7 = SPI CLK output + *(ptr + 7) = PM_UCA0CLK; + + // Disable write-access to port mapping registers: + PMAPPWD = 0; + // Re-enable all interrupts + __enable_interrupt(); + + // --------------------------------------------------------------------- + // Configure ports + + // --------------------------------------------------------------------- + // Reset radio core + radio_reset(); + radio_powerdown(); + + // --------------------------------------------------------------------- + // Init acceleration sensor + as_init(); + + // --------------------------------------------------------------------- + // Init LCD + lcd_init(); + + // --------------------------------------------------------------------- + // Init buttons + init_buttons(); + + // --------------------------------------------------------------------- + // Configure Timer0 for use by the clock and delay functions + Timer0_Init(); + + // --------------------------------------------------------------------- + // Init pressure sensor + ps_init(); +} + +// ************************************************************************************************* +// @fn init_global_variables +// @brief Initialize global variables. +// @param none +// @return none +// ************************************************************************************************* +void init_global_variables(void) +{ + // -------------------------------------------- + // Apply default settings + + // set menu pointers to default menu items + ptrMenu_L1 = &menu_L1_Time; + ptrMenu_L2 = &menu_L2_DataLog; + + // Assign LINE1 and LINE2 display functions + fptr_lcd_function_line1 = ptrMenu_L1->display_function; + fptr_lcd_function_line2 = ptrMenu_L2->display_function; + + // Init system flags + button.all_flags = 0; + sys.all_flags = 0; + request.all_flags = 0; + display.all_flags = 0; + message.all_flags = 0; + + // Force full display update when starting up + display.flag.full_update = 1; + +#ifndef ISM_US + // Use metric units for display + sys.flag.use_metric_units = 1; +#endif + + // Read calibration values from info memory + read_calibration_values(); + + // Set system time to default value + reset_clock(); + + // Set date to default value + reset_date(); + + // Set buzzer to default value + reset_buzzer(); + + // Reset altitude measurement + reset_altitude_measurement(); + + // Reset acceleration measurement + reset_acceleration(); + +#ifdef INCLUDE_BLUEROBIN_SUPPORT + // Reset BlueRobin stack + reset_bluerobin(); +#endif + + // Reset SimpliciTI stack + reset_rf(); + + // Reset battery measurement + reset_batt_measurement(); + + // Reset data logger + reset_datalog(); +} + +// ************************************************************************************************* +// @fn wakeup_event +// @brief Process external / internal wakeup events. +// @param none +// @return none +// ************************************************************************************************* +void wakeup_event(void) +{ + // Enable idle timeout + sys.flag.idle_timeout_enabled = 1; + + // If buttons are locked, only display "buttons are locked" message + if (button.all_flags && sys.flag.lock_buttons) + { + // Show "buttons are locked" message synchronously with next second tick + if (!(BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED)) + { + message.flag.prepare = 1; + message.flag.type_locked = 1; + } + + // Clear buttons + button.all_flags = 0; + } + // Process long button press event (while button is held) + else if (button.flag.star_long) + { + // Clear button event + button.flag.star_long = 0; + + // Call sub menu function + ptrMenu_L1->mx_function(LINE1); + + // Set display update flag + display.flag.full_update = 1; + } + else if (button.flag.num_long) + { + // Clear button event + button.flag.num_long = 0; + + // Call sub menu function + ptrMenu_L2->mx_function(LINE2); + + // Set display update flag + display.flag.full_update = 1; + } + // Process single button press event (after button was released) + else if (button.all_flags) + { + // STAR button event --------------------------------------------------------------------- + // (Short) Advance to next menu item + if (button.flag.star) + { + // Clean up display before activating next menu item + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + + // Go to next menu entry + ptrMenu_L1 = ptrMenu_L1->next; + + // Assign new display function + fptr_lcd_function_line1 = ptrMenu_L1->display_function; + + // Set Line1 display update flag + display.flag.line1_full_update = 1; + + // Clear button flag + button.flag.star = 0; + } + // NUM button event --------------------------------------------------------------------- + // (Short) Advance to next menu item + else if (button.flag.num) + { + // Clear rfBSL confirmation flag + rfBSL_button_confirmation = 0; + + // Clean up display before activating next menu item + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_CLEAR); + + // Go to next menu entry + ptrMenu_L2 = ptrMenu_L2->next; + + // Assign new display function + fptr_lcd_function_line2 = ptrMenu_L2->display_function; + + // Set Line2 display update flag + display.flag.line2_full_update = 1; + + // Clear button flag + button.flag.num = 0; + } + // UP button event --------------------------------------------------------------------- + // Activate user function for Line1 menu item + else if (button.flag.up) + { + // Call direct function + ptrMenu_L1->sx_function(LINE1); + + // Set Line1 display update flag + display.flag.line1_full_update = 1; + + // Clear button flag + button.flag.up = 0; + } + // DOWN button event --------------------------------------------------------------------- + // Activate user function for Line2 menu item + else if (button.flag.down) + { + // Call direct function + ptrMenu_L2->sx_function(LINE2); + + // Set Line1 display update flag + display.flag.line2_full_update = 1; + + // Clear button flag + button.flag.down = 0; + } + } + + // Process internal events + if (sys.all_flags) + { + // Idle timeout --------------------------------------------------------------------- + if (sys.flag.idle_timeout) + { + // Clear timeout flag + sys.flag.idle_timeout = 0; + + // Clear display + clear_display(); + + // Set display update flags + display.flag.full_update = 1; + } + } + + // Disable idle timeout + sys.flag.idle_timeout_enabled = 0; +} + +// ************************************************************************************************* +// @fn process_requests +// @brief Process requested actions outside ISR context. +// @param none +// @return none +// ************************************************************************************************* +void process_requests(void) +{ + // Do temperature and pressure measurement + if (request.flag.altitude_measurement) + do_altitude_measurement(FILTER_ON); + + // Add data to datalog buffer + if (request.flag.datalog) + do_datalog(); + + // Do voltage measurement + if (request.flag.voltage_measurement) + battery_measurement(); + + // Reset request flag + request.all_flags = 0; +} + +// ************************************************************************************************* +// @fn display_update +// @brief Process display flags and call LCD update routines. +// @param none +// @return none +// ************************************************************************************************* +void display_update(void) +{ + u8 line; + u8 string[8]; + + // --------------------------------------------------------------------- + // Call Line1 display function + if (display.flag.full_update || display.flag.line1_full_update) + { + clear_line(LINE1); + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_UPDATE_FULL); + } + else if (ptrMenu_L1->display_update()) + { + // Update line1 only when new data is available + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + + // --------------------------------------------------------------------- + // If message text should be displayed on Line2, skip normal update + if (message.flag.show) + { + // Select message to display + line = LINE2; + if (message.flag.type_locked) + memcpy(string, " LO?T", 6); + else if (message.flag.type_unlocked) + memcpy(string, " OPEN", 6); + else if (message.flag.type_lobatt) + memcpy(string, "LOBATT", 6); + else if (message.flag.type_nomem) + memcpy(string, " NOMEM", 6); + else + { + line = LINE1; + if (message.flag.type_on) + memcpy(string, " ON", 4); + else if (message.flag.type_off) + memcpy(string, " OFF", 4); + } + + // Clear previous content + clear_line(line); + fptr_lcd_function_line2(line, DISPLAY_LINE_CLEAR); + + if (line == LINE2) + display_chars(LCD_SEG_L2_5_0, string, SEG_ON); + else + display_chars(LCD_SEG_L1_3_0, string, SEG_ON); + + // Next second tick erases message and repaints original screen content + message.all_flags = 0; + message.flag.erase = 1; + } + // --------------------------------------------------------------------- + // Call Line2 display function + else if (display.flag.full_update || display.flag.line2_full_update) + { + clear_line(LINE2); + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_UPDATE_FULL); + } + else if (ptrMenu_L2->display_update() && !message.all_flags) + { + // Update line2 only when new data is available + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_UPDATE_PARTIAL); + } + + // --------------------------------------------------------------------- + // Restore blinking icons (blinking memory is cleared when calling set_value) + if (display.flag.full_update) + { + if (is_bluerobin() == BLUEROBIN_CONNECTED) + { + // Turn on beeper icon to show activity + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF); + } + } + + // Clear display flag + display.all_flags = 0; +} + +// ************************************************************************************************* +// @fn to_lpm +// @brief Go to LPM0/3. +// @param none +// @return none +// ************************************************************************************************* +void to_lpm(void) +{ + // Go to LPM3 + _BIS_SR(LPM3_bits + GIE); + __no_operation(); +} + +// ************************************************************************************************* +// @fn idle_loop +// @brief Go to LPM. Service watchdog timer when waking up. +// @param none +// @return none +// ************************************************************************************************* +void idle_loop(void) +{ + // To low power mode + to_lpm(); + +#ifdef USE_WATCHDOG + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; +#endif +} + +// ************************************************************************************************* +// @fn read_calibration_values +// @brief Read calibration values for temperature measurement, voltage measurement +// and radio from INFO memory. +// @param none +// @return none +// ************************************************************************************************* +void read_calibration_values(void) +{ + u8 cal_data[CALIBRATION_DATA_LENGTH]; // Temporary storage for constants + u8 i; + u8 *flash_mem; // Memory pointer + + // Read calibration data from Info D memory + flash_mem = (u8 *) 0x1800; + for (i = 0; i < CALIBRATION_DATA_LENGTH; i++) + { + cal_data[i] = *flash_mem++; + } + + if (cal_data[0] == 0xFF) + { + // If no values are available (i.e. INFO D memory has been erased by user), assign + // experimentally derived values + rf_frequoffset = 4; + sBatt.offset = -10; + simpliciti_ed_address[0] = 0x79; + simpliciti_ed_address[1] = 0x56; + simpliciti_ed_address[2] = 0x34; + simpliciti_ed_address[3] = 0x12; + sAlt.altitude_offset = 0; + } + else + { + // Assign calibration data to global variables + rf_frequoffset = cal_data[1]; + // Range check for calibrated FREQEST value (-20 .. + 20 is ok, else use default value) + if ((rf_frequoffset > 20) && (rf_frequoffset < (256 - 20))) + { + rf_frequoffset = 0; + } + sBatt.offset = (s16) ((cal_data[4] << 8) + cal_data[5]); + simpliciti_ed_address[0] = cal_data[6]; + simpliciti_ed_address[1] = cal_data[7]; + simpliciti_ed_address[2] = cal_data[8]; + simpliciti_ed_address[3] = cal_data[9]; + // S/W version byte set during calibration? + if (cal_data[12] != 0xFF) + { + sAlt.altitude_offset = (s16) ((cal_data[10] << 8) + cal_data[11]); + } + else + { + sAlt.altitude_offset = 0; + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.cspy.bat b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.cspy.bat new file mode 100755 index 0000000..8523a0b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.cspy.bat @@ -0,0 +1,15 @@ +@REM This batch file has been generated by the IAR Embedded Workbench +@REM C-SPY Debugger, as an aid to preparing a command line for running +@REM the cspybat command line utility using the appropriate settings. +@REM +@REM You can launch cspybat by typing the name of this batch file followed +@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). +@REM Note that this file is generated every time a new debug session +@REM is initialized, so you may want to move or rename the file before +@REM making changes. +@REM + + +"C:\Program Files\IAR Systems\Embedded Workbench 6.0\common\bin\cspybat" "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\bin\430proc.dll" "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\bin\430fet.dll" %1 --plugin "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\bin\430bat.dll" --backend -B "-p" "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\config\CC430F6137.ddf" "--core=430Xv2" "--data_model=small" "--iv_base" "0xFF80" "--no_wrap_around" "-d" "fet" "--erase_main" "--derivative" "CC430F6137" "--protocol" "spy-bi-wire" "--eem" "EMEX_SMALL_5XX" "--port" "Automatic" "--connection" "ti_usb" "--settlingtime=0" "--msp430_dll" "msp430.dll" "--vccDefault" "3.3" + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.dbgdt b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.dbgdt new file mode 100755 index 0000000..c116f04 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.dbgdt @@ -0,0 +1,78 @@ + + + + + + + + + 201221 + + + + + + 2091524461 + + + + + + + 298272727 + + + + + 020010 + 200Register285201100100200Watch1052775904 + + + + + + + + TabID-24903-19240 + Debug Log + Debug-Log + + + + TabID-24380-19250 + Build + Build + + + TabID-20596-29664BreakpointsBreakpointsTabID-125-5262MemoryMemory06144614410000377TabID-4077-5393Find in FilesFind-in-Files + + 0 + + + TabID-2883-19244 + Workspace + Workspace + + + ez430_chronos_datalogger + + + + 0 + + + + + + TextEditor$WS_DIR$\main.c01385821582100100000010000001 + + + + + + + iaridepm.enu1debuggergui.enu1430fet1-2-2595372-2-2180273140625284969292188623173-2-22711282-2-212842731003125284969140625284969 + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.dni b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.dni new file mode 100755 index 0000000..c285ee1 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.dni @@ -0,0 +1,87 @@ +[DebugChecksum] +Checksum=262336797 +[DisAssemblyWindow] +NumStates=_ 1 +State 1=_ 1 +[CodeCoverage] +Enabled=_ 0 +[Profiling] +Enabled=0 +[StackPlugin] +Enabled=1 +OverflowWarningsEnabled=1 +WarningThreshold=90 +SpWarningsEnabled=1 +WarnHow=0 +UseTrigger=1 +TriggerName=main +LimitSize=0 +ByteLimit=50 +[State Storage] +Control Register=0 +[Sequencer] +Control Register=0 +NextState0=0 +NextState1=0 +[Action Register] +Break=3 +State Storage=0 +[InstructionProfiling] +Enabled=_ 0 +[Interrupts] +Enabled=1 +[MemoryMap] +Enabled=0 +Base=0 +UseAuto=0 +TypeViolation=1 +UnspecRange=1 +ActionState=1 +[TraceHelper] +Enabled=0 +ShowSource=1 +[Log file] +LoggingEnabled=_ 0 +LogFile=_ "" +Category=_ 0 +[TermIOLog] +LoggingEnabled=_ 0 +LogFile=_ "" +[CallStackLog] +Enabled=0 +[DriverProfiling] +Enabled=0 +Mode=1229342020 +Graph=0 +Symbiont=0 +[Breakpoints] +Bp0=_ "STD_CODE" "{$PROJ_DIR$\logic\bluerobin.c}.309.10@1" 0 0 0 0 "" 0 "" +Bp1=_ "STD_CODE" "{$PROJ_DIR$\logic\bluerobin.c}.361.4@1" 0 0 0 0 "" 0 "" +Bp2=_ "STD_CODE" "{$PROJ_DIR$\driver\radio.c}.185.8@1" 0 0 0 0 "" 0 "" +Bp3=_ "STD_CODE" "{$PROJ_DIR$\driver\radio.c}.185.8@1" 0 0 0 0 "" 0 "" +Bp4=_ "STD_CODE" "{$PROJ_DIR$\driver\radio.c}.185.8@1" 0 0 0 0 "" 0 "" +Bp5=_ "STD_CODE" "{$PROJ_DIR$\logic\bluerobin.c}.291.4@1" 1 0 0 0 "" 0 "" +Count=6 +[FET] +Clock mode=14 +Extended Clock mode=61663 +Secure Password= +Extended Clock Control Enable=1 +Advanced Extended Clock Control=0 +Emulation mode=0 +Free running=0 +Shutting Down=3 +[Memory Dump] +Start address= +Lenghth= +Address info=0 +Format=0 +Dump registers=0 +PC=0 +SP=0 +SR=0 +all registers=0 +File name= +[Aliases] +Count=0 +SuppressDialog=0 diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.wsdt b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.wsdt new file mode 100755 index 0000000..91f2798 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/settings/ez430_chronos_datalogger.wsdt @@ -0,0 +1,37 @@ + + + + + + ez430_chronos_datalogger/433MHz - Unrestricted IAR Workbench (Other regions) + + + + + + + + + 28241270 + 100SourceBrowser + 209152446120122147167807100Workspace + + + TabID-12355-9241BuildBuildTabID-11374-19903Debug LogDebug-LogTabID-19476-23171Find in FilesFind-in-FilesTabID-26297-1149Tool OutputTool-Output0TabID-19628-18239WorkspaceWorkspaceez430_chronos_datalogger0 + + + + + + TextEditor$WS_DIR$\main.c02425782578TextEditor$WS_DIR$\driver\timer.c0036436410100000010000001 + + + + + + + iaridepm.enu1-2-2697370-2-2149137116406143006290625729645-2-22171282-2-212842191003125228601116406188935 + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Applications/application/End Device/main_ED_BM.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Applications/application/End Device/main_ED_BM.c new file mode 100755 index 0000000..af83d41 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Applications/application/End Device/main_ED_BM.c @@ -0,0 +1,264 @@ +/********************************************************************************************** + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +// ************************************************************************************************* +// Include section +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "bsp_leds.h" +#include "bsp_buttons.h" +#include "simpliciti.h" + + +// ************************************************************************************************* +// Defines section +#define TIMEOUT (10u) + +// Conversion from msec to ACLK timer ticks +#define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000) + +// U16 +typedef unsigned short u16; + +// ************************************************************************************************* +// Prototypes section + + +// ************************************************************************************************* +// Extern section +extern uint8_t sInit_done; + +// SimpliciTI has no low power delay function, so we have to use ours +extern void Timer0_A4_Delay(u16 ticks); + + +// ************************************************************************************************* +// Global Variable section +static linkID_t sLinkID1; + + + +// ************************************************************************************************* +// @fn simpliciti_link +// @brief Init hardware and try to link to access point. +// @param none +// @return unsigned char 0 = Could not link, timeout or external cancel. +// 1 = Linked successful. +// ************************************************************************************************* +unsigned char simpliciti_link(void) +{ + uint8_t timeout; + addr_t lAddr; + uint8_t i; + uint8_t pwr; + + // Configure timer + BSP_InitBoard(); + + // Change network address to value set in calling function + for (i=0; i TIMEOUT) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + simpliciti_flag = SIMPLICITI_STATUS_ERROR; + return (0); + } + + // Break when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + return (0); + } + } + + // Set output power to +3.3dmB + pwr = IOCTL_LEVEL_2; + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &pwr); + + /* Unconditional link to AP which is listening due to successful join. */ + timeout = 0; + while (SMPL_SUCCESS != SMPL_Link(&sLinkID1)) + { + NWK_DELAY(1000); + + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; + + // Stop linking after timeout + if (timeout++ > TIMEOUT) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + simpliciti_flag = SIMPLICITI_STATUS_ERROR; + return (0); + } + + // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + return (0); + } + } + simpliciti_flag = SIMPLICITI_STATUS_LINKED; + + return (1); +} + + + +// ************************************************************************************************* +// @fn simpliciti_main_tx_only +// @brief Get data through callback. Transfer data when external trigger is set. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_main_tx_only(void) +{ + while(1) + { + // Get end device data from callback function + simpliciti_get_ed_data_callback(); + + // Send data when flag bit SIMPLICITI_TRIGGER_SEND_DATA is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA)) + { + // Get radio ready. Wakes up in IDLE state. + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); + + // Acceleration / button events packets are 4 bytes long + SMPL_SendOpt(sLinkID1, simpliciti_data, 4, SMPL_TXOPTION_NONE); + + // Put radio back to SLEEP state + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); + + clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA); + } + + // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + break; + } + } +} + + + +// ************************************************************************************************* +// @fn simpliciti_main_sync +// @brief Send ready-to-receive packets in regular intervals. Listen shortly for host reply. +// Decode received host command and trigger action. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_main_sync(void) +{ + uint8_t len, i; + uint8_t ed_data[2]; + + while(1) + { + // Sleep 0.5sec between ready-to-receive packets + // SimpliciTI has no low power delay function, so we have to use ours + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); + + // Get radio ready. Radio wakes up in IDLE state. + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); + + // Send 2 byte long ready-to-receive packet to stimulate host reply + ed_data[0] = SYNC_ED_TYPE_R2R; + ed_data[1] = 0xCB; + SMPL_SendOpt(sLinkID1, ed_data, 2, SMPL_TXOPTION_NONE); + + // Wait shortly for host reply + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); + NWK_DELAY(10); + + // Check if a command packet was received + while (SMPL_Receive(sLinkID1, simpliciti_data, &len) == SMPL_SUCCESS) + { + // Decode received data + if (len > 0) + { + // Use callback function in application to decode data and react + simpliciti_sync_decode_ap_cmd_callback(); + + // Get reply data and send out reply packet burst (19 bytes each) + for (i=0; i level) + SetVCoreDown(--actLevel); /* Set VCore (step by step) */ + }while (actLevel != level); +} + +/************************************************************************************************** + * @fn SetVCoreUp + * + * @brief Set VCore up. Change level by one step only. + * + * @param level - VcCore level + * + * @return none + ************************************************************************************************* + */ +static void SetVCoreUp (uint8_t level) +{ + PMMCTL0_H = 0xA5; /* Open PMM module registers for write access */ + + SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; /* Set SVS/M high side to new level */ + + SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; /* Set SVM new Level */ + while ((PMMIFG & SVSMLDLYIFG) == 0); /* Wait till SVM is settled (Delay) */ + PMMCTL0_L = PMMCOREV0 * level; /* Set VCore to x */ + PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); /* Clear already set flags */ + if ((PMMIFG & SVMLIFG)) + while ((PMMIFG & SVMLVLRIFG) == 0); /* Wait till level is reached */ + + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; /* Set SVS/M Low side to new level */ + PMMCTL0_H = 0x00; /* Lock PMM module registers for write access */ +} + +/************************************************************************************************** + * @fn SetVCoreDown + * + * @brief Set VCore down + * + * @param level - VcCore level + * + * @return none + ************************************************************************************************** + */ +static void SetVCoreDown (uint8_t level) +{ + PMMCTL0_H = 0xA5; /* Open PMM module registers for write access */ + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; /* Set SVS/M Low side to new level */ + while ((PMMIFG & SVSMLDLYIFG) == 0); /* Wait till SVM is settled (Delay) */ + PMMCTL0_L = (level * PMMCOREV0); /* Set VCore to 1.85 V for Max Speed. */ + PMMCTL0_H = 0x00; /* Lock PMM module registers for write access */ +} + +/************************************************************************************************** + * @fn Bsp_SetVCore + * + * @brief Setup the core voltage. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Bsp_SetVCore(void) +{ + SetVCore(3); +} + +/************************************************************************************************** + * @fn Bsp_SetClocks + * + * @brief Set up system clocks. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Bsp_SetClocks(void) +{ + /* Configure CPU clock for 12MHz */ + + /* If clock settings are changed, remember to update BSP_TIMER_CLK_MHZ. + * Otherwise, all timer settings would be incorrect. + */ + UCSCTL3 |= SELREF_2; /* Set DCO FLL reference = REFO */ + UCSCTL4 |= SELA_2; /* Set ACLK = REFO */ + + __bis_SR_register(SCG0); /* Disable the FLL control loop */ + UCSCTL0 = 0x0000; /* Set lowest possible DCOx, MODx */ + UCSCTL1 = DCORSEL_5; /* Select DCO range 24MHz operation */ + UCSCTL2 = FLLD_1 + 374; /* Set DCO Multiplier for 12MHz */ + /* (N + 1) * FLLRef = Fdco */ + /* (374 + 1) * 32768 = 12MHz */ + /* Set FLL Div = fDCOCLK/2 */ + __bic_SR_register(SCG0); /* Enable the FLL control loop */ + + /* Worst-case settling time for the DCO when the DCO range bits have been + * changed is n x 32 x 32 x f_MCLK / f_FLL_reference. + * 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle + */ + __delay_cycles(375000); + + /* Loop until XT1,XT2 & DCO fault flag is cleared */ + do + { + UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); + /* Clear XT2,XT1,DCO fault flags */ + SFRIFG1 &= ~OFIFG; /* Clear fault flags */ + }while (SFRIFG1&OFIFG); /* Test oscillator fault flag */ + + /* Select REFO as ACLK source and DCOCLK as MCLK and SMCLK source */ + UCSCTL4 = SELA__REFOCLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; +} + +/************************************************************************************************** + * @fn BSP_EARLY_INIT + * + * @brief This function is called by start-up code before doing the normal initialization + * of data segments. If the return value is zero, initialization is not performed. + * The global macro label "BSP_EARLY_INIT" gets #defined in the bsp_msp430_defs.h + * file, according to the specific compiler environment (CCE or IAR). In the CCE + * environment this macro invokes "_system_pre_init()" and in the IAR environment + * this macro invokes "__low_level_init()". + * + * @param None + * + * @return 0 - don't intialize data segments / 1 - do initialization + ************************************************************************************************* + */ +BSP_EARLY_INIT(void) +{ + /* Disable watchdog timer */ + WDTCTL = WDTPW | WDTHOLD; + + /* Setup Vcore */ + Bsp_SetVCore(); + + /* Configure System clocks */ + Bsp_SetClocks(); + + /* Return 1 - run seg_init */ + return (1); +} + +/************************************************************************************************** + * @fn BSP_InitBoard + * + * @brief Initialize the board. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitBoard(void) +{ + /* Configure TimerA for use by the delay function */ + + /* Reset the timer */ + //TA0CTL |= TACLR; /* Set the TACLR */ + + /* Clear all settings */ + //TA0CTL = 0x0; + + /* Select the clk source to be - SMCLK (Sub-Main CLK)*/ + //TA0CTL |= TASSEL_2; + + // [BM] We need to use TA1 for delay function, because TA0 is already occupied + TA1CTL |= TACLR; /* Set the TACLR */ + TA1CTL = 0x0; + TA1CTL |= TASSEL_2; +} + +/************************************************************************************************** + * @fn BSP_Delay + * + * @brief Delay for the requested amount of time. + * + * @param # of microseconds to delay. + * + * @return none + ************************************************************************************************** + */ +void BSP_Delay(uint16_t usec) +{ + BSP_ASSERT(usec < BSP_DELAY_MAX_USEC); + + //TA0R = 0; /* initial count */ + //TA0CCR0 = BSP_TIMER_CLK_MHZ*usec; /* compare count. (delay in ticks) */ + + /* Start the timer in UP mode */ + //TA0CTL |= MC_1; + + /* Loop till compare interrupt flag is set */ + //while(!(TA0CCTL0 & CCIFG)); + + /* Stop the timer */ + //TA0CTL &= ~(MC_1); + + /* Clear the interrupt flag */ + //TA0CCTL0 &= ~CCIFG; + + // [BM] We need to use TA1 for delay function, because TA0 is already occupied + TA1R = 0; + TA1CCR0 = BSP_TIMER_CLK_MHZ*usec; + TA1CTL |= MC_1; + while(!(TA1CCTL0 & CCIFG)); + TA1CTL &= ~(MC_1); + TA1CCTL0 &= ~CCIFG; +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h new file mode 100755 index 0000000..f3e01ad --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h @@ -0,0 +1,83 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Board definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BOARD_DEFS_H +#define BSP_BOARD_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Board Unique Define + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BOARD_CC430EM + + +/* ------------------------------------------------------------------------------------------------ + * Mcu + * ------------------------------------------------------------------------------------------------ + */ +#include "mcus/bsp_msp430_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Clock + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_config.h" +#define __bsp_CLOCK_MHZ__ BSP_CONFIG_CLOCK_MHZ + + +/* ------------------------------------------------------------------------------------------------ + * Board Initialization + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BOARD_C "bsp_board.c" +#define BSP_INIT_BOARD() BSP_InitBoard() +#define BSP_DELAY_USECS(x) BSP_Delay(x) + +void BSP_InitBoard(void); +void BSP_Delay(uint16_t usec); + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h new file mode 100755 index 0000000..453863c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h @@ -0,0 +1,91 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Button definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BUTTON_DEFS_H +#define BSP_BUTTON_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Button Configuration + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_NUM_BUTTONS__ 1 +#define __bsp_BUTTON_DEBOUNCE_WAIT__(expr) st( int i; for(i=0; i<500; i++) { if (!(expr)) i = 0; } ) + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * BUTTON #1 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : S2 + * Description : Push Button + * Polarity : Active Low + * GPIO : P1.7 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_BUTTON1_BIT__ 7 +#define __bsp_BUTTON1_PORT__ P1IN +#define __bsp_BUTTON1_IS_ACTIVE_LOW__ 1 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Extended Configuration + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +/* Enable the internal PullUp for button #1. */ +#define __bsp_BUTTON_EXTENDED_CONFIG__() st( P1OUT |= BV(__bsp_BUTTON1_BIT__); /* PullUp */ \ + P1REN |= BV(__bsp_BUTTON1_BIT__);)/* Enable PullUp */ + + +/* ------------------------------------------------------------------------------------------------ + * Include Generic Button Macros + * ------------------------------------------------------------------------------------------------ + */ +#include "code/bsp_generic_buttons.h" + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h new file mode 100755 index 0000000..a4550e2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h @@ -0,0 +1,47 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Board configuration file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_CONFIG_H +#define BSP_CONFIG_H + + +/* Nothing needed for this platform. */ + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h new file mode 100755 index 0000000..b3f7066 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h @@ -0,0 +1,54 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Driver definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_DRIVER_DEFS_H +#define BSP_DRIVER_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Driver Initialization + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_DRIVERS_C "bsp_drivers.c" +#define BSP_INIT_DRIVERS() BSP_InitDrivers() +void BSP_InitDrivers(void); + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c new file mode 100755 index 0000000..563f59c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c @@ -0,0 +1,88 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Top-level driver file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_driver_defs.h" +#include "bsp_leds.h" +#include "bsp_buttons.h" +#include "bsp_config.h" + + +/************************************************************************************************** + * @fn BSP_InitDrivers + * + * @brief Initialize all enabled BSP drivers. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitDrivers(void) +{ +#if (!defined BSP_NO_LEDS) + BSP_InitLeds(); +#endif + +#if (!defined BSP_NO_BUTTONS) + BSP_InitButtons(); +#endif +} + + +/* ================================================================================================ + * C Code Includes + * ================================================================================================ + */ +#ifndef BSP_NO_LEDS +#include "drivers/code/bsp_leds.c" +#endif + +#ifndef BSP_NO_BUTTONS +#include "drivers/code/bsp_buttons.c" +#endif + + +/************************************************************************************************** +*/ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h new file mode 100755 index 0000000..38840c0 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h @@ -0,0 +1,81 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Board definition file. + * Target : Texas Instruments CC430EM + * Radios : CC430 + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_BOARD_DEFS_H +#define MRFI_BOARD_DEFS_H + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + + +/* ------------------------------------------------------------------------------------------------ + * Radio Selection + * ------------------------------------------------------------------------------------------------ + */ +#if (!defined MRFI_CC430) + #error "ERROR: A compatible radio must be specified for the CC430EM board." +#endif + + +/* Radio Interface critical section macros */ +typedef bspIState_t mrfiRIFIState_t; +#define MRFI_RIF_ENTER_CRITICAL_SECTION(x) BSP_ENTER_CRITICAL_SECTION(x) +#define MRFI_RIF_EXIT_CRITICAL_SECTION(x) BSP_EXIT_CRITICAL_SECTION(x) + + +/************************************************************************************************** + * Compile Time Integrity Checks + ************************************************************************************************** + */ +#ifndef BSP_BOARD_CC430EM +#error "ERROR: Mismatch between specified board and MRFI configuration." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h new file mode 100755 index 0000000..5cd33b6 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h @@ -0,0 +1,97 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * LED definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_LED_DEFS_H +#define BSP_LED_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Configuration + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_NUM_LEDS__ 2 +#define __bsp_LED_BLINK_LOOP_COUNT__ 0x34000 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * LED #1 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : LED1 + * Color : Green + * Polarity : Active High + * GPIO : P1.0 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_LED1_BIT__ 0 +#define __bsp_LED1_PORT__ P1OUT +#define __bsp_LED1_DDR__ P1DIR +#define __bsp_LED1_IS_ACTIVE_LOW__ 0 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * LED #2 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : LED2 + * Color : Green + * Polarity : Active High + * GPIO : P3.6 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_LED2_BIT__ 6 +#define __bsp_LED2_PORT__ P3OUT +#define __bsp_LED2_DDR__ P3DIR +#define __bsp_LED2_IS_ACTIVE_LOW__ 0 + + +/* ------------------------------------------------------------------------------------------------ + * Include Generic LED Macros + * ------------------------------------------------------------------------------------------------ + */ +#include "code/bsp_generic_leds.h" + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/bsp.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/bsp.c new file mode 100755 index 0000000..cee0b33 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/bsp.c @@ -0,0 +1,101 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Top-level BSP code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "bsp_driver_defs.h" + + +/************************************************************************************************** + * @fn BSP_Init + * + * @brief Initialize the board and drivers. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_Init(void) +{ + BSP_INIT_BOARD(); + BSP_INIT_DRIVERS(); + + /*------------------------------------------------------------- + * Run time integrity checks. Perform only if asserts + * are enabled. + */ +#ifdef BSP_ASSERTS_ARE_ON + /* verify endianess is correctly specified */ + { + uint16_t test = 0x00AA; /* first storage byte of 'test' is non-zero for little endian */ + BSP_ASSERT(!(*((uint8_t *)&test)) == !BSP_LITTLE_ENDIAN); /* endianess mismatch */ + } +#endif +} + + +/* ================================================================================================ + * C Code Includes + * ================================================================================================ + */ +#ifdef BSP_BOARD_C +#include BSP_BOARD_C +#endif + +#ifdef BSP_DRIVERS_C +#include BSP_DRIVERS_C +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +BSP_STATIC_ASSERT( sizeof( uint8_t ) == 1 ); +BSP_STATIC_ASSERT( sizeof( int8_t ) == 1 ); +BSP_STATIC_ASSERT( sizeof( uint16_t ) == 2 ); +BSP_STATIC_ASSERT( sizeof( int16_t ) == 2 ); +BSP_STATIC_ASSERT( sizeof( uint32_t ) == 4 ); +BSP_STATIC_ASSERT( sizeof( int32_t ) == 4 ); + + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/bsp.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/bsp.h new file mode 100755 index 0000000..8cff5a0 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/bsp.h @@ -0,0 +1,183 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Include file for core BSP services. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_H +#define BSP_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + +/* ------------------------------------------------------------------------------------------------ + * BSP Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP +#define BSP_VER 100 /* BSP version 1.00a */ +#define BSP_SUBVER a + + +/* ------------------------------------------------------------------------------------------------ + * Clock + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CLOCK_MHZ __bsp_CLOCK_MHZ__ + + +/* ------------------------------------------------------------------------------------------------ + * Memory + * ------------------------------------------------------------------------------------------------ + */ +#ifndef __bsp_LITTLE_ENDIAN__ +#error ERROR: Endianess not defined +#endif + +#define BSP_LITTLE_ENDIAN __bsp_LITTLE_ENDIAN__ + +#define CODE __bsp_CODE_MEMSPACE__ +#define XDATA __bsp_XDATA_MEMSPACE__ + +/* ------------------------------------------------------------------------------------------------ + * Interrupts + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_ISR_FUNCTION(func,vect) __bsp_ISR_FUNCTION__(func,vect) + +#define BSP_ENABLE_INTERRUPTS() __bsp_ENABLE_INTERRUPTS__() +#define BSP_DISABLE_INTERRUPTS() __bsp_DISABLE_INTERRUPTS__() +#define BSP_INTERRUPTS_ARE_ENABLED() __bsp_INTERRUPTS_ARE_ENABLED__() + + +/* ------------------------------------------------------------------------------------------------ + * Critical Sections + * ------------------------------------------------------------------------------------------------ + */ +typedef __bsp_ISTATE_T__ bspIState_t; + +#define BSP_ENTER_CRITICAL_SECTION(x) st( x = __bsp_GET_ISTATE__(); __bsp_DISABLE_INTERRUPTS__(); ) +#define BSP_EXIT_CRITICAL_SECTION(x) __bsp_RESTORE_ISTATE__(x) +#define BSP_CRITICAL_STATEMENT(x) st( bspIState_t s; \ + BSP_ENTER_CRITICAL_SECTION(s); \ + x; \ + BSP_EXIT_CRITICAL_SECTION(s); ) + + +/* ------------------------------------------------------------------------------------------------ + * Asserts + * ------------------------------------------------------------------------------------------------ + */ + +/* + * BSP_ASSERT( expression ) - The given expression must evaluate as "true" or else the assert + * handler is called. From here, the call stack feature of the debugger can pinpoint where + * the problem occurred. + * + * BSP_FORCE_ASSERT() - If asserts are in use, immediately calls the assert handler. + * + * BSP_ASSERTS_ARE_ON - can use #ifdef to see if asserts are enabled + * + * Asserts can be disabled for optimum performance and minimum code size (ideal for + * finalized, debugged production code). + */ + +#if (!defined BSP_NO_DEBUG) +#ifndef BSP_ASSERT_HANDLER +#define BSP_ASSERT_HANDLER() st( __bsp_DISABLE_INTERRUPTS__(); while(1); ) +#endif +#define BSP_ASSERT(expr) st( if (!(expr)) BSP_ASSERT_HANDLER(); ) +#define BSP_FORCE_ASSERT() BSP_ASSERT_HANDLER() +#define BSP_ASSERTS_ARE_ON +#else +#define BSP_ASSERT(expr) /* empty */ +#define BSP_FORCE_ASSERT() /* empty */ +#endif + +/* static assert */ +#define BSP_STATIC_ASSERT(expr) void bspDummyPrototype( char dummy[1/((expr)!=0)] ) + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_Init(void); +/************************************************************************************************** + */ + +/**************************************************************************************** + * BEGIN ENDIAN SUPPORT + * + * Security encrypt/decrypt operates on unsigned long quantities. These must match on + * source and destination platforms. These macros enforce the standard conversions. + * Currently all platforms (CC2520/CC2x30 and MSP430) are little endian. + * + ******************* Network order for encryption is LITTLE ENDIAN ****************** + * + ****************************************************************************************/ + +#if (BSP_LITTLE_ENDIAN != 0) +#define ntohs(x) (x) +#define htons(x) (x) + +#define ntohl(x) (x) +#define htonl(x) (x) + +#else + +#define ntohs(x) (((x>>8) & 0xFF) | ((x & 0xFF)<<8)) +#define htons(x) (((x>>8) & 0xFF) | ((x & 0xFF)<<8)) + +#define ntohl(x) ( ((x>>24) & 0xFF) | ((x>>8) & 0xFF00) | \ + ((x & 0xFF00)<<8) | ((x & 0xFF)<<24) \ + ) +#define htonl(x) ( ((x>>24) & 0xFF) | ((x>>8) & 0xFF00) | \ + ((x & 0xFF00)<<8) | ((x & 0xFF)<<24) \ + ) + +#endif /* (BSP_LITTLE_ENDIAN != 0) */ + +/*************************************************************************************** + * END ENDIAN SUPPORT + ***************************************************************************************/ + + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/bsp_macros.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/bsp_macros.h new file mode 100755 index 0000000..ee99a19 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/bsp_macros.h @@ -0,0 +1,79 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Include file for BSP utility macros. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_MACROS_H +#define BSP_MACROS_H + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +/* bit value */ +#ifndef BV +#define BV(n) (1 << (n)) +#endif + +/* + * This macro is for use by other macros to form a fully valid C statement. + * Without this, the if/else conditionals could show unexpected behavior. + * + * For example, use... + * #define SET_REGS() st( ioreg1 = 0; ioreg2 = 0; ) + * instead of ... + * #define SET_REGS() { ioreg1 = 0; ioreg2 = 0; } + * or + * #define SET_REGS() ioreg1 = 0; ioreg2 = 0; + * The last macro would not behave as expected in the if/else construct. + * The second to last macro will cause a compiler error in certain uses + * of if/else construct + * + * It is not necessary, or recommended, to use this macro where there is + * already a valid C statement. For example, the following is redundant... + * #define CALL_FUNC() st( func(); ) + * This should simply be... + * #define CALL_FUNC() func() + * + * (The while condition below evaluates false without generating a + * constant-controlling-loop type of warning on most compilers.) + */ +#define st(x) do { x } while (__LINE__ == -1) + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/bsp_buttons.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/bsp_buttons.h new file mode 100755 index 0000000..b73d615 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/bsp_buttons.h @@ -0,0 +1,90 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Button driver include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BUTTONS_H +#define BSP_BUTTONS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_button_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_NUM_BUTTONS __bsp_NUM_BUTTONS__ + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BUTTON_DEBOUNCE_WAIT(expr) __bsp_BUTTON_DEBOUNCE_WAIT__(expr) + +#define BSP_BUTTON1() __bsp_BUTTON1__() +#define BSP_BUTTON2() __bsp_BUTTON2__() +#define BSP_BUTTON3() __bsp_BUTTON3__() +#define BSP_BUTTON4() __bsp_BUTTON4__() +#define BSP_BUTTON5() __bsp_BUTTON5__() +#define BSP_BUTTON6() __bsp_BUTTON6__() +#define BSP_BUTTON7() __bsp_BUTTON7__() +#define BSP_BUTTON8() __bsp_BUTTON8__() + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_InitButtons(void); + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +#ifdef BSP_NO_BUTTONS +#error "ERROR: The button driver is disabled. This file should not be included." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/bsp_leds.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/bsp_leds.h new file mode 100755 index 0000000..b01338b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/bsp_leds.h @@ -0,0 +1,133 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * LED driver include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_LEDS_H +#define BSP_LEDS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_led_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_NUM_LEDS __bsp_NUM_LEDS__ + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ + +/* blink delay loop */ +#define BSP_LED_BLINK_DELAY() st( { volatile uint32_t i; \ + for (i=0; i<__bsp_LED_BLINK_LOOP_COUNT__; i++) { }; } ) + +/* LED1 */ +#define BSP_TURN_ON_LED1() __bsp_LED1_TURN_ON__() +#define BSP_TURN_OFF_LED1() __bsp_LED1_TURN_OFF__() +#define BSP_TOGGLE_LED1() __bsp_LED1_TOGGLE__() +#define BSP_LED1_IS_ON() __bsp_LED1_IS_ON__() + +/* LED2 */ +#define BSP_TURN_ON_LED2() __bsp_LED2_TURN_ON__() +#define BSP_TURN_OFF_LED2() __bsp_LED2_TURN_OFF__() +#define BSP_TOGGLE_LED2() __bsp_LED2_TOGGLE__() +#define BSP_LED2_IS_ON() __bsp_LED2_IS_ON__() + +/* LED3 */ +#define BSP_TURN_ON_LED3() __bsp_LED3_TURN_ON__() +#define BSP_TURN_OFF_LED3() __bsp_LED3_TURN_OFF__() +#define BSP_TOGGLE_LED3() __bsp_LED3_TOGGLE__() +#define BSP_LED3_IS_ON() __bsp_LED3_IS_ON__() + +/* LED4 */ +#define BSP_TURN_ON_LED4() __bsp_LED4_TURN_ON__() +#define BSP_TURN_OFF_LED4() __bsp_LED4_TURN_OFF__() +#define BSP_TOGGLE_LED4() __bsp_LED4_TOGGLE__() +#define BSP_LED4_IS_ON() __bsp_LED4_IS_ON__() + +/* LED5 */ +#define BSP_TURN_ON_LED5() __bsp_LED5_TURN_ON__() +#define BSP_TURN_OFF_LED5() __bsp_LED5_TURN_OFF__() +#define BSP_TOGGLE_LED5() __bsp_LED5_TOGGLE__() +#define BSP_LED5_IS_ON() __bsp_LED5_IS_ON__() + +/* LED6 */ +#define BSP_TURN_ON_LED6() __bsp_LED6_TURN_ON__() +#define BSP_TURN_OFF_LED6() __bsp_LED6_TURN_OFF__() +#define BSP_TOGGLE_LED6() __bsp_LED6_TOGGLE__() +#define BSP_LED6_IS_ON() __bsp_LED6_IS_ON__() + +/* LED7 */ +#define BSP_TURN_ON_LED7() __bsp_LED7_TURN_ON__() +#define BSP_TURN_OFF_LED7() __bsp_LED7_TURN_OFF__() +#define BSP_TOGGLE_LED7() __bsp_LED7_TOGGLE__() +#define BSP_LED7_IS_ON() __bsp_LED7_IS_ON__() + +/* LED8 */ +#define BSP_TURN_ON_LED8() __bsp_LED8_TURN_ON__() +#define BSP_TURN_OFF_LED8() __bsp_LED8_TURN_OFF__() +#define BSP_TOGGLE_LED8() __bsp_LED8_TOGGLE__() +#define BSP_LED8_IS_ON() __bsp_LED8_IS_ON__() + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_InitLeds(void); + + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +#ifdef BSP_NO_LEDS +#error "ERROR: The LED driver is disabled. This file should not be included." +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_buttons.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_buttons.c new file mode 100755 index 0000000..b8f2018 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_buttons.c @@ -0,0 +1,97 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic button driver code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_buttons.h" +#include "bsp_button_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CONFIG_BUTTON1() __bsp_BUTTON1_CONFIG__() +#define BSP_CONFIG_BUTTON2() __bsp_BUTTON2_CONFIG__() +#define BSP_CONFIG_BUTTON3() __bsp_BUTTON3_CONFIG__() +#define BSP_CONFIG_BUTTON4() __bsp_BUTTON4_CONFIG__() +#define BSP_CONFIG_BUTTON5() __bsp_BUTTON5_CONFIG__() +#define BSP_CONFIG_BUTTON6() __bsp_BUTTON6_CONFIG__() +#define BSP_CONFIG_BUTTON7() __bsp_BUTTON7_CONFIG__() +#define BSP_CONFIG_BUTTON8() __bsp_BUTTON8_CONFIG__() + +#ifdef __bsp_BUTTON_EXTENDED_CONFIG__ +#define BSP_BUTTON_EXTENDED_CONFIG() __bsp_BUTTON_EXTENDED_CONFIG__() +#else +#define BSP_BUTTON_EXTENDED_CONFIG() +#endif + + +/************************************************************************************************** + * @fn BSP_InitButtons + * + * @brief Initialize button hardware and driver code. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitButtons(void) +{ + /* configure LEDs */ + BSP_CONFIG_BUTTON1(); + BSP_CONFIG_BUTTON2(); + BSP_CONFIG_BUTTON3(); + BSP_CONFIG_BUTTON4(); + BSP_CONFIG_BUTTON5(); + BSP_CONFIG_BUTTON6(); + BSP_CONFIG_BUTTON7(); + BSP_CONFIG_BUTTON8(); + + /* peform extended configuration if needed */ + BSP_BUTTON_EXTENDED_CONFIG(); +} + + +/************************************************************************************************** +*/ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h new file mode 100755 index 0000000..e9ae165 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h @@ -0,0 +1,203 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic button macro include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_GENERIC_BUTTONS_H +#define BSP_GENERIC_BUTTONS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_BUTTON__(port,bit,low) ((low) ? (!((port) & BV(bit))) : ((port) & BV(bit)) ) + + +/* ------------------------- populate BUTTON #1 macros ------------------------- */ +#define __bsp_NUM_BUTTON1_DEFINES__ ((defined __bsp_BUTTON1_PORT__) + \ + (defined __bsp_BUTTON1_BIT__) + \ + (defined __bsp_BUTTON1_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON1_DEFINES__ == 3) +#define __bsp_BUTTON1__() __bsp_BUTTON__( __bsp_BUTTON1_PORT__, __bsp_BUTTON1_BIT__, __bsp_BUTTON1_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON1_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON1_DEFINES__ == 0) +#define __bsp_BUTTON1__() /* no button */ 0 +#define __bsp_BUTTON1_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON1." +#endif + +/* ------------------------- populate BUTTON #2 macros ------------------------- */ +#define __bsp_NUM_BUTTON2_DEFINES__ ((defined __bsp_BUTTON2_PORT__) + \ + (defined __bsp_BUTTON2_BIT__) + \ + (defined __bsp_BUTTON2_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON2_DEFINES__ == 3) +#define __bsp_BUTTON2__() __bsp_BUTTON__( __bsp_BUTTON2_PORT__, __bsp_BUTTON2_BIT__, __bsp_BUTTON2_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON2_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON2_DEFINES__ == 0) +#define __bsp_BUTTON2__() /* no button */ 0 +#define __bsp_BUTTON2_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON2." +#endif + +/* ------------------------- populate BUTTON #3 macros ------------------------- */ +#define __bsp_NUM_BUTTON3_DEFINES__ ((defined __bsp_BUTTON3_PORT__) + \ + (defined __bsp_BUTTON3_BIT__) + \ + (defined __bsp_BUTTON3_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON3_DEFINES__ == 3) +#define __bsp_BUTTON3__() __bsp_BUTTON__( __bsp_BUTTON3_PORT__, __bsp_BUTTON3_BIT__, __bsp_BUTTON3_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON3_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON3_DEFINES__ == 0) +#define __bsp_BUTTON3__() /* no button */ 0 +#define __bsp_BUTTON3_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON3." +#endif + +/* ------------------------- populate BUTTON #4 macros ------------------------- */ +#define __bsp_NUM_BUTTON4_DEFINES__ ((defined __bsp_BUTTON4_PORT__) + \ + (defined __bsp_BUTTON4_BIT__) + \ + (defined __bsp_BUTTON4_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON4_DEFINES__ == 3) +#define __bsp_BUTTON4__() __bsp_BUTTON__( __bsp_BUTTON4_PORT__, __bsp_BUTTON4_BIT__, __bsp_BUTTON4_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON4_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON4_DEFINES__ == 0) +#define __bsp_BUTTON4__() /* no button */ 0 +#define __bsp_BUTTON4_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON4." +#endif + +/* ------------------------- populate BUTTON #5 macros ------------------------- */ +#define __bsp_NUM_BUTTON5_DEFINES__ ((defined __bsp_BUTTON5_PORT__) + \ + (defined __bsp_BUTTON5_BIT__) + \ + (defined __bsp_BUTTON5_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON5_DEFINES__ == 3) +#define __bsp_BUTTON5__() __bsp_BUTTON__( __bsp_BUTTON5_PORT__, __bsp_BUTTON5_BIT__, __bsp_BUTTON5_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON5_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON5_DEFINES__ == 0) +#define __bsp_BUTTON5__() /* no button */ 0 +#define __bsp_BUTTON5_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON5." +#endif + +/* ------------------------- populate BUTTON #6 macros ------------------------- */ +#define __bsp_NUM_BUTTON6_DEFINES__ ((defined __bsp_BUTTON6_PORT__) + \ + (defined __bsp_BUTTON6_BIT__) + \ + (defined __bsp_BUTTON6_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON6_DEFINES__ == 3) +#define __bsp_BUTTON6__() __bsp_BUTTON__( __bsp_BUTTON6_PORT__, __bsp_BUTTON6_BIT__, __bsp_BUTTON6_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON6_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON6_DEFINES__ == 0) +#define __bsp_BUTTON6__() /* no button */ 0 +#define __bsp_BUTTON6_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON6." +#endif + +/* ------------------------- populate BUTTON #7 macros ------------------------- */ +#define __bsp_NUM_BUTTON7_DEFINES__ ((defined __bsp_BUTTON7_PORT__) + \ + (defined __bsp_BUTTON7_BIT__) + \ + (defined __bsp_BUTTON7_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON7_DEFINES__ == 3) +#define __bsp_BUTTON7__() __bsp_BUTTON__( __bsp_BUTTON7_PORT__, __bsp_BUTTON7_BIT__, __bsp_BUTTON7_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON7_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON7_DEFINES__ == 0) +#define __bsp_BUTTON7__() /* no button */ 0 +#define __bsp_BUTTON7_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON7." +#endif + +/* ------------------------- populate BUTTON #8 macros ------------------------- */ +#define __bsp_NUM_BUTTON8_DEFINES__ ((defined __bsp_BUTTON8_PORT__) + \ + (defined __bsp_BUTTON8_BIT__) + \ + (defined __bsp_BUTTON8_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON8_DEFINES__ == 3) +#define __bsp_BUTTON8__() __bsp_BUTTON__( __bsp_BUTTON8_PORT__, __bsp_BUTTON8_BIT__, __bsp_BUTTON8_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON8_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON8_DEFINES__ == 0) +#define __bsp_BUTTON8__() /* no button */ 0 +#define __bsp_BUTTON8_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON8." +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* -------------------- number of buttons defined -------------------- */ +#ifndef __bsp_NUM_BUTTONS__ +#error "ERROR: Number of buttons is not specified." +#else +#if ((__bsp_NUM_BUTTONS__ > 8) || (__bsp_NUM_BUTTONS__ < 0)) +#error "ERROR: Unsupported number of buttons specified. Maximum is eight." +#endif +#endif + +#if (((__bsp_NUM_BUTTON1_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON2_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON3_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON4_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON5_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON6_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON7_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON8_DEFINES__ != 0)) != __bsp_NUM_BUTTONS__) +#error "ERROR: Inconsistency between defined macros and specified number of buttons." +#endif + +/* -------------------- debounce macro -------------------- */ +#ifndef __bsp_BUTTON_DEBOUNCE_WAIT__ +#error "ERROR: Debounce delay macro is missing." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h new file mode 100755 index 0000000..6e1e42b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h @@ -0,0 +1,278 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic LED macro include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_GENERIC_LEDS_H +#define BSP_GENERIC_LEDS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ + +/* + * Note : The conditionals in the following macros evaulate compile time constants. + * Any compiler worth its salt will optimize these conditionals out for the + * smallest possible code. + */ + +#define __bsp_LED_TURN_ON__(bit,port,ddr,low) \ + st( if (low) { port &= ~BV(bit); } else { port |= BV(bit); } ) + +#define __bsp_LED_TURN_OFF__(bit,port,ddr,low) \ + st( if (low) { port |= BV(bit); } else { port &= ~BV(bit); } ) + +#define __bsp_LED_IS_ON__(bit,port,ddr,low) \ + ( (low) ? (!((port) & BV(bit))) : ((port) & BV(bit)) ) + +#define __bsp_LED_TOGGLE__(bit,port,ddr,low) st( port ^= BV(bit); ) +#define __bsp_LED_CONFIG__(bit,port,ddr,low) st( ddr |= BV(bit); ) + + + +/* ------------------------- populate LED1 macros ------------------------- */ +#define __bsp_NUM_LED1_DEFINES__ ((defined __bsp_LED1_BIT__) + \ + (defined __bsp_LED1_PORT__) + \ + (defined __bsp_LED1_DDR__) + \ + (defined __bsp_LED1_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED1_DEFINES__ == 4) +#define __bsp_LED1_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED1_DEFINES__ == 0) +#define __bsp_LED1_TURN_ON__() /* no LED */ +#define __bsp_LED1_TURN_OFF__() /* no LED */ +#define __bsp_LED1_TOGGLE__() /* no LED */ +#define __bsp_LED1_IS_ON__() /* no LED */ 0 +#define __bsp_LED1_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED1." +#endif + + +/* ------------------------- populate LED2 macros ------------------------- */ +#define __bsp_NUM_LED2_DEFINES__ ((defined __bsp_LED2_BIT__) + \ + (defined __bsp_LED2_PORT__) + \ + (defined __bsp_LED2_DDR__) + \ + (defined __bsp_LED2_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED2_DEFINES__ == 4) +#define __bsp_LED2_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED2_DEFINES__ == 0) +#define __bsp_LED2_TURN_ON__() /* no LED */ +#define __bsp_LED2_TURN_OFF__() /* no LED */ +#define __bsp_LED2_TOGGLE__() /* no LED */ +#define __bsp_LED2_IS_ON__() /* no LED */ 0 +#define __bsp_LED2_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED2." +#endif + + +/* ------------------------- populate LED3 macros ------------------------- */ +#define __bsp_NUM_LED3_DEFINES__ ((defined __bsp_LED3_BIT__) + \ + (defined __bsp_LED3_PORT__) + \ + (defined __bsp_LED3_DDR__) + \ + (defined __bsp_LED3_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED3_DEFINES__ == 4) +#define __bsp_LED3_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED3_DEFINES__ == 0) +#define __bsp_LED3_TURN_ON__() /* no LED */ +#define __bsp_LED3_TURN_OFF__() /* no LED */ +#define __bsp_LED3_TOGGLE__() /* no LED */ +#define __bsp_LED3_IS_ON__() /* no LED */ 0 +#define __bsp_LED3_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED3." +#endif + + +/* ------------------------- populate LED4 macros ------------------------- */ +#define __bsp_NUM_LED4_DEFINES__ ((defined __bsp_LED4_BIT__) + \ + (defined __bsp_LED4_PORT__) + \ + (defined __bsp_LED4_DDR__) + \ + (defined __bsp_LED4_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED4_DEFINES__ == 4) +#define __bsp_LED4_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED4_DEFINES__ == 0) +#define __bsp_LED4_TURN_ON__() /* no LED */ +#define __bsp_LED4_TURN_OFF__() /* no LED */ +#define __bsp_LED4_TOGGLE__() /* no LED */ +#define __bsp_LED4_IS_ON__() /* no LED */ 0 +#define __bsp_LED4_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED4." +#endif + +/* ------------------------- populate LED5 macros ------------------------- */ +#define __bsp_NUM_LED5_DEFINES__ ((defined __bsp_LED5_BIT__) + \ + (defined __bsp_LED5_PORT__) + \ + (defined __bsp_LED5_DDR__) + \ + (defined __bsp_LED5_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED5_DEFINES__ == 4) +#define __bsp_LED5_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED5_DEFINES__ == 0) +#define __bsp_LED5_TURN_ON__() /* no LED */ +#define __bsp_LED5_TURN_OFF__() /* no LED */ +#define __bsp_LED5_TOGGLE__() /* no LED */ +#define __bsp_LED5_IS_ON__() /* no LED */ 0 +#define __bsp_LED5_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED5." +#endif + +/* ------------------------- populate LED6 macros ------------------------- */ +#define __bsp_NUM_LED6_DEFINES__ ((defined __bsp_LED6_BIT__) + \ + (defined __bsp_LED6_PORT__) + \ + (defined __bsp_LED6_DDR__) + \ + (defined __bsp_LED6_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED6_DEFINES__ == 4) +#define __bsp_LED6_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED6_DEFINES__ == 0) +#define __bsp_LED6_TURN_ON__() /* no LED */ +#define __bsp_LED6_TURN_OFF__() /* no LED */ +#define __bsp_LED6_TOGGLE__() /* no LED */ +#define __bsp_LED6_IS_ON__() /* no LED */ 0 +#define __bsp_LED6_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED6." +#endif + +/* ------------------------- populate LED7 macros ------------------------- */ +#define __bsp_NUM_LED7_DEFINES__ ((defined __bsp_LED7_BIT__) + \ + (defined __bsp_LED7_PORT__) + \ + (defined __bsp_LED7_DDR__) + \ + (defined __bsp_LED7_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED7_DEFINES__ == 4) +#define __bsp_LED7_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED7_DEFINES__ == 0) +#define __bsp_LED7_TURN_ON__() /* no LED */ +#define __bsp_LED7_TURN_OFF__() /* no LED */ +#define __bsp_LED7_TOGGLE__() /* no LED */ +#define __bsp_LED7_IS_ON__() /* no LED */ 0 +#define __bsp_LED7_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED7." +#endif + +/* ------------------------- populate LED8 macros ------------------------- */ +#define __bsp_NUM_LED8_DEFINES__ ((defined __bsp_LED8_BIT__) + \ + (defined __bsp_LED8_PORT__) + \ + (defined __bsp_LED8_DDR__) + \ + (defined __bsp_LED8_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED8_DEFINES__ == 4) +#define __bsp_LED8_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED8_DEFINES__ == 0) +#define __bsp_LED8_TURN_ON__() /* no LED */ +#define __bsp_LED8_TURN_OFF__() /* no LED */ +#define __bsp_LED8_TOGGLE__() /* no LED */ +#define __bsp_LED8_IS_ON__() /* no LED */ 0 +#define __bsp_LED8_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED8." +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* -------------------- number of LEDs defined -------------------- */ +#ifndef __bsp_NUM_LEDS__ +#error "ERROR: Number of LEDs is not specified." +#else +#if ((__bsp_NUM_LEDS__ > 8) || (__bsp_NUM_LEDS__ < 0)) +#error "ERROR: Unsupported number of LEDs specified. Maximum is eight." +#endif +#endif + +#if (((__bsp_NUM_LED1_DEFINES__ != 0) + \ + (__bsp_NUM_LED2_DEFINES__ != 0) + \ + (__bsp_NUM_LED3_DEFINES__ != 0) + \ + (__bsp_NUM_LED4_DEFINES__ != 0) + \ + (__bsp_NUM_LED5_DEFINES__ != 0) + \ + (__bsp_NUM_LED6_DEFINES__ != 0) + \ + (__bsp_NUM_LED7_DEFINES__ != 0) + \ + (__bsp_NUM_LED8_DEFINES__ != 0)) != __bsp_NUM_LEDS__) +#error "ERROR: Inconsistency between defined macros and specified number of LEDs." +#endif + +/* -------------------- blink delay loop count -------------------- */ +#ifndef __bsp_LED_BLINK_LOOP_COUNT__ +#error "ERROR: Blink delay count is missing." +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_leds.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_leds.c new file mode 100755 index 0000000..4bc83e0 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/drivers/code/bsp_leds.c @@ -0,0 +1,107 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic LED driver code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_leds.h" +#include "bsp_led_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CONFIG_LED1() __bsp_LED1_CONFIG__() +#define BSP_CONFIG_LED2() __bsp_LED2_CONFIG__() +#define BSP_CONFIG_LED3() __bsp_LED3_CONFIG__() +#define BSP_CONFIG_LED4() __bsp_LED4_CONFIG__() +#define BSP_CONFIG_LED5() __bsp_LED5_CONFIG__() +#define BSP_CONFIG_LED6() __bsp_LED6_CONFIG__() +#define BSP_CONFIG_LED7() __bsp_LED7_CONFIG__() +#define BSP_CONFIG_LED8() __bsp_LED8_CONFIG__() + +#ifdef __bsp_LED_EXTENDED_CONFIG__ +#define BSP_LED_EXTENDED_CONFIG() __bsp_LED_EXTENDED_CONFIG__() +#else +#define BSP_LED_EXTENDED_CONFIG() +#endif + + +/************************************************************************************************** + * @fn BSP_InitLeds + * + * @brief Initialize LED hardware and driver. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitLeds(void) +{ + /* configure LEDs */ + BSP_CONFIG_LED1(); + BSP_CONFIG_LED2(); + BSP_CONFIG_LED3(); + BSP_CONFIG_LED4(); + BSP_CONFIG_LED5(); + BSP_CONFIG_LED6(); + BSP_CONFIG_LED7(); + BSP_CONFIG_LED8(); + + /* peform extended configuration if needed */ + BSP_LED_EXTENDED_CONFIG(); + + /* turn all LEDs off as power-up default */ + BSP_TURN_OFF_LED1(); + BSP_TURN_OFF_LED2(); + BSP_TURN_OFF_LED3(); + BSP_TURN_OFF_LED4(); + BSP_TURN_OFF_LED5(); + BSP_TURN_OFF_LED6(); + BSP_TURN_OFF_LED7(); + BSP_TURN_OFF_LED8(); +} + + +/************************************************************************************************** +*/ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h new file mode 100755 index 0000000..af9357f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h @@ -0,0 +1,141 @@ +/************************************************************************************************** + Filename: bsp_msp430_defs.h + Revised: $Date: 2009-10-11 18:52:46 -0700 (Sun, 11 Oct 2009) $ + Revision: $Revision: 20897 $ + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * MCU : Texas Instruments MSP430 family + * Microcontroller definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_MSP430_DEFS_H +#define BSP_MSP430_DEFS_H + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_MCU_MSP430 + +/* ------------------------------------------------------------------------------------------------ + * Compiler Abstraction + * ------------------------------------------------------------------------------------------------ + */ + +/* ---------------------- IAR Compiler ---------------------- */ +#ifdef __IAR_SYSTEMS_ICC__ +#define BSP_COMPILER_IAR + +#if (__VER__ < 342) + #error "ERROR: This IAR compiler port requires at least revision v3.42A." +/* + * Compiler versions previous to v3.42A do not have the universal msp430.h include file. + * To use an earlier version of the compiler, replace the above #error statement with + * the appropriate, device specific #include statement. + */ +#endif + +/* Workaround for release v3.42A - the msp430.h file did not include support for some devices */ +#if ((__VER__ == 342) && (__SUBVERSION__ == 'A')) && \ + (defined (__MSP430F1610__) || defined (__MSP430F1611__) || defined (__MSP430F1612__)) +#include +#else +#include +#endif + +#define __bsp_ISTATE_T__ istate_t +#define __bsp_ISR_FUNCTION__(f,v) __bsp_QUOTED_PRAGMA__(vector=v) __interrupt void f(void); \ + __bsp_QUOTED_PRAGMA__(vector=v) __interrupt void f(void) + +/* Initialization call provided in IAR environment before standard C-startup */ +#include +#define BSP_EARLY_INIT(void) __intrinsic int __low_level_init(void) + +/* ---------------------- Code Composer ---------------------- */ +#elif (defined __TI_COMPILER_VERSION__) && (defined __MSP430__) +#define BSP_COMPILER_CODE_COMPOSER + +/* At time of 1.1.0 release, CC430 support not in msp430.h */ +#if (__CC430F6137__) +#include +#else +#include +#endif + +#define __bsp_ISTATE_T__ unsigned short +#define __bsp_ISR_FUNCTION__(f,v) __bsp_QUOTED_PRAGMA__(vector=v) __interrupt void f(void) + +/* Initialization call provided in CCE environment before standard C-startup */ +// [BM] Cannot have a second low level init! Already done by application! +//#define BSP_EARLY_INIT(void) int _system_pre_init(void) + +/* ------------------ Unrecognized Compiler ------------------ */ +#else +#error "ERROR: Unknown compiler." +#endif + +#if (defined BSP_COMPILER_IAR) || (defined BSP_COMPILER_CODE_COMPOSER) +#include +#define __bsp_ENABLE_INTERRUPTS__() __enable_interrupt() +#define __bsp_DISABLE_INTERRUPTS__() __disable_interrupt() +#define __bsp_INTERRUPTS_ARE_ENABLED__() (__get_SR_register() & GIE) + +#define __bsp_GET_ISTATE__() __get_interrupt_state() +#define __bsp_RESTORE_ISTATE__(x) __set_interrupt_state(x) + +#define __bsp_QUOTED_PRAGMA__(x) _Pragma(#x) + +#endif + +/* ------------------------------------------------------------------------------------------------ + * Common + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_LITTLE_ENDIAN__ 1 +#define __bsp_CODE_MEMSPACE__ /* blank */ +#define __bsp_XDATA_MEMSPACE__ /* blank */ + +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed long int32_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; + +#ifndef NULL +#define NULL 0 +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/mrfi.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/mrfi.c new file mode 100755 index 0000000..5b7337b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/mrfi.c @@ -0,0 +1,87 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Top-level code file. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "mrfi_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * C Code Includes + * ------------------------------------------------------------------------------------------------ + */ + +/* ----- Radio Family 1 ----- */ +#if (defined MRFI_RADIO_FAMILY1) +#include "radios/family1/mrfi_radio.c" +#include "radios/family1/mrfi_spi.c" +#include "radios/common/mrfi_f1f2.c" +#include "bsp_external/mrfi_board.c" + +/* ----- Radio Family 2 ----- */ +#elif (defined MRFI_RADIO_FAMILY2) +#include "radios/family2/mrfi_radio.c" +#include "radios/common/mrfi_f1f2.c" + +/* ----- Radio Family 3 ----- */ +#elif (defined MRFI_RADIO_FAMILY3) +#include "bsp_external/mrfi_board.c" +#include "radios/family3/mrfi_spi.c" +#include "radios/family3/mrfi_radio.c" + +/* ----- Radio Family 4 ----- */ +#elif (defined MRFI_RADIO_FAMILY4) +#include "radios/family4/mrfi_radio.c" + +/* ----- Radio Family 5 ----- */ +#elif (defined MRFI_RADIO_FAMILY5) +#include "radios/family5/mrfi_radio.c" +#include "radios/family5/mrfi_radio_interface.c" + +/* ----- Radio Family 6 ----- */ +#elif (defined MRFI_RADIO_FAMILY6) +#include "radios/family6/mrfi_radio.c" + +#else +#error "ERROR: Radio family is not defined." +#endif + + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/mrfi.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/mrfi.h new file mode 100755 index 0000000..ca49e02 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/mrfi.h @@ -0,0 +1,182 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Include file for all MRFI services. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_H +#define MRFI_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "mrfi_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_NUM_LOGICAL_CHANS __mrfi_NUM_LOGICAL_CHANS__ + +#define MRFI_NUM_POWER_SETTINGS __mrfi_NUM_POWER_SETTINGS__ + +/* return values for MRFI_Transmit */ +#define MRFI_TX_RESULT_SUCCESS 0 +#define MRFI_TX_RESULT_FAILED 1 + +/* transmit type parameter for MRFI_Transmit */ +#define MRFI_TX_TYPE_FORCED 0 +#define MRFI_TX_TYPE_CCA 1 + +/* Network header size definition */ +/* ********************************* NOTE **************************************** + * There is a dependency here that really shouldn't exist. A reimplementation + * is necessary to avoid it. + * + * MRFI allocates the frame buffer which means it needs to know at compile time + * how big the buffer is. This means in must know the NWK header size, the + * maximum NWK and User application payload sizes and whether Security is enabled. + * ******************************************************************************** + */ +#ifndef SMPL_SECURE +#define NWK_HDR_SIZE 3 +#define NWK_PAYLOAD MAX_NWK_PAYLOAD +#else +#define NWK_HDR_SIZE 6 +#define NWK_PAYLOAD (MAX_NWK_PAYLOAD+4) +#endif + +/* if external code has defined a maximum payload, use that instead of default */ +#ifdef MAX_APP_PAYLOAD +#ifndef MAX_NWK_PAYLOAD +#error ERROR: MAX_NWK_PAYLOAD not defined +#endif +#if MAX_APP_PAYLOAD < NWK_PAYLOAD +#define MAX_PAYLOAD NWK_PAYLOAD +#else +#define MAX_PAYLOAD MAX_APP_PAYLOAD +#endif +#define MRFI_MAX_PAYLOAD_SIZE (MAX_PAYLOAD+NWK_HDR_SIZE) /* SimpliciTI payload size plus six byte overhead */ +#endif + + +/* frame definitions */ +#define MRFI_ADDR_SIZE __mrfi_ADDR_SIZE__ +#ifndef MRFI_MAX_PAYLOAD_SIZE +#define MRFI_MAX_PAYLOAD_SIZE __mrfi_MAX_PAYLOAD_SIZE__ +#endif +#define MRFI_MAX_FRAME_SIZE (MRFI_MAX_PAYLOAD_SIZE + __mrfi_FRAME_OVERHEAD_SIZE__) +#define MRFI_RX_METRICS_SIZE __mrfi_RX_METRICS_SIZE__ +#define MRFI_RX_METRICS_RSSI_OFS __mrfi_RX_METRICS_RSSI_OFS__ +#define MRFI_RX_METRICS_CRC_LQI_OFS __mrfi_RX_METRICS_CRC_LQI_OFS__ + +/* Radio States */ +#define MRFI_RADIO_STATE_UNKNOWN 0 +#define MRFI_RADIO_STATE_OFF 1 +#define MRFI_RADIO_STATE_IDLE 2 +#define MRFI_RADIO_STATE_RX 3 + +/* Platform constant used to calculate worst-case for an application + * acknowledgment delay. Used in the NWK_REPLY_DELAY() macro. + * + + processing time on peer + | round trip + | | max number of replays + | | | number of backoff opportunities + | | | | average number of backoffs + | | | | | */ +#define PLATFORM_FACTOR_CONSTANT (2 + 2*(MAX_HOPS*(MRFI_CCA_RETRIES*(8*MRFI_BACKOFF_PERIOD_USECS)/1000))) + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_GET_PAYLOAD_LEN(p) __mrfi_GET_PAYLOAD_LEN__(p) +#define MRFI_SET_PAYLOAD_LEN(p,x) __mrfi_SET_PAYLOAD_LEN__(p,x) + +#define MRFI_P_DST_ADDR(p) __mrfi_P_DST_ADDR__(p) +#define MRFI_P_SRC_ADDR(p) __mrfi_P_SRC_ADDR__(p) +#define MRFI_P_PAYLOAD(p) __mrfi_P_PAYLOAD__(p) + +/* ------------------------------------------------------------------------------------------------ + * Typdefs + * ------------------------------------------------------------------------------------------------ + */ +typedef struct +{ + uint8_t frame[MRFI_MAX_FRAME_SIZE]; + uint8_t rxMetrics[MRFI_RX_METRICS_SIZE]; +} mrfiPacket_t; + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void MRFI_Init(void); +uint8_t MRFI_Transmit(mrfiPacket_t *, uint8_t); +void MRFI_Receive(mrfiPacket_t *); +void MRFI_RxCompleteISR(void); /* populated by code using MRFI */ +uint8_t MRFI_GetRadioState(void); +void MRFI_RxOn(void); +void MRFI_RxIdle(void); +int8_t MRFI_Rssi(void); +void MRFI_SetLogicalChannel(uint8_t); +uint8_t MRFI_SetRxAddrFilter(uint8_t *); +void MRFI_EnableRxAddrFilter(void); +void MRFI_DisableRxAddrFilter(void); +void MRFI_Sleep(void); +void MRFI_WakeUp(void); +uint8_t MRFI_RandomByte(void); +void MRFI_DelayMs(uint16_t); +void MRFI_ReplyDelay(void); +void MRFI_PostKillSem(void); +void MRFI_SetRFPwr(uint8_t); + +/* ------------------------------------------------------------------------------------------------ + * Global Constants + * ------------------------------------------------------------------------------------------------ + */ +extern const uint8_t mrfiBroadcastAddr[]; + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/mrfi_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/mrfi_defs.h new file mode 100755 index 0000000..2e1c546 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/mrfi_defs.h @@ -0,0 +1,226 @@ +/************************************************************************************************** + Revised: $Date: 2009-01-13 16:32:00 -0700 (Wed, 13 Jan 2009) $ + Revision: $Revision: 18768 $ + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Definition and abstraction for radio targets. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ +#ifndef MRFI_DEFS_H +#define MRFI_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + + +/* ------------------------------------------------------------------------------------------------ + * Common Defines + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_CCA_RETRIES 4 + +#define MRFI_ASSERT(x) BSP_ASSERT(x) +#define MRFI_FORCE_ASSERT() BSP_FORCE_ASSERT() +#define MRFI_ASSERTS_ARE_ON BSP_ASSERTS_ARE_ON + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family Assigment + * ------------------------------------------------------------------------------------------------ + */ + +/* ------ Radio Family 1 ------ */ +#if (defined MRFI_CC1100) /* Sub 1 GHz RF Transceiver */ || \ + (defined MRFI_CC1101) /* Sub 1 GHz RF Transceiver */ || \ + (defined MRFI_CC1100E_470) /* Sub 1 GHz RF Transceiver (CC1100E Asia) */ || \ + (defined MRFI_CC1100E_950) /* Sub 1 GHz RF Transceiver (CC1100E Asia) */ || \ + (defined MRFI_CC2500) /* 2.4 GHz RF Transceiver */ +#define MRFI_RADIO_FAMILY1 + +/* ------ Radio Family 2 ------ */ +#elif (defined MRFI_CC1110) /* Sub 1 GHz SoC */ || \ + (defined MRFI_CC1111) /* Sub 1 GHz SoC with USB controller */ || \ + (defined MRFI_CC2510) /* 2.4 GHz SoC */ || \ + (defined MRFI_CC2511) /* 2.4 GHz SoC with USB controller */ +#define MRFI_RADIO_FAMILY2 + +/* ------ Radio Family 3 ------ */ +#elif (defined MRFI_CC2420) /* 2.4 GHz IEEE 802.15.4 RF Transceiver */ || \ + (defined MRFI_CC2520) /* 2.4 GHz IEEE 802.15.4 RF Transceiver */ + +#define MRFI_RADIO_FAMILY3 + +/* ------ Radio Family 4 ------ */ +#elif (defined MRFI_CC2430) /* 2.4 GHz IEEE 802.15.4 SoC */ || \ + (defined MRFI_CC2431) /* 2.4 GHz IEEE 802.15.4 SoC */ +#define MRFI_RADIO_FAMILY4 + +/* ------ Radio Family 5 ------ */ +#elif (defined MRFI_CC430) /* Sub 1 GHz MSP SoC */ +#define MRFI_RADIO_FAMILY5 + +/* ------ Radio Family 6 ------ */ +#elif (defined MRFI_CC2530) /* 2.4 GHz IEEE 802.15.4 SoC */ + +#define MRFI_RADIO_FAMILY6 + +#else +#error "ERROR: Unknown or missing radio selection." +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family 1 / Radio Family 2 / Radio Family 5 + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_RADIO_FAMILY1) || (defined MRFI_RADIO_FAMILY2) || (defined MRFI_RADIO_FAMILY5) + +#define __mrfi_LENGTH_FIELD_SIZE__ 1 +#define __mrfi_ADDR_SIZE__ 4 +#define __mrfi_MAX_PAYLOAD_SIZE__ 20 + +#define __mrfi_RX_METRICS_SIZE__ 2 +#define __mrfi_RX_METRICS_RSSI_OFS__ 0 +#define __mrfi_RX_METRICS_CRC_LQI_OFS__ 1 +#define __mrfi_RX_METRICS_CRC_OK_MASK__ 0x80 +#define __mrfi_RX_METRICS_LQI_MASK__ 0x7F + +#define __mrfi_NUM_LOGICAL_CHANS__ 4 +#define __mrfi_NUM_POWER_SETTINGS__ 3 + +#define __mrfi_BACKOFF_PERIOD_USECS__ 250 + +#define __mrfi_LENGTH_FIELD_OFS__ 0 +#define __mrfi_DST_ADDR_OFS__ (__mrfi_LENGTH_FIELD_OFS__ + __mrfi_LENGTH_FIELD_SIZE__) +#define __mrfi_SRC_ADDR_OFS__ (__mrfi_DST_ADDR_OFS__ + __mrfi_ADDR_SIZE__) +#define __mrfi_PAYLOAD_OFS__ (__mrfi_SRC_ADDR_OFS__ + __mrfi_ADDR_SIZE__) + +#define __mrfi_HEADER_SIZE__ (2 * __mrfi_ADDR_SIZE__) +#define __mrfi_FRAME_OVERHEAD_SIZE__ (__mrfi_LENGTH_FIELD_SIZE__ + __mrfi_HEADER_SIZE__) + +#define __mrfi_GET_PAYLOAD_LEN__(p) ((p)->frame[__mrfi_LENGTH_FIELD_OFS__] - __mrfi_HEADER_SIZE__) +#define __mrfi_SET_PAYLOAD_LEN__(p,x) st( (p)->frame[__mrfi_LENGTH_FIELD_OFS__] = x + __mrfi_HEADER_SIZE__; ) + +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family 3 / Radio Family 4 / Radio Family 6 + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_RADIO_FAMILY3) || (defined MRFI_RADIO_FAMILY4) || (defined MRFI_RADIO_FAMILY6) + +#define __mrfi_LENGTH_FIELD_SIZE__ 1 +#define __mrfi_FCF_SIZE__ 2 +#define __mrfi_DSN_SIZE__ 1 +#define __mrfi_ADDR_SIZE__ 4 +#define __mrfi_MAX_PAYLOAD_SIZE__ 20 + +#define __mrfi_RX_METRICS_SIZE__ 2 +#define __mrfi_RX_METRICS_RSSI_OFS__ 0 +#define __mrfi_RX_METRICS_CRC_LQI_OFS__ 1 +#define __mrfi_RX_METRICS_CRC_OK_MASK__ 0x80 +#define __mrfi_RX_METRICS_LQI_MASK__ 0x7F + +#define __mrfi_NUM_LOGICAL_CHANS__ 4 +#define __mrfi_NUM_POWER_SETTINGS__ 3 + +#define __mrfi_BACKOFF_PERIOD_USECS__ 250 + +#define __mrfi_LENGTH_FIELD_OFS__ 0 +#define __mrfi_FCF_OFS__ (__mrfi_LENGTH_FIELD_OFS__ + __mrfi_LENGTH_FIELD_SIZE__) +#define __mrfi_DSN_OFS__ (__mrfi_FCF_OFS__ + __mrfi_FCF_SIZE__) +#define __mrfi_DST_ADDR_OFS__ (__mrfi_DSN_OFS__ + __mrfi_DSN_SIZE__) +#define __mrfi_SRC_ADDR_OFS__ (__mrfi_DST_ADDR_OFS__ + __mrfi_ADDR_SIZE__) +#define __mrfi_PAYLOAD_OFS__ (__mrfi_SRC_ADDR_OFS__ + __mrfi_ADDR_SIZE__) + +#define __mrfi_HEADER_SIZE__ ((2 * __mrfi_ADDR_SIZE__) + __mrfi_FCF_SIZE__ + __mrfi_DSN_SIZE__) +#define __mrfi_FRAME_OVERHEAD_SIZE__ (__mrfi_LENGTH_FIELD_SIZE__ + __mrfi_HEADER_SIZE__) + +#define __mrfi_GET_PAYLOAD_LEN__(p) ((p)->frame[__mrfi_LENGTH_FIELD_OFS__] - __mrfi_HEADER_SIZE__) +#define __mrfi_SET_PAYLOAD_LEN__(p,x) st( (p)->frame[__mrfi_LENGTH_FIELD_OFS__] = x + __mrfi_HEADER_SIZE__; ) + +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family Commonality + * ------------------------------------------------------------------------------------------------ + */ +#define __mrfi_P_DST_ADDR__(p) (&((p)->frame[__mrfi_DST_ADDR_OFS__])) +#define __mrfi_P_SRC_ADDR__(p) (&((p)->frame[__mrfi_SRC_ADDR_OFS__])) +#define __mrfi_P_PAYLOAD__(p) (&((p)->frame[__mrfi_PAYLOAD_OFS__])) + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* verify that only one supported radio is selected */ +#define MRFI_NUM_SUPPORTED_RADIOS_SELECTED ((defined MRFI_CC1100) + \ + (defined MRFI_CC1101) + \ + (defined MRFI_CC1110) + \ + (defined MRFI_CC1111) + \ + (defined MRFI_CC1100E_470) + \ + (defined MRFI_CC1100E_950) + \ + (defined MRFI_CC2500) + \ + (defined MRFI_CC2510) + \ + (defined MRFI_CC2511) + \ + (defined MRFI_CC2430) + \ + (defined MRFI_CC2431) + \ + (defined MRFI_CC2520) + \ + (defined MRFI_CC430) + \ + (defined MRFI_CC2530)) +#if (MRFI_NUM_SUPPORTED_RADIOS_SELECTED == 0) +#error "ERROR: A valid radio is not selected." +#elif (MRFI_NUM_SUPPORTED_RADIOS_SELECTED > 1) +#error "ERROR: More than one radio is selected." +#endif + +/* verify that a radio family is selected */ +#if (!defined MRFI_RADIO_FAMILY1) && \ + (!defined MRFI_RADIO_FAMILY2) && \ + (!defined MRFI_RADIO_FAMILY3) && \ + (!defined MRFI_RADIO_FAMILY4) && \ + (!defined MRFI_RADIO_FAMILY5) && \ + (!defined MRFI_RADIO_FAMILY6) +#error "ERROR: A radio family has not been assigned." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c new file mode 100755 index 0000000..9de4b6a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c @@ -0,0 +1,1778 @@ +/************************************************************************************************** + Revised: $Date: 2009-11-23 07:50:43 -0800 (Mon, 23 Nov 2009) $ + Revision: $Revision: 21225 $ + + Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS? + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radios: CC430 + * Primary code file for supported radios. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include +#include "mrfi.h" +#include "bsp.h" +#include "bsp_macros.h" +#include "bsp_external/mrfi_board_defs.h" +#include "mrfi_defs.h" +#include "mrfi_radio_interface.h" +#include "smartrf/CC430/smartrf_CC430.h" + +/* ------------------------------------------------------------------------------------------------ + * Global Constants + * ------------------------------------------------------------------------------------------------ + */ +const uint8_t mrfiBroadcastAddr[] = { 0xFF, 0xFF, 0xFF, 0xFF }; + +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(MRFI_ADDR_SIZE == ((sizeof(mrfiBroadcastAddr)/sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0]))); + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_CC430) + #define MRFI_RSSI_OFFSET 74 /* no units */ +#else + #error "ERROR: RSSI offset value not defined for this radio" +#endif + +#define MRFI_LENGTH_FIELD_OFS __mrfi_LENGTH_FIELD_OFS__ +#define MRFI_LENGTH_FIELD_SIZE __mrfi_LENGTH_FIELD_SIZE__ +#define MRFI_HEADER_SIZE __mrfi_HEADER_SIZE__ +#define MRFI_FRAME_BODY_OFS __mrfi_DST_ADDR_OFS__ +#define MRFI_BACKOFF_PERIOD_USECS __mrfi_BACKOFF_PERIOD_USECS__ + +#define MRFI_RANDOM_OFFSET 67 +#define MRFI_RANDOM_MULTIPLIER 109 +#define MRFI_MIN_SMPL_FRAME_SIZE (MRFI_HEADER_SIZE + NWK_HDR_SIZE) + +/* rx metrics definitions, known as appended "packet status bytes" in datasheet parlance */ +#define MRFI_RX_METRICS_CRC_OK_MASK __mrfi_RX_METRICS_CRC_OK_MASK__ +#define MRFI_RX_METRICS_LQI_MASK __mrfi_RX_METRICS_LQI_MASK__ + + +/* ---------- Radio Abstraction ---------- */ + +#define MRFI_RADIO_PARTNUM 0x00 +#define MRFI_RADIO_VERSION 0x06 + +/* GDO0 == PA_PD signal */ +#define MRFI_SETTING_IOCFG0 27 + +/* GDO1 == RSSI_VALID signal */ +#define MRFI_SETTING_IOCFG1 30 + +/* Main Radio Control State Machine control configuration: + * Auto Calibrate - when going from IDLE to RX/TX + * XOSC is OFF in Sleep state. + */ +#define MRFI_SETTING_MCSM0 (0x10) + +/* Main Radio Control State Machine control configuration: + * - Remain RX state after RX + * - Go to IDLE after TX + * - RSSI below threshold and NOT receiving. + */ +#define MRFI_SETTING_MCSM1 0x3C + +/* + * Packet Length - Setting for maximum allowed packet length. + * The PKTLEN setting does not include the length field but maximum frame size does. + * Subtract length field size from maximum frame size to get value for PKTLEN. + */ +#define MRFI_SETTING_PKTLEN (MRFI_MAX_FRAME_SIZE - MRFI_LENGTH_FIELD_SIZE) + +/* Packet automation control - Original value except WHITE_DATA is extracted from SmartRF setting. */ +#define MRFI_SETTING_PKTCTRL0 (0x05 | (SMARTRF_SETTING_PKTCTRL0 & BV(6))) + +/* FIFO threshold - this register has fields that need to be configured for the CC1101 */ +#define MRFI_SETTING_FIFOTHR (0x07 | (SMARTRF_SETTING_FIFOTHR & (BV(4)|BV(5)|BV(6)|BV(7)))) + +/* Max time we can be in a critical section within the delay function. + * This could be fine-tuned by observing the overhead is calling the bsp delay + * function. The overhead should be very small compared to this value. + */ +#define MRFI_MAX_DELAY_US 16 /* usec */ + +/* Packet automation control - base value is power up value whick has APPEND_STATUS enabled; no CRC autoflush */ +#define PKTCTRL1_BASE_VALUE BV(2) +#define PKTCTRL1_ADDR_FILTER_OFF PKTCTRL1_BASE_VALUE +#define PKTCTRL1_ADDR_FILTER_ON (PKTCTRL1_BASE_VALUE | (BV(0)|BV(1))) + +#ifdef MRFI_ASSERTS_ARE_ON +#define RX_FILTER_ADDR_INITIAL_VALUE 0xFF +#endif + + /* The SW timer is calibrated by adjusting the call to the microsecond delay + * routine. This allows maximum calibration control with repects to the longer + * times requested by applicationsd and decouples internal from external calls + * to the microsecond routine which can be calibrated independently. + */ +#if defined(SW_TIMER) +#define APP_USEC_VALUE 1000 +#else +#define APP_USEC_VALUE 1000 +#endif + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_ENABLE_SYNC_PIN_INT() (RF1AIE |= BV(9)) +#define MRFI_DISABLE_SYNC_PIN_INT() (RF1AIE &= ~BV(9)) +#define MRFI_CLEAR_SYNC_PIN_INT_FLAG() (RF1AIFG &= ~BV(9)) +#define MRFI_SYNC_PIN_INT_IS_ENABLED() (RF1AIE & BV(9)) +#define MRFI_SYNC_PIN_IS_HIGH() (RF1AIN & BV(9)) +#define MRFI_SYNC_PIN_INT_FLAG_IS_SET() (RF1AIFG & BV(9)) + + +#define MRFI_CLEAR_PAPD_PIN_INT_FLAG() (RF1AIFG &= ~BV(0)) +#define MRFI_PAPD_PIN_IS_HIGH() (RF1AIN & BV(0)) +#define MRFI_PAPD_INT_FLAG_IS_SET() (RF1AIFG & BV(0)) + + +/* RSSI valid signal is available on the GDO_1 */ +#define MRFI_RSSI_VALID_WAIT() while(!(RF1AIN & BV(1))); + + +/* Abstract radio interface calls. Could use these later to + * merge code from similar radio but different interface. + */ +#define MRFI_STROBE(cmd) mrfiRadioInterfaceCmdStrobe(cmd) +#define MRFI_RADIO_REG_READ(reg) mrfiRadioInterfaceReadReg(reg) +#define MRFI_RADIO_REG_WRITE(reg, value) mrfiRadioInterfaceWriteReg(reg, value) +#define MRFI_RADIO_WRITE_TX_FIFO(pData, len) mrfiRadioInterfaceWriteTxFifo(pData, len) +#define MRFI_RADIO_READ_RX_FIFO(pData, len) mrfiRadioInterfaceReadRxFifo(pData, len) + + +#define MRFI_STROBE_IDLE_AND_WAIT() \ +{ \ + MRFI_STROBE( SIDLE ); \ + /* Wait for XOSC to be stable and radio in IDLE state */ \ + while (MRFI_STROBE( SNOP ) & 0xF0) ; \ +} + + +/* ------------------------------------------------------------------------------------------------ + * Local Constants + * ------------------------------------------------------------------------------------------------ + */ +const uint8_t mrfiRadioCfg[][2] = +{ + /* internal radio configuration */ + { IOCFG0, MRFI_SETTING_IOCFG0 }, /* Configure GDO_0 to output PA_PD signal (low during TX, high otherwise). */ + { IOCFG1, MRFI_SETTING_IOCFG1 }, /* Configure GDO_1 to output RSSI_VALID signal (high when RSSI is valid, low otherwise). */ + { MCSM1, MRFI_SETTING_MCSM1 }, /* CCA mode, RX_OFF_MODE and TX_OFF_MODE */ + { MCSM0, MRFI_SETTING_MCSM0 }, /* AUTO_CAL and XOSC state in sleep */ + { PKTLEN, MRFI_SETTING_PKTLEN }, + { PKTCTRL0, MRFI_SETTING_PKTCTRL0 }, + { FIFOTHR, MRFI_SETTING_FIFOTHR }, + +/* imported SmartRF radio configuration */ + + { FSCTRL1, SMARTRF_SETTING_FSCTRL1 }, + { FSCTRL0, SMARTRF_SETTING_FSCTRL0 }, + { FREQ2, SMARTRF_SETTING_FREQ2 }, + { FREQ1, SMARTRF_SETTING_FREQ1 }, + { FREQ0, SMARTRF_SETTING_FREQ0 }, + { MDMCFG4, SMARTRF_SETTING_MDMCFG4 }, + { MDMCFG3, SMARTRF_SETTING_MDMCFG3 }, + { MDMCFG2, SMARTRF_SETTING_MDMCFG2 }, + { MDMCFG1, SMARTRF_SETTING_MDMCFG1 }, + { MDMCFG0, SMARTRF_SETTING_MDMCFG0 }, + { DEVIATN, SMARTRF_SETTING_DEVIATN }, + { FOCCFG, SMARTRF_SETTING_FOCCFG }, + { BSCFG, SMARTRF_SETTING_BSCFG }, + { AGCCTRL2, SMARTRF_SETTING_AGCCTRL2 }, + { AGCCTRL1, SMARTRF_SETTING_AGCCTRL1 }, + { AGCCTRL0, SMARTRF_SETTING_AGCCTRL0 }, + { FREND1, SMARTRF_SETTING_FREND1 }, + { FREND0, SMARTRF_SETTING_FREND0 }, + { FSCAL3, SMARTRF_SETTING_FSCAL3 }, + { FSCAL2, SMARTRF_SETTING_FSCAL2 }, + { FSCAL1, SMARTRF_SETTING_FSCAL1 }, + { FSCAL0, SMARTRF_SETTING_FSCAL0 }, + { TEST2, SMARTRF_SETTING_TEST2 }, + { TEST1, SMARTRF_SETTING_TEST1 }, + { TEST0, SMARTRF_SETTING_TEST0 }, +}; + + +/* + * Logical channel table - this table translates logical channel into + * actual radio channel number. Channel 0, the default channel, is + * determined by the channel exported from SmartRF Studio. The other + * table entries are derived from that default. Each derived channel is + * masked with 0xFF to prevent generation of an illegal channel number. + * + * This table is easily customized. Just replace or add entries as needed. + * If the number of entries changes, the corresponding #define must also + * be adjusted. It is located in mrfi_defs.h and is called __mrfi_NUM_LOGICAL_CHANS__. + * The static assert below ensures that there is no mismatch. + */ +// [BM] Changed channel assignment to comply with local regulations +#ifdef ISM_EU +static const uint8_t mrfiLogicalChanTable[] = +{ + 0, + 50, + 80, + 110 +}; +#else + #ifdef ISM_US + static const uint8_t mrfiLogicalChanTable[] = + { + 20, + 50, + 80, + 110 + }; + #else + #ifdef ISM_LF + static const uint8_t mrfiLogicalChanTable[] = + { + 0, + 50, + 80, + 110 + }; + #else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" + #endif + #endif +#endif +//static const uint8_t mrfiLogicalChanTable[] = +//{ +// SMARTRF_SETTING_CHANNR, +// 50, +// 80, +// 110 +//}; +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(__mrfi_NUM_LOGICAL_CHANS__ == ((sizeof(mrfiLogicalChanTable)/sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0]))); + +/* + * RF Power setting table - this table translates logical power value + * to radio register setting. The logical power value is used directly + * as an index into the power setting table. The values in the table are + * from low to high. The default settings set 3 values: -20 dBm, -10 dBm, + * and 0 dBm. The default at startup is the highest value. Note that these + * are approximate depending on the radio. Information is taken from the + * data sheet. + * + * This table is easily customized. Just replace or add entries as needed. + * If the number of entries changes, the corresponding #define must also + * be adjusted. It is located in mrfi_defs.h and is called __mrfi_NUM_POWER_SETTINGS__. + * The static assert below ensures that there is no mismatch. + * + * For the CC430 use the CC1100 values. + */ +static const uint8_t mrfiRFPowerTable[] = +{ +// [BM] Changed default output power to comply with dongle settings + 0x0F, + 0x27, +// [BM] Increase output power from -0.3dBm to +1.4dBm (433MHz) / +1.1dBm (868MHz) / +1.3dBm (915MHz) to compensate antenna loss +#ifdef ISM_EU + 0x8C +#else + #ifdef ISM_US + 0x8B + #else + #ifdef ISM_LF + 0x8D + #else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" + #endif + #endif +#endif +}; +//static const uint8_t mrfiRFPowerTable[] = +//{ +// 0x0D, +// 0x34, +// 0x8E +//}; + +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(__mrfi_NUM_POWER_SETTINGS__ == ((sizeof(mrfiRFPowerTable)/sizeof(mrfiRFPowerTable[0])) * sizeof(mrfiRFPowerTable[0]))); + +/* ------------------------------------------------------------------------------------------------ + * Local Prototypes + * ------------------------------------------------------------------------------------------------ + */ +static void Mrfi_SyncPinRxIsr(void); +static void Mrfi_RxModeOn(void); +static void Mrfi_RandomBackoffDelay(void); +static void Mrfi_RxModeOff(void); +static void Mrfi_DelayUsec(uint16_t howLong); +static void Mrfi_DelayUsecSem(uint16_t howLong); +static int8_t Mrfi_CalculateRssi(uint8_t rawValue); +static uint8_t Mrfi_RxAddrIsFiltered(uint8_t * pAddr); + + +/* ------------------------------------------------------------------------------------------------ + * Local Variables + * ------------------------------------------------------------------------------------------------ + */ +static uint8_t mrfiRadioState = MRFI_RADIO_STATE_UNKNOWN; +static mrfiPacket_t mrfiIncomingPacket; +static uint8_t mrfiRndSeed = 0; + +/* reply delay support */ +static volatile uint8_t sKillSem = 0; +static volatile uint8_t sReplyDelayContext = 0; +static uint16_t sReplyDelayScalar = 0; +static uint16_t sBackoffHelper = 0; + +static uint8_t mrfiRxFilterEnabled = 0; +static uint8_t mrfiRxFilterAddr[MRFI_ADDR_SIZE] = { RX_FILTER_ADDR_INITIAL_VALUE }; + +/* These counters are only for diagnostic purpose */ +static uint32_t crcFail = 0; +static uint32_t crcPass = 0; +static uint32_t noFrame = 0; + +// [BM] Radio frequency offset read from calibration memory +// Compensates crystal deviation from 26MHz nominal value +extern unsigned char rf_frequoffset; + +/************************************************************************************************** + * @fn MRFI_Init + * + * @brief Initialize MRFI. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_Init(void) +{ + /* ------------------------------------------------------------------ + * Radio power-up reset + * ---------------------- + */ + memset(&mrfiIncomingPacket, 0x0, sizeof(mrfiIncomingPacket)); + + /* Initialize the radio interface */ + mrfiRadioInterfaceInit(); + + /* Strobe Reset: Resets the radio and puts it in SLEEP state. */ + MRFI_STROBE( SRES ); + + /* verify the correct radio is installed */ + MRFI_ASSERT( MRFI_RADIO_REG_READ( PARTNUM ) == MRFI_RADIO_PARTNUM ); /* incorrect radio specified */ + MRFI_ASSERT( MRFI_RADIO_REG_READ( VERSION ) == MRFI_RADIO_VERSION ); /* incorrect radio specified */ + + /* Put radio in Idle state */ + MRFI_STROBE_IDLE_AND_WAIT(); + + + /* ------------------------------------------------------------------ + * Configure radio + * ----------------- + */ + + /* Configure Radio interrupts: + * + * RF1AIN_0 => Programmed to PA_PD signal. + * Configure it to interrupt on falling edge. + * + * RF1AIN_1 => Programmed to RSSI Valid signal. + * No need to configure for interrupt. This value will be read + * through polling. + * + * RF1AIN_9 => Rising edge indicates SYNC sent/received and + * Falling edge indicates end of packet. + * Configure it to interrupt on falling edge. + */ + + /* Select Interrupt edge for PA_PD and SYNC signal: + * Interrupt Edge select register: 1 == Interrupt on High to Low transition. + */ + RF1AIES = BV(0) | BV(9); + + /* Write the power output to the PA_TABLE and verify the write operation. */ + { + uint8_t readbackPATableValue = 0; + bspIState_t s; + + BSP_ENTER_CRITICAL_SECTION(s); + + while( !(RF1AIFCTL1 & RFINSTRIFG)); + RF1AINSTRW = 0x7E51; /* PA Table write (burst) */ + + while( !(RF1AIFCTL1 & RFINSTRIFG)); + RF1AINSTRB = RF_SNOP; /* reset pointer */ + + while( !(RF1AIFCTL1 & RFINSTRIFG)); + RF1AINSTRB = 0xFE; /* PA Table read (burst) */ + + while( !(RF1AIFCTL1 & RFDINIFG)); + RF1ADINB = 0x00; /* dummy write */ + + while( !(RF1AIFCTL1 & RFDOUTIFG)); + readbackPATableValue = RF1ADOUT0B; + + MRFI_ASSERT(readbackPATableValue == 0x51); + + while( !(RF1AIFCTL1 & RFINSTRIFG)); + RF1AINSTRB = RF_SNOP; + + BSP_EXIT_CRITICAL_SECTION(s); + } + + /* initialize radio registers */ + { + uint8_t i; + + for (i=0; i<(sizeof(mrfiRadioCfg)/sizeof(mrfiRadioCfg[0])); i++) + { + MRFI_RADIO_REG_WRITE(mrfiRadioCfg[i][0], mrfiRadioCfg[i][1]); + } + } + + /* Confirm that the values were written correctly. + */ + { + uint8_t i; + + for (i=0; i<(sizeof(mrfiRadioCfg)/sizeof(mrfiRadioCfg[0])); i++) + { + MRFI_ASSERT( mrfiRadioCfg[i][1] == MRFI_RADIO_REG_READ(mrfiRadioCfg[i][0]) ); + } + } + + // [BM] Apply global frequency offset to FSCTRL0 + MRFI_STROBE_IDLE_AND_WAIT(); + MRFI_RADIO_REG_WRITE(FSCTRL0, rf_frequoffset); + + /* set default channel */ + MRFI_SetLogicalChannel( 0 ); + + /* Set default power level */ + MRFI_SetRFPwr(MRFI_NUM_POWER_SETTINGS- 1); + + /* Generate Random seed: + * We will use the RSSI value to generate our random seed. + */ + + /* Put the radio in RX state */ + MRFI_STROBE( SRX ); + + /* delay for the rssi to be valid */ + MRFI_RSSI_VALID_WAIT(); + + { + uint8_t i; + for(i=0; i<16; i++) + { + /* use most random bit of rssi to populate the random seed */ + mrfiRndSeed = (mrfiRndSeed << 1) | (MRFI_RADIO_REG_READ(RSSI) & 0x01); + } + } + + /* Force the seed to be non-zero by setting one bit, just in case... */ + mrfiRndSeed |= 0x0080; + + /* Turn off RF. */ + Mrfi_RxModeOff(); + + /* Strobe Power Down (SPWD): puts the radio in SLEEP state. */ + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + MRFI_STROBE( SXOFF ); + + /* Initial radio state is IDLE state */ + mrfiRadioState = MRFI_RADIO_STATE_OFF; + + /***************************************************************************************** + * Compute reply delay scalar + * + * Formula from data sheet for all the narrow band radios is: + * + * (256 + DATAR_Mantissa) * 2^(DATAR_Exponent) + * DATA_RATE = ------------------------------------------ * f(xosc) + * 2^28 + * + * To try and keep some accuracy we change the exponent of the denominator + * to (28 - (exponent from the configuration register)) so we do a division + * by a smaller number. We find the power of 2 by shifting. + * + * The maximum delay needed depends on the MAX_APP_PAYLOAD parameter. Figure + * out how many bits that will be when overhead is included. Bits/bits-per-second + * is seconds to transmit (or receive) the maximum frame. We multiply this number + * by 1000 to find the time in milliseconds. We then additionally multiply by + * 10 so we can add 5 and divide by 10 later, thus rounding up to the number of + * milliseconds. This last won't matter for slow transmissions but for faster ones + * we want to err on the side of being conservative and making sure the radio is on + * to receive the reply. The semaphore monitor will shut it down. The delay adds in + * a fudge factor that includes processing time on peer plus lags in Rx and processing + * time on receiver's side. + * + * Note that we assume a 26 MHz clock for the radio... + * *************************************************************************************** + */ +#define MRFI_RADIO_OSC_FREQ 26000000 +#define PHY_PREAMBLE_SYNC_BYTES 8 + + { + uint32_t dataRate, bits; + uint16_t exponent, mantissa; + + /* mantissa is in MDMCFG3 */ + mantissa = 256 + SMARTRF_SETTING_MDMCFG3; + + /* exponent is lower nibble of MDMCFG4. */ + exponent = 28 - (SMARTRF_SETTING_MDMCFG4 & 0x0F); + + /* we can now get data rate */ + dataRate = mantissa * (MRFI_RADIO_OSC_FREQ>>exponent); + + bits = ((uint32_t)((PHY_PREAMBLE_SYNC_BYTES + MRFI_MAX_FRAME_SIZE)*8))*10000; + + /* processing on the peer + the Tx/Rx time plus more */ + sReplyDelayScalar = PLATFORM_FACTOR_CONSTANT + (((bits/dataRate)+5)/10); + + /* This helper value is used to scale the backoffs during CCA. At very + * low data rates we need to backoff longer to prevent continual sampling + * of valid frames which take longer to send at lower rates. Use the scalar + * we just calculated divided by 32. With the backoff algorithm backing + * off up to 16 periods this will result in waiting up to about 1/2 the total + * scalar value. For high data rates this does not contribute at all. Value + * is in microseconds. + */ + sBackoffHelper = MRFI_BACKOFF_PERIOD_USECS + (sReplyDelayScalar>>5)*1000; + } + + /* Clean out buffer to protect against spurious frames */ + memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame)); + memset(mrfiIncomingPacket.rxMetrics, 0x00, sizeof(mrfiIncomingPacket.rxMetrics)); + + /* enable global interrupts */ + BSP_ENABLE_INTERRUPTS(); +} + + +/************************************************************************************************** + * @fn MRFI_Transmit + * + * @brief Transmit a packet using CCA algorithm. + * + * @param pPacket - pointer to packet to transmit + * + * @return Return code indicates success or failure of transmit: + * MRFI_TX_RESULT_SUCCESS - transmit succeeded + * MRFI_TX_RESULT_FAILED - transmit failed because CCA failed + ************************************************************************************************** + */ +uint8_t MRFI_Transmit(mrfiPacket_t * pPacket, uint8_t txType) +{ + uint8_t ccaRetries; + uint8_t txBufLen; + uint8_t returnValue = MRFI_TX_RESULT_SUCCESS; + + /* radio must be awake to transmit */ + MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF ); + + /* Turn off reciever. We can ignore/drop incoming packets during transmit. */ + Mrfi_RxModeOff(); + + /* compute number of bytes to write to transmit FIFO */ + txBufLen = pPacket->frame[MRFI_LENGTH_FIELD_OFS] + MRFI_LENGTH_FIELD_SIZE; + + /* ------------------------------------------------------------------ + * Write packet to transmit FIFO + * -------------------------------- + */ + MRFI_RADIO_WRITE_TX_FIFO(&(pPacket->frame[0]), txBufLen); + + + /* ------------------------------------------------------------------ + * Immediate transmit + * --------------------- + */ + if (txType == MRFI_TX_TYPE_FORCED) + { + /* Issue the TX strobe. */ + MRFI_STROBE( STX ); + + /* Wait for transmit to complete */ + while(!MRFI_SYNC_PIN_INT_FLAG_IS_SET()); + + /* Clear the interrupt flag */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + } + else + { + /* ------------------------------------------------------------------ + * CCA transmit + * --------------- + */ + + MRFI_ASSERT( txType == MRFI_TX_TYPE_CCA ); + + /* set number of CCA retries */ + ccaRetries = MRFI_CCA_RETRIES; + + + /* =============================================================================== + * Main Loop + * ============= + */ + for (;;) + { + /* Radio must be in RX mode for CCA to happen. + * Otherwise it will transmit without CCA happening. + */ + + /* Can not use the Mrfi_RxModeOn() function here since it turns on the + * Rx interrupt, which we don't want in this case. + */ + MRFI_STROBE( SRX ); + + /* wait for the rssi to be valid. */ + MRFI_RSSI_VALID_WAIT(); + + /* + * Clear the PA_PD pin interrupt flag. This flag, not the interrupt itself, + * is used to capture the transition that indicates a transmit was started. + * The pin level cannot be used to indicate transmit success as timing may + * prevent the transition from being detected. The interrupt latch captures + * the event regardless of timing. + */ + MRFI_CLEAR_PAPD_PIN_INT_FLAG(); + + /* send strobe to initiate transmit */ + MRFI_STROBE( STX ); + + /* Delay long enough for the PA_PD signal to indicate a + * successful transmit. This is the 250 XOSC periods + * (9.6 us for a 26 MHz crystal). + * Found out that we need a delay of atleast 25 us on CC1100 to see + * the PA_PD signal change. Hence keeping the same for CC430 + */ + Mrfi_DelayUsec(25); + + + /* PA_PD signal goes from HIGH to LOW when going from RX to TX state. + * This transition is trapped as a falling edge interrupt flag + * to indicate that CCA passed and the transmit has started. + */ + if (MRFI_PAPD_INT_FLAG_IS_SET()) + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment passed. + * ---------------------------------- + */ + + /* Clear the PA_PD int flag */ + MRFI_CLEAR_PAPD_PIN_INT_FLAG(); + + /* PA_PD signal stays LOW while in TX state and goes back to HIGH when + * the radio transitions to RX state. + */ + /* wait for transmit to complete */ + while (!MRFI_PAPD_PIN_IS_HIGH()); + + /* transmit done, break */ + break; + } + else + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment failed. + * ---------------------------------- + */ + + /* Turn off radio and save some power during backoff */ + + /* NOTE: Can't use Mrfi_RxModeOff() - since it tries to update the + * sync signal status which we are not using during the TX operation. + */ + MRFI_STROBE_IDLE_AND_WAIT(); + + /* flush the receive FIFO of any residual data */ + MRFI_STROBE( SFRX ); + + /* Retry ? */ + if (ccaRetries != 0) + { + /* delay for a random number of backoffs */ + Mrfi_RandomBackoffDelay(); + + /* decrement CCA retries before loop continues */ + ccaRetries--; + } + else /* No CCA retries are left, abort */ + { + /* set return value for failed transmit and break */ + returnValue = MRFI_TX_RESULT_FAILED; + break; + } + } /* CCA Failed */ + } /* CCA loop */ + }/* txType is CCA */ + + + /* Done with TX. Clean up time... */ + + /* Radio is already in IDLE state */ + + /* + * Flush the transmit FIFO. It must be flushed so that + * the next transmit can start with a clean slate. + */ + MRFI_STROBE( SFTX ); + + /* If the radio was in RX state when transmit was attempted, + * put it back to Rx On state. + */ + if(mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOn(); + } + + return( returnValue ); +} + +/************************************************************************************************** + * @fn MRFI_Receive + * + * @brief Copies last packet received to the location specified. + * This function is meant to be called after the ISR informs + * higher level code that there is a newly received packet. + * + * @param pPacket - pointer to location of where to copy received packet + * + * @return none + ************************************************************************************************** + */ +void MRFI_Receive(mrfiPacket_t * pPacket) +{ + *pPacket = mrfiIncomingPacket; +} + +/************************************************************************************************** + * @fn Mrfi_SyncPinRxIsr + * + * @brief This interrupt is called when the SYNC signal transition from high to low. + * The sync signal is routed to the sync pin which is a GPIO pin. This high-to-low + * transition signifies a receive has completed. The SYNC signal also goes from + * high to low when a transmit completes. This is protected against within the + * transmit function by disabling sync pin interrupts until transmit completes. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Mrfi_SyncPinRxIsr(void) +{ + uint8_t frameLen = 0x00; + uint8_t rxBytes; + + /* We should receive this interrupt only in RX state + * Should never receive it if RX was turned On only for + * some internal mrfi processing like - during CCA. + * Otherwise something is terribly wrong. + */ + MRFI_ASSERT( mrfiRadioState == MRFI_RADIO_STATE_RX ); + + /* ------------------------------------------------------------------ + * Get RXBYTES + * ------------- + */ + + /* + * Read the RXBYTES register from the radio. + * Bit description of RXBYTES register: + * bit 7 - RXFIFO_OVERFLOW, set if receive overflow occurred + * bits 6:0 - NUM_BYTES, number of bytes in receive FIFO + * + * Due a chip bug, the RXBYTES register must read the same value twice + * in a row to guarantee an accurate value. + */ + { + uint8_t rxBytesVerify; + + rxBytesVerify = MRFI_RADIO_REG_READ( RXBYTES ); + + do + { + rxBytes = rxBytesVerify; + rxBytesVerify = MRFI_RADIO_REG_READ( RXBYTES ); + } + while (rxBytes != rxBytesVerify); + } + + + /* ------------------------------------------------------------------ + * FIFO empty? + * ------------- + */ + + /* + * See if the receive FIFIO is empty before attempting to read from it. + * It is possible nothing the FIFO is empty even though the interrupt fired. + * This can happen if address check is enabled and a non-matching packet is + * received. In that case, the radio automatically removes the packet from + * the FIFO. + */ + if (rxBytes == 0) + { + /* receive FIFO is empty - do nothing, skip to end */ + } + else + { + /* receive FIFO is not empty, continue processing */ + + /* ------------------------------------------------------------------ + * Process frame length + * ---------------------- + */ + + /* read the first byte from FIFO - the packet length */ + MRFI_RADIO_READ_RX_FIFO(&frameLen, MRFI_LENGTH_FIELD_SIZE); + + + /* + * Make sure that the frame length just read corresponds to number of bytes in the buffer. + * If these do not match up something is wrong. + * + * This can happen for several reasons: + * 1) Incoming packet has an incorrect format or is corrupted. + * 2) The receive FIFO overflowed. Overflow is indicated by the high + * bit of rxBytes. This guarantees the value of rxBytes value will not + * match the number of bytes in the FIFO for overflow condition. + * 3) Interrupts were blocked for an abnormally long time which + * allowed a following packet to at least start filling the + * receive FIFO. In this case, all received and partially received + * packets will be lost - the packet in the FIFO and the packet coming in. + * This is the price the user pays if they implement a giant + * critical section. + * 4) A failed transmit forced radio to IDLE state to flush the transmit FIFO. + * This could cause an active receive to be cut short. + * + * Also check the sanity of the length to guard against rogue frames. + */ + if ((rxBytes != (frameLen + MRFI_LENGTH_FIELD_SIZE + MRFI_RX_METRICS_SIZE)) || + ((frameLen + MRFI_LENGTH_FIELD_SIZE) > MRFI_MAX_FRAME_SIZE) || + (frameLen < MRFI_MIN_SMPL_FRAME_SIZE) + ) + { + bspIState_t s; + noFrame++; + + /* mismatch between bytes-in-FIFO and frame length */ + + /* + * Flush receive FIFO to reset receive. Must go to IDLE state to do this. + * The critical section guarantees a transmit does not occur while cleaning up. + */ + BSP_ENTER_CRITICAL_SECTION(s); + MRFI_STROBE_IDLE_AND_WAIT(); + MRFI_STROBE( SFRX ); + MRFI_STROBE( SRX ); + BSP_EXIT_CRITICAL_SECTION(s); + + /* flush complete, skip to end */ + } + else + { + /* bytes-in-FIFO and frame length match up - continue processing */ + + /* ------------------------------------------------------------------ + * Get packet + * ------------ + */ + + /* clean out buffer to help protect against spurious frames */ + memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame)); + + /* set length field */ + mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFS] = frameLen; + + /* get packet from FIFO */ + MRFI_RADIO_READ_RX_FIFO(&(mrfiIncomingPacket.frame[MRFI_FRAME_BODY_OFS]), frameLen); + + /* get receive metrics from FIFO */ + MRFI_RADIO_READ_RX_FIFO(&(mrfiIncomingPacket.rxMetrics[0]), MRFI_RX_METRICS_SIZE); + + + /* ------------------------------------------------------------------ + * CRC check + * ------------ + */ + + /* + * Note! Automatic CRC check is not, and must not, be enabled. This feature + * flushes the *entire* receive FIFO when CRC fails. If this feature is + * enabled it is possible to be reading from the FIFO and have a second + * receive occur that fails CRC and automatically flushes the receive FIFO. + * This could cause reads from an empty receive FIFO which puts the radio + * into an undefined state. + */ + + /* determine if CRC failed */ + if (!(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & MRFI_RX_METRICS_CRC_OK_MASK)) + { + /* CRC failed - do nothing, skip to end */ + crcFail++; + } + else + { + /* CRC passed - continue processing */ + crcPass++; + + /* ------------------------------------------------------------------ + * Filtering + * ----------- + */ + + /* if address is not filtered, receive is successful */ + if (!Mrfi_RxAddrIsFiltered(MRFI_P_DST_ADDR(&mrfiIncomingPacket))) + { + { + /* ------------------------------------------------------------------ + * Receive successful + * -------------------- + */ + + /* Convert the raw RSSI value and do offset compensation for this radio */ + mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS] = + Mrfi_CalculateRssi(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS]); + + /* Remove the CRC valid bit from the LQI byte */ + mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] = + (mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & MRFI_RX_METRICS_LQI_MASK); + + + /* call external, higher level "receive complete" processing routine */ + MRFI_RxCompleteISR(); + } + } + } + } + } + + /* ------------------------------------------------------------------ + * End of function + * ------------------- + */ +} + +/************************************************************************************************** + * @fn Mrfi_RxModeOn + * + * @brief Put radio into receive mode. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Mrfi_RxModeOn(void) +{ + /* clear any residual receive interrupt */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + + /* send strobe to enter receive mode */ + MRFI_STROBE( SRX ); + + /* enable receive interrupts */ + MRFI_ENABLE_SYNC_PIN_INT(); +} + +/************************************************************************************************** + * @fn MRFI_RxOn + * + * @brief Turn on the receiver. No harm is done if this function is called when + * receiver is already on. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_RxOn(void) +{ + /* radio must be awake before we can move it to RX state */ + MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF ); + + /* if radio is off, turn it on */ + if(mrfiRadioState != MRFI_RADIO_STATE_RX) + { + mrfiRadioState = MRFI_RADIO_STATE_RX; + Mrfi_RxModeOn(); + } +} + +/************************************************************************************************** + * @fn Mrfi_RxModeOff + * + * @brief - + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Mrfi_RxModeOff(void) +{ + /* disable receive interrupts */ + MRFI_DISABLE_SYNC_PIN_INT(); + + /* turn off radio */ + MRFI_STROBE_IDLE_AND_WAIT(); + + /* flush the receive FIFO of any residual data */ + MRFI_STROBE( SFRX ); + + /* clear receive interrupt */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); +} + + +/************************************************************************************************** + * @fn MRFI_RxIdle + * + * @brief Put radio in idle mode (receiver if off). No harm is done this function is + * called when radio is already idle. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_RxIdle(void) +{ + /* radio must be awake to move it to idle mode */ + MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF ); + + /* if radio is on, turn it off */ + if(mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOff(); + mrfiRadioState = MRFI_RADIO_STATE_IDLE; + } +} + + +/************************************************************************************************** + * @fn MRFI_Sleep + * + * @brief Request radio go to sleep. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_Sleep(void) +{ + bspIState_t s; + + /* Critical section necessary for watertight testing and + * setting of state variables. + */ + BSP_ENTER_CRITICAL_SECTION(s); + + /* If radio is not asleep, put it to sleep */ + if(mrfiRadioState != MRFI_RADIO_STATE_OFF) + { + /* go to idle so radio is in a known state before sleeping */ + MRFI_RxIdle(); + + /* Strobe Power Down (SPWD): puts the radio in SLEEP state. */ + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + MRFI_STROBE( SXOFF ); + + /* Our new state is OFF */ + mrfiRadioState = MRFI_RADIO_STATE_OFF; + } + + BSP_EXIT_CRITICAL_SECTION(s); +} + + +/************************************************************************************************** + * @fn MRFI_WakeUp + * + * @brief Wake up radio from sleep state. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_WakeUp(void) +{ + /* if radio is already awake, just ignore wakeup request */ + if(mrfiRadioState != MRFI_RADIO_STATE_OFF) + { + return; + } + + MRFI_STROBE_IDLE_AND_WAIT(); + + /* enter idle mode */ + mrfiRadioState = MRFI_RADIO_STATE_IDLE; +} + + +/************************************************************************************************** + * @fn MRFI_RadioIsr + * + * @brief Radio Interface interrupts as well as Radio interrupts are + * mapped to this interrupt vector. + * + * @param - + * + * @return - + ************************************************************************************************** + */ +// [BM] Changed because CC1101_VECTOR ISR is declared of source code and this handler is called indirect +//BSP_ISR_FUNCTION( MRFI_RadioIsr, CC1101_VECTOR ) +void MRFI_RadioIsr(void) +{ + uint16_t coreIntSource = RF1AIV; /* Radio Core interrupt register */ + uint16_t interfaceIntSource = RF1AIFIV; /* Radio Interface interrupt register */ + + /* Interface interrupt */ + if(interfaceIntSource) + { + if(interfaceIntSource == RF1AIFIV_RFERRIFG) + { + uint16_t interfaceError = RF1AIFERRV; + + if(interfaceError == RF1AIFERRV_LVERR) + { + /* Low core voltage error */ + } + else if(interfaceError == RF1AIFERRV_OPERR) + { + /* Operand error */ + } + else if(interfaceError == RF1AIFERRV_OUTERR) + { + /* output data not available error */ + } + else if(interfaceError == RF1AIFERRV_OPOVERR) + { + /* Operand overwrite error */ + } + else + { + /* Can't possibly happen. If interface error flag was set, + * then one of the interface errors must be set. + */ + MRFI_FORCE_ASSERT(); + } + + /* Assert anyways. No error handling implemented. */ + MRFI_FORCE_ASSERT(); + } + else + { + /* Not expecting any other interface interrupts (data in/out, status/instr in, fifo rx/tx) */ + MRFI_FORCE_ASSERT(); + } + } + + /* Radio Core interrupt */ + if(coreIntSource) + { + /* Check for SYNC interrupt */ + if(coreIntSource == RF1AIV_RFIFG9) + { + if(MRFI_SYNC_PIN_INT_IS_ENABLED()) + { + /* clear the sync pin interrupt, run sync pin ISR */ + /* + * NOTE! The following macro clears the interrupt flag but it also *must* + * reset the interrupt capture. In other words, if a second interrupt + * occurs after the flag is cleared it must be processed, i.e. this interrupt + * exits then immediately starts again. Most microcontrollers handle this + * naturally but it must be verified for every target. + */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + + Mrfi_SyncPinRxIsr(); + } + else + { + /* Fatal error. SYNC interrupt is not supposed to happen at this time. */ + MRFI_FORCE_ASSERT(); + } + } + else + { + /* Fatal error. No other Radio interurpt is enabled. */ + MRFI_FORCE_ASSERT(); + } + } +} + + +/************************************************************************************************** + * @fn MRFI_Rssi + * + * @brief Returns "live" RSSI value + * + * @param none + * + * @return RSSI value in units of dBm. + ************************************************************************************************** + */ +int8_t MRFI_Rssi(void) +{ + uint8_t regValue; + + /* Radio must be in RX state to measure rssi. */ + MRFI_ASSERT( mrfiRadioState == MRFI_RADIO_STATE_RX ); + + /* Wait for the RSSI to be valid: + * Just having the Radio ON is not enough to read + * the correct RSSI value. The Radio must in RX mode for + * a certain duration. This duration depends on + * the baud rate and the received signal strength itself. + */ + MRFI_RSSI_VALID_WAIT(); + + /* Read the RSSI value */ + regValue = MRFI_RADIO_REG_READ( RSSI ); + + /* convert and do offset compensation */ + return( Mrfi_CalculateRssi(regValue) ); +} + + +/************************************************************************************************** + * @fn Mrfi_CalculateRssi + * + * @brief Does binary to decimal conversion and offset compensation. + * + * @param none + * + * @return RSSI value in units of dBm. + ************************************************************************************************** + */ +int8_t Mrfi_CalculateRssi(uint8_t rawValue) +{ + int16_t rssi; + + /* The raw value is in 2's complement and in half db steps. Convert it to + * decimal taking into account the offset value. + */ + if(rawValue >= 128) + { + rssi = (int16_t)(rawValue - 256)/2 - MRFI_RSSI_OFFSET; + } + else + { + rssi = (rawValue/2) - MRFI_RSSI_OFFSET; + } + + /* Restrict this value to least value can be held in an 8 bit signed int */ + if(rssi < -128) + { + rssi = -128; + } + + return rssi; +} + +/************************************************************************************************** + * @fn MRFI_RandomByte + * + * @brief Returns a random byte. This is a pseudo-random number generator. + * The generated sequence will repeat every 256 values. + * The sequence itself depends on the initial seed value. + * + * @param none + * + * @return a random byte + ************************************************************************************************** + */ +uint8_t MRFI_RandomByte(void) +{ + mrfiRndSeed = (mrfiRndSeed*MRFI_RANDOM_MULTIPLIER) + MRFI_RANDOM_OFFSET; + + return mrfiRndSeed; +} + +/************************************************************************************************** + * @fn Mrfi_RandomBackoffDelay + * + * @brief - + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Mrfi_RandomBackoffDelay(void) +{ + uint8_t backoffs; + uint8_t i; + + /* calculate random value for backoffs - 1 to 16 */ + backoffs = (MRFI_RandomByte() & 0x0F) + 1; + + /* delay for randomly computed number of backoff periods */ + for (i=0; i MRFI_RADIO_MAX_PKTLEN) +#error "ERROR: Maximum possible value for PKTLEN exceeded. Decrease value of maximum payload." +#endif + +/* verify largest possible packet fits within FIFO buffer */ +#if ((MRFI_MAX_FRAME_SIZE + MRFI_RX_METRICS_SIZE) > MRFI_RADIO_TX_FIFO_SIZE) +#error "ERROR: Maximum possible packet length exceeds FIFO buffer. Decrease value of maximum payload." +#endif + +/* verify that the SmartRF file supplied is compatible */ +#if ((!defined SMARTRF_RADIO_CC430)) + #error "ERROR: The SmartRF export file is not compatible." +#endif + +/* + * These asserts happen if there is extraneous compiler padding of arrays. + * Modify compiler settings for no padding, or, if that is not possible, + * comment out the offending asserts. + */ +BSP_STATIC_ASSERT(sizeof(mrfiRadioCfg) == ((sizeof(mrfiRadioCfg)/sizeof(mrfiRadioCfg[0])) * sizeof(mrfiRadioCfg[0]))); + + +/* + * These asserts happen if there is extraneous compiler padding of arrays. + * Modify compiler settings for no padding, or, if that is not possible, + * comment out the offending asserts. + */ +BSP_STATIC_ASSERT(sizeof(mrfiLogicalChanTable) == ((sizeof(mrfiLogicalChanTable)/sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0]))); +BSP_STATIC_ASSERT(sizeof(mrfiBroadcastAddr) == ((sizeof(mrfiBroadcastAddr)/sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0]))); + +/************************************************************************************************** +*/ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c new file mode 100755 index 0000000..99c5bd9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c @@ -0,0 +1,374 @@ +/************************************************************************************************** + Revised: $Date: 2009-11-23 07:50:43 -0800 (Mon, 23 Nov 2009) $ + Revision: $Revision: 21225 $ + + Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS? + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radios: CC430 + * Radio Interface (RIF) code. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "mrfi_radio_interface.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_RADIO_STATUS_READ_CLEAR() RF1AIFCTL1 &= ~(RFSTATIFG); + +#define MRFI_RADIO_STATUS_READ_WAIT() while( !(RF1AIFCTL1 & RFSTATIFG) ); +#define MRFI_RADIO_INST_WRITE_WAIT() while( !(RF1AIFCTL1 & RFINSTRIFG)); +#define MRFI_RADIO_DATA_WRITE_WAIT() while( !(RF1AIFCTL1 & RFDINIFG) ); +#define MRFI_RADIO_DATA_READ_WAIT() while( !(RF1AIFCTL1 & RFDOUTIFG) ); + +#define MRFI_RIF_DEBUG +#ifdef MRFI_RIF_DEBUG +#define MRFI_RIF_ASSERT(x) BSP_ASSERT(x) +#else +#define MRFI_RIF_ASSERT(x) +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Local Prototypes + * ------------------------------------------------------------------------------------------------ + */ + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceInit + * + * @brief Initialize the Radio Interface + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void mrfiRadioInterfaceInit(void) +{ + /* Enable interrupt on interface error. + * The code behaves differently between different runs on the debugger, and seemingly fails + * due to error flags on the bench. The code does not fail, however, on functional tests. + * This points to problems with the debugger that need to be sorted through carefully. + * For the time being, remove the following line, since it will likely cause operational + * failures. + */ + // RF1AIFCTL1 |= RFERRIE; +} + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceCmdStrobe + * + * @brief Send command strobe to the radio. Returns status byte read during transfer + * of strobe command. + * + * @param addr - address of register to strobe + * + * @return status byte of radio + ************************************************************************************************** + */ +uint8_t mrfiRadioInterfaceCmdStrobe(uint8_t addr) +{ + uint8_t statusByte, gdoState; + mrfiRIFIState_t s; + + /* Check for invalid address. + * 0xBD is for SNOP with MSP set to read the bytes available in RX FIFO. + */ + MRFI_RIF_ASSERT( (addr == 0xBD) || (addr >= RF_SRES) && (addr <= RF_SNOP)); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Clear the Status read flag */ + MRFI_RADIO_STATUS_READ_CLEAR(); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + if ((addr > RF_SRES) && (addr < RF_SNOP)) + { + /* buffer IOCFG2 state */ + gdoState = MRFI_RADIO_REG_READ(IOCFG2); + + /* c-ready to GDO2 */ + MRFI_RADIO_REG_WRITE(IOCFG2, 0x29); + + RF1AINSTRB = addr; + + /* chip at sleep mode */ + if ((RF1AIN & 0x04) == 0x04) + { + if ( (addr == RF_SXOFF) || (addr == RF_SPWD) || (addr == RF_SWOR) ) + { + /* Do nothing */ + } + else + { + /* c-ready */ + while ((RF1AIN & 0x04) == 0x04); + + /* Delay should be 760us */ + Mrfi_DelayUsec(760); + } + } + + /* restore IOCFG2 setting */ + MRFI_RADIO_REG_WRITE(IOCFG2, gdoState); + } + else + { + /* chip active mode */ + RF1AINSTRB = addr; + } + + /* Read status byte */ + statusByte = RF1ASTAT0B; + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); + + /* return the status byte */ + return statusByte; +} + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceReadReg + * + * @brief Read value from radio register. + * + * @param addr - address of register + * + * @return register value + ************************************************************************************************** + */ +uint8_t mrfiRadioInterfaceReadReg(uint8_t addr) +{ + mrfiRIFIState_t s; + uint8_t regValue; + + /* Check for valid range. 0x3E is for PATABLE access */ + MRFI_RIF_ASSERT( (addr <= 0x3B) || (addr == 0x3E) ); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + if( (addr <= 0x2E) || (addr == 0x3E)) + { + /* Write cmd: read the Configuration register */ + RF1AINSTR1B = (0x80 | addr); + } + else + { + /* Write cmd: read the Status register */ + RF1AINSTR1B = (0xC0 | addr); + } + + /* Read out the register value */ + regValue = RF1ADOUT1B; //auto read + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); + + return( regValue); +} + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceWriteReg + * + * @brief Write value to radio register. + * + * @param addr - address of register + * @param value - register value to write + * + * @return none + ************************************************************************************************** + */ +void mrfiRadioInterfaceWriteReg(uint8_t addr, uint8_t value) +{ + mrfiRIFIState_t s; + + /* Check for valid range. 0x3E is for PATABLE access */ + MRFI_RIF_ASSERT((addr <= 0x2E) || (addr == 0x3E)); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: 'write to register' */ + RF1AINSTRB = (0x00 | addr); + + /* Wait for radio to be ready to accept the data */ + MRFI_RADIO_DATA_WRITE_WAIT(); + + /* Write the register value */ + RF1ADINB = value; /* value to be written to the radio register */ + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceWriteTxFifo + * + * @brief Write data to radio transmit FIFO. + * + * @param pData - pointer for storing write data + * @param len - length of data in bytes + * + * @return none + ************************************************************************************************** + */ +void mrfiRadioInterfaceWriteTxFifo(uint8_t * pData, uint8_t len) +{ + mrfiRIFIState_t s; + + MRFI_RIF_ASSERT(len != 0); /* zero length is not allowed */ + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: TXFIFOWR */ + RF1AINSTRB = 0x7F; + + do + { + /* Wait for radio to be ready to accept the data */ + MRFI_RADIO_DATA_WRITE_WAIT(); + + /* Write one byte to FIFO */ + RF1ADINB = *pData; + + pData++; + len--; + + }while(len); + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceReadRxFifo + * + * @brief Read data from radio receive FIFO. + * + * @param pData - pointer for storing read data + * @param len - length of data in bytes + * + * @return none + ************************************************************************************************** + */ +uint8_t method = 2; +void mrfiRadioInterfaceReadRxFifo(uint8_t * pData, uint8_t len) +{ + mrfiRIFIState_t s; + + MRFI_RIF_ASSERT(len != 0); /* zero length is not allowed */ + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + if(method == 1) + { + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: RXFIFORD */ + RF1AINSTRB = 0xFF; + + do + { + /* dummy write */ + RF1ADINB = 0; + + /* Wait for data to be available for reading */ + MRFI_RADIO_DATA_READ_WAIT(); + + /* Read one byte from FIFO */ + *pData = RF1ADOUT0B; + + pData++; + len--; + + }while(len); + } + + if(method == 2) + { + do + { + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: SNGLRXRD */ + RF1AINSTR1B = 0xBF; + + /* Read byte from FIFO */ + *pData = RF1ADOUT1B; //auto read register + + pData++; + len--; + + }while(len); + } + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + + +/************************************************************************************************** +*/ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h new file mode 100755 index 0000000..ebdacfc --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h @@ -0,0 +1,150 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radio interface code for CC430 + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_RADIO_INTERFACE_H +#define MRFI_RADIO_INTERFACE_H + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + +/* configuration registers */ +#define IOCFG2 0x00 /* IOCFG2 - GDO2 output pin configuration */ +#define IOCFG1 0x01 /* IOCFG1 - GDO1 output pin configuration */ +#define IOCFG0 0x02 /* IOCFG1 - GDO0 output pin configuration */ +#define FIFOTHR 0x03 /* FIFOTHR - RX FIFO and TX FIFO thresholds */ +#define SYNC1 0x04 /* SYNC1 - Sync word, high byte */ +#define SYNC0 0x05 /* SYNC0 - Sync word, low byte */ +#define PKTLEN 0x06 /* PKTLEN - Packet length */ +#define PKTCTRL1 0x07 /* PKTCTRL1 - Packet automation control */ +#define PKTCTRL0 0x08 /* PKTCTRL0 - Packet automation control */ +#define ADDR 0x09 /* ADDR - Device address */ +#define CHANNR 0x0A /* CHANNR - Channel number */ +#define FSCTRL1 0x0B /* FSCTRL1 - Frequency synthesizer control */ +#define FSCTRL0 0x0C /* FSCTRL0 - Frequency synthesizer control */ +#define FREQ2 0x0D /* FREQ2 - Frequency control word, high byte */ +#define FREQ1 0x0E /* FREQ1 - Frequency control word, middle byte */ +#define FREQ0 0x0F /* FREQ0 - Frequency control word, low byte */ +#define MDMCFG4 0x10 /* MDMCFG4 - Modem configuration */ +#define MDMCFG3 0x11 /* MDMCFG3 - Modem configuration */ +#define MDMCFG2 0x12 /* MDMCFG2 - Modem configuration */ +#define MDMCFG1 0x13 /* MDMCFG1 - Modem configuration */ +#define MDMCFG0 0x14 /* MDMCFG0 - Modem configuration */ +#define DEVIATN 0x15 /* DEVIATN - Modem deviation setting */ +#define MCSM2 0x16 /* MCSM2 - Main Radio Control State Machine configuration */ +#define MCSM1 0x17 /* MCSM1 - Main Radio Control State Machine configuration */ +#define MCSM0 0x18 /* MCSM0 - Main Radio Control State Machine configuration */ +#define FOCCFG 0x19 /* FOCCFG - Frequency Offset Compensation configuration */ +#define BSCFG 0x1A /* BSCFG - Bit Synchronization configuration */ +#define AGCCTRL2 0x1B /* AGCCTRL2 - AGC control */ +#define AGCCTRL1 0x1C /* AGCCTRL1 - AGC control */ +#define AGCCTRL0 0x1D /* AGCCTRL0 - AGC control */ +#define WOREVT1 0x1E /* WOREVT1 - High byte Event0 timeout */ +#define WOREVT0 0x1F /* WOREVT0 - Low byte Event0 timeout */ +#define WORCTRL 0x20 /* WORCTRL - Wake On Radio control */ +#define FREND1 0x21 /* FREND1 - Front end RX configuration */ +#define FREND0 0x22 /* FREDN0 - Front end TX configuration */ +#define FSCAL3 0x23 /* FSCAL3 - Frequency synthesizer calibration */ +#define FSCAL2 0x24 /* FSCAL2 - Frequency synthesizer calibration */ +#define FSCAL1 0x25 /* FSCAL1 - Frequency synthesizer calibration */ +#define FSCAL0 0x26 /* FSCAL0 - Frequency synthesizer calibration */ +#define RCCTRL1 0x27 /* RCCTRL1 - RC oscillator configuration */ +#define RCCTRL0 0x28 /* RCCTRL0 - RC oscillator configuration */ +#define FSTEST 0x29 /* FSTEST - Frequency synthesizer calibration control */ +#define PTEST 0x2A /* PTEST - Production test */ +#define AGCTEST 0x2B /* AGCTEST - AGC test */ +#define TEST2 0x2C /* TEST2 - Various test settings */ +#define TEST1 0x2D /* TEST1 - Various test settings */ +#define TEST0 0x2E /* TEST0 - Various test settings */ + +/* status registers */ +#define PARTNUM 0x30 /* PARTNUM - Chip ID */ +#define VERSION 0x31 /* VERSION - Chip ID */ +#define FREQEST 0x32 /* FREQEST – Frequency Offset Estimate from demodulator */ +#define LQI 0x33 /* LQI – Demodulator estimate for Link Quality */ +#define RSSI 0x34 /* RSSI – Received signal strength indication */ +#define MARCSTATE 0x35 /* MARCSTATE – Main Radio Control State Machine state */ +#define WORTIME1 0x36 /* WORTIME1 – High byte of WOR time */ +#define WORTIME0 0x37 /* WORTIME0 – Low byte of WOR time */ +#define PKTSTATUS 0x38 /* PKTSTATUS – Current GDOx status and packet status */ +#define VCO_VC_DAC 0x39 /* VCO_VC_DAC – Current setting from PLL calibration module */ +#define TXBYTES 0x3A /* TXBYTES – Underflow and number of bytes */ +#define RXBYTES 0x3B /* RXBYTES – Overflow and number of bytes */ + +/* burst write registers */ +#define PATABLE 0x3E /* PATABLE - PA control settings table */ + +/* command strobe registers */ +#define SRES 0x30 /* SRES - Reset chip. */ +#define SFSTXON 0x31 /* SFSTXON - Enable and calibrate frequency synthesizer. */ +#define SXOFF 0x32 /* SXOFF - Turn off crystal oscillator. */ +#define SCAL 0x33 /* SCAL - Calibrate frequency synthesizer and turn it off. */ +#define SRX 0x34 /* SRX - Enable RX. Perform calibration if enabled. */ +#define STX 0x35 /* STX - Enable TX. If in RX state, only enable TX if CCA passes. */ +#define SIDLE 0x36 /* SIDLE - Exit RX / TX, turn off frequency synthesizer. */ +#define SRSVD 0x37 /* SRVSD - Reserved. Do not use. */ +#define SWOR 0x38 /* SWOR - Start automatic RX polling sequence (Wake-on-Radio) */ +#define SPWD 0x39 /* SPWD - Enter power down mode when CSn goes high. */ +#define SFRX 0x3A /* SFRX - Flush the RX FIFO buffer. */ +#define SFTX 0x3B /* SFTX - Flush the TX FIFO buffer. */ +#define SWORRST 0x3C /* SWORRST - Reset real time clock. */ +#define SNOP 0x3D /* SNOP - No operation. Returns status byte. */ + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void mrfiRadioInterfaceInit(void); +void mrfiRadioInterfaceWriteReg(uint8_t addr, uint8_t value); +void mrfiRadioInterfaceWriteTxFifo(uint8_t * pWriteData, uint8_t len); +void mrfiRadioInterfaceReadRxFifo(uint8_t * pReadData, uint8_t len); + +uint8_t mrfiRadioInterfaceCmdStrobe(uint8_t addr); +uint8_t mrfiRadioInterfaceReadReg(uint8_t addr); + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/smartrf/CC1101/smartrf_CC1101.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/smartrf/CC1101/smartrf_CC1101.h new file mode 100755 index 0000000..f014b1a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/smartrf/CC1101/smartrf_CC1101.h @@ -0,0 +1,130 @@ +/*************************************************************** + * SmartRF Studio(tm) Export + * + * Radio register settings specifed with C-code + * compatible #define statements. + * + ***************************************************************/ + +#ifndef SMARTRF_CC1101_H +#define SMARTRF_CC1101_H + +// ISM_EU configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 869.524963 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_US configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 905.998993 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +#define SMARTRF_RADIO_CC1101 + +#define SMARTRF_SETTING_FSCTRL1 0x08 +#define SMARTRF_SETTING_FSCTRL0 0x00 +#ifdef ISM_EU + #define SMARTRF_SETTING_FREQ2 0x21 + #define SMARTRF_SETTING_FREQ1 0x71 + #define SMARTRF_SETTING_FREQ0 0x7A +#else + #ifdef ISM_US + // 902MHz (CHANNR=20->906MHz) + #define SMARTRF_SETTING_FREQ2 0x22 + #define SMARTRF_SETTING_FREQ1 0xB1 + #define SMARTRF_SETTING_FREQ0 0x3B + #else + #ifdef ISM_LF + // 433.92MHz + #define SMARTRF_SETTING_FREQ2 0x10 + #define SMARTRF_SETTING_FREQ1 0xB0 + #define SMARTRF_SETTING_FREQ0 0x71 + #else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" + #endif // ISM_LF + #endif // ISM_US +#endif // ISM_EU +#define SMARTRF_SETTING_MDMCFG4 0x7B +#define SMARTRF_SETTING_MDMCFG3 0x83 +#define SMARTRF_SETTING_MDMCFG2 0x13 +#define SMARTRF_SETTING_MDMCFG1 0x22 +#define SMARTRF_SETTING_MDMCFG0 0xF8 +#define SMARTRF_SETTING_CHANNR 0x00 +#define SMARTRF_SETTING_DEVIATN 0x42 +#define SMARTRF_SETTING_FREND1 0xB6 +#define SMARTRF_SETTING_FREND0 0x10 +#define SMARTRF_SETTING_MCSM0 0x18 +#define SMARTRF_SETTING_FOCCFG 0x1D +#define SMARTRF_SETTING_BSCFG 0x1C +#define SMARTRF_SETTING_AGCCTRL2 0xC7 +#define SMARTRF_SETTING_AGCCTRL1 0x00 +#define SMARTRF_SETTING_AGCCTRL0 0xB2 +#define SMARTRF_SETTING_FSCAL3 0xEA +#define SMARTRF_SETTING_FSCAL2 0x2A +#define SMARTRF_SETTING_FSCAL1 0x00 +#define SMARTRF_SETTING_FSCAL0 0x1F +#define SMARTRF_SETTING_FSTEST 0x59 +#define SMARTRF_SETTING_TEST2 0x81 +#define SMARTRF_SETTING_TEST1 0x35 +#define SMARTRF_SETTING_TEST0 0x09 +#define SMARTRF_SETTING_FIFOTHR 0x47 +#define SMARTRF_SETTING_IOCFG2 0x29 +#define SMARTRF_SETTING_IOCFG0D 0x06 +#define SMARTRF_SETTING_PKTCTRL1 0x04 +#define SMARTRF_SETTING_PKTCTRL0 0x05 +#define SMARTRF_SETTING_ADDR 0x00 +#define SMARTRF_SETTING_PKTLEN 0xFF + +#endif // SMARTRF_CC1101_H diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h new file mode 100755 index 0000000..fc6b49e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h @@ -0,0 +1,164 @@ +/*************************************************************** + * SmartRF Studio(tm) Export + * + * Radio register settings specifed with C-code + * compatible #define statements. + * + ***************************************************************/ + +#ifndef SMARTRF_CC430_H +#define SMARTRF_CC430_H + +// [BM] Modified radio settings for 433MHz, 868MHz, 915MHz + +// ISM_LF configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 433.92 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_EU configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 869.524963 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_US configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 905.998993 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +#define SMARTRF_RADIO_CC430 + +#define SMARTRF_SETTING_FSCTRL1 0x08 +#define SMARTRF_SETTING_FSCTRL0 0x00 +#ifdef ISM_EU + // 869.50MHz + #define SMARTRF_SETTING_FREQ2 0x21 + #define SMARTRF_SETTING_FREQ1 0x71 + #define SMARTRF_SETTING_FREQ0 0x7A +#else + #ifdef ISM_US + // 902MHz (CHANNR=20->906MHz) + #define SMARTRF_SETTING_FREQ2 0x22 + #define SMARTRF_SETTING_FREQ1 0xB1 + #define SMARTRF_SETTING_FREQ0 0x3B + #else + #ifdef ISM_LF + // 433.92MHz + #define SMARTRF_SETTING_FREQ2 0x10 + #define SMARTRF_SETTING_FREQ1 0xB0 + #define SMARTRF_SETTING_FREQ0 0x71 + #else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" + #endif // ISM_LF + #endif // ISM_US +#endif // ISM_EU +#define SMARTRF_SETTING_MDMCFG4 0x7B +#define SMARTRF_SETTING_MDMCFG3 0x83 +#define SMARTRF_SETTING_MDMCFG2 0x13 +#define SMARTRF_SETTING_MDMCFG1 0x22 +#define SMARTRF_SETTING_MDMCFG0 0xF8 +#define SMARTRF_SETTING_CHANNR 0x00 +#define SMARTRF_SETTING_DEVIATN 0x42 +#define SMARTRF_SETTING_FREND1 0xB6 +#define SMARTRF_SETTING_FREND0 0x10 +#define SMARTRF_SETTING_MCSM0 0x18 +#define SMARTRF_SETTING_FOCCFG 0x1D +#define SMARTRF_SETTING_BSCFG 0x1C +#define SMARTRF_SETTING_AGCCTRL2 0xC7 +#define SMARTRF_SETTING_AGCCTRL1 0x00 +#define SMARTRF_SETTING_AGCCTRL0 0xB2 +#define SMARTRF_SETTING_FSCAL3 0xEA +#define SMARTRF_SETTING_FSCAL2 0x2A +#define SMARTRF_SETTING_FSCAL1 0x00 +#define SMARTRF_SETTING_FSCAL0 0x1F +#define SMARTRF_SETTING_FSTEST 0x59 +#define SMARTRF_SETTING_TEST2 0x81 +#define SMARTRF_SETTING_TEST1 0x35 +#define SMARTRF_SETTING_TEST0 0x09 +#define SMARTRF_SETTING_FIFOTHR 0x47 +#define SMARTRF_SETTING_IOCFG2 0x29 +#define SMARTRF_SETTING_IOCFG0D 0x06 +#define SMARTRF_SETTING_PKTCTRL1 0x04 +#define SMARTRF_SETTING_PKTCTRL0 0x05 +#define SMARTRF_SETTING_ADDR 0x00 +#define SMARTRF_SETTING_PKTLEN 0xFF + +#endif // SMARTRF_CC430_H diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk.c new file mode 100755 index 0000000..e02c77c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk.c @@ -0,0 +1,1078 @@ +/************************************************************************************************** + Filename: nwk.c + Revised: $Date: 2009-03-11 15:29:07 -0700 (Wed, 11 Mar 2009) $ + Revision: $Revision: 19382 $ + Author $Author: lfriedman $ + + Description: This file supports the SimpliciTI network layer. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "nwk_globals.h" +#include "nwk_QMgmt.h" + +/****************************************************************************** + * MACROS + */ +/************************* NETWORK MANIFEST CONSTANT SANITY CHECKS ****************************/ +#if !defined(ACCESS_POINT) && !defined(RANGE_EXTENDER) && !defined(END_DEVICE) +#error ERROR: No SimpliciTI device type defined +#endif + +#if defined(END_DEVICE) && !defined(RX_POLLS) +#define RX_USER +#endif + +#ifndef MAX_HOPS +#define MAX_HOPS 3 +#elif MAX_HOPS > 4 +#error ERROR: MAX_HOPS must be 4 or fewer +#endif + +#ifndef MAX_APP_PAYLOAD +#error ERROR: MAX_APP_PAYLOAD must be defined +#endif + +#if ( MAX_PAYLOAD < MAX_FREQ_APP_FRAME ) +#error ERROR: Application payload size too small for Frequency frame +#endif + +#if ( MAX_PAYLOAD < MAX_JOIN_APP_FRAME ) +#error ERROR: Application payload size too small for Join frame +#endif + +#if ( MAX_PAYLOAD < MAX_LINK_APP_FRAME ) +#error ERROR: Application payload size too small for Link frame +#endif + +#if ( MAX_PAYLOAD < MAX_MGMT_APP_FRAME ) +#error ERROR: Application payload size too small for Management frame +#endif + +#if ( MAX_PAYLOAD < MAX_SEC_APP_FRAME ) +#error ERROR: Application payload size too small for Security frame +#endif + +#if ( MAX_PAYLOAD < MAX_PING_APP_FRAME ) +#error ERROR: Application payload size too small for Ping frame +#endif + +#if NWK_FREQ_TBL_SIZE < 1 +#error ERROR: NWK_FREQ_TBL_SIZE must be > 0 +#endif + +/************************* END NETWORK MANIFEST CONSTANT SANITY CHECKS ************************/ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ +#define SYS_NUM_CONNECTIONS (NUM_CONNECTIONS+1) + +/* Increment this if the persistentContext_t structure is changed. It will help + * detect the upgrade context: any saved values will have a version with a + * lower number. + */ +#define CONNTABLEINFO_STRUCTURE_VERSION 1 + +#define SIZEOF_NV_OBJ sizeof(sPersistInfo) + +/****************************************************************************** + * TYPEDEFS + */ +/* This structure aggregates eveything necessary to save if we want to restore + * the connection information later. + */ +typedef struct +{ + const uint8_t structureVersion; /* to dectect upgrades... */ + uint8_t numConnections; /* count includes the UUD port/link ID */ +/* The next two are used to detect overlapping port assignments. When _sending_ a + * link frame the local port is assigned from the top down. When sending a _reply_ + * the assignment is bottom up. Overlapping assignments are rejected. That said it + * is extremely unlikely that this will ever happen. If it does the test implemented + * here is overly cautious (it will reject assignments when it needn't). But we leave + * it that way on the assumption that it will never happen anyway. + */ + uint8_t curNextLinkPort; + uint8_t curMaxReplyPort; + linkID_t nextLinkID; +#ifdef ACCESS_POINT + sfInfo_t sSandFContext; +#endif +/* Connection table entries last... */ + connInfo_t connStruct[SYS_NUM_CONNECTIONS]; +} persistentContext_t; + +/****************************************************************************** + * LOCAL VARIABLES + */ + +/* This will be overwritten if we restore the structure from NV for example. + * Note that restoring will not permit overwriting the version element as it + * is declared 'const'. + */ +static persistentContext_t sPersistInfo = {CONNTABLEINFO_STRUCTURE_VERSION}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static uint8_t map_lid2idx(linkID_t, uint8_t *); +static void initializeConnection(connInfo_t *); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_nwkInit + * + * @brief Initialize NWK conext. + * + * input parameters + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_nwkInit(uint8_t (*f)(linkID_t)) +{ + // [BM] Added variable + uint8_t i; + + /* Truly ugly initialization because CCE won't initialize properly. Must + * skip first const element. Yuk. + */ + memset((((uint8_t *)&sPersistInfo)+1), 0x0, (sizeof(sPersistInfo)-1)); + /* OK. The zeroed elements are set. Now go back and do fixups... */ + + sPersistInfo.numConnections = SYS_NUM_CONNECTIONS; + sPersistInfo.curNextLinkPort = SMPL_PORT_USER_MAX; + sPersistInfo.curMaxReplyPort = PORT_BASE_NUMBER; + sPersistInfo.nextLinkID = 1; + + /* initialize globals */ + nwk_globalsInit(); + + /* initialize frame processing */ + nwk_frameInit(f); + + /* initialize queue manager */ + nwk_QInit(); + + /* initialize each network application. */ + nwk_freqInit(); + nwk_pingInit(); + nwk_joinInit(f); + nwk_mgmtInit(); + nwk_linkInit(); + nwk_securityInit(); + + // [BM] Workaround to enable stack restarting + for (i=0; iportTx = 0; + + pCInfo->connState = CONNSTATE_CONNECTED; + pCInfo->thisLinkID = *locLID; + + /* Generate the next Link ID. This isn't foolproof. If the count wraps + * we can end up with confusing duplicates. We can protect aginst using + * one that is already in use but we can't protect against a stale Link ID + * remembered by an application that doesn't know its connection has been + * torn down. The test for 0 will hopefully never be true (indicating a wrap). + */ + (*locLID)++; + + while (!*locLID || (*locLID == SMPL_LINKID_USER_UUD) || map_lid2idx(*locLID, &tmp)) + { + (*locLID)++; + } + + return; +} + + +/****************************************************************************** + * @fn nwk_freeConnection + * + * @brief Return the connection structure to the free pool. Currently + * this routine is only called when a link freame is sent and + * no reply is received so the freeing steps are pretty simple. + * But eventually this will be more complex so this place-holder + * is introduced. + * + * input parameters + * @param pCInfo - pointer to entry to be freed + * + * output parameters + * + * @return None. + */ +void nwk_freeConnection(connInfo_t *pCInfo) +{ +#if NUM_CONNECTIONS > 0 + pCInfo->connState = CONNSTATE_FREE; +#endif +} + +/****************************************************************************** + * @fn nwk_getConnInfo + * + * @brief Return the connection info structure to which the input Link ID maps. + * + * input parameters + * @param port - port for which mapping desired + * + * output parameters + * + * @return pointer to connInfo_t structure found. NULL if no mapping + * found or entry not valid. + */ +connInfo_t *nwk_getConnInfo(linkID_t linkID) +{ + uint8_t idx, rc; + + rc = map_lid2idx(linkID, &idx); + + return (rc && (CONNSTATE_CONNECTED == sPersistInfo.connStruct[idx].connState)) ? &sPersistInfo.connStruct[idx] : (connInfo_t *)0; +} + +/****************************************************************************** + * @fn nwk_isLinkDuplicate + * + * @brief Help determine if the link has already been established.. Defense + * against duplicate link frames. This file owns the data structure + * so the comparison is done here. + * + * input parameters + * @param addr - pointer to address of linker in question + * @param remotePort - remote port number provided by linker + * + * output parameters + * + * @return Returns pointer to connection entry if the address and remote Port + * match an existing entry, otherwise 0. + */ +connInfo_t *nwk_isLinkDuplicate(uint8_t *addr, uint8_t remotePort) +{ +#if NUM_CONNECTIONS > 0 + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + if (!(memcmp(ptr->peerAddr, addr, NET_ADDR_SIZE)) && + (ptr->portTx == remotePort)) + { + return ptr; + } + } + } +#endif + + return (connInfo_t *)NULL; +} + +/****************************************************************************** + * @fn nwk_findAddressMatch + * + * @brief Used to look for an address match in the Connection table. + * Match is based on source address in frame. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns non-zero if a match is found, otherwise 0. + */ +uint8_t nwk_findAddressMatch(mrfiPacket_t *frame) +{ +#if NUM_CONNECTIONS > 0 + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + if (!(memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + return 1; + } + } + } +#endif + + return 0; +} + +#ifdef ACCESS_POINT +/****************************************************************************** + * @fn nwk_getSFInfoPtr + * + * @brief Get pointer to store-and-forward information object kept in the + * NV object aggregate. + * + * input parameters + * + * output parameters + * + * @return Returns pointer to the store-nad-forward object. + */ +sfInfo_t *nwk_getSFInfoPtr(void) +{ + return &sPersistInfo.sSandFContext; +} + +#if defined(AP_IS_DATA_HUB) +/*************************************************************************************** + * @fn nwk_saveJoinedDevice + * + * @brief Save the address of a joining device on the Connection Table expecting + * a Link frame to follow. Only for when AP is a data hub. We want to + * use the space already allocated for a connection able entry instead + * of having redundant arrays for alread-joined devices in the data hub + * case. + * + * input parameters + * @param frame - pointer to frame containing address or joining device. + * + * output parameters + * + * @return Returns non-zero if this is a new device and it is saved. Returns + * 0 if device already there or there is no room in the Connection + * Table. + */ +uint8_t nwk_saveJoinedDevice(mrfiPacket_t *frame) +{ + uint8_t i; + connInfo_t *avail = 0; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState == CONNSTATE_CONNECTED) || (ptr->connState == CONNSTATE_JOINED)) + { + if (!memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + return 0; + } + } + else + { + avail = ptr; + } + } + + if (!avail) + { + return 0; + } + + avail->connState = CONNSTATE_JOINED; + memcpy(avail->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + return 1; +} + +/*********************************************************************************** + * @fn nwk_findAlreadyJoined + * + * @brief Used when AP is a data hub to look for an address match in the + * Connection table for a device that is already enterd in the joined + * state. This means that the Connection Table resource is already + * allocated so the link-listen doesn't have to do it again. Match is + * based on source address in frame. Thsi shoudl only be called from + * the Link-listen context during the link frame reply. + * + * If found the Connection Table entry is initialized as if it were + * found using the nwk_getNextConnection() method. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns pointer to Connection Table entry if match is found, otherwise + * 0. This call will only fail if the Connection Table was full when the + * device tried to join initially. + */ +connInfo_t *nwk_findAlreadyJoined(mrfiPacket_t *frame) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + /* Is this it? */ + if (!(memcmp(&ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + /* Yes. Initilize tabel entry and return the pointer. */ + initializeConnection(ptr); + return ptr; + } + } + } + + /* Nothing found... */ + return (connInfo_t *)NULL; +} +#endif /* AP_IS_DATA_HUB */ +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_checkConnInfo + * + * @brief Do a sanity/validity check on the connection info + * + * input parameters + * @param ptr - pointer to a valid connection info structure to validate + * @param which - Tx or Rx port checked + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_checkConnInfo(connInfo_t *ptr, uint8_t which) +{ + uint8_t port; + + /* make sure port isn't null and that the entry is active */ + port = (CHK_RX == which) ? ptr->portRx : ptr->portTx; + if (!port || (CONNSTATE_FREE == ptr->connState)) + { + return SMPL_BAD_PARAM; + } + + /* validate port number */ + if (port < PORT_BASE_NUMBER) + { + return SMPL_BAD_PARAM; + } + + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_isConnectionValid + * + * @brief Do a sanity/validity check on the frame target address by + * validating frame against connection info + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * @param lid - link ID of found connection + * + * @return 0 if connection specified in frame is not valid, otherwise non-zero. + */ +uint8_t nwk_isConnectionValid(mrfiPacket_t *frame, linkID_t *lid) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + uint8_t port = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_PORT_OS); + + for (i=0; iconnState) + { + /* check port first since we're done if the port is the user bcast port. */ + if (port == ptr->portRx) + { + /* yep...ports match. */ + if ((SMPL_PORT_USER_BCAST == port) || !(memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + uint8_t rc = 1; + + /* we're done. */ + *lid = ptr->thisLinkID; +#ifdef APP_AUTO_ACK + /* can't ack the broadcast port... */ + if (!(SMPL_PORT_USER_BCAST == port)) + { + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_ACK_REQ)) + { + /* Ack requested. Send ack now */ + nwk_sendAckReply(frame, ptr->portTx); + } + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_ACK_RPLY)) + { + /* This is a reply. Signal that it was received by resetting the + * saved transaction ID in the connection object if they match. The + * main thread is polling this value. The setting here is in the + * Rx ISR thread. + */ + if (ptr->ackTID == GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS)) + { + ptr->ackTID = 0; + } + /* This causes the frame to be dropped. All ack frames are + * dropped. + */ + rc = 0; + } + } +#endif /* APP_AUTO_ACK */ + /* Unconditionally kill the reply delay semaphore. This used to be done + * unconditionally in the calling routine. + */ + MRFI_PostKillSem(); + return rc; + } + } + } + } + + /* no matches */ + return 0; +} + +/****************************************************************************** + * @fn nwk_allocateLocalRxPort + * + * @brief Allocate a local port on which to receive frames from a peer. + * + * Allocation differs depending on whether the allocation is for + * a link reply frame or a link frame. In the former case we + * know the address of the peer so we can ensure allocating a + * unique port number for that address. The same port number can be + * used mulitple times for distinct peers. Allocations are done from + * the bottom of the namespace upward. + * + * If allocation is for a link frame we do not yet know the peer + * address so we must ensure the port number is unique now. + * Allocations are done from the top of the namespace downward. + * + * The two allocation methods track the extreme values used in each + * case to detect overlap, i.e., exhausted namespace. This can only + * happen if the number of connections supported is greater than the + * total namespace available. + * + * input parameters + * @param which - Sending a link frame or a link reply frame + * @param newPtr - pointer to connection info structure to be populated + * + * output parameters + * @param newPtr->portRx - element is populated with port number. + * + * @return Non-zero if port number assigned. 0 if no port available. + */ +uint8_t nwk_allocateLocalRxPort(uint8_t which, connInfo_t *newPtr) +{ +#if NUM_CONNECTIONS > 0 + uint8_t num, i; + uint8_t marker[NUM_CONNECTIONS]; + connInfo_t *ptr = sPersistInfo.connStruct; + + memset(&marker, 0x0, sizeof(marker)); + + for (i=0; iconnState) && (ptr->portRx <= SMPL_PORT_USER_MAX)) + { + if (LINK_SEND == which) + { + if (ptr->portRx > sPersistInfo.curNextLinkPort) + { + marker[SMPL_PORT_USER_MAX - ptr->portRx] = 1; + } + } + else if (!memcmp(ptr->peerAddr, newPtr->peerAddr, NET_ADDR_SIZE)) + { + marker[ptr->portRx - PORT_BASE_NUMBER] = 1; + } + } + } + + num = 0; + for (i=0; i sPersistInfo.curMaxReplyPort) + { + /* remember maximum port number used */ + sPersistInfo.curMaxReplyPort = num; + } + } + else + { + /* the port number we need has already been used in the other context. It may or + * may not have been used for the same address but we don't bother to check...we + * just reject the asignment. This is the overly cautious part but is extermely + * unlikely to ever occur. + */ + num = 0; + } + } + else + { + /* if the number we have doesn't overlap the assignment of ports used + * for sending link frame replies, use it. + */ + if (num >= sPersistInfo.curMaxReplyPort) + { + if (num == sPersistInfo.curNextLinkPort) + { + sPersistInfo.curNextLinkPort--; + } + } + else + { + /* the port number we need has already been used in the other context. It may or + * may not have been used for the same address but we don't bother to check...we + * just reject the asignment. This is the overly cautious part but is extermely + * unlikely to ever occur. + */ + num = 0; + } + } + + newPtr->portRx = num; + + return num; +#else + return 0; +#endif /* NUM_CONNECTIONS > 0 */ + +} + +/******************************************************************************* + * @fn nwk_isValidReply + * + * @brief Examine a frame to see if it is a valid reply when compared with + * expected parameters. + * + * input parameters + * @param frame - pointer to frmae being examined + * @param tid - expected transaction ID in application payload + * @param infoOffset - offset to payload information containing reply hint + * @param tidOffset - offset to transaction ID in payload + * + * output parameters + * + * @return reply category: + * SMPL_NOT_REPLY: not a reply + * SMPL_MY_REPLY : a reply that matches input parameters + * SMPL_A_REPLY : a reply but does not match input parameters + */ +uint8_t nwk_isValidReply(mrfiPacket_t *frame, uint8_t tid, uint8_t infoOffset, uint8_t tidOffset) +{ + uint8_t rc = SMPL_NOT_REPLY; + + if ((*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+infoOffset) & NWK_APP_REPLY_BIT)) + { + if ((*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+tidOffset) == tid) && + !memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + rc = SMPL_MY_REPLY; + } + else + { + rc = SMPL_A_REPLY; + } + } + + return rc; +} + +/****************************************************************************** + * @fn map_lid2idx + * + * @brief Map link ID to index into connection table. + * + * input parameters + * @param lid - Link ID to be matched + * + * output parameters + * @param idx - populated with index into connection table + * + * @return Non-zero if Link ID found and output is valid else 0. + */ +static uint8_t map_lid2idx(linkID_t lid, uint8_t *idx) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) && (ptr->thisLinkID == lid)) + { + *idx = i; + return 1; + } + } + + return 0; +} + +/****************************************************************************** + * @fn nwk_findPeer + * + * @brief Find connection entry for a peer + * + * input parameters + * @param peerAddr - address of peer + * @param peerPort - port on which this device was sending to peer. + * + * output parameters + * + * @return Pointer to matching connection table entry else 0. + */ +connInfo_t *nwk_findPeer(addr_t *peerAddr, uint8_t peerPort) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + if (!memcmp(peerAddr, ptr->peerAddr, NET_ADDR_SIZE)) + { + if (peerPort == ptr->portTx) + { + return ptr; + } + } + } + } + + return (connInfo_t *)NULL; +} + +/****************************************************************************** + * @fn nwk_checkAppMsgTID + * + * @brief Compare received TID to last-seen TID to decide whether the + * received message is a duplicate or we missed some. + * + * input parameters + * @param lastTID - last-seen TID + * @param appMsgTID - TID from current application payload. + * + * output parameters + * + * @return Returns zero if message with supplied TID should be discarded. + * Otherwise returns non-zero. In this case the message should be + * processed. The last-seen TID should be updated with the current + * application payload TID. + * + */ +uint8_t nwk_checkAppMsgTID(appPTid_t lastTID, appPTid_t appMsgTID) +{ + uint8_t rc = 0; + + /* If the values are equal this is a duplicate. We're done. */ + if (lastTID != appMsgTID) + { + /* Is the new TID bigger? */ + if (appMsgTID > lastTID) + { + /* In this case the current payload is OK unless we've received a late + * (duplicate) message that occurred just before the TID wrapped. This is + * considered a duplicate and we should discard it. + */ + if (!(DUP_TID_AFTER_WRAP(lastTID, appMsgTID))) + { + rc = 1; + } + } + else + { + /* New TID is smaller. Accept the payload if this is the wrap case or we missed + * the specific wrap frame but are still within the range in which we assume + * we missed it. Otherwise is a genuine late frame so we should ignore it. + */ + if (CHECK_TID_WRAP(lastTID, appMsgTID)) + { + rc = 1; + } + } + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_getNumObjectFromMsg + * + * @brief Get a numeric object from a message buffer. Take care of + * alignment and endianess issues. + * + * input parameters + * @param src - pointer to object location in message buffer + * @param objSize - size of numeric object + * + * output parameters + * @param dest - pointer to numeric type variable receiving the object + * contains aligned number in correct endian order on return. + * + * @return void. There is no warning if there is no case for the supplied + * object size. A simple copy is then done. Alignment is + * guaranteed only for object size cases defined (and + * vacuously size 1). + * + */ +void nwk_getNumObjectFromMsg(void *src, void *dest, uint8_t objSize) +{ + /* Take care of alignment */ + memmove(dest, src, objSize); + + /* Take care of endianess */ + switch(objSize) + { + case 2: + *((uint16_t *)dest) = ntohs(*((uint16_t *)dest)); + break; + + case 4: + *((uint32_t *)dest) = ntohl(*((uint32_t *)dest)); + break; + } + + return; +} + +/****************************************************************************** + * @fn nwk_putNumObjectIntoMsg + * + * @brief Put a numeric object into a message buffer. Take care of + * alignment and endianess issues. + * + * input parameters + * @param src - pointer to numeric type variable providing the object + * @param objSize - size of numeric object. Fuction works for object size 1. + * + * output parameters + * @param dest - pointer to object location in message buffer where the + * correct endian order representation will be placed. + * + * @return void. There is no warning if there is no case for the supplied + * object size. A simple copy is then done. + * + */ +void nwk_putNumObjectIntoMsg(void *src, void *dest, uint8_t objSize) +{ + + uint8_t *ptr; + uint16_t u16; + uint32_t u32; + + /* Take care of endianess */ + switch(objSize) + { + case 1: + ptr = (uint8_t *)src; + break; + + case 2: + u16 = htons(*((uint16_t *)src)); + ptr = (uint8_t *)&u16; + break; + + case 4: + u32 = htonl(*((uint32_t *)src)); + ptr = (uint8_t *)&u32; + break; + + default: + ptr = (uint8_t *)src; + break; + } + + /* Take care of alignment */ + memmove(dest, ptr, objSize); + + return; +} +/****************************************************************************** + * @fn nwk_NVObj + * + * @brief GET and SET support for NV object (connection context). + * + * input parameters + * @param action - GET or SET + * @param val - (GET/SET) pointer to NV IOCTL object. + * (SET) NV length and version values to be used for sanity + * checks. + * + * output parameters + * @param val - (GET) Version number of NV object, size of NV object and + * pointer to the connection context memory. + * - (SET) Pointer to the connection context memory. + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Object version or size do not conform on a SET call + * or illegal action specified. + */ +smplStatus_t nwk_NVObj(ioctlAction_t action, ioctlNVObj_t *val) +{ +#ifdef NVOBJECT_SUPPORT + smplStatus_t rc = SMPL_SUCCESS; + + if (IOCTL_ACT_GET == action) + { + /* Populate helper objects */ + val->objLen = SIZEOF_NV_OBJ; + val->objVersion = sPersistInfo.structureVersion; + /* Set pointer to connection context if address of pointer is not null */ + if (val->objPtr) + { + *(val->objPtr) = (uint8_t *)&sPersistInfo; + } + } + else + { + rc = SMPL_BAD_PARAM; + } + + return rc; +#else /* NVOBJECT_SUPPORT */ + return SMPL_BAD_PARAM; +#endif +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk.h new file mode 100755 index 0000000..6009f38 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk.h @@ -0,0 +1,159 @@ +/************************************************************************************************** + Filename: nwk.h + Revised: $Date: 2008-12-01 11:58:33 -0800 (Mon, 01 Dec 2008) $ + Revision: $Revision: 18551 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI network layer. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_H +#define NWK_H + + +/* well known ports*/ +#define SMPL_PORT_PING 0x01 +#define SMPL_PORT_LINK 0x02 +#define SMPL_PORT_JOIN 0x03 +#define SMPL_PORT_SECURITY 0x04 +#define SMPL_PORT_FREQ 0x05 +#define SMPL_PORT_MGMT 0x06 + +#define SMPL_PORT_NWK_BCAST 0x1F +#define SMPL_PORT_USER_BCAST 0x3F + +/* Unconnected User Datagram Link ID */ +#define SMPL_LINKID_USER_UUD ((linkID_t) ~0) + +#define PORT_BASE_NUMBER 0x20 + +/* Reserve the top of the User port namespace below the broadcast + * address for static allocation. + */ +#define PORT_USER_STATIC_NUM 1 +#define SMPL_PORT_STATIC_MAX 0x3E +#define SMPL_PORT_USER_MAX (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM) + + +/* to check connection info sanity */ +#define CHK_RX 0 +#define CHK_TX 1 + +/* return types for validating a reply frame */ +#define SMPL_MY_REPLY 0 +#define SMPL_A_REPLY 1 +#define SMPL_NOT_REPLY 2 + +/* when allocating local Rx port it depends on whether the allocation + * is being done as a result of a link or a link reply + */ +#define LINK_SEND 1 +#define LINK_REPLY 2 + +#define CONNSTATE_FREE (0x00) +#define CONNSTATE_JOINED (0x01) +#define CONNSTATE_CONNECTED (0x02) + +typedef struct +{ + volatile uint8_t connState; + uint8_t hops2target; +#ifdef APP_AUTO_ACK + volatile uint8_t ackTID; +#endif + uint8_t peerAddr[NET_ADDR_SIZE]; + rxMetrics_t sigInfo; + uint8_t portRx; + uint8_t portTx; + linkID_t thisLinkID; +#ifdef SMPL_SECURE + uint32_t connTxCTR; + uint32_t connRxCTR; +#endif +} connInfo_t; + +/**************************************************************************************** + * Application Payload TID support + * + * Sometimes the receiving application uses a payload TID to determine if either it + * missed frames (received TID > (last-seen TID+1)) or is seeing a duplicate (received + * TID <= last-seen TID). Typically the TID simply increments for each successive frame. + * But when the count wraps there is a problem. The received TID should always be one + * more than the last TID. If it's equal, it's a duplicate. If it's less it's late. If + * it's one more it's the one we expect. If it's more than 1 more then we missed frames. + * Simple increments work for the wrap arithmetically. If the received TID is 0 and the last + * seen ID is the biggest number in the world -- 0xFF... depending on type we can detect + * the wrap. But if the receiver misses the 0 TID value for any reason or the biggest + * number in the world TID is missed then susbequent testing for missed or duplicate + * frames can get confused. We resolve this by allowing some leeway in the wrap testing. + * this testing is assisted by the following macros. Setting TID_VALID_WINDOW to 0 + * will enforce a no leniency policy. In this case you'd better not miss either the + * biggest number or the 0. The CHECK_TID_WRAP macro is only needed if the received + * TID is less than the last-seen TID. The DUP_TID_AFTER_WRAP macro is only needed if the + * received TID is greater than 1 more than the last-seen TID. + ***************************************************************************************/ +#define MAX_APT ((appPTid_t)~0) /* max value of application payload TID type */ +#define TID_VALID_WINDOW 2 /* window around max and 0 */ + +#define CHECK_TID_WRAP(lastTID, newTID) ((lastTID >= (MAX_APT - TID_VALID_WINDOW)) && \ + (newTID <= TID_VALID_WINDOW) \ + ) +#define DUP_TID_AFTER_WRAP(lastTID, newTID) ((newTID >= (MAX_APT - TID_VALID_WINDOW)) && \ + (lastTID <= TID_VALID_WINDOW) \ + ) + +/* prototypes */ +smplStatus_t nwk_nwkInit(uint8_t (*)(linkID_t)); +connInfo_t *nwk_getNextConnection(void); +void nwk_freeConnection(connInfo_t *); +uint8_t nwk_getNextClientPort(void); +connInfo_t *nwk_getConnInfo(linkID_t port); +connInfo_t *nwk_isLinkDuplicate(uint8_t *, uint8_t); +uint8_t nwk_findAddressMatch(mrfiPacket_t *); +smplStatus_t nwk_checkConnInfo(connInfo_t *, uint8_t); +uint8_t nwk_isConnectionValid(mrfiPacket_t *, linkID_t *); +uint8_t nwk_allocateLocalRxPort(uint8_t, connInfo_t *); +uint8_t nwk_isValidReply(mrfiPacket_t *, uint8_t, uint8_t, uint8_t); +connInfo_t *nwk_findPeer(addr_t *, uint8_t); +smplStatus_t nwk_NVObj(ioctlAction_t, ioctlNVObj_t *); + + +uint8_t nwk_checkAppMsgTID(appPTid_t, appPTid_t); +void nwk_getNumObjectFromMsg(void *, void *, uint8_t); +void nwk_putNumObjectIntoMsg(void *, void *, uint8_t); +#ifdef ACCESS_POINT +sfInfo_t *nwk_getSFInfoPtr(void); +#ifdef AP_IS_DATA_HUB +uint8_t nwk_saveJoinedDevice(mrfiPacket_t *); +connInfo_t *nwk_findAlreadyJoined(mrfiPacket_t *); +#endif +#endif + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.c new file mode 100755 index 0000000..4cb34ea --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.c @@ -0,0 +1,417 @@ +/************************************************************************************************** + Filename: nwk_QMgmt.c + Revised: $Date: 2009-03-10 17:01:56 -0700 (Tue, 10 Mar 2009) $ + Revision: $Revision: 19372 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI input and output frame queues + + Copyright 2007-2008 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk.h" +#include "nwk_frame.h" +#include "nwk_QMgmt.h" +#include "nwk_mgmt.h" /* need offsets for poll frames */ + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +#if SIZE_INFRAME_Q > 0 +static frameInfo_t sInFrameQ[SIZE_INFRAME_Q]; +#else +static frameInfo_t *sInFrameQ = NULL; +#endif /* SIZE_INFRAME_Q > 0 */ + +static frameInfo_t sOutFrameQ[SIZE_OUTFRAME_Q]; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** +* @fn nwk_QInit +* +* @brief Initialize the input and output frame queues to hold no packets. +* +* input parameters +* +* output parameters +* +* @return void +*/ +void nwk_QInit(void) +{ +#if SIZE_INFRAME_Q > 0 + memset(sInFrameQ, 0, sizeof(sInFrameQ)); +#endif // SIZE_INFRAME_Q > 0 + memset(sOutFrameQ, 0, sizeof(sOutFrameQ)); +} + +/****************************************************************************** + * @fn nwk_QfindSlot + * + * @brief Finds a slot to use to retrieve the frame from the radio. It + * uses a LRU cast-out scheme. It is possible that this routine + * finds no slot. This can happen if the queue is of size 1 or 2 + * and the Rx interrupt occurs during a retrieval call from an + * application. There are meta-states for frames as the application + * looks for the oldest frame on the port being requested. + * + * This routine is running in interrupt context. + * + * input parameters + * @param which - INQ or OUTQ to search + * + * output parameters + * + * @return Pointer to oldest available frame in the queue + */ +frameInfo_t *nwk_QfindSlot(uint8_t which) +{ + frameInfo_t *pFI, *oldest= 0, *newFI = 0; + uint8_t i, num, newOrder = 0, orderTest; + + if (INQ == which) + { + pFI = sInFrameQ; + num = SIZE_INFRAME_Q; + } + else + { + pFI = sOutFrameQ; + num = SIZE_OUTFRAME_Q; + } + + orderTest = num + 1; + + for (i=0; ifi_usage != FI_AVAILABLE) + { + if (INQ == which) /* TODO: do cast-out for Tx as well */ + { + + /* need to know the number of occupied slots so we know the age value + * for the unoccupied slot (if there is one). + */ + newOrder++; + + /* make sure nwk_retrieveFrame() is not processing this frame */ + if (FI_INUSE_TRANSITION == pFI->fi_usage) + { + continue; + } + /* is this frame older than any we've seen? */ + if (orderTest > pFI->orderStamp) + { + /* yes. */ + oldest = pFI; + orderTest = pFI->orderStamp; + } + } + } + else + { + if (OUTQ == which) /* TODO: do cast-out for Tx as well */ + { + return pFI; + } + newFI = pFI; + } + } + + /* did we find anything? */ + if (!newFI) + { + /* queue was full. cast-out happens here...unless... */ + if (!oldest) + { + /* This can happen if the queue is only of size 1 or 2 and all + * the frames are in transition when the Rx interrupt occurs. + */ + return (frameInfo_t *)0; + } + newFI = oldest; + nwk_QadjustOrder(which, newFI->orderStamp); + newFI->orderStamp = i; + } + else + { + /* mark the available slot. */ + newFI->orderStamp = ++newOrder; + } + + return newFI; +} + +/****************************************************************************** + * @fn nwk_QadjustOrder + * + * @brief Adjusts the age of everyone in the queue newer than the frame + * being removed. + * + * input parameters + * @param which - INQ or OUTQ to adjust + * @param stamp - value of frame being removed + * + * output parameters + * + * @return void + */ +void nwk_QadjustOrder(uint8_t which, uint8_t stamp) +{ + frameInfo_t *pFI; + uint8_t i, num; + bspIState_t intState; + + if (INQ == which) + { + pFI = sInFrameQ; + num = SIZE_INFRAME_Q; + } + else + { +/* pFI = sOutFrameQ; */ +/* num = SIZE_OUTFRAME_Q; */ + return; + } + + BSP_ENTER_CRITICAL_SECTION(intState); + + for (i=0; ifi_usage != FI_AVAILABLE) && (pFI->orderStamp > stamp)) + { + pFI->orderStamp--; + } + } + + BSP_EXIT_CRITICAL_SECTION(intState); + + return; +} + +/****************************************************************************** + * @fn nwk_QfindOldest + * + * @brief Look through frame queue and find the oldest available frame + * in the context in question. Supports connection-based (user), + * non-connection based (NWK applications), and the special case + * of store-and-forward. + * + * input parameters + * @param which - INQ or OUTQ to adjust + * @param rcvContext - context information for finding the oldest + * @param usage - normal usage or store-and-forward usage + * + * output parameters + * + * @return Pointer to frame that is the oldsest on the requested port, or + * 0 if there are none. + */ +frameInfo_t *nwk_QfindOldest(uint8_t which, rcvContext_t *rcv, uint8_t fi_usage) +{ + uint8_t i, oldest, num, port; + uint8_t uType, addr12Compare; + bspIState_t intState; + frameInfo_t *fPtr = 0, *wPtr; + connInfo_t *pCInfo = 0; + uint8_t *pAddr1, *pAddr2, *pAddr3 = 0; + + if (INQ == which) + { + wPtr = sInFrameQ; + num = SIZE_INFRAME_Q; + oldest = SIZE_INFRAME_Q+1; + } + else + { +/* pFI = sOutFrameQ; */ +/* num = SIZE_OUTFRAME_Q; */ + return 0; + } + + if (RCV_APP_LID == rcv->type) + { + pCInfo = nwk_getConnInfo(rcv->t.lid); + if (!pCInfo) + { + return (frameInfo_t *)0; + } + port = pCInfo->portRx; + pAddr2 = pCInfo->peerAddr; + } + else if (RCV_NWK_PORT == rcv->type) + { + port = rcv->t.port; + } +#ifdef ACCESS_POINT + else if (RCV_RAW_POLL_FRAME == rcv->type) + { + port = *(MRFI_P_PAYLOAD(rcv->t.pkt)+F_APP_PAYLOAD_OS+M_POLL_PORT_OS); + pAddr2 = MRFI_P_SRC_ADDR(rcv->t.pkt); + pAddr3 = MRFI_P_PAYLOAD(rcv->t.pkt)+F_APP_PAYLOAD_OS+M_POLL_ADDR_OS; + } +#endif + else + { + return (frameInfo_t *)0; + } + + uType = (USAGE_NORMAL == fi_usage) ? FI_INUSE_UNTIL_DEL : FI_INUSE_UNTIL_FWD; + + for (i=0; ifi_usage) + { + wPtr->fi_usage = FI_INUSE_TRANSITION; + + BSP_EXIT_CRITICAL_SECTION(intState); /* release hold */ + /* message sent to this device? */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&wPtr->mrfiPkt), F_PORT_OS) == port) + { + /* Port matches. If the port of interest is a NWK applicaiton we're a + * match...the NWK applications are not connection-based. If it is a + * NWK application we need to check the source address for disambiguation. + * Also need to check source address if it's a raw frame lookup (S&F frame) + */ + if (RCV_APP_LID == rcv->type) + { + if (SMPL_PORT_USER_BCAST == port) + { + /* guarantee a match... */ + pAddr1 = pCInfo->peerAddr; + } + else + { + pAddr1 = MRFI_P_SRC_ADDR(&wPtr->mrfiPkt); + } + } +#ifdef ACCESS_POINT + else if (RCV_RAW_POLL_FRAME == rcv->type) + { + pAddr1 = MRFI_P_DST_ADDR(&wPtr->mrfiPkt); + } +#endif + + addr12Compare = memcmp(pAddr1, pAddr2, NET_ADDR_SIZE); + if ( (RCV_NWK_PORT == rcv->type) || + (!pAddr3 && !addr12Compare) || + (pAddr3 && !memcmp(pAddr3, MRFI_P_SRC_ADDR(&wPtr->mrfiPkt), NET_ADDR_SIZE)) + ) + { + if (wPtr->orderStamp < oldest) + { + if (fPtr) + { + /* restore previous oldest one */ + fPtr->fi_usage = uType; + } + oldest = wPtr->orderStamp; + fPtr = wPtr; + continue; + } + else + { + /* not oldest. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + /* not a match. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + /* wrong port. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + BSP_EXIT_CRITICAL_SECTION(intState); + } + } + + return fPtr; +} + +/****************************************************************************** + * @fn nwk_getQ + * + * @brief Get location of teh specified frame queue. + * + * input parameters + * @param which - INQ or OUTQ to get + * + * output parameters + * + * @return Pointer to frame queue + */ +frameInfo_t *nwk_getQ(uint8_t which) +{ + return (INQ == which) ? sInFrameQ : sOutFrameQ; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.h new file mode 100755 index 0000000..aa5535b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_QMgmt.h @@ -0,0 +1,53 @@ +/************************************************************************************************** + Filename: nwk_QMgmt.h + Revised: $Date: 2009-01-17 15:14:16 -0800 (Sat, 17 Jan 2009) $ + Revision: $Revision: 18788 $ + Author: $Author: rlord $ + + Description: This header file supports the SimpliciTI input and output frame queues. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_QMGMT_H +#define NWK_QMGMT_H + + +#define INQ 1 +#define OUTQ 2 + +#define USAGE_NORMAL 1 +#define USAGE_FWD 2 + +/* prototypes */ +void nwk_QInit(void); +frameInfo_t *nwk_QfindSlot(uint8_t); +void nwk_QadjustOrder(uint8_t, uint8_t); +frameInfo_t *nwk_QfindOldest(uint8_t, rcvContext_t *, uint8_t); +frameInfo_t *nwk_getQ(uint8_t); + +#endif /* NWK_QMGMT_H */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_api.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_api.c new file mode 100755 index 0000000..da5c0b7 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_api.c @@ -0,0 +1,858 @@ +/************************************************************************************************** + Filename: nwk_api.c + Revised: $Date: 2009-01-28 18:27:38 -0800 (Wed, 28 Jan 2009) $ + Revision: $Revision: 18875 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI appliction layer API. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "mrfi.h" +#include "nwk_globals.h" +#include "nwk_freq.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/* These defines are in support an application listening for a link frame to + * terminate after some amount of time. The intention is that this guard be + * the exception. The intention of the SimpliciTI design is that the + * temporal contiguity between the listen and the reception of the link frame + * from the peer be very tight. The SMPL_LinkListen() should be termninated + * by the reception of the link frame. But in case it does not receive the frame + * the support below allows intervention by the application. + */ + +/* The intention is for user to modify just the following single value */ +#define LINKLISTEN_MILLISECONDS_2_WAIT (5000) + +#define LINKLISTEN_POLL_PERIOD_MS (10) +#define LINKLISTEN_POLL_COUNT ( (LINKLISTEN_MILLISECONDS_2_WAIT) / (LINKLISTEN_POLL_PERIOD_MS) ) + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +// [BM] Workaround to enable multiple stack restarts +// static uint8_t sInit_done = 0; +uint8_t sInit_done = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static uint8_t ioctlPreInitAccessIsOK(ioctlObject_t); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/*********************************************************************************** + * @fn SMPL_Init + * + * @brief Initialize the SimpliciTI stack. + * + * input parameters + * @param f - Pointer to call back function. Function called by NWK when + * user application frame received. The callback is done in the + * ISR thread. Argument is Link ID associated with frame. Function + * returns 0 if frame is to be kept by NWK, otherwise 1. Frame + * should be kept if application will do a SMPL_Receive() in the + * user thread (recommended). Pointer may be NULL. + * + * output parameters + * + * @return Status of operation: + * SMPL_SUCCESS + * SMPL_NO_JOIN No Join reply. AP possibly not yet up. + * SMPL_NO_CHANNEL Only if Frequency Agility enabled. Channel scan + * failed. AP possibly not yet up. + */ +smplStatus_t SMPL_Init(uint8_t (*f)(linkID_t)) +{ + smplStatus_t rc; + + if (!sInit_done) + { + /* set up radio. */ + MRFI_Init(); + + /* initialize network */ + if ((rc=nwk_nwkInit(f)) != SMPL_SUCCESS) + { + return rc; + } + + MRFI_WakeUp(); +#if defined( FREQUENCY_AGILITY ) + { + freqEntry_t chan; + + chan.logicalChan = 0; + /* ok to set default channel explicitly now that MRFI initialized. */ + nwk_setChannel(&chan); + } +#endif + /* don't turn Rx on if we're an end device that isn't always on. */ +#if !defined( END_DEVICE ) + MRFI_RxOn(); +#endif + +#if defined( END_DEVICE ) + /* All except End Devices are in promiscuous mode */ + MRFI_SetRxAddrFilter((uint8_t *)nwk_getMyAddress()); + MRFI_EnableRxAddrFilter(); +#endif + } + sInit_done = 1; + + /* Join. if no AP or Join fails that status is returned. */ + rc = nwk_join(); + + return rc; +} + +/****************************************************************************** + * @fn SMPL_LinkListen + * + * @brief Listen for a link frame from a 'client' device. + * + * input parameters + * + * output parameters + * @param linkID - pointer to Link ID to be used by application to + * read and write to the linked peer. + * + * @return status of operation. + * SMPL_SUCCESS + * SMPL_TIMEOUT No link frame received during listen interval. +* Interval set in #defines above. linkID not valid. + * + */ + +smplStatus_t SMPL_LinkListen(linkID_t *linkID) +{ + uint8_t radioState = MRFI_GetRadioState(); + uint16_t i; + linkID_t locLinkID; + + /* Set the context. We want to reject any link frames received if + * we're not listening. For example if we're an AP we are in + * promiscuous mode and we'll see any broadcast link frames. + */ + nwk_setListenContext(LINK_LISTEN_ON); + + NWK_CHECK_FOR_SETRX(radioState); + + for (i=0; i MAX_APP_PAYLOAD)) + { + return rc; + } + + /* Build an outgoing message frame destined for the port from the + * connection info using the destination address also from the + * connection info. + */ + if (SMPL_TXOPTION_NONE == options) + { + pFrameInfo = nwk_buildFrame(pCInfo->portTx, msg, len, pCInfo->hops2target); + } +#if defined(APP_AUTO_ACK) + else if (options & SMPL_TXOPTION_ACKREQ) + { + if (SMPL_LINKID_USER_UUD != lid) + { + pFrameInfo = nwk_buildAckReqFrame(pCInfo->portTx, msg, len, pCInfo->hops2target, &pCInfo->ackTID); + ackreq = 1; + } + else + { + /* can't request an ack on the UUD link ID */ + return SMPL_BAD_PARAM; + } + } +#endif /* APP_AUTO_ACK */ + else + { + return SMPL_BAD_PARAM; + } + + if (!pFrameInfo) + { + return SMPL_NOMEM; + } + memcpy(MRFI_P_DST_ADDR(&pFrameInfo->mrfiPkt), pCInfo->peerAddr, NET_ADDR_SIZE); + +#if defined(SMPL_SECURE) + { + uint32_t *pUL = 0; + + if (pCInfo->thisLinkID != SMPL_LINKID_USER_UUD) + { + pUL = &pCInfo->connTxCTR; + } + nwk_setSecureFrame(&pFrameInfo->mrfiPkt, len, pUL); + } +#endif /* SMPL_SECURE */ + +#if defined(ACCESS_POINT) + /* If we are an AP trying to send to a polling device, don't do it. + * See if the target is a store-and-forward client. + */ + if (nwk_isSandFClient(MRFI_P_DST_ADDR(&pFrameInfo->mrfiPkt), &loc)) + { + pFrameInfo->fi_usage = FI_INUSE_UNTIL_FWD; + return SMPL_SUCCESS; + } + else +#endif /* ACCESS_POINT */ + { + rc = nwk_sendFrame(pFrameInfo, MRFI_TX_TYPE_CCA); + } + +#if !defined(APP_AUTO_ACK) + /* save a little code space with this #if */ + (void) ackreq; /* keep compiler happy */ + return rc; +#else + /* we're done if the send failed or no ack requested. */ + if (SMPL_SUCCESS != rc || !ackreq) + { + return rc; + } + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + { + bspIState_t intState; + + /* If the saved TID hasn't been reset then we never got the ack. */ + BSP_ENTER_CRITICAL_SECTION(intState); + if (pCInfo->ackTID) + { + pCInfo->ackTID = 0; + rc = SMPL_NO_ACK; + } + BSP_EXIT_CRITICAL_SECTION(intState); + } + + return rc; +#endif /* APP_AUTO_ACK */ +} + +/************************************************************************************** + * @fn SMPL_Receive + * + * @brief Receive a message from a peer application. + * + * input parameters + * @param lid - Link ID (port) from application + * + * + * output parameters + * @param msg - pointer to where received message should be copied. + * buffer should be of size == MAX_APP_PAYLOAD + * @param len - pointer to receive length of received message + * + * @return Status of operation. + * Caller should not use the value returned in 'len' to decide + * whether there is a frame or not. It could be useful to the + * Caller to distinguish between no frame and a frame with no data. + * For example, in the polling case a frame with no application payload + * is the way the AP conveys that there are no frames waiting. + * + * SMPL_SUCCESS + * + * SMPL_BAD_PARAM No valid Connection Table entry for Link ID + * Data in Connection Table entry bad + * SMPL_NO_FRAME No frame received. + * SMPL_NO_PAYLOAD Frame received with no payload (not necessarily + * an error and could be deduced by application + * because the returned length will be 0) + * + * Polling device only: + * + * SMPL_TIMEOUT No response from Access Point + * SMPL_NO_AP_ADDRESS Access Point address unknown + * SMPL_TX_CCA_FAIL Could not send poll frame + * SMPL_NOMEM No memory in output frame queue + * SMPL_NO_CHANNEL Frequency Agility enabled and could not find channel + */ +smplStatus_t SMPL_Receive(linkID_t lid, uint8_t *msg, uint8_t *len) +{ + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + rcvContext_t rcv; + + if (!pCInfo || ((rc=nwk_checkConnInfo(pCInfo, CHK_RX)) != SMPL_SUCCESS)) + { + return rc; + } + + rcv.type = RCV_APP_LID; + rcv.t.lid = lid; + +#if defined(RX_POLLS) + { + uint8_t numChans = 1; +#if defined(FREQUENCY_AGILITY) + freqEntry_t chans[NWK_FREQ_TBL_SIZE]; + uint8_t scannedB4 = 0; +#endif + + do + { + uint8_t radioState = MRFI_GetRadioState(); + + /* I'm polling. Do the poll to stimulate the sending of a frame. If the + * frame has application length of 0 it means there were no frames. If + * no reply is received infer that the channel is changed. We then need + * to scan and then retry the poll on each channel returned. + */ + if (SMPL_SUCCESS != (rc=nwk_poll(pCInfo->portRx, pCInfo->peerAddr))) + { + /* for some reason couldn't send the poll out. */ + return rc; + } + + /* do this before code block below which may reset it. */ + numChans--; + + /* Wait until there's a frame. if the len is 0 then return SMPL_NO_FRAME + * to the caller. In the poll case the AP always sends something. + */ + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + /* TODO: deal with pending */ + rc = nwk_retrieveFrame(&rcv, msg, len, 0, 0); + +#if defined(FREQUENCY_AGILITY) + if (SMPL_SUCCESS == rc) + { + /* we received something... */ + return (*len) ? SMPL_SUCCESS : SMPL_NO_PAYLOAD; + } + + /* No reply. scan for other channel(s) if we haven't already. Then set + * one and try again. + */ + if (!scannedB4) + { + numChans = nwk_scanForChannels(chans); + scannedB4 = 1; + } + if (numChans) + { + nwk_setChannel(&chans[numChans-1]); + } +#else /* FREQUENCY_AGILITY */ + return (*len) ? rc : ((SMPL_SUCCESS == rc) ? SMPL_NO_PAYLOAD : SMPL_TIMEOUT); +#endif + } while (numChans); + } + +#if defined(FREQUENCY_AGILITY) + return SMPL_NO_CHANNEL; +#endif + +#else /* RX_POLLS */ + return nwk_retrieveFrame(&rcv, msg, len, 0, 0); +#endif /* RX_POLLS */ +} + + +/****************************************************************************** + * @fn SMPL_Link + * + * @brief Link to a peer. + * + * input parameters + * + * output parameters + * @param lid - pointer to where we should write the link ID to which the + * application will read and write. + * + * @return Status of operation. + * SMPL_SUCCESS + * SMPL_NOMEM No room to allocate local Rx port, no more + * room in Connection Table, or no room in + * output frame queue. + * SMPL_NO_LINK No reply frame during wait window. + * SMPL_TX_CCA_FAIL Could not send Link frame. + */ +smplStatus_t SMPL_Link(linkID_t *lid) +{ + return nwk_link(lid); +} + +#if defined(EXTENDED_API) +/************************************************************************************** + * @fn SMPL_Unlink + * + * @brief Tear down connection to a peer. + * + * input parameters + * @param lid - Link ID whose connection is to be terminated. + * + * output parameters + * + * @return Status of operation. The Connection Table entry for the Link ID + * is always freed successfuly. The returned status value is the + * status of the _peer's_ connection tear-down as a result of the + * message sent here. + * SMPL_SUCCESS Local and remote connection destroyed. + * SMPL_BAD_PARAM No local connection table entry for this Link ID + * SMPL_TIMEOUT No reply from peer. + * SMPL_NO_PEER_UNLINK Peer did not have a Connection Table entry for me. + */ +smplStatus_t SMPL_Unlink(linkID_t lid) +{ + return nwk_unlink(lid); +} + +/************************************************************************************** + * @fn SMPL_Ping + * + * @brief Ping a peer. Synchronous call. Although a link ID is used it is the + * NWK Ping application that is pinged, not the peer of this Link ID. The + * peer is not expected to be the responder to the frame sent from here. + * This API is a proxy for a real ping since the application doesn't + * have direct access to SimpliciTI device addresses. Kind of hokey but a + * useful keep-alive mechanism without having to support it with + * user application service. + * + * input parameters + * @param lid - The link ID whose peer device address is used to direct the NWK Ping + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t SMPL_Ping(linkID_t lid) +{ + return nwk_ping(lid); +} + +/************************************************************************************** + * @fn SMPL_Commission + * + * @brief Commission a connection. + * + * input parameters + * @param peerAddr - Pointer to address of the peer for this connection + * @param locPort - Port on which to listen for messages from the peer + * @param rmtPort - Port on which to send messages to the peer. + * @param lid - Pointer to Link ID object. If content of location is + * non-zero on input the value is placed in the Connection + * object. + * + * output parameters + * @param lid - Pointer to Link ID object. If content of location is zero + * on input the value in the Connection object is stored there. + * + * @return SMPL_SUCCESS + * SMPL_NOMEM - No room left in Connection table. + * SMPL_BAD_PARAM - A pointer to a Link object was not supplied. + */ +smplStatus_t SMPL_Commission(addr_t *peerAddr, uint8_t locPort, uint8_t rmtPort, linkID_t *lid) +{ + connInfo_t *pCInfo = nwk_getNextConnection(); + smplStatus_t rc = SMPL_BAD_PARAM; + + do { + if (pCInfo) + { + /* sanity checks... */ + + /* Check port info. */ + if ((locPort > SMPL_PORT_STATIC_MAX) || (locPort < (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM + 1))) + { + continue; + } + + if ((rmtPort > SMPL_PORT_STATIC_MAX) || (rmtPort < (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM + 1))) + { + continue; + } + + /* Must supply a pointer to the Link ID object */ + if (!lid) + { + /* No Link ID pointer supplied */ + continue; + } + + /* we're sane */ + + /* Use the value generated at connection object assign time. */ + *lid = pCInfo->thisLinkID; + + /* store peer's address */ + memcpy(pCInfo->peerAddr, peerAddr, NET_ADDR_SIZE); + + /* store port info */ + pCInfo->portRx = locPort; + pCInfo->portTx = rmtPort; + + pCInfo->hops2target = MAX_HOPS; + + rc = SMPL_SUCCESS; + } + else + { + /* No room in Connection table */ + rc = SMPL_NOMEM; + } + } while (0); + + if ((SMPL_SUCCESS != rc) && pCInfo) + { + nwk_freeConnection(pCInfo); + } + + return rc; +} +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn SMPL_Ioctl + * + * @brief This routine supplies the SimpliciTI IOCTL support. + * + * input parameters + * @param object - The IOCTL target object + * @param action - The IOCTL target action on the object + * @param val - pointer to value. exact forn depends on object type. + * + * output parameters + * + * @return Status of action. Value depends on object, action, and result. + * + * SMPL_BAD_PARAM is returned if this API is called before + * initialization and the object is not one of + * the valid exceptions. + */ +smplStatus_t SMPL_Ioctl(ioctlObject_t object, ioctlAction_t action, void *val) +{ + smplStatus_t rc; + + /* if init hasn't occurred see if access is still valid */ + if (!sInit_done && !ioctlPreInitAccessIsOK(object)) + { + return SMPL_BAD_PARAM; + } + + switch (object) + { +#if defined(EXTENDED_API) + case IOCTL_OBJ_TOKEN: + { + ioctlToken_t *t = (ioctlToken_t *)val; + + rc = SMPL_SUCCESS; + if (TT_LINK == t->tokenType) + { + if (IOCTL_ACT_SET == action) + { + nwk_setLinkToken(t->token.linkToken); + } + else if (IOCTL_ACT_GET == action) + { + nwk_getLinkToken(&t->token.linkToken); + } + else + { + rc = SMPL_BAD_PARAM; + } + } + else if (TT_JOIN == t->tokenType) + { + if (IOCTL_ACT_SET == action) + { + nwk_setJoinToken(t->token.joinToken); + } + else if (IOCTL_ACT_GET == action) + { + nwk_getJoinToken(&t->token.joinToken); + } + else + { + rc = SMPL_BAD_PARAM; + } + } + else + { + rc = SMPL_BAD_PARAM; + } + } + break; + + case IOCTL_OBJ_NVOBJ: + rc = nwk_NVObj(action, (ioctlNVObj_t *)val); + break; +#endif /* EXTENDED_API */ + + case IOCTL_OBJ_CONNOBJ: + rc = nwk_connectionControl(action, val); + break; + + case IOCTL_OBJ_ADDR: + if ((IOCTL_ACT_GET == action) || (IOCTL_ACT_SET == action)) + { + rc = nwk_deviceAddress(action, (addr_t *)val); + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_RAW_IO: + if (IOCTL_ACT_WRITE == action) + { + rc = nwk_rawSend((ioctlRawSend_t *)val); + } + else if (IOCTL_ACT_READ == action) + { + rc = nwk_rawReceive((ioctlRawReceive_t *)val); + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_RADIO: + rc = nwk_radioControl(action, val); + break; + +#if defined(ACCESS_POINT) + case IOCTL_OBJ_AP_JOIN: + rc = nwk_joinContext(action); + break; +#endif +#if defined(FREQUENCY_AGILITY) + case IOCTL_OBJ_FREQ: + rc = nwk_freqControl(action, val); + break; +#endif + case IOCTL_OBJ_FWVER: + if (IOCTL_ACT_GET == action) + { + memcpy(val, nwk_getFWVersion(), SMPL_FWVERSION_SIZE); + rc = SMPL_SUCCESS; + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_PROTOVER: + if (IOCTL_ACT_GET == action) + { + *((uint8_t *)val) = nwk_getProtocolVersion(); + rc = SMPL_SUCCESS; + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + default: + rc = SMPL_BAD_PARAM; + break; + } + + return rc; +} + +/****************************************************************************** + * @fn ioctlPreInitAccessIsOK + * + * @brief Is the request legal yet? Most requests are not legal before + * SMPL_Init(). + * + * input parameters + * @param object - The IOCTL target object + * + * output parameters + * + * @return Returns non-zero if request should be honored for further + * processing, otherwise returns 0. This function does not + * determine of the object-action pair are valid. It only knows + * about exceptions, i.e., those that are valid before the + * SMPL_Init() call. + * + */ +static uint8_t ioctlPreInitAccessIsOK(ioctlObject_t object) +{ + uint8_t rc; + + /* Currently the only legal pre-init accesses are the address and + * the token objects. + */ + switch (object) + { + case IOCTL_OBJ_ADDR: + case IOCTL_OBJ_TOKEN: + rc = 1; /* legal */ + break; + + default: + rc = 0; /* not legal when init not done */ + break; + } + + return rc; +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_api.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_api.h new file mode 100755 index 0000000..07ccf85 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_api.h @@ -0,0 +1,56 @@ +/************************************************************************************************** + Filename: nwk_api.h + Revised: $Date: 2008-11-24 12:09:31 -0800 (Mon, 24 Nov 2008) $ + Revision: $Revision: 18508 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI appliction layer API. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_API_H +#define NWK_API_H + +/* Tx options (bit map) */ +#define SMPL_TXOPTION_NONE ((txOpt_t)0x00) +#define SMPL_TXOPTION_ACKREQ ((txOpt_t)0x01) + +smplStatus_t SMPL_Init(uint8_t (*)(linkID_t)); +smplStatus_t SMPL_Link(linkID_t *); +smplStatus_t SMPL_LinkListen(linkID_t *); +smplStatus_t SMPL_Send(linkID_t lid, uint8_t *msg, uint8_t len); +smplStatus_t SMPL_SendOpt(linkID_t lid, uint8_t *msg, uint8_t len, txOpt_t); +smplStatus_t SMPL_Receive(linkID_t lid, uint8_t *msg, uint8_t *len); +smplStatus_t SMPL_Ioctl(ioctlObject_t, ioctlAction_t, void *); +#ifdef EXTENDED_API +smplStatus_t SMPL_Ping(linkID_t); +smplStatus_t SMPL_Unlink(linkID_t); +smplStatus_t SMPL_Commission(addr_t *, uint8_t, uint8_t, linkID_t *); +#endif /* EXTENDED_API */ + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_app.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_app.h new file mode 100755 index 0000000..45883b4 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_app.h @@ -0,0 +1,53 @@ + +/************************************************************************************************** + Filename: nwk_app.h + Revised: $Date: 2007-07-10 11:21:35 -0700 (Tue, 10 Jul 2007) $ + Revision: $Revision: 14865 $ + Author: $Author: lfriedman $ + + Description: This header file is for convenience and includes the headers for all the + network applications. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + + + +#ifndef NWK_APP_H +#define NWK_APP_H + +#include "nwk_freq.h" +#include "nwk_ping.h" +#include "nwk_link.h" +#include "nwk_mgmt.h" +#include "nwk_join.h" +#include "nwk_security.h" +#include "nwk_ioctl.h" + +#endif + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_frame.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_frame.c new file mode 100755 index 0000000..4279b25 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_frame.c @@ -0,0 +1,948 @@ +/************************************************************************************************** + Filename: nwk_frame.c + Revised: $Date: 2009-03-10 16:21:40 -0700 (Tue, 10 Mar 2009) $ + Revision: $Revision: 19368 $ + Author $Author: lfriedman $ + + Description: This file supports the SimpliciTI frame handling functions. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "nwk_QMgmt.h" +#include "nwk_globals.h" +#include "nwk_mgmt.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +#if SIZE_INFRAME_Q > 0 +/* array of function pointers to handle NWK application frames */ +static fhStatus_t (* const func[])(mrfiPacket_t *) = { nwk_processPing, + nwk_processLink, + nwk_processJoin, + nwk_processSecurity, + nwk_processFreq, + nwk_processMgmt + }; +#endif /* SIZE_INFRAME_Q > 0 */ + +static uint8_t sTRACTID = 0; + +static addr_t const *sMyAddr = NULL; + +static uint8_t sMyRxType = 0, sMyTxType = 0; + +#if !defined(RX_POLLS) +static uint8_t (*spCallback)(linkID_t) = NULL; +#endif + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +#if SIZE_INFRAME_Q > 0 +/* local helper functions for Rx devices */ +static void dispatchFrame(frameInfo_t *); +#if !defined(END_DEVICE) +#if defined(ACCESS_POINT) +/* only Access Points need to worry about duplicate S&F frames */ +uint8_t isDupSandFFrame(mrfiPacket_t *); +#endif /* ACCESS_POINT */ +#endif /* !END_DEVICE */ +#endif /* SIZE_INFRAME_Q > 0 */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_frameInit + * + * @brief Initialize network context. + * + * input parameters + * pF - Pointer to callback function. If none intended should be NULL. + * + * output parameters + * + * @return void + */ + +void nwk_frameInit(uint8_t (*pF)(linkID_t)) +{ + +/****** Fill static values for the DEVICEINFO byte that will go in each frame ******/ + /* Rx type when frame originates from this device. Set in nwk_buildFrame() */ + /* Tx type when frame sent from this device. Set in nwk_sendframe() */ +#if !defined(END_DEVICE) + sMyRxType = F_RX_TYPE_USER_CTL; + #if defined(ACCESS_POINT) + sMyTxType = F_TX_DEVICE_AP; + #else + sMyTxType = F_TX_DEVICE_RE; + #endif +#else + sMyTxType = F_TX_DEVICE_ED; + #if defined(RX_POLLS) + sMyRxType = F_RX_TYPE_POLLS; + #endif + #if defined(RX_USER) + sMyRxType = F_RX_TYPE_USER_CTL; + #endif +#endif +/****** DONE fill static values for the DEVICEINFO byte that will go in each frame ******/ + +#if !defined(RX_POLLS) + spCallback = pF; +#else + (void) pF; +#endif + + sMyAddr = nwk_getMyAddress(); + + while (!(sTRACTID=MRFI_RandomByte())) ; + + return; +} + +/****************************************************************************** + * @fn nwk_buildFrame + * + * @brief Builds an output frame for the port and message enclosed. + * This routine prepends the frame header and populates the + * frame in the output queue. + * + * input parameters + * @param port - port from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param hops - number of hops allowed. this is less than MAX_HOPS + * whenever the frame is being sent to the AP. this is to + * help mitigate the (short) broadcast storms + * + * output parameters + * + * @return pointer to frameInfo_t structure created. NULL if there is + * no room in output queue. + */ +frameInfo_t *nwk_buildFrame(uint8_t port, uint8_t *msg, uint8_t len, uint8_t hops) +{ + frameInfo_t *fInfoPtr; + + if (!(fInfoPtr=nwk_QfindSlot(OUTQ))) + { + return (frameInfo_t *)NULL; + } + + MRFI_SET_PAYLOAD_LEN(&fInfoPtr->mrfiPkt, len+F_APP_PAYLOAD_OS); + + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ENCRYPT_OS, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_PORT_OS, port); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_TRACTID_OS, sTRACTID); + while (!(++sTRACTID)) ; /* transaction ID can't be 0 */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_RX_TYPE, sMyRxType); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_HOP_COUNT, hops); + + /* reset ack-relevant bits */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_REQ, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_RPLY, 0); + + /* reset forwarding bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_FWD_FRAME, 0); + + memcpy(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt)+F_APP_PAYLOAD_OS, msg, len); + memcpy(MRFI_P_SRC_ADDR(&fInfoPtr->mrfiPkt), sMyAddr, NET_ADDR_SIZE); + + return fInfoPtr; +} + +#if defined(APP_AUTO_ACK) +/****************************************************************************** + * @fn nwk_buildAckReqFrame + * + * @brief Builds an output frame for the port and message enclosed. + * This routine prepends the frame header and populates the + * frame in the output queue. The frame is set to request that + * an ack frame be sent by the peer. + * + * input parameters + * @param port - port from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param hops - number of hops allowed. this is less than MAX_HOPS + * whenever the frame is being sent to the AP. this is to + * help mitigate the (short) broadcast storms + * @param tid - Transaction ID to insert in NWK header used to match + * the ack reply. + * + * output parameters + * + * @return pointer to frameInfo_t structure created. NULL if there is + * no room in output queue. + */ +frameInfo_t *nwk_buildAckReqFrame(uint8_t port, uint8_t *msg, uint8_t len, uint8_t hops, volatile uint8_t *tid) +{ + frameInfo_t *fInfoPtr; + + /* Build a normal frame first. */ + if (!(fInfoPtr=nwk_buildFrame(port, msg, len, hops))) + { + return (frameInfo_t *)NULL; + } + + /* save TID */ + *tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_TRACTID_OS); + /* Set REQ_ACK bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_REQ, F_ACK_REQ_TYPE); + + return fInfoPtr; +} +#endif /* APP_AUTO_ACK */ + +#if SIZE_INFRAME_Q > 0 +/****************************************************************************** + * @fn MRFI_RxCompleteISR + * + * @brief Here on Rx interrupt from radio. Process received frame from the + * radio Rx FIFO. + * + * input parameters + * + * output parameters + * + * @return void + */ +void MRFI_RxCompleteISR() +{ + frameInfo_t *fInfoPtr; + + /* room for more? */ + if (fInfoPtr=nwk_QfindSlot(INQ)) + { + MRFI_Receive(&fInfoPtr->mrfiPkt); + + dispatchFrame(fInfoPtr); + } + + return; +} + +/****************************************************************************** + * @fn nwk_retrieveFrame + * + * @brief Retrieve frame from Rx frame queue. Invoked by application-level + * code either app through SMPL_Receive() or IOCTL through raw Rx. This + * should run in a user thread, not an ISR thread. + * + * input parameters + * @param port - port on which to get a frame + * + * output parameters + * @param msg - pointer to where app payload should be copied. Buffer + * allocated should be == MAX_APP_PAYLOAD. + * + * @param len - pointer to where payload length should be stored. Caller + * can check for non-zero when polling the port. initialized + * to 0 even if no frame is retrieved. + * @param srcAddr - if non-NULL, a pointer to where to copy the source address + * of the retrieved message. + * @param hopCount - if non-NULL, a pointer to where to copy the hop count + of the retrieved message. + * + * @return SMPL_SUCCESS + * SMPL_NO_FRAME - no frame found for specified destination + * SMPL_BAD_PARAM - no valid connection info for the Link ID + * + */ +smplStatus_t nwk_retrieveFrame(rcvContext_t *rcv, uint8_t *msg, uint8_t *len, addr_t *srcAddr, uint8_t *hopCount) +{ + frameInfo_t *fPtr; + uint8_t done; + + do { + /* look for a frame on requested port. */ + *len = 0; + done = 1; + + fPtr = nwk_QfindOldest(INQ, rcv, USAGE_NORMAL); + if (fPtr) + { + connInfo_t *pCInfo = 0; + + if (RCV_APP_LID == rcv->type) + { + pCInfo = nwk_getConnInfo(rcv->t.lid); + if (!pCInfo) + { + return SMPL_BAD_PARAM; + } +#if defined(SMPL_SECURE) + /* decrypt here...we have all the context we need. */ + { + uint32_t ctr = pCInfo->connRxCTR; + uint32_t *pctr = &ctr; + uint8_t len = MRFI_GET_PAYLOAD_LEN(&fPtr->mrfiPkt) - F_SEC_CTR_OS; + + if (pCInfo->thisLinkID == SMPL_LINKID_USER_UUD) + { + pctr = NULL; + } +#if defined(RX_POLLS) + else if ((F_APP_PAYLOAD_OS - F_SEC_CTR_OS) == len) + { + /* This was an empty poll reply frame generated by the AP. + * It uses the single-byte CTR value like network applications. + * We do not want to use the application layer counter in this case. + */ + pctr = NULL; + } +#endif + if (nwk_getSecureFrame(&fPtr->mrfiPkt, len, pctr)) + { + if (pctr) + { + /* Update connection's counter. */ + pCInfo->connRxCTR = ctr; + } + } + else + { + /* Frame bogus. Check for another frame. */ + done = 0; + continue; + } + } +#endif /* SMPL_SECURE */ + } + + /* it's on the requested port. */ + *len = MRFI_GET_PAYLOAD_LEN(&fPtr->mrfiPkt) - F_APP_PAYLOAD_OS; + memcpy(msg, MRFI_P_PAYLOAD(&fPtr->mrfiPkt)+F_APP_PAYLOAD_OS, *len); + /* save signal info */ + if (pCInfo) + { + /* Save Rx metrics... */ + pCInfo->sigInfo.rssi = fPtr->mrfiPkt.rxMetrics[MRFI_RX_METRICS_RSSI_OFS]; + pCInfo->sigInfo.lqi = fPtr->mrfiPkt.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS]; + } + if (srcAddr) + { + /* copy source address if requested */ + memcpy(srcAddr, MRFI_P_SRC_ADDR(&fPtr->mrfiPkt), NET_ADDR_SIZE); + } + if (hopCount) + { + /* copy hop count if requested */ + *hopCount = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fPtr->mrfiPkt), F_HOP_COUNT); + } + /* input frame no longer needed. free it. */ + nwk_QadjustOrder(INQ, fPtr->orderStamp); + + fPtr->fi_usage = FI_AVAILABLE; + return SMPL_SUCCESS; + } + } while (!done); + + return SMPL_NO_FRAME; +} + +/****************************************************************************** + * @fn dispatchFrame + * + * @brief Received frame looks OK so far. Dispatch to either NWK app by + * invoking the handler or the user's app by simply leaving the + * frame in the queue and letting the app poll the port. + * + * input parameters + * @param fiPtr - frameInfo_t pointer to received frame + * + * output parameters + * + * @return void + */ +static void dispatchFrame(frameInfo_t *fiPtr) +{ + uint8_t port = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_PORT_OS); + uint8_t nwkAppSize = sizeof(func)/sizeof(func[0]); + fhStatus_t rc; + linkID_t lid; +#if defined(ACCESS_POINT) + uint8_t loc; +#endif +#if !defined(END_DEVICE) + uint8_t isForMe; +#endif + + /* be sure it's not an echo... */ + if (!memcmp(MRFI_P_SRC_ADDR(&fiPtr->mrfiPkt), sMyAddr, NET_ADDR_SIZE)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + + /* Make sure encyrption bit conforms to our security support context. */ +#if defined(SMPL_SECURE) + if (!(GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ENCRYPT_OS))) + { + /* Encyrption bit is not on when when it should be */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +#else + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ENCRYPT_OS)) + { + /* Encyrption bit is on when when it should not be */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +#endif /* SMPL_SECURE */ + + /* If it's a network application port dispatch to service routine. Dispose + * of frame depending on return code. + */ + if (port && (port <= nwkAppSize)) + { +#if defined(SMPL_SECURE) + /* Non-connection-based frame. We can decode here if it was encrypted */ + if (!nwk_getSecureFrame(&fiPtr->mrfiPkt, MRFI_GET_PAYLOAD_LEN(&fiPtr->mrfiPkt) - F_SEC_CTR_OS, 0)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +#endif + rc = func[port-1](&fiPtr->mrfiPkt); + if (FHS_KEEP == rc) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + } +#if !defined(END_DEVICE) + else if (FHS_REPLAY == rc) + { + /* an AP or an RE could be relaying a NWK application frame... */ + nwk_replayFrame(fiPtr); + } +#endif + else /* rc == FHS_RELEASE (default...) */ + { + fiPtr->fi_usage = FI_AVAILABLE; + } + return; + } + /* sanity check */ + else if ((port != SMPL_PORT_USER_BCAST) && ((port < PORT_BASE_NUMBER) || (port > SMPL_PORT_STATIC_MAX))) + { + /* bogus port. drop frame */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + + /* At this point we know the target is a user app. If this is an end device + * and we got this far save the frame and we're done. If we're an AP there + * are 3 cases: it's for us, it's for s store-and-forward client, or we need + * to replay the frame. If we're and RE and the frame didn't come from an RE + * and it's not for us, replay the frame. + */ + +#if defined(END_DEVICE) + /* If we're s polling end device we only accept application frames from + * the AP. This prevents duplicate reception if we happen to be on when + * a linked peer sends. + */ +#if defined(RX_POLLS) + if (F_TX_DEVICE_ED != GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE)) + { + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } +#else + /* it's destined for a user app. */ + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + if (spCallback && spCallback(lid)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } +#endif /* RX_POLLS */ + +#else /* END_DEVICE */ + + /* We have an issue if the frame is broadcast to the UUD port. The AP (or RE) must + * handle this frame as if it were the target in case there is an application + * running that is listening on that port. But if it's a broadcast it must also be + * replayed. It isn't enough just to test for the UUD port because it could be a + * directed frame to another device. We must check explicitly for broadcast + * destination address. + */ + isForMe = !memcmp(sMyAddr, MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), NET_ADDR_SIZE); + if (isForMe || ((port == SMPL_PORT_USER_BCAST) && !memcmp(nwk_getBCastAddress(), MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), NET_ADDR_SIZE))) + { + /* The folllowing test will succeed for the UUD port regardless of the + * source address. + */ + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + /* If this is for the UUD port and we are here then the device is either + * an AP or an RE. In either case it must replay the UUD port frame if the + * frame is not "for me". But it also must handle it since it could have a + * UUD-listening application. Do the reply first and let the subsequent code + * correctly set the frame usage state. Note that the routine return can be + * from this code block. If not it will drop through to the bottom without + * doing a replay. + */ + /* Do I need to replay it? */ + if (!isForMe) + { + /* must be a broadcast for the UUD port */ + nwk_replayFrame(fiPtr); + } + /* OK. Now I handle it... */ + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + if (spCallback && spCallback(lid)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } +#if defined( ACCESS_POINT ) + /* Check to see if we need to save this for a S and F client. Otherwise, + * if it's not for us, get rid of it. + */ + else if (nwk_isSandFClient(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), &loc)) + { + /* Don't bother if it is a duplicate frame or if it's a forwarded frame + * echoed back from an RE. + */ + if (!isDupSandFFrame(&fiPtr->mrfiPkt) && + !(GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_FWD_FRAME)) + ) + { +#if defined(APP_AUTO_ACK) + /* Make sure ack request bit is off. Sender will have gone away. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ACK_REQ, 0); +#endif + fiPtr->fi_usage = FI_INUSE_UNTIL_FWD; + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE) == F_TX_DEVICE_AP) + { + /* I'm an AP and this frame came from an AP. Don't replay. */ + fiPtr->fi_usage = FI_AVAILABLE; + } +#elif defined( RANGE_EXTENDER ) + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE) == F_TX_DEVICE_RE) + { + /* I'm an RE and this frame came from an RE. Don't replay. */ + fiPtr->fi_usage = FI_AVAILABLE; + } +#endif + else + { + /* It's not for me and I'm either an AP or I'm an RE and the frame + * didn't come from an RE. Replay the frame. + */ + nwk_replayFrame(fiPtr); + } +#endif /* !END_DEVICE */ + return; +} +#endif /* SIZE_INFRAME_Q > 0 */ + +/****************************************************************************** + * @fn nwk_sendFrame + * + * @brief Send a frame by copying it to the radio Tx FIFO. + * + * input parameters + * @param pFrameInfo - pointer to frame to be sent + * @param txOption - do CCA or force frame out. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_TX_CCA_FAIL Tx failed because of CCA failure. + * Tx FIFO flushed in this case. + */ +smplStatus_t nwk_sendFrame(frameInfo_t *pFrameInfo, uint8_t txOption) +{ + smplStatus_t rc; + + /* set the type of device sending the frame in the header */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_TX_DEVICE, sMyTxType); + + if (MRFI_TX_RESULT_SUCCESS == MRFI_Transmit(&pFrameInfo->mrfiPkt, txOption)) + { + rc = SMPL_SUCCESS; + } + else + { + /* Tx failed -- probably CCA. free up frame buffer. We do not have NWK + * level retries. Let application do it. + */ + rc = SMPL_TX_CCA_FAIL; + } + + /* TX is done. free up the frame buffer */ + pFrameInfo->fi_usage = FI_AVAILABLE; + + return rc; +} + + +/****************************************************************************** + * @fn nwk_getMyRxType + * + * @brief Get my Rx type. Used to help populate the hops count in the + * frame header to try and limit the broadcast storm. Info is + * exchanged when linking. + * + * input parameters + * + * output parameters + * + * @return The address LSB. + */ +uint8_t nwk_getMyRxType(void) +{ + return sMyRxType; +} + +#if defined(APP_AUTO_ACK) +/****************************************************************************** + * @fn nwk_sendAckReply + * + * @brief Send an acknowledgement reply frame. + * + * input parameters + * @param frame - pointer to frame with ack request. + * @param port - port on whcih reply expected. + * + * output parameters + * + * @return void + */ +void nwk_sendAckReply(mrfiPacket_t *frame, uint8_t port) +{ + mrfiPacket_t dFrame; + uint8_t tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS); + + /* set the type of device sending the frame in the header */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, sMyTxType); + + /* set the listen type of device sending the frame in the header. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); + + /* destination address from received frame */ + memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + /* source address */ + memcpy(MRFI_P_SRC_ADDR(&dFrame), sMyAddr, NET_ADDR_SIZE); + + /* port is the source the Tx port from the connection object */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); + + /* frame length... */ + MRFI_SET_PAYLOAD_LEN(&dFrame,F_APP_PAYLOAD_OS); + + /* transaction ID taken from source frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, tid); + + /* hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS); + + /* set ACK field */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, F_ACK_RPLY_TYPE); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); + + /* This is not a forwarded frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, 0); + + /* Encryption state */ +#if !defined(SMPL_SECURE) + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); +#else + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + nwk_setSecureFrame(&dFrame, 0, 0); +#endif + + MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); + + return; +} +#endif /* APP_AUTO_ACK */ + +#if !defined(END_DEVICE) +/****************************************************************************** + * @fn nwk_replayFrame + * + * @brief Deal with hop count on a Range Extender or Access Point replay. + * Queue entry usage always left as available when done. + * + * input parameters + * @param pFrameInfo - pointer to frame information structure + * + * output parameters + * + * @return void + */ +void nwk_replayFrame(frameInfo_t *pFrameInfo) +{ + uint8_t hops = GET_FROM_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_HOP_COUNT); + + /* if hops are zero, drop frame. othewise send it. */ + if (hops--) + { + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt),F_HOP_COUNT,hops); + /* Don't care if the Tx fails because of TO. Either someone else + * will retransmit or the application itself will recover. + */ +#if defined(SMPL_SECURE) + /* If the frame was targeted to a NWK port it was decrypted on spec in + * the 'dispatchFrame()' method. It must be re-encypted in this case. + */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_PORT_OS) <= SMPL_PORT_NWK_BCAST) + { + nwk_setSecureFrame(&pFrameInfo->mrfiPkt, MRFI_GET_PAYLOAD_LEN(&pFrameInfo->mrfiPkt)-F_APP_PAYLOAD_OS, 0); + } +#endif + MRFI_DelayMs(1); + nwk_sendFrame(pFrameInfo, MRFI_TX_TYPE_CCA); + } + else + { + pFrameInfo->fi_usage = FI_AVAILABLE; + } + return; +} + +#if defined(ACCESS_POINT) +/****************************************************************************** + * @fn nwk_getSandFFrame + * + * @brief Get any frame waiting for the client on the port supplied in + * the frame payload. + * TODO: support returning NWK application frames always. the + * port requested in the call should be an user application port. + * NWK app ports will never be in the called frame. + * TODO: deal with broadcast NWK frames from AP. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return pointer to frame if there is one, otherwise 0. + */ +frameInfo_t *nwk_getSandFFrame(mrfiPacket_t *frame, uint8_t osPort) +{ + uint8_t i, port = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+osPort); + frameInfo_t *fiPtr; + rcvContext_t rcv; + + rcv.type = RCV_RAW_POLL_FRAME; + rcv.t.pkt = frame; + /* check the input queue for messages sent by others. */ + if (fiPtr=nwk_QfindOldest(INQ, &rcv, USAGE_FWD)) + { + return fiPtr; + } + + /* Check the output queue to see if we ourselves need to send anything. + * TODO: use the cast-out scheme for output queue so this routine finds + * the oldest in either queue. + */ + fiPtr = nwk_getQ(OUTQ); + for (i=0; ifi_usage) + { + if (!memcmp(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_PORT_OS) == port) + { + return fiPtr; + } + } + } + } + return 0; +} + +/****************************************************************************** + * @fn nwk_SendEmptyPollRspFrame + * + * @brief There are no frames waiting for the requester on the specified + * port. Send a frame back to that port with no payload. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return void + */ +void nwk_SendEmptyPollRspFrame(mrfiPacket_t *frame) +{ + mrfiPacket_t dFrame; + uint8_t port = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+M_POLL_PORT_OS); + + /* set the type of device sending the frame in the header. we know it's an AP */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, F_TX_DEVICE_AP); + /* set the listen type of device sending the frame in the header. we know it's + * an AP is is probably always on...but use the static variable anyway. + */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); + /* destination address from received frame (polling device) */ + memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + /* source address */ + memcpy(MRFI_P_SRC_ADDR(&dFrame), MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+M_POLL_ADDR_OS, NET_ADDR_SIZE); + /* port is the port requested */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); + /* frame length... */ + MRFI_SET_PAYLOAD_LEN(&dFrame,F_APP_PAYLOAD_OS); + /* transaction ID... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, sTRACTID); + sTRACTID++; + /* hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS_FROM_AP); + + /* Ack fields */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); + + /* This is logically a forwarded frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, F_FRAME_FWD_TYPE); + + /* Encryption state */ +#if !defined(SMPL_SECURE) + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); +#else + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + nwk_setSecureFrame(&dFrame, 0, 0); +#endif + + MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +/****************************************************************************** + * @fn isDupSandFFrame + * + * @brief Have we already stored this frame on behalf of a client? + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns 1 if the frame is a duplicate, otherwise 0. + */ +uint8_t isDupSandFFrame(mrfiPacket_t *frame) +{ + uint8_t i, plLen = MRFI_GET_PAYLOAD_LEN(frame); + frameInfo_t *fiPtr; + + /* check the input queue for duplicate S&F frame. */ + fiPtr = nwk_getQ(INQ); + for (i=0; ifi_usage) + { + /* compare everything except the DEVICE INFO byte. */ + if (MRFI_GET_PAYLOAD_LEN(&fiPtr->mrfiPkt) == plLen && + !memcmp(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), MRFI_P_DST_ADDR(frame), NET_ADDR_SIZE) && + !memcmp(MRFI_P_SRC_ADDR(&fiPtr->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE) && + !memcmp(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), MRFI_P_PAYLOAD(frame), 1) && + !memcmp(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt)+F_TRACTID_OS, MRFI_P_PAYLOAD(frame)+F_TRACTID_OS, plLen-F_TRACTID_OS) + ) + { + return 1; + } + } + } + return 0; +} +#endif /* ACCESS_POINT */ + +#endif /* !END_DEVICE */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_frame.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_frame.h new file mode 100755 index 0000000..6c616f8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_frame.h @@ -0,0 +1,151 @@ +/************************************************************************************************** + Filename: nwk_frame.h + Revised: $Date: 2008-12-23 13:49:41 -0800 (Tue, 23 Dec 2008) $ + Revision: $Revision: 18651 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI frame handling functions. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_FRAME_H +#define NWK_FRAME_H + +/* Frame field defines and masks. Mask name must be field name with '_MSK' appended + * so the GET and PUT macros work correctly -- they use token pasting. Offset values + * are with respect to the MRFI payload and not the entire frame. + */ +#define F_PORT_OS 0 +#define F_PORT_OS_MSK (0x3F) +#define F_ENCRYPT_OS 0 +#define F_ENCRYPT_OS_MSK (0x40) +#define F_FWD_FRAME 0 +#define F_FWD_FRAME_MSK (0x80) +#define F_RX_TYPE 1 +#define F_RX_TYPE_MSK (0x40) +#define F_ACK_REQ 1 +#define F_ACK_REQ_MSK (0x80) +#define F_ACK_RPLY 1 +#define F_ACK_RPLY_MSK (0x08) +#define F_TX_DEVICE 1 +#define F_TX_DEVICE_MSK (0x30) +#define F_HOP_COUNT 1 +#define F_HOP_COUNT_MSK (0x07) +#define F_TRACTID_OS 2 +#define F_TRACTID_OS_MSK (0xFF) +#define SMPL_NWK_HDR_SIZE 3 + +#ifdef SMPL_SECURE + +#define F_SECURE_OS 3 + +#define F_SEC_CTR_OS 3 /* counter hint */ +#define F_SEC_CTR_OS_MSK (0xFF) +#define F_SEC_ICHK_OS 4 /* Message integrity check */ +#define F_SEC_ICHK_OS_MSK (0xFF) +#define F_SEC_MAC_OS 5 /* Message authentication code */ +#define F_SEC_MAC_OS_MSK (0xFF) + +#else + +#define F_SECURE_OS 0 + +#endif /* SMPL_SECURE */ + +#define F_APP_PAYLOAD_OS (SMPL_NWK_HDR_SIZE+F_SECURE_OS) + +/* sub field details. they are in the correct bit locations (already shifted) */ +#define F_RX_TYPE_USER_CTL 0x00 /* does not poll... */ +#define F_RX_TYPE_POLLS 0x40 /* polls for held messages */ + +#define F_ACK_REQ_TYPE 0x80 +#define F_ACK_RPLY_TYPE 0x08 +#define F_FRAME_FWD_TYPE 0x80 +#define F_FRAME_ENCRYPT_TYPE 0x40 + +/* device type fields */ +#define F_TX_DEVICE_ED 0x00 /* End Device */ +#define F_TX_DEVICE_RE 0x10 /* Range Extender */ +#define F_TX_DEVICE_AP 0x20 /* Access Point */ + +/* macro to get a field from a frame buffer */ +#define GET_FROM_FRAME(b,f) ((b)[f] & (f##_MSK)) + +/* Macro to put a value 'v' into a frame buffer 'b'. 'v' value must already be shifted + * if necessary. 'b' is a byte array + */ +#define PUT_INTO_FRAME(b,f,v) do {(b)[f] = ((b)[f] & ~(f##_MSK)) | (v); } while(0) + + +/* **** frame information objects + * info kept on each frame object + */ +#define FI_AVAILABLE 0 /* entry available for use */ +#define FI_INUSE_UNTIL_DEL 1 /* in use. will be explicitly reclaimed */ +#define FI_INUSE_UNTIL_TX 2 /* in use. will be reclaimed after Tx */ +#define FI_INUSE_UNTIL_FWD 3 /* in use until forwarded by AP */ +#define FI_INUSE_TRANSITION 4 /* being retrieved. do not delete in Rx ISR thread. */ + +typedef struct +{ + uint8_t rssi; + uint8_t lqi; +} sigInfo_t; + +typedef struct +{ + volatile uint8_t fi_usage; + uint8_t orderStamp; + mrfiPacket_t mrfiPkt; +} frameInfo_t; + + +/* prototypes */ +frameInfo_t *nwk_buildFrame(uint8_t, uint8_t *msg, uint8_t len, uint8_t hops); +#ifdef APP_AUTO_ACK +frameInfo_t *nwk_buildAckReqFrame(uint8_t, uint8_t *, uint8_t, uint8_t, volatile uint8_t *); +#endif +void nwk_receiveFrame(void); +void nwk_frameInit(uint8_t (*)(linkID_t)); +smplStatus_t nwk_retrieveFrame(rcvContext_t *, uint8_t *, uint8_t *, addr_t *, uint8_t *); +smplStatus_t nwk_sendFrame(frameInfo_t *, uint8_t txOption); +frameInfo_t *nwk_getSandFFrame(mrfiPacket_t *, uint8_t); +uint8_t nwk_getMyRxType(void); +void nwk_SendEmptyPollRspFrame(mrfiPacket_t *); +#ifdef APP_AUTO_ACK +void nwk_sendAckReply(mrfiPacket_t *, uint8_t); +#endif + +#ifndef END_DEVICE +/* only APs and REs repeat frames */ +void nwk_replayFrame(frameInfo_t *); +#endif + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_globals.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_globals.c new file mode 100755 index 0000000..121b5e3 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_globals.c @@ -0,0 +1,258 @@ +/************************************************************************************************** + Filename: nwk_globals.c + Revised: $Date: 2009-10-27 20:48:11 -0700 (Tue, 27 Oct 2009) $ + Revision: $Revision: 20995 $ + + Description: This file manages global NWK data. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_globals.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static const addr_t sMyROMAddress = THIS_DEVICE_ADDRESS; +static addr_t sAPAddress; +static addr_t sMyRAMAddress; +static uint8_t sRAMAddressIsSet = 0; + +/* Version number set as a 4 byte quantity. Each byte is a revision number + * in the form w.x.y.z. The subfields are each limited to values 0x0-0xFF. + */ +static const smplVersionInfo_t sVersionInfo = { + 0x02, /* protocol version */ + 0x01, /* major revision number */ + 0x01, /* minor revision number */ + 0x01, /* maintenance release number */ + 0x00 /* special release */ + }; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_globalsInit + * + * @brief Initialization of global symbols + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_globalsInit(void) +{ + + memset(&sAPAddress, 0x00, sizeof(addr_t)); + + /* populate RAM address from ROM default if it hasn't laready been set + * using the IOCTL interface. + */ + if (!sRAMAddressIsSet) + { + memcpy(&sMyRAMAddress, &sMyROMAddress, sizeof(addr_t)); + sRAMAddressIsSet = 1; /* RAM address is now valid */ + } + + return; +} + +/****************************************************************************** + * @fn nwk_getMyAddress + * + * @brief Return a pointer to my address. It comes either from ROM as + * set in the configuration file or it was set using the IOCTL + * interface -- probably from random bytes. + * + * input parameters + * + * output parameters + * + * @return pointer to a constant address type object. + */ +addr_t const *nwk_getMyAddress(void) +{ + /* This call supports returning a valid pointer before either the + * initialization or external setting of the address. But caller needs + * to be careful -- if this routine is called immediately it will return + * the ROM address. If the application then sets the address using the + * IOCTL before doing the SMPL_Init() the original pointer is no longer + * valid as it points to the wrong address. + */ + return sRAMAddressIsSet ? &sMyRAMAddress : &sMyROMAddress; +} + +/****************************************************************************** + * @fn nwk_getFWVersion + * + * @brief Return a pointer to the current firmware version string. + * + * input parameters + * + * output parameters + * + * @return pointer to a constant uint16_t object. + */ +uint8_t const *nwk_getFWVersion() +{ + return sVersionInfo.fwVerString; +} + +/****************************************************************************** + * @fn nwk_getProtocolVersion + * + * @brief Return the current protocol version. + * + * input parameters + * + * output parameters + * + * @return Protocol version. + */ +uint8_t nwk_getProtocolVersion(void) +{ + return sVersionInfo.protocolVersion; +} + +/****************************************************************************** + * @fn nwk_setMyAddress + * + * @brief Set my address object if it hasn't already been set. This call + * is referenced by the IOCTL support used to change the device + * address. It is effective only if the address has not already + * been set. + * + * input parameters + * + * @param addr - pointer to the address object to be used to set my address. + * + * output parameters + * + * @return Returns non-zero if request is respected, otherwise returns 0. + */ +uint8_t nwk_setMyAddress(addr_t *addr) +{ + uint8_t rc = 0; + + if (!sRAMAddressIsSet) + { + memcpy(&sMyRAMAddress, addr, sizeof(addr_t)); + sRAMAddressIsSet = 1; /* RAM address is now valid */ + rc = 1; + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_setAPAddress + * + * @brief Set the AP's address. Called after the AP address is gleaned + * from the Join reply. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_setAPAddress(addr_t *addr) +{ + + memcpy((void *)&sAPAddress, (void *)addr, NET_ADDR_SIZE); + + return; +} + +/****************************************************************************** + * @fn nwk_getAPAddress + * + * @brief Get the AP's address. + * + * input parameters + * + * output parameters + * + * @return Pointer to a constant address object or null if the address has not + * yet been set. + */ +addr_t const *nwk_getAPAddress(void) +{ + addr_t addr; + + memset(&addr, 0x0, sizeof(addr)); + + return !memcmp(&sAPAddress, &addr, NET_ADDR_SIZE) ? 0 : &sAPAddress; +} + +/****************************************************************************** + * @fn nwk_getBCastAddress + * + * @brief Get the network broadcast address. + * + * input parameters + * + * output parameters + * + * @return Pointer to a constant address object. + */ +addr_t const *nwk_getBCastAddress(void) +{ + return (addr_t const *)mrfiBroadcastAddr; +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_globals.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_globals.h new file mode 100755 index 0000000..728c2ab --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_globals.h @@ -0,0 +1,51 @@ +/************************************************************************************************** + Filename: nwk_globals.h + Revised: $Date: 2008-07-30 11:22:21 -0700 (Wed, 30 Jul 2008) $ + Revision: $Revision: 17655 $ + Author: $Author: lfriedman $ + + Description: This header file supports the management of NWK global symbols. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_GLOBALS_H +#define NWK_GLOBALS_H + + +/* Prototypes */ +void nwk_globalsInit(void); +addr_t const *nwk_getMyAddress(void); +uint8_t nwk_setMyAddress(addr_t *addr); +void nwk_setAPAddress(addr_t *addr); +addr_t const *nwk_getAPAddress(void); +addr_t const *nwk_getBCastAddress(void); +uint8_t const *nwk_getFWVersion(void); +uint8_t nwk_getProtocolVersion(void); + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_types.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_types.h new file mode 100755 index 0000000..bb277ba --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk/nwk_types.h @@ -0,0 +1,344 @@ +/************************************************************************************************** + Filename: nwk_types.h + Revised: $Date: 2009-01-13 11:31:14 -0800 (Tue, 13 Jan 2009) $ + Revision: $Revision: 18744 $ + Author: $Author: lfriedman $ + + Description: This header file defines the SimpliciTI typedefs. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_TYPES_H +#define NWK_TYPES_H + +#define NWK_TX_RETRY_COUNT 10 +#define NWK_RX_RETRY_COUNT 10 + +#define NWK_APP_REPLY_BIT (0x80) + +#define NET_ADDR_SIZE MRFI_ADDR_SIZE /* size of address in bytes */ + +#ifdef FREQUENCY_AGILITY +#define NWK_FREQ_TBL_SIZE MRFI_NUM_LOGICAL_CHANS +#else +#define NWK_FREQ_TBL_SIZE 1 +#endif + +typedef struct +{ + uint8_t addr[NET_ADDR_SIZE]; +} addr_t; + +typedef uint8_t linkID_t; +typedef uint8_t ccRadioStatus_t; + + +/* *********************************************** + * Begin IOCTL Support + * *********************************************** + */ +enum ioctlObject { + IOCTL_OBJ_FREQ, + IOCTL_OBJ_CRYPTKEY, + IOCTL_OBJ_RAW_IO, + IOCTL_OBJ_RADIO, + IOCTL_OBJ_AP_JOIN, + IOCTL_OBJ_ADDR, + IOCTL_OBJ_CONNOBJ, + IOCTL_OBJ_FWVER, + IOCTL_OBJ_PROTOVER, + IOCTL_OBJ_NVOBJ, + IOCTL_OBJ_TOKEN +}; + +enum ioctlAction { + IOCTL_ACT_SET, + IOCTL_ACT_GET, + IOCTL_ACT_READ, + IOCTL_ACT_WRITE, + IOCTL_ACT_RADIO_SLEEP, + IOCTL_ACT_RADIO_AWAKE, + IOCTL_ACT_RADIO_SIGINFO, + IOCTL_ACT_RADIO_RSSI, + IOCTL_ACT_RADIO_RXON, + IOCTL_ACT_RADIO_RXIDLE, + IOCTL_ACT_RADIO_SETPWR, + IOCTL_ACT_ON, + IOCTL_ACT_OFF, + IOCTL_ACT_SCAN, + IOCTL_ACT_DELETE +}; + +typedef enum ioctlObject ioctlObject_t; +typedef enum ioctlAction ioctlAction_t; + +enum ioctlLevel +{ + IOCTL_LEVEL_0, + IOCTL_LEVEL_1, + IOCTL_LEVEL_2 +}; + +typedef enum ioctlLevel ioctlLevel_t; + +typedef struct +{ + addr_t *addr; + uint8_t *msg; + uint8_t len; + uint8_t port; +} ioctlRawSend_t; + +typedef struct +{ + addr_t *addr; + uint8_t *msg; + uint8_t len; + uint8_t port; + uint8_t hopCount; +} ioctlRawReceive_t; + +/* + * Signal information support + */ +typedef int8_t rssi_t; + +typedef struct +{ + rssi_t rssi; + uint8_t lqi; +} rxMetrics_t; + +typedef struct +{ + linkID_t lid; /* input: Link ID for which signal info desired */ + rxMetrics_t sigInfo; +} ioctlRadioSiginfo_t; + + +/* *** Begin SET/GET token support *** */ +enum tokenType +{ + TT_LINK, /* Token Type is Link */ + TT_JOIN /* Token Type is Join */ +}; + +typedef enum tokenType tokenType_t; + +/* Create a union. If either token ever changes type it will make things easier. */ +typedef union +{ + uint32_t linkToken; + uint32_t joinToken; +} token_t; + +typedef struct +{ + tokenType_t tokenType; + token_t token; +} ioctlToken_t; +/* *** End SET/GET token support *** */ + + +/* + * Frequency Agility support + */ +typedef struct +{ + uint8_t logicalChan; +} freqEntry_t; + +typedef struct +{ + uint8_t numChan; + freqEntry_t *freq; +} ioctlScanChan_t; + +/* Security typedefs to make things easier if they change types */ +typedef uint8_t secMAC_t; +typedef uint8_t secFCS_t; + +/*************************************************************************************** + * ** NV Object support ** + * + * The following object supports saving and restoring the information + * necessary to save and restore a device connection context. + * + * On a GET interface populates the IOCTL object with the version and length (in bytes) + * of the current static connection iformation area. In addition it populates the address + * pointed to by 'objPtr' with the base address of the connection context. At this point + * the caller can either copy to or from the address. Note that this is a dangerous + * interface, as the caller is provided with direct access to the connection context. + * + * When restoring the connection context some sanity checks are possible. If the + * version or length elements of the saved context do not match those of the current + * static object the static object should not be populated. If this sanity fails the + * caller is not provided with the pointer to the conneciton ocntext. + * + * This interface is fairly simple and it is possible to get the address of the + * connection context to do a restore by simply doing a GET call. This avoids the + * sanity checks. However, this is not recommended because there may be other side + * effects of doing a SET that are necessary when restoring a context and are done + * only when the proper option is used to restore the connection context. + * + *************************************************************************************/ +typedef struct +{ + uint8_t objVersion; + uint16_t objLen; + uint8_t **objPtr; +} ioctlNVObj_t; + +/* *********************************************** + * End IOCTL Support + * *********************************************** + */ + +enum smplStatus { + SMPL_SUCCESS, + SMPL_TIMEOUT, + SMPL_BAD_PARAM, + SMPL_NOMEM, + SMPL_NO_FRAME, + SMPL_NO_LINK, + SMPL_NO_JOIN, + SMPL_NO_CHANNEL, + SMPL_NO_PEER_UNLINK, + SMPL_TX_CCA_FAIL, + SMPL_NO_PAYLOAD, + SMPL_NO_AP_ADDRESS, + SMPL_NO_ACK +}; + +typedef enum smplStatus smplStatus_t; + +/* NWK application frame handling status codes */ +enum fhStatus +{ + FHS_RELEASE, /* handled in interrupt thread */ + FHS_KEEP, /* handled by background application */ + FHS_REPLAY /* non-ED case: NWK frame not for me that should be replayed */ +}; + +typedef enum fhStatus fhStatus_t; + +/******** BEGIN: Object support for parameter context in queue management *********/ +enum rcvType +{ + RCV_NWK_PORT, + RCV_APP_LID, + RCV_RAW_POLL_FRAME +}; + +typedef enum rcvType rcvType_t; + +/* Tx options type */ +typedef uint16_t txOpt_t; + +typedef struct +{ + rcvType_t type; + union + { + linkID_t lid; + uint8_t port; + mrfiPacket_t *pkt; + } t; +} rcvContext_t; +/******** END: Object support for parameter context in queue management *********/ + +#define SMPL_FWVERSION_SIZE 4 + +typedef struct +{ + uint8_t protocolVersion; + uint8_t fwVerString[SMPL_FWVERSION_SIZE]; +} smplVersionInfo_t; + +/* The following typedef is used to standardize the application Transaction ID field. + * This field can be used for detection of out-of-order application payloads if this + * is an issue. There is no real reason to use more than a byte for this support. But + * if this typedef is anything other than uint8_t be sure to attend to alignment and + * endian issues. + */ +typedef uint8_t appPTid_t; + +#ifdef ACCESS_POINT +/* Store-and-forward client info object */ +typedef struct +{ + addr_t clientAddr; + appPTid_t lastTID; +} sfClientInfo_t; + +typedef struct +{ + uint8_t curNumSFClients; + sfClientInfo_t sfClients[NUM_STORE_AND_FWD_CLIENTS]; +} sfInfo_t; +#endif + +/**************************************************************************************** + * SOME USEFUL MACROS + ****************************************************************************************/ + +/* Delay loop support. Requires mrfi.h */ +#define NWK_DELAY(spin) MRFI_DelayMs(spin) +#define NWK_REPLY_DELAY() MRFI_ReplyDelay(); + +/* Network applications may need to remember radio state because the user + * application may choose to turn Rx off. These macros help get and restore + * the radio Rx state. The macros should be in the same code block at the same level. + * The argument 's' is the 'current' radio state and should be set in the code block + * with a call to MRFI_GetRadioState() _before_ using the macros. + * + * Used extensively by NWK but user applications may use them as well. But it is + * much more liekly that an application will know the radio state since it likely + * will have set it with IOCTL calls. Requires mrfi.h. + */ +#define NWK_CHECK_FOR_SETRX(s) if (MRFI_RADIO_STATE_RX != s) \ + { \ + if (MRFI_RADIO_STATE_OFF == s) \ + { \ + MRFI_WakeUp(); \ + } \ + MRFI_RxOn(); \ + } + +#define NWK_CHECK_FOR_RESTORE_STATE(s) if (MRFI_RADIO_STATE_RX != s) \ + { \ + if (MRFI_RADIO_STATE_OFF == s) \ + { \ + MRFI_Sleep(); \ + } \ + else \ + { \ + MRFI_RxIdle(); \ + } \ + } +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.c new file mode 100755 index 0000000..2a93c39 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.c @@ -0,0 +1,619 @@ +/************************************************************************************************** + Filename: nwk_freq.c + Revised: $Date: 2008-12-10 13:50:46 -0800 (Wed, 10 Dec 2008) $ + Revision: $Revision: 18594 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Freq network application. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk.h" +#include "nwk_frame.h" +#include "nwk_freq.h" +#include "nwk_globals.h" +#include "nwk_api.h" +#include "nwk_security.h" + +#if defined( FREQUENCY_AGILITY ) +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static freqEntry_t sCurLogicalChan; +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +static fhStatus_t handle_freq_cmd(mrfiPacket_t *); +static fhStatus_t send_ping_reply(mrfiPacket_t *); +#ifndef ACCESS_POINT +static uint8_t change_channel_cmd_is_valid(mrfiPacket_t *); +#endif +#ifdef RANGE_EXTENDER +/* REs must replay frame before changing channels */ +static void replayFirst(mrfiPacket_t *); +#endif +#ifdef ACCESS_POINT +/* only the AP can broadcast this command */ +static void broadcast_channel_change(uint8_t); +#else +/* APs do not process this frame */ +static void change_channel_cmd(mrfiPacket_t *); +#endif + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_freqInit + * + * @brief Initialize NWK Frequency application. + * + * @return none. + */ +void nwk_freqInit(void) +{ + + memset(&sCurLogicalChan, 0x0, sizeof(sCurLogicalChan)); + + /* pick a random value to start the transaction ID for this app. */ + sTid = MRFI_RandomByte(); + + return; +} + +/*************************************************************************** + * @fn nwk_setChannel + * + * @brief Set requested logical channel. Accessed by application + * through IOCTL interface + * + * input parameters + * @param chan - pointer to channel object of requested channel + * + * @return status of operation: + * SMPL_SUCCESS if channel set + * SMPL_BAD_PARAM if requested channel is out of range + */ +smplStatus_t nwk_setChannel(freqEntry_t *chan) +{ + smplStatus_t rc = SMPL_BAD_PARAM; + + if (chan->logicalChan < NWK_FREQ_TBL_SIZE) + { + MRFI_SetLogicalChannel(chan->logicalChan); + sCurLogicalChan = *chan; + rc = SMPL_SUCCESS; + } + return rc; +} + +/****************************************************************************** + * @fn nwk_getChannel + * + * @brief Get current logical channel. Accessed by application through + * IOCTL interface + * + * input parameters + * @param chan - pointer to channel object of requested channel + * + * output parameters + * @param chan - populated channel object + * + * @return none. + */ +void nwk_getChannel(freqEntry_t *chan) +{ + *chan = sCurLogicalChan; + + return; +} + +/****************************************************************************** + * @fn handle_freq_cmd + * + * @brief Handle a Frequency application command. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return Return FHS_RELEASE if caller should release frame otherwise + * return FHS_REPLAY. + */ +static fhStatus_t handle_freq_cmd(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS)) + { + case FREQ_REQ_PING: + rc = send_ping_reply(frame); + break; + +#ifndef ACCESS_POINT + case FREQ_REQ_MOVE: +#ifdef RANGE_EXTENDER + replayFirst(frame); +#endif + /* Make sure the change channel Freq command came from + * a valid source before obeying. + */ + if (change_channel_cmd_is_valid(frame)) + { + change_channel_cmd(frame); + } + break; +#endif + +#ifdef ACCESS_POINT + case FREQ_REQ_REQ_MOVE: + break; +#endif + default: + break; + } + + return rc; +} + +#ifndef ACCESS_POINT +/****************************************************************************** + * @fn change_channel_cmd_is_valid + * + * @brief Check validity of a change channel command frame. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return Returns non-zero if command is valid, otherwise returns 0. + * Command is valid if either: + * - frame is directed + * - frame is from an AP and we know about that AP + * + * It is possible that either we don't know about an AP or that + * we do but this frame comes from another AP in range. + */ +static uint8_t change_channel_cmd_is_valid(mrfiPacket_t *frame) +{ + uint8_t rc = 0; + addr_t const *apAddr; + + /* If this was a directed frame obey the command. */ + if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + rc = 1; + } + else + { + /* Do we know about an AP? If not assume frame bogus. */ + apAddr = nwk_getAPAddress(); + if (apAddr) + { + /* Yes, we know about an AP. Is that who sent it? */ + if (!memcmp(apAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + /* OK. We obey. */ + rc = 1; + } + } + } + + return rc; +} +#endif /* !ACCESS_POINT */ + +#ifdef RANGE_EXTENDER +/****************************************************************************** + * @fn replayFirst + * + * @brief Range Extenders must replay the change-channel boradcast + * frame before actually changing its own channel. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return void + */ + +/* This routine takes care of some awkwardness. From the dispatch thread all + * we have is a pointer to the mrfiPacket_t element in the frame buffer into + * which the frame was retrieved. But to call the replay routine we need the + * entire frame information structure frameInfo_t. This routine regenerates + * the frame information structure pointer and then calls the replay routine. + * + * This approach requires that the disptach thread guarantee that it will + * always pass a pointer to the mrfiPacket_t structure in the frame + * information structure and not a copy of the mrfipacket_t element. It is + * either the approach here or change all the NWK application dispatch routine + * argument types. This latter has the downside of interfering with any + * user-implemented NWK applications. It also needlessly complicates the argument + * handling: except for this instance all any routine needs is the mrfiPacket_t + * pointer. + */ +static void replayFirst(mrfiPacket_t *frame) +{ + frameInfo_t *fiptr; + uint16_t offset = (uint16_t)&(((frameInfo_t *)0)->mrfiPkt); + + fiptr = (frameInfo_t *)(((uint8_t *)frame) - ((uint8_t *)offset)); + + nwk_replayFrame(fiptr); + + return; +} +#endif /* RANGE_EXTENDER */ + +#ifndef ACCESS_POINT +/******************************************************************************** + * @fn change_channel_cmd + * + * @brief Change to channel specified in received frame. Polling devices + * might be awake when the broadcast occurs but we want the channel + * change recovery to occur in a disciplined manner using the + * polling code. Also, with certain Test sceanrios in which a + * sleeping device is emulated we want to emulate 'missing' the + * broadcast change-channel command. + * + * input parameters + * @param frame - pointer to frame containing target logical channel. + * + * @return none. + */ +static void change_channel_cmd(mrfiPacket_t *frame) +{ +#if !defined( RX_POLLS ) + freqEntry_t chan; + + chan.logicalChan = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+F_CHAN_OS); + + nwk_setChannel(&chan); +#endif + return; +} +#endif /* !ACCESS_POINT */ + +/****************************************************************************** + * @fn send_ping_reply + * + * @brief Send Frequency application ping reply. + * + * input parameters + * @param frame - pointer to frame from pinger. + * + * @return FHS_RELEASE unless this isn't an Access Point. In this case for + * flow to et this far it is a Range Extender, so replay the frame + * by returning FHW_REPLAY + */ +static fhStatus_t send_ping_reply(mrfiPacket_t *frame) +{ +#ifdef ACCESS_POINT + uint8_t msg[FREQ_REQ_PING_FRAME_SIZE]; + frameInfo_t *pOutFrame; + + /* original request with reply bit on */ + msg[FB_APP_INFO_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS) | NWK_APP_REPLY_BIT; + msg[FB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+FB_TID_OS); + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_FREQ, msg, sizeof(msg), MAX_HOPS_FROM_AP)) + { + /* destination address is the source address of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + /* must use transaction ID of source frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_TRACTID_OS, (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS))); +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + + return FHS_RELEASE; +#else + return FHS_REPLAY; +#endif /* ACCESS_POINT */ +} + +/**************************************************************************************** + * @fn nwk_processFreq + * + * @brief Process a Frequency application frame. + * + * input parameters + * @param frame - pointer to frame + * + * @return Disposition for frame: either release (FHS_RELEASE) or replay (FHS_REPLAY). + */ +fhStatus_t nwk_processFreq(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + uint8_t replyType; + + /* Make sure this is a reply and see if we sent this. Validate the + * packet for reception by client app. + */ + if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, FB_APP_INFO_OS, FB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else if (SMPL_NOT_REPLY == replyType) + { + rc = handle_freq_cmd(frame); + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_scanForChannels + * + * @brief Scan for channels by sending a ping frame on each channel in the + * channel table and listen for a reply. + * + * input parameters + * @param channels - pointer to area to receive list of channels from which + * ping replies were received. + * + * output parameters + * @param channels - populated list of channels. + * + * @return statuis of operation.. + */ +uint8_t nwk_scanForChannels(freqEntry_t *channels) +{ + uint8_t msg[FREQ_REQ_PING_FRAME_SIZE], i, num=0, notBcast = 1; + addr_t *apAddr, retAddr; + uint8_t radioState = MRFI_GetRadioState(); + freqEntry_t chan; + freqEntry_t curChan; + + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + nwk_getChannel(&curChan); + + /* send to AP. If we don't know AP address, broadcast. */ + apAddr = (addr_t *)nwk_getAPAddress(); + if (!apAddr) + { + apAddr = (addr_t *)nwk_getBCastAddress(); + notBcast = 0; + } + + for (i=0; ilogicalChan); +#endif /* ACCESS_POINT */ + rc = nwk_setChannel((freqEntry_t *)val); + break; + + case IOCTL_ACT_GET: + nwk_getChannel((freqEntry_t *)val); + rc = SMPL_SUCCESS; + break; + + case IOCTL_ACT_SCAN: + { + ioctlScanChan_t *sc = (ioctlScanChan_t *)val; + + sc->numChan = nwk_scanForChannels(sc->freq); + rc = SMPL_SUCCESS; + } + break; + + default: + rc = SMPL_BAD_PARAM; + break; + } + + return rc; +} + +/****************************************************************************** + * @fn broadcast_channel_change + * +* @brief For Access Point only: broadcast a channel change frame. + * + * input parameters + * @param idx - index into channel table of new (logical) channel + * + * @return none. + */ +#ifdef ACCESS_POINT +#define CC_REDUNDANCY 1 /* Change-channel redundancy count */ +static void broadcast_channel_change(uint8_t idx) +{ + ioctlRawSend_t send; + uint8_t msg[FREQ_REQ_MOVE_FRAME_SIZE]; + uint8_t repeat = CC_REDUNDANCY; + + if (idx >= NWK_FREQ_TBL_SIZE) + { + return; + } + + msg[FB_APP_INFO_OS] = FREQ_REQ_MOVE; + msg[F_CHAN_OS] = idx; + + send.addr = (addr_t *)nwk_getBCastAddress(); + send.msg = msg; + send.len = sizeof(msg); + send.port = SMPL_PORT_FREQ; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); + /* Redundancy addresses the fact that an RE (or any always-listening + * device) might miss the command + */ + while (repeat--) + { + NWK_DELAY(250); + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); + } +} +#endif /* ACCESS_POINT */ + +#else /* FREQUENCY_AGILITY */ + +/********************************************************************************** + * @fn nwk_freqInit + * + * @brief Initialize NWK Frequency application. Stub when Frequency Agility + * not supported. + * + * @return none. + */ +void nwk_freqInit(void) +{ + return; +} + +/**************************************************************************************** + * @fn nwk_processFreq + * + * @brief Process a Frequency application frame. Stub when Frequency Agility + * not supported. + * + * input parameters + * @param frame - pointer to frame + * + * @return Disposition for frame: either release (FHS_RELEASE) or replay (FHS_REPLAY). + */ +fhStatus_t nwk_processFreq(mrfiPacket_t *frame) +{ + return FHS_RELEASE; +} + +#endif /* FREQUENCY_AGILITY */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.h new file mode 100755 index 0000000..4cc5f11 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_freq.h @@ -0,0 +1,72 @@ +/************************************************************************************************** + Filename: nwk_freq.h + Revised: $Date: 2008-05-06 16:48:33 -0700 (Tue, 06 May 2008) $ + Revision: $Revision: 17025 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI Freq network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_FREQ_H +#define NWK_FREQ_H + +/* application payload offsets */ +/* both */ +#define FB_APP_INFO_OS 0 +#define FB_TID_OS 1 + +/* Logical channel number for MOVE request. Frame brodcast so no TID + * is used. Channel number can occupy the TID location. Same offset + * used for channel change request. No reply to that frame. + */ +#define F_CHAN_OS 1 + +/* MGMT frame application requests */ +#define FREQ_REQ_MOVE 0x01 +#define FREQ_REQ_PING 0x02 +#define FREQ_REQ_REQ_MOVE 0x03 + +/* change the following as protocol developed */ +#define MAX_FREQ_APP_FRAME 2 + +/* set the out frame sizes */ +#define FREQ_REQ_MOVE_FRAME_SIZE 2 +#define FREQ_REQ_PING_FRAME_SIZE 2 + +/* prototypes */ +void nwk_freqInit(void); +fhStatus_t nwk_processFreq(mrfiPacket_t *); +#if defined( FREQUENCY_AGILITY ) +smplStatus_t nwk_setChannel(freqEntry_t *); +void nwk_getChannel(freqEntry_t *); +uint8_t nwk_scanForChannels(freqEntry_t *); +smplStatus_t nwk_freqControl(ioctlAction_t, void *); +#endif + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.c new file mode 100755 index 0000000..0dcd14a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.c @@ -0,0 +1,349 @@ + +/************************************************************************************************** + Filename: nwk_ioctl.c + Revised: $Date: 2009-01-13 11:31:14 -0800 (Tue, 13 Jan 2009) $ + Revision: $Revision: 18744 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI IOCTL implmentation. This interface + gives applications access to the "driver" network level functions + when necessary. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_ioctl.h" +#include "nwk_globals.h" +#include "nwk_security.h" +#ifdef ACCESS_POINT +#include "nwk_join.h" +#endif + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + + +/****************************************************************************** + * @fn nwk_rawSend + * + * @brief Builds an outut frame based on information provided by the + * caller. This function allows a raw transmission to the target + * if the network address is known. this function is used a lot + * to support NWK applications. + * + * input parameters + * @param info - pointer to strcuture containing info on how to build + * the outgoing frame. + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_NOMEM - no room in output frame queue + * SMPL_TX_CCA_FAIL - CCA failure + */ +smplStatus_t nwk_rawSend(ioctlRawSend_t *info) +{ + frameInfo_t *pOutFrame; + uint8_t hops; + + /* If we know frame is going to or from the AP then we can reduce the hop + * count. + */ + switch (info->port) + { + case SMPL_PORT_JOIN: + case SMPL_PORT_FREQ: + case SMPL_PORT_MGMT: + hops = MAX_HOPS_FROM_AP; + break; + + default: + hops = MAX_HOPS; + break; + } + + if (pOutFrame = nwk_buildFrame(info->port, info->msg, info->len, hops)) + { + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), info->addr, NET_ADDR_SIZE); +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, info->len, 0); +#endif /* SMPL_SECURE */ + return nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_CCA); + } + return SMPL_NOMEM; +} + +/****************************************************************************** + * @fn nwk_rawReceive + * + * @brief Retriievs specified from from the input frame queue. Additional + * information such as source address and hop count may also be + * retrieved + * + * input parameters + * @param info - pointer to structure containing info on what to retrieve + * + * output parameters - actually populated by nwk_retrieveFrame() + * info->msg - application payload copied here + * info->len - length of received application payload + * info->addr - if non-NULL points to memory to be populated with + * source address of retrieved frame. + * info->hopCount - if non-NULL points to memory to be populated with + * hop count of retrieved frame. + * + * @return Status of operation. + */ +smplStatus_t nwk_rawReceive(ioctlRawReceive_t *info) +{ + rcvContext_t rcv; + + rcv.type = RCV_NWK_PORT; + rcv.t.port = info->port; + + return nwk_retrieveFrame(&rcv, info->msg, &info->len, info->addr, &info->hopCount); +} + +/****************************************************************************** + * @fn nwk_radioControl + * + * @brief Handle radio control functions. + * + * input parameters + * @param action - radio operation to perform. currently suppoerted: + * sleep/unsleep + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_radioControl(ioctlAction_t action, void *val) +{ + smplStatus_t rc = SMPL_SUCCESS; + + if (IOCTL_ACT_RADIO_SLEEP == action) + { + /* go to sleep mode. */ + MRFI_RxIdle(); + MRFI_Sleep(); + } + else if (IOCTL_ACT_RADIO_AWAKE == action) + { + MRFI_WakeUp(); + +#if !defined( END_DEVICE ) + MRFI_RxOn(); +#endif + + } + else if (IOCTL_ACT_RADIO_SIGINFO == action) + { + ioctlRadioSiginfo_t *pSigInfo = (ioctlRadioSiginfo_t *)val; + connInfo_t *pCInfo = nwk_getConnInfo(pSigInfo->lid); + + if (!pCInfo) + { + return SMPL_BAD_PARAM; + } + memcpy(&pSigInfo->sigInfo, &pCInfo->sigInfo, sizeof(pCInfo->sigInfo)); + } + else if (IOCTL_ACT_RADIO_RSSI == action) + { + *((rssi_t *)val) = MRFI_Rssi(); + } + else if (IOCTL_ACT_RADIO_RXON == action) + { + MRFI_RxOn(); + } + else if (IOCTL_ACT_RADIO_RXIDLE == action) + { + MRFI_RxIdle(); + } +#ifdef EXTENDED_API + else if (IOCTL_ACT_RADIO_SETPWR == action) + { + uint8_t idx; + + switch (*(ioctlLevel_t *)val) + { + case IOCTL_LEVEL_2: + idx = 2; + break; + + case IOCTL_LEVEL_1: + idx = 1; + break; + + case IOCTL_LEVEL_0: + idx = 0; + break; + + default: + return SMPL_BAD_PARAM; + } + MRFI_SetRFPwr(idx); + return SMPL_SUCCESS; + } +#endif /* EXTENDED_API */ + else + { + rc = SMPL_BAD_PARAM; + } + return rc; +} + +/****************************************************************************** + * @fn nwk_joinContext + * + * @brief For Access Points we need a way to support changing the Join + * context. This will allow arbitration bewteen potentially nearby + * Access Points when a new device is joining. + * + * input parameters + * @param action - Join context is either on or off. + * + * output parameters + * + * @return Status of operation. Currently always succeeds. + */ +#ifdef ACCESS_POINT +smplStatus_t nwk_joinContext(ioctlAction_t action) +{ + nwk_setJoinContext((IOCTL_ACT_ON == action) ? JOIN_CONTEXT_ON : JOIN_CONTEXT_OFF); + + return SMPL_SUCCESS; +} +#endif + +/****************************************************************************** + * @fn nwk_deviceAddress + * + * @brief Set or Get this device address. The Set must be done before + * SMPL_Init() for it to take effect. The Get is always legal but + * the value could be invalid if it is called before a valid set + * call is made. + * + * input parameters + * @param action - Gte or Set + * @param addr - pointer to address object containing value on Set + * + * output parameters + * @param addr - pointer to address object to receive value on Get. + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Action request illegal or a Set request + * was not respected. + */ +smplStatus_t nwk_deviceAddress(ioctlAction_t action, addr_t *addr) +{ + smplStatus_t rc = SMPL_BAD_PARAM; + + if (IOCTL_ACT_GET == action) + { + memcpy(addr, nwk_getMyAddress(), sizeof(addr_t)); + rc = SMPL_SUCCESS; + } + else if (IOCTL_ACT_SET == action) + { + if (nwk_setMyAddress(addr)) + { + rc = SMPL_SUCCESS; + } + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_connectionControl + * + * @brief Access to connection table. Currently supports only deleting + * a connection from the table. + * + * input parameters + * @param action - Connection control action (only delete is curently valid). + * @param val - pointer to Link ID of connection on which to operate. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Action is not delete + * Link ID is the UUD Link ID + * No connection table info for Link ID + */ +smplStatus_t nwk_connectionControl(ioctlAction_t action, void *val) +{ + connInfo_t *pCInfo; + linkID_t lid = *((linkID_t *)val); + + if (IOCTL_ACT_DELETE != action) + { + return SMPL_BAD_PARAM; + } + + if ((SMPL_LINKID_USER_UUD == lid) || + (!(pCInfo=nwk_getConnInfo(lid)))) + { + return SMPL_BAD_PARAM; + } + + nwk_freeConnection(pCInfo); + + return SMPL_SUCCESS; +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.h new file mode 100755 index 0000000..fa5b961 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ioctl.h @@ -0,0 +1,53 @@ +/************************************************************************************************** + Filename: nwk_ioctl.h + Revised: $Date: 2008-04-29 15:47:05 -0700 (Tue, 29 Apr 2008) $ + Revision: $Revision: 16972 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI IOCTL implmentation. This interface + gives applications access to the "driver" network level functions + when necessary. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + + +#ifndef NWK_IOCTL_H +#define NWK_IOCTL_H + +/* prototypes */ +smplStatus_t nwk_rawSend(ioctlRawSend_t *); +smplStatus_t nwk_rawReceive(ioctlRawReceive_t *); +smplStatus_t nwk_radioControl(ioctlAction_t, void *); +smplStatus_t nwk_deviceAddress(ioctlAction_t, addr_t *); +smplStatus_t nwk_connectionControl(ioctlAction_t, void *); +#ifdef ACCESS_POINT +smplStatus_t nwk_joinContext(ioctlAction_t); +#endif + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_join.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_join.c new file mode 100755 index 0000000..b96325f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_join.c @@ -0,0 +1,583 @@ +/************************************************************************************************** + Filename: nwk_join.c + Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ + Revision: $Revision: 18697 $ + + Description: This file supports the SimpliciTI Join network application. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_link.h" +#include "nwk_join.h" +#include "nwk_globals.h" +#include "nwk_freq.h" +#include "nwk_security.h" +#include "nwk_mgmt.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +static uint32_t sJoinToken = 0; +static uint8_t (*spCallback)(linkID_t) = NULL; +static volatile uint8_t sTid = 0; + +#ifdef ACCESS_POINT +static sfInfo_t *spSandFContext = NULL; +static uint8_t sJoinOK = 0; +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +#ifdef ACCESS_POINT +static void smpl_send_join_reply(mrfiPacket_t *frame); +static uint32_t generateLinkToken(void); +static void handleJoinRequest(mrfiPacket_t *); +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_joinInit + * + * @brief Initialize Join application. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_joinInit(uint8_t (*pf)(linkID_t)) +{ + if (!sJoinToken) + { + sJoinToken = DEFAULT_JOIN_TOKEN; + } + + spCallback = pf; + (void) spCallback; /* keep compiler happy if we don't use this */ + + sTid = MRFI_RandomByte() ; + +#ifdef ACCESS_POINT + /* set link token to something other than deafult if desired */ + nwk_setLinkToken(generateLinkToken()); +#if defined(STARTUP_JOINCONTEXT_ON) + sJoinOK = 1; +#elif defined(STARTUP_JOINCONTEXT_OFF) + sJoinOK = 0; +#else +#error ERROR: Must define either STARTUP_JOINCONTEXT_ON or STARTUP_JOINCONTEXT_OFF +#endif + spSandFContext = nwk_getSFInfoPtr(); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_setJoinToken + * + * @brief Sets the join token. + * + * input parameters + * @param token - join token to be used on this network. + * + * output parameters + * no room in output queue. + * + * @return void + */ +void nwk_setJoinToken(uint32_t token) +{ + /* only set if the supplied token is non-zero. */ + if (token) + { + sJoinToken = token; + } + + return; +} + +/****************************************************************************** + * @fn nwk_getJoinToken + * + * @brief Gets the current join token. + * + * input parameters + * + * output parameters + * @param pToken - pointer to the returned value. + * + * @return Current link token + */ +void nwk_getJoinToken(uint32_t *pToken) +{ + /* only set if the supplied token is non-zero. */ + if (pToken) + { + *pToken = sJoinToken; + } + + return; +} + +/****************************************************************************** + * @fn generateLinkToken + * + * @brief Generate the link token to be used for the network controlled + * by this Access Point. + * + * input parameters + * + * output parameters + * + * @return void + */ +#ifdef ACCESS_POINT +static uint32_t generateLinkToken(void) +{ + return 0xDEADBEEF; +} + +/****************************************************************************** + * @fn smpl_send_join_reply + * + * @brief Send the Join reply. Include the Link token. If the device is + * a polling sleeper put it into the list of store-and-forward + * clients. + * + * input parameters + * @param frame - join frame for which a reply is needed...maybe + * + * output parameters + * + * @return void + */ +static void smpl_send_join_reply(mrfiPacket_t *frame) +{ + frameInfo_t *pOutFrame; + uint8_t msg[JOIN_REPLY_FRAME_SIZE]; + + /* Is this a legacy frame? If so continue. Otherwise check verion.*/ + if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > JOIN_LEGACY_MSG_LENGTH) + { + /* see if protocol version is correct... */ + if (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_PROTOCOL_VERSION_OS) != nwk_getProtocolVersion()) + { + /* Accommodation of protocol version differences can be noted or accomplished here. + * Otherwise, no match and the board goes back + */ + return; + } + } + + + /* see if join token is correct */ + { + uint32_t jt; + + nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_JOIN_TOKEN_OS, &jt, sizeof(jt)); + if (jt != sJoinToken) + { + return; + } + } + + /* send reply with tid, the link token, and the encryption context */ + { + uint32_t linkToken; + + nwk_getLinkToken(&linkToken); + nwk_putNumObjectIntoMsg((void *)&linkToken, msg+JR_LINK_TOKEN_OS, sizeof(linkToken)); + } + msg[JR_CRYPTKEY_SIZE_OS] = SEC_CRYPT_KEY_SIZE; + msg[JB_REQ_OS] = JOIN_REQ_JOIN | NWK_APP_REPLY_BIT; + /* sender's tid... */ + msg[JB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+JB_TID_OS); + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_JOIN, msg, sizeof(msg), MAX_HOPS_FROM_AP)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + +#ifdef AP_IS_DATA_HUB + /* if source device supports ED objects save source address to detect duplicate joins */ + if (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_NUMCONN_OS)) + { + if (nwk_saveJoinedDevice(frame) && spCallback) + { + spCallback(0); + } + } +#endif + } + else + { + /* oops -- no room left for Tx frame. Don't send reply. */ + return; + } + + /* If this device polls we need to provide store-and-forward support */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame),F_RX_TYPE) == F_RX_TYPE_POLLS) + { + uint8_t loc; + + /* Check duplicate status */ + if (!nwk_isSandFClient(MRFI_P_SRC_ADDR(frame), &loc)) + { + uint8_t *pNumc = &spSandFContext->curNumSFClients; + sfClientInfo_t *pClient = &spSandFContext->sfClients[*pNumc]; + + /* It's not a duplicate. Save it if there's room */ + if (*pNumc < NUM_STORE_AND_FWD_CLIENTS) + { + memcpy(pClient->clientAddr.addr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + *pNumc = *pNumc + 1; + } + else + { + /* No room left. Just return and don't send reply. */ + return; + } + } + else + { + /* We get here if it's a duplicate. We drop through and send reply. + * Reset the S&F marker in the Management application -- we should + * assume that the Client reset so the TID will be random. If this is + * simply a duplicate frame it causes no harm. + */ + nwk_resetSFMarker(loc); + } + } + +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + + /* It's not S&F or it is but we're OK to send reply. */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +/****************************************************************************** + * @fn nwk_join + * + * @brief Stub Join function for Access Points. + * + * input parameters + * + * output parameters + * + * @return Always returns SMPL_SUCCESS. + */ +smplStatus_t nwk_join(void) +{ + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_isSandFClient + * + * @brief Helper function to see if the destination of a frame we have is + * one of AP's store-and-forward clients. + * + * input parameters + * @param fPtr - pointer to address in frame in question + * + * output parameters + * @param entLoc - pointer to receive entry location in array of clients. + * + * @return Returns client info structure pointer if the destination is a + * store-and-forward client, else 0. + */ +sfClientInfo_t *nwk_isSandFClient(uint8_t *pAddr, uint8_t *entLoc) +{ + uint8_t i; + sfClientInfo_t *pSFClient = spSandFContext->sfClients; + + for (i=0; icurNumSFClients; ++i, ++pSFClient) + { + if (!memcmp(&pSFClient->clientAddr.addr, pAddr, NET_ADDR_SIZE)) + { + *entLoc = i; + return pSFClient; + } + } + + return 0; +} + +/****************************************************************************** + * @fn nwk_setJoinContext + * + * @brief Helper function to set Join context for Access Point. This will + * allow arbitration bewteen potentially nearby Access Points when + * a new device is joining. + * + * input parameters + * @param which - Join context is either off or on + * + * output parameters + * + * @return void + */ +void nwk_setJoinContext(uint8_t which) +{ + sJoinOK = (JOIN_CONTEXT_ON == which) ? 1 : 0; + + return; +} + +/****************************************************************************** + * @fn handleJoinRequest + * + * @brief Dispatches handler for specfic join request + * + * input parameters + * + * @param frame - Join frame received + * + * output parameters + * + * @return void + */ +static void handleJoinRequest(mrfiPacket_t *frame) +{ + if (JOIN_LEGACY_MSG_LENGTH == (MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS)) + { + /* Legacy frame. Spoof a join request */ + *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS) = JOIN_REQ_JOIN; + } + + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS)) + { + case JOIN_REQ_JOIN: + smpl_send_join_reply(frame); + break; + + default: + break; + } + + return; +} + +#else /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_join + * + * @brief Join functioanlity for non-AP devices. Send the Join token + * and wait for the reply. + * + * input parameters + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_join(void) +{ + uint8_t msg[JOIN_FRAME_SIZE]; + uint32_t linkToken; + addr_t apAddr; + uint8_t radioState = MRFI_GetRadioState(); + smplStatus_t rc = SMPL_NO_JOIN; + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + +#if defined( FREQUENCY_AGILITY ) + uint8_t i, numChan; + freqEntry_t channels[NWK_FREQ_TBL_SIZE]; + + if (!(numChan=nwk_scanForChannels(channels))) + { + return SMPL_NO_CHANNEL; + } + + for (i=0; i +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_link.h" +#include "nwk_globals.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static uint32_t sLinkToken = 0; +static volatile uint8_t sListenActive = 0; +#if NUM_CONNECTIONS > 0 +static volatile linkID_t sServiceLinkID[NUM_CONNECTIONS]; +#endif +static volatile uint8_t sNumLinkers = 0; +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +#define SENT_REPLY 1 +#define SENT_NO_REPLY 2 +static uint8_t smpl_send_link_reply(mrfiPacket_t *); +static fhStatus_t handleLinkRequest(mrfiPacket_t *); +#if defined(EXTENDED_API) +static void smpl_send_unlink_reply(mrfiPacket_t *); +#endif + + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_linkInit + * + * @brief Initialize link app. Set link token to the default. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_linkInit(void) +{ + if (!sLinkToken) + { + /* if the link token has not been set externally by the time we get here + * (such as by the ioctl token-setting interface) assign the default + */ + sLinkToken = DEFAULT_LINK_TOKEN; + } + + /* set a non-zero TID. */ + while (!(sTid = MRFI_RandomByte())) ; + +#if NUM_CONNECTIONS > 0 + memset((void *)&sServiceLinkID, 0x0, sizeof(sServiceLinkID)); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_setLinkToken + * + * @brief Sets the link token received in a Join reply. + * + * input parameters + * @param token - Link token to be used on this network to link to any peer. + * + * output parameters + * + * @return void + */ +void nwk_setLinkToken(uint32_t token) +{ + /* only set if the supplied token is non-zero. */ + if (token) + { + sLinkToken = token; + } + + return; +} + +/****************************************************************************** + * @fn nwk_getLinkToken + * + * @brief Gets the current link token. + * + * input parameters + * + * output parameters + * @param pToken - pointer to the returned value. + * + * @return Current link token + */ +void nwk_getLinkToken(uint32_t *pToken) +{ + /* only set if the supplied token is non-zero. */ + if (pToken) + { + *pToken = sLinkToken; + } + + return; +} + +#if defined(EXTENDED_API) +/****************************************************************************** + * @fn nwk_unlink + * + * @brief Called from the application level to tear down a link. + * + * input parameters + * + * output parameters + * @param lid - Link ID assigned for this link + * + * @return Status of the operation. + * SMPL_SUCCESS + * SMPL_BAD_PARAM No connection table entry for this Link ID; + * SMPL_LINKID_USER_UUD not valid since it is not + * connection-based. + * SMPL_TIMEOUT No reply from peer. + * SMPL_NO_PEER_UNLINK Peer did not have a Connection Table entry for me. + */ +smplStatus_t nwk_unlink(linkID_t lid) +{ + uint8_t msg[UNLINK_FRAME_SIZE]; + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_SUCCESS; + addr_t addr; + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + /* is there connection info? */ + if (!pCInfo || (lid == SMPL_LINKID_USER_UUD)) + { + return SMPL_BAD_PARAM; + } + + /* set request byte */ + msg[LB_REQ_OS] = LINK_REQ_UNLINK; + + /* set the transaction ID. this allows target to figure out duplicates */ + msg[LB_TID_OS] = sTid; + + /* remote port to be sent in message to help match connection */ + msg[UL_RMT_PORT_OS] = pCInfo->portRx; + + /* setup for ioctl raw I/O */ + memcpy(addr.addr, pCInfo->peerAddr, NET_ADDR_SIZE); + ioctl_info.send.addr = &addr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_LINK; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + { + uint8_t spin = NWK_RX_RETRY_COUNT; + uint8_t radioState = MRFI_GetRadioState(); + + ioctl_info.recv.port = SMPL_PORT_LINK; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = (addr_t *)0; + + do + { + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + if ((msg[LB_REQ_OS] & (~NWK_APP_REPLY_BIT)) == LINK_REQ_UNLINK) + { + rc = (smplStatus_t)msg[ULR_RESULT_OS]; + break; + } + } + if (!spin) + { + rc = SMPL_TIMEOUT; + break; + } + --spin; + } while (1); + + /* it's ok to unconditionally invalidate connection object */ + nwk_freeConnection(pCInfo); + } + return rc; +} +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn nwk_link + * + * @brief Called from the application level to accomplish the link + * + * input parameters + * + * output parameters + * @param lid - pointer to Link ID (port) assigned for this link + * + * @return Status of the operation. + */ +smplStatus_t nwk_link(linkID_t *lid) +{ + uint8_t msg[LINK_FRAME_SIZE]; + connInfo_t *pCInfo = nwk_getNextConnection(); + smplStatus_t rc; + + if (pCInfo) + { + addr_t addr; + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + if (!nwk_allocateLocalRxPort(LINK_SEND, pCInfo)) + { + nwk_freeConnection(pCInfo); + return SMPL_NOMEM; + } + + memcpy(addr.addr, nwk_getBCastAddress(), NET_ADDR_SIZE); + ioctl_info.send.addr = &addr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_LINK; + + /* Put link token in */ + nwk_putNumObjectIntoMsg((void *)&sLinkToken, msg+L_LINK_TOKEN_OS, sizeof(sLinkToken)); + + /* set port to which the remote device should send */ + msg[L_RMT_PORT_OS] = pCInfo->portRx; + + /* set the transaction ID. this allows target to figure out duplicates */ + msg[LB_TID_OS] = sTid; + + /* set my Rx type */ + msg[L_MY_RXTYPE_OS] = nwk_getMyRxType(); + + /* set request byte */ + msg[LB_REQ_OS] = LINK_REQ_LINK; + + /* protocol version number */ + msg[L_PROTOCOL_VERSION_OS] = nwk_getProtocolVersion(); + +#if defined(SMPL_SECURE) + pCInfo->connTxCTR = MRFI_RandomByte() | \ + ((uint32_t)(MRFI_RandomByte())<<8) | \ + ((uint32_t)(MRFI_RandomByte())<<16) | \ + ((uint32_t)(MRFI_RandomByte())<<24); + + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[L_CTR_OS], 4); +#endif + + + if (SMPL_SUCCESS != (rc=SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send))) + { + return rc; + } + + { + uint8_t radioState = MRFI_GetRadioState(); + + ioctl_info.recv.port = SMPL_PORT_LINK; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = (addr_t *)pCInfo->peerAddr; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + uint8_t firstByte = msg[LB_REQ_OS] & (~NWK_APP_REPLY_BIT); + + /* Sanity check for correct reply frame. Older version + * has the length instead of the request as the first byte. + */ + if ((firstByte != LINK_REQ_LINK) && + (firstByte != LINK_REPLY_LEGACY_MSG_LENGTH) + ) + { + /* invalidate connection object */ + nwk_freeConnection(pCInfo); + return SMPL_NO_LINK; + + } + } + else + { + /* no successful receive */ + nwk_freeConnection(pCInfo); + return SMPL_TIMEOUT; + } + + pCInfo->connState = CONNSTATE_CONNECTED; + pCInfo->portTx = msg[LR_RMT_PORT_OS]; /* link reply returns remote port */ + *lid = pCInfo->thisLinkID; /* return our local port number */ + + /* Set hop count. If it's a polling device set the count to the + * distance to the AP. Otherwise, set it to the max less the remaining + * which will be the path taken for this frame. It will be no worse + * then tha max and probably will be better. + */ + if (F_RX_TYPE_POLLS == msg[LR_MY_RXTYPE_OS]) + { + pCInfo->hops2target = MAX_HOPS_FROM_AP; + } + else + { + /* Can't really use this trick because the device could move. If the + * devices are all static this may work unless the initial reception + * was marginal. + */ +#if defined(DEVICE_DOES_NOT_MOVE) + pCInfo->hops2target = MAX_HOPS - ioctl_info.recv.hopCount; +#else + pCInfo->hops2target = MAX_HOPS; +#endif + } + +#if defined(SMPL_SECURE) + nwk_getNumObjectFromMsg((void *)&msg[LR_CTR_OS], (void *)&pCInfo->connRxCTR, 4); +#endif + } + + /* guard against duplicates... */ + ++sTid; + if (!sTid) + { + sTid = 1; + } + return SMPL_SUCCESS; + } + + return SMPL_NOMEM; +} + +#if defined(EXTENDED_API) +/****************************************************************************** + * @fn smpl_send_unlink_reply + * + * @brief Send the unlink reply to the device trying to unlink + * + * input parameters + * @param frame - frame received from linker + * + * output parameters + * + * @return void + */ +static void smpl_send_unlink_reply(mrfiPacket_t *frame) +{ + connInfo_t *pCInfo; + frameInfo_t *pOutFrame; + uint8_t msg[UNLINK_REPLY_FRAME_SIZE]; + smplStatus_t rc = SMPL_NO_PEER_UNLINK; + + /* match the remote port and source address with a connection table entry */ + if (pCInfo = nwk_findPeer((addr_t *)MRFI_P_SRC_ADDR(frame), *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+UL_RMT_PORT_OS))) + { + /* Note we unconditionally free the connection resources */ + nwk_freeConnection(pCInfo); + rc = SMPL_SUCCESS; + } + + /* set reply bit */ + msg[LB_REQ_OS] = LINK_REQ_UNLINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+LB_TID_OS); + + /* result of freeing local connection */ + msg[ULR_RESULT_OS] = rc; + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +#if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } +} +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn smpl_send_link_reply + * + * @brief Send the link reply to the device trying to link. This routine + * will handle duplicates. + * + * input parameters + * @param frame - frame received from linker + * + * output parameters + * + * @return Returns SENT_REPLY if reply sent, else SENT_NO_REPLY. + * The return value is used as this routine unwinds to know + * whether to replay the frame. An RE or AP can host an ED + * object in which case it might send a reply (possibly from + * a duplicate frame). If we do reply we do not want to replay. + */ +static uint8_t smpl_send_link_reply(mrfiPacket_t *frame) +{ +#if NUM_CONNECTIONS > 0 + frameInfo_t *pOutFrame; + connInfo_t *pCInfo; + uint8_t remotePort; + uint8_t msg[LINK_REPLY_FRAME_SIZE]; + + /* Is this a legacy frame? If so continue. Otherwise check version.*/ + if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > LINK_LEGACY_MSG_LENGTH) + { + /* see if protocol version is correct... */ + if (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_PROTOCOL_VERSION_OS) != nwk_getProtocolVersion()) + { + /* Accommodation of protocol version differences can be noted or accomplished here. + * This field was also checked in the join transaction but it is checked again here + * because that check may not have occurred if thre is no AP in this topology. + * Otherwise, no match and the board goes back + */ + return SENT_NO_REPLY; + } + } + + /* see if token is correct */ + { + uint32_t lt; + + nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_LINK_TOKEN_OS, <, sizeof(lt)); + if (lt != sLinkToken) + { + return SENT_NO_REPLY; + } + } + + /* if we get here the token matched. */ + + /* is this a duplicate request? */ + remotePort = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_RMT_PORT_OS); + if (pCInfo=nwk_isLinkDuplicate(MRFI_P_SRC_ADDR(frame), remotePort)) + { + /* resend reply */ + msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+LB_TID_OS); + + /* Send reply with the local port number so the remote device knows where to + * send packets. + */ + msg[LR_RMT_PORT_OS] = pCInfo->portRx; + + /* put my Rx type in there. used to know how to set hops when sending back. */ + msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); +#if defined(SMPL_SECURE) + /* Set the Tx counter value for peer's Rx counter object */ + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); + /* We also need to save the newly generated Rx counter value. */ + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_CTR_OS), (void *)&pCInfo->connRxCTR, 4); +#endif + if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS-(GET_FROM_FRAME(MRFI_P_PAYLOAD(frame),F_HOP_COUNT)))) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +#if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + return SENT_REPLY; + } + + if (!sListenActive) + { + /* We've checked for duplicate and resent reply. In that case we weren't listening + * so just go back`. + */ + return SENT_NO_REPLY; + } + + /* room to link? */ +#if defined(AP_IS_DATA_HUB) + pCInfo = nwk_findAlreadyJoined(frame); + + if (!pCInfo) +#endif + { + pCInfo = nwk_getNextConnection(); + } + + if (pCInfo) + { + /* yes there's room and it's not a dup. address. */ + memcpy(&pCInfo->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + if (!nwk_allocateLocalRxPort(LINK_REPLY, pCInfo)) + { + nwk_freeConnection(pCInfo); + /* we're done with the packet */ + return SENT_REPLY; + } + + /* The local Rx port is the one returned in the connection structure. The + * caller is waiting on this to be set. The code here is running in an ISR + * thread so the caller will see this change after RETI. + */ + if (NUM_CONNECTIONS == sNumLinkers) + { + /* Something is wrong -- no room to stack Link request */ + nwk_freeConnection(pCInfo); + /* we're done with the packet */ + return SENT_REPLY; + } + sServiceLinkID[sNumLinkers++] = pCInfo->thisLinkID; + + /* save the remote Tx port */ + pCInfo->portTx = remotePort; + + /* connection is valid... */ + pCInfo->connState = CONNSTATE_CONNECTED; + + /* Set hop count. If it's a polling device set the count to the + * distance to the AP. otherwise, set it to the max less the remaining + * which will be the path taken for this frame. It will be no worse + * then tha max and probably will be better. + */ + if (F_RX_TYPE_POLLS == *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_MY_RXTYPE_OS)) + { + /* It polls. so. we'll be sending to the AP which will store the + * frame. The AP is only MAX_HOPS_FROM_AP hops away from us. + */ + pCInfo->hops2target = MAX_HOPS_FROM_AP; + } + else + { + /* Can't really use this trick because the device could move. If the + * devices are all static this may work unless the initial reception + * was marginal. + */ +#if defined(DEVICE_DOES_NOT_MOVE) + pCInfo->hops2target = MAX_HOPS - GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT); +#else + pCInfo->hops2target = MAX_HOPS; +#endif + } + /* Send reply with the local port number so the remote device knows where to + * send packets. + */ + msg[LR_RMT_PORT_OS] = pCInfo->portRx; + + /* put my Rx type in there. used to know how to set hops when sending back. */ + msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); + + msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+LB_TID_OS); +#if defined(SMPL_SECURE) + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_CTR_OS), (void *)&pCInfo->connRxCTR, 4); + pCInfo->connTxCTR = MRFI_RandomByte() | \ + ((uint32_t)(MRFI_RandomByte())<<8) | \ + ((uint32_t)(MRFI_RandomByte())<<16) | \ + ((uint32_t)(MRFI_RandomByte())<<24); + + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); +#endif + if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS-(GET_FROM_FRAME(MRFI_P_PAYLOAD(frame),F_HOP_COUNT)))) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +#if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif + if (SMPL_SUCCESS != nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED)) + { + /* better release the connection structure */ + nwk_freeConnection(pCInfo); + } + } + else + { + /* better release the connection structure */ + nwk_freeConnection(pCInfo); + } + } + /* we're done with the packet */ + return SENT_REPLY; +#else + return SENT_NO_REPLY; +#endif /* NUM_CONNECTIONS */ +} + +/****************************************************************************** + * @fn nwk_processLink + * + * @brief Process Link frame. Just save the frame for the Link app if it + * a reply. If it isn't a reply, send the reply in this thread. + * + * input parameters + * @param frame - pointer to frame to be processed + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame.. + */ +fhStatus_t nwk_processLink(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. send the reply. + */ + if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, LB_REQ_OS, LB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* No, we didn't send it. Process request assuming it's + * intended for us. + */ + rc = handleLinkRequest(frame); + } + + (void) replyType; /* keep compiler happy when ED built... */ + + return rc; +} + +/****************************************************************************** + * @fn nwk_getLocalLinkID + * + * @brief This routine checks to see if a service port has been assigned + * as a result of a link reply frame being received. It is the means + * by which the user thread knows that the waiting is over for the + * link listen. the value is set in an interrupt thread. + * + * input parameters + * + * output parameters + * + * @return Local port assigned when the link reply was received. + */ +linkID_t nwk_getLocalLinkID(void) +{ + linkID_t lid = 0; +#if NUM_CONNECTIONS > 0 + uint8_t i; + bspIState_t intState; + + + BSP_ENTER_CRITICAL_SECTION(intState); + if (sNumLinkers) + { + sNumLinkers--; + BSP_EXIT_CRITICAL_SECTION(intState); + + nwk_setListenContext(LINK_LISTEN_OFF); + lid = sServiceLinkID[0]; + /* If more than one Link frame has been processed without an intervening + * Listen assume that there will be another Link Listen call that will + * poll for completion which has already occurred. Age any existing entries. + * This code was added to deal with the possibility of mulitple EDs being + * activated simultaneously in the AP-as-data-hub example. This opens a + * window of opportunity for a "typical" scenario to get hosed. But for + * a "typical" scenario to get hosed a number of improbable events have to + * occur. These are deemed far less likely than the multiple-ED-activation + * scenario in the AP-as-dat-hub case. + */ + for (i=0; i +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_mgmt.h" +#include "nwk_join.h" +#include "nwk_globals.h" +#include "nwk_QMgmt.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +#ifndef ACCESS_POINT +static addr_t const *sAPAddr = NULL; +#else +static uint8_t sSFMarker[NUM_STORE_AND_FWD_CLIENTS] = {0}; +#endif + +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static void smpl_send_mgmt_reply(mrfiPacket_t *); +#ifdef ACCESS_POINT +static void send_poll_reply(mrfiPacket_t *); +#endif + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_mgmtInit + * + * @brief Initialize Management functions. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_mgmtInit(void) +{ + sTid = MRFI_RandomByte(); + +#ifdef ACCESS_POINT + memset(&sSFMarker, 0x0, sizeof(sSFMarker)); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_processMgmt + * + * @brief Process Management frame. Just save the frame for the Management + * app it it is a reply. If it isn't a reply, send the reply in this + * thread. + * + * input parameters + * @param frame - pointer to frame to be processed + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ +fhStatus_t nwk_processMgmt(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. send the reply. + */ + if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, MB_APP_INFO_OS, MB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* no, we didn't send it. send reply if it's intended for us */ + if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + smpl_send_mgmt_reply(frame); + + /* we're done with the frame. */ + rc = FHS_RELEASE; + } + else + { + rc = FHS_REPLAY; + } + } + + (void) replyType; /* keep compiler happy */ + + return rc; +} + +/****************************************************************************** + * @fn smpl_send_mgmt_reply + * + * @brief Send appropriate reply to Management frame. + * + * input parameters + * @param frame - Pointer to frame for which reply required. + * + * output parameters + * + * @return void + */ +static void smpl_send_mgmt_reply(mrfiPacket_t *frame) +{ +#ifdef ACCESS_POINT + /* what kind of management frame is this? */ + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+MB_APP_INFO_OS)) + { + case MGMT_REQ_POLL: + send_poll_reply(frame); + break; + + default: + break; + } +#endif /* ACCESS_POINT */ + return; +} + + +#ifdef ACCESS_POINT +/****************************************************************************** + * @fn send_poll_reply + * + * @brief Send reply to polling frame. + * + * input parameters + * @param frame - Pointer to frame for which reply required. + * + * output parameters + * + * @return void + */ +static void send_poll_reply(mrfiPacket_t *frame) +{ + uint8_t msgtid = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+MB_TID_OS); + frameInfo_t *pOutFrame; + sfClientInfo_t *pClientInfo; + uint8_t loc; + + /* Make sure this guy is really a client. We can tell from the source address. */ + if (!(pClientInfo=nwk_isSandFClient(MRFI_P_SRC_ADDR(frame), &loc))) + { + /* TODO: maybe send an error frame? */ + return; + } + + /* If we have to resync the TID then do it based on the first + * poll frame we see + */ + if (!sSFMarker[loc]) + { + /* If the marker flag is null then it has been initialized, i.e., + * there has been a reset. In this case infer that we need to update + * a (probably) stale last TID. The test will always be true the first + * time through after a client is established even when an NV restore + * did not take place but this does no harm. + */ + pClientInfo->lastTID = msgtid; + sSFMarker[loc] = 1; + } + /* If we've seen this poll frame before ignore it. Otherwise we + * may send a stored frame when we shouldn't. + */ + else if (nwk_checkAppMsgTID(pClientInfo->lastTID, msgtid)) + { + pClientInfo->lastTID = msgtid; + } + else + { + return; + } + + if (pOutFrame = nwk_getSandFFrame(frame, M_POLL_PORT_OS)) + { + /* We need to adjust the order in the queue in this case. Currently + * we know it is in the input queue and that this adjustment is safe + * because we're in an ISR thread. This is a fragile fix, though, and + * should be revisited when time permits. + */ + nwk_QadjustOrder(INQ, pOutFrame->orderStamp); + + /* reset hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_HOP_COUNT, MAX_HOPS_FROM_AP); + /* It's gonna be a forwarded frame. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_FWD_FRAME, 0x80); + + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + else + { + nwk_SendEmptyPollRspFrame(frame); + } + + return; +} + +/****************************************************************************** + * @fn nwk_resetSFMarker + * + * @brief Reset S&F cklient marker so the TIDs resync. + * + * input parameters + * @param idx - index of the client that should be reset. + * + * output parameters + * + * @return void + */ +void nwk_resetSFMarker(uint8_t idx) +{ + sSFMarker[idx] = 0; + + return; +} + +#else /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_poll + * + * @brief Poll S&F server for any waiting frames. + * + * input parameters + * @param port - Port on peer. + * @param addr - SimpliciTI address of peer. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_NO_AP_ADDRESS - We don't know Access Point's address + * SMPL_NOMEM - no room in output frame queue + * SMPL_TX_CCA_FAIL - CCA failure + */ +smplStatus_t nwk_poll(uint8_t port, uint8_t *addr) +{ + uint8_t msg[MGMT_POLL_FRAME_SIZE]; + ioctlRawSend_t send; + + msg[MB_APP_INFO_OS] = MGMT_REQ_POLL; + msg[MB_TID_OS] = sTid; + msg[M_POLL_PORT_OS] = port; + memcpy(msg+M_POLL_ADDR_OS, addr, NET_ADDR_SIZE); + + /* it's OK to increment the TID here because the reply will not be + * matched based on this number. The reply to the poll comes back + * to the client port, not the Management port. + */ + sTid++; + + if (!sAPAddr) + { + sAPAddr = nwk_getAPAddress(); + if (!sAPAddr) + { + return SMPL_NO_AP_ADDRESS; + } + } + send.addr = (addr_t *)sAPAddr; + send.msg = msg; + send.len = sizeof(msg); + send.port = SMPL_PORT_MGMT; + + return SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); +} + +#endif /* ACCESS_POINT */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_mgmt.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_mgmt.h new file mode 100755 index 0000000..d913abb --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_mgmt.h @@ -0,0 +1,67 @@ +/************************************************************************************************** + Filename: nwk_mgmt.h + Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ + Revision: $Revision: 18697 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI Mgmt network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_MGMT_H +#define NWK_MGMT_H + +/* MGMT frame application requests */ +#define MGMT_REQ_POLL 0x01 + +/* change the following as protocol developed */ +#define MAX_MGMT_APP_FRAME 7 + +/* application payload offsets */ +/* both */ +#define MB_APP_INFO_OS 0 +#define MB_TID_OS 1 + +/* Poll frame */ +#define M_POLL_PORT_OS 2 +#define M_POLL_ADDR_OS 3 + +/* change the following as protocol developed */ +#define MAX_MGMT_APP_FRAME 7 + +/* frame sizes */ +#define MGMT_POLL_FRAME_SIZE 7 + +/* prototypes */ +void nwk_mgmtInit(void); +fhStatus_t nwk_processMgmt(mrfiPacket_t *); +smplStatus_t nwk_poll(uint8_t, uint8_t *); +void nwk_resetSFMarker(uint8_t); + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.c new file mode 100755 index 0000000..2e55a48 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.c @@ -0,0 +1,314 @@ +/************************************************************************************************** + Filename: nwk_ping.c + Revised: $Date: 2009-01-18 16:01:08 -0800 (Sun, 18 Jan 2009) $ + Revision: $Revision: 18796 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Ping network application. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_ping.h" +#include "nwk_globals.h" +#include "nwk_api.h" +#include "nwk_freq.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static void smpl_send_ping_reply(mrfiPacket_t *); +static void handlePingRequest(mrfiPacket_t *); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_pingInit + * + * @brief Initialize Ping application. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_pingInit(void) +{ + sTid = MRFI_RandomByte(); + + return; +} + +/****************************************************************************** + * @fn nwk_ping + * + * @brief Called from the application level to ping a peer. A small + * payload is sent that includes a tid to detect correct reply. + * Caller does not supply payload. + * + * input parameters + * @param lid - Link ID representing peer to ping + * + * output parameters + * + * @return SMPL_SUCCESS valid reply received + * SMPL_TIMEOUT no valid reply received + * SMPL_NO_CHANNEL no channels returned on a scan + */ +smplStatus_t nwk_ping(linkID_t lid) +{ + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + uint8_t done = 0; + uint8_t repeatIt = 2; + uint8_t msg[MAX_PING_APP_FRAME]; + uint8_t radioState = MRFI_GetRadioState(); + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + if (!pCInfo || (SMPL_LINKID_USER_UUD == lid)) + { + /* either link ID bogus or tried to ping the unconnected user datagram link ID. */ + return rc; + } + + do + { +#if defined(FREQUENCY_AGILITY) && !defined(ACCESS_POINT) + uint8_t i, numChan; + freqEntry_t channels[NWK_FREQ_TBL_SIZE]; + + if (repeatIt == 2) + { + /* If FA enabled, first time through set up so that the 'for' + * loop checks the current channel. This saves time (no scan) + * and is very likely to succeed. Populate the proper strucure. + */ + SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_GET, channels); + numChan = 1; + } + else + { + /* If we get here we must scan for the channel we're now on */ + if (!(numChan=nwk_scanForChannels(channels))) + { + return SMPL_NO_CHANNEL; + } + } + /* Either we scan next time through or we're done */ + repeatIt--; + + /* this loop Pings on each channel (probably only 1) looking + * for peer. + */ + for (i=0; ipeerAddr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_PING; + + /* fill in msg */ + msg[PB_REQ_OS] = PING_REQ_PING; + msg[PB_TID_OS] = sTid; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + ioctl_info.recv.port = SMPL_PORT_PING; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = 0; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + repeatIt = 0; + done = 1; + sTid++; /* guard against duplicates */ + } + } + } while (repeatIt); + + return done ? SMPL_SUCCESS : SMPL_TIMEOUT; + +} + +/****************************************************************************** + * @fn smpl_send_ping_reply + * + * @brief Send a reply to a ping request. + * + * input parameters + * @param frame - pointer to frame containing request + * + * output parameters + * + * @return void + */ +static void smpl_send_ping_reply(mrfiPacket_t *frame) +{ + frameInfo_t *pOutFrame; + + /* Build the reply frame. The application payload is the one included in the + * received frame payload. + */ + if (pOutFrame = nwk_buildFrame(SMPL_PORT_PING, MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS, MRFI_GET_PAYLOAD_LEN(frame)-F_APP_PAYLOAD_OS, MAX_HOPS)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + /* turn on the reply bit in the application payload */ + *(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt)+F_APP_PAYLOAD_OS+PB_REQ_OS) |= NWK_APP_REPLY_BIT; +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, MRFI_GET_PAYLOAD_LEN(frame)-F_APP_PAYLOAD_OS, 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } +} + +/****************************************************************************** + * @fn nwk_processPing + * + * @brief Ping network application frame handler. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ +fhStatus_t nwk_processPing(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. Send the reply. + */ + replyType = nwk_isValidReply(frame, sTid, PB_REQ_OS, PB_TID_OS); + if (SMPL_MY_REPLY == replyType) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. If I'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* No, we didn't send it. Send reply assuming it's a Ping intended for us. */ + handlePingRequest(frame); + + rc = FHS_RELEASE; + } + + return rc; +} + +/****************************************************************************** + * @fn handlePingRequest + * + * @brief Dispatches handler for specfic Ping request + * + * input parameters + * + * @param frame - Ping frame received + * + * output parameters + * + * @return void + */ +static void handlePingRequest(mrfiPacket_t *frame) +{ + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS)) + { + case PING_REQ_PING: + smpl_send_ping_reply(frame); + break; + + default: + break; + } + + return; +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.h new file mode 100755 index 0000000..c7dd3be --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_ping.h @@ -0,0 +1,58 @@ +/************************************************************************************************** + Filename: nwk_ping.h + Revised: $Date: 2008-05-14 14:22:31 -0700 (Wed, 14 May 2008) $ + Revision: $Revision: 17075 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Ping network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_PING_H +#define NWK_PING_H + +/* change the following as protocol developed */ +#define MAX_PING_APP_FRAME 2 + +/* application payload offsets */ +/* both */ +#define PB_REQ_OS 0 +#define PB_TID_OS 1 + + +/* ping requests */ +#define PING_REQ_PING 1 + +/* prototypes */ +fhStatus_t nwk_processPing(mrfiPacket_t *); +void nwk_pingInit(void); +smplStatus_t nwk_ping(linkID_t); + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_security.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_security.c new file mode 100755 index 0000000..5ee4acc --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_security.c @@ -0,0 +1,549 @@ +/************************************************************************************************** + Filename: nwk_security.c + Revised: $Date: 2009-01-20 14:05:46 -0800 (Tue, 20 Jan 2009) $ + Revision: $Revision: 18816 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Security network application. + + Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include /* needed for NULL */ +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_security.h" +#include "nwk_frame.h" +#include "nwk.h" + +#ifdef SMPL_SECURE + +/* *** GENERAL SECURITY OUTLINE *** + * + * We are using XTEA (eXtended Tiny Encryption Algorithm) with a fixed + * number of rounds (32). We have removed the parameters from the API + * we harvested from the public domain. + * + * We are using a CTR-like mode. We use the 64-bit block cipher function of the + * XTEA code to encipher a concatenation of the 32-bit initialization vector and + * a 32-bit counter that increments each block. We encrypt using a fixed 128-bit + * key. The resulting 64-bit output is XOR'ed with the message. If the message is + * longer than 64 bits we encipher the next block (incrementing the counter) and + * continue until the message is exhausted. If the last cipher block is longer + * than the message we simply discard the remaining cipher block. + */ + + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/* The counter can be off by quite a bit because the number of cipher + * blocks can easily be more than 1 per frame. Value limited to a + * maximum of 255. + */ +#define CTR_WINDOW 255 + +#if (CTR_WINDOW > 255) || (CTR_WINDOW < 0) +#error ERROR: 0 <= CTR_WINDOW < 256 +#endif + +/* Number of rounds for XTEA algorithm. A parameter in the public domain code + * but we fix it here at 32. + */ +#define NUM_ROUNDS 32 + +/* Key and cipher block size constants */ +#define SMPL_KEYSIZE_BYTES 16 +#define SMPL_KEYSIZE_LONGS 4 + +/****************************************************************************** + * TYPEDEFS + */ +/* Union used to access key as both a string and as unsigned longs */ +typedef union +{ + uint8_t keyS[SMPL_KEYSIZE_BYTES]; + uint32_t keyL[SMPL_KEYSIZE_LONGS]; +} key_t; + + +/****************************************************************************** + * LOCAL VARIABLES + */ +/* 32-bit Initialization vector */ +static uint32_t const sIV = 0x87654321; + +/* 128-bit (16 byte) key. Initialized as string but fetched and used in XTEA + * encryption as 4 unsigned longs. Endianess could count if the peers are on + * two different MCUs. Endianess is rectified in initialization code. + * + * Initialization _MUST_ be done as a string (or character array). Though it + * won't matter how the initialization is done if both peers are the same + * endianness, good prectice will initialize these as a string (or character + * array) so that the endianess reconciliation works properly for all cases. + */ +static key_t sKey = {"SimpliciTI's Key"}; + +/* Constant set as an authentication code. Note that since it is a + * fixed value as opposed to a hash of the message it does not provide + * an integrity check. It will only differentiate two message encryptions + * with the same LSB but different MSB components. Thus it helps guard + * against replays. + */ +static secMAC_t const sMAC = 0xA5; + +/* This is the 64-bit cipher block target. It is this 64-bit block that + * is XOR'ed with the actual message to be encrypted. + */ +static uint32_t sMsg[2] = {0, 0}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static secFCS_t calcFCS(uint8_t *, uint8_t); +static void msg_encipher(uint8_t *, uint8_t, uint32_t *); +static void msg_decipher(uint8_t *, uint8_t, uint32_t *); +static void xtea_encipher(void); + +#endif /* SMPL_SECURE */ + +/****************************************************************************** + * @fn nwk_securityInit + * + * @brief Initialize Security network application. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_securityInit(void) +{ +#ifdef SMPL_SECURE + uint8_t i; + + /* The key is set as a string. But the XTEA routines operate on 32-bit + * unsigned longs. Endianess should be taken into account and we do that + * here by treating the key as being an array of unsigned longs in + * network order. + */ + for (i=0; i= len) + { + /* we're done */ + done = 1; + } + } while (!done); + + /* return counter value start for next time */ + *cntStart = ctr; + + return; +} + +/****************************************************************************** + * @fn msg_decipher + * + * @brief Decipher a message using the XTEA algorithm and the modified + * CTR mode method. + * + * input parameters + * @param msg - pointer to message to decipher + * @param len - length of message + * @param cntStart - pointer to the counter used in the cipher block. + * + * output parameters + * @param cntStart - counter is updated during decryption. + * + * @return void + */ +static void msg_decipher(uint8_t *msg, uint8_t len, uint32_t *cntStart) +{ + msg_encipher(msg, len, cntStart); + + return; +} + +/****************************************************************************** + * @fn xtea_encipher + * + * @brief XTEA encipher algorithm. Calling arguments removed from public + * domain code and static-scope values used instead. + * + * input parameters + * + * output parameters + * + * @return void + */ +void xtea_encipher(void) +{ + uint32_t v0=sMsg[0], v1=sMsg[1]; + uint16_t i; + uint32_t sum=0, delta=0x9E3779B9; + + for(i=0; i> 5)) + v1) ^ (sum + sKey.keyL[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + sKey.keyL[(sum>>11) & 3]); + } + + sMsg[0]=v0; + sMsg[1]=v1; +} + +/****************************************************************************** + * @fn nwk_setSecureFrame + * + * @brief Called from NWK to secure a frame. + * + * input parameters + * @param frame - pointer to frame to secure + * @param msglen - length of message + * @param ctr - pointer to the counter used in the cipher block. This will + * be NULL if a network application is sending a frame. Since + * these are not connection-based there is no counter sync + * issue but we still need a counter value. A random value + * is used. + * + * output parameters + * @param cntStart - counter is updated during encryption. + * + * @return void + */ +void nwk_setSecureFrame(mrfiPacket_t *frame, uint8_t msglen, uint32_t *ctr) +{ + uint32_t locCnt; + + /* If an encrypted frame is to be sent to a non-connection based port use a + * random number as the lsb counter value. In this case only the lsb is used + * for a counter value during decryption. Not as secure but there are still + * the 32 bits in the IV. + */ + locCnt = ctr ? *ctr : MRFI_RandomByte(); + + /* place counter value into frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(frame), F_SEC_CTR_OS, (uint8_t)(locCnt & 0xFF)); + + /* Put MAC value in */ + nwk_putNumObjectIntoMsg((void *)&sMAC, (void *)(MRFI_P_PAYLOAD(frame)+F_SEC_MAC_OS), sizeof(secMAC_t)); + + /* Put FCS value in */ + { + secFCS_t fcs = calcFCS(MRFI_P_PAYLOAD(frame)+F_SEC_MAC_OS, msglen+sizeof(secMAC_t)); + + nwk_putNumObjectIntoMsg((void *)&fcs, (void *)(MRFI_P_PAYLOAD(frame)+F_SEC_ICHK_OS), sizeof(secFCS_t)); + } + + /* Encrypt frame */ + msg_encipher(MRFI_P_PAYLOAD(frame)+F_SEC_ICHK_OS, msglen+sizeof(secMAC_t)+sizeof(secFCS_t), &locCnt); + + /* Set the Encryption bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(frame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + + /* Update the counter if it was a "real" counter. */ + if (ctr) + { + *ctr = locCnt; + } + + return; +} + +/****************************************************************************** + * @fn calcFCS + * + * @brief Calculate the frame check sequence. Currently it's just a + * cumulative XOR of each byte starting with the MAC byte. The + * FCS is placed in front of the MAC after the counter hint and is + * included in the encryption. + * + * input parameters + * @param msg - pointer to message + * @param len - length of message + * + * output parameters + * + * @return Returns the FCS using the typedef. + */ +static secFCS_t calcFCS(uint8_t *msg, uint8_t len) +{ + uint8_t i; + secFCS_t result = 0; + + for (i=0; i locCnt) + { + /* frameCnt is bigger. Second part of test below takes care of + * the unlikely case of a complete counter wrap (msb's all 0) in + * which case the test will incorrectly fail when the count is + * actually within the (wrapped) window. #ifdef'ed to avoid compiler + * warning in case user sets CNT_WINDOW to 0 (pointless comparison of + * unsigned value). + */ + if (((frameCnt-CTR_WINDOW) <= locCnt) +#if CTR_WINDOW > 0 + || (frameCnt < CTR_WINDOW) +#endif + ) + { + /* Value within window. We probably missed something. Adjust and decipher. + * If locCnt is less because it wrapped and frameCnt didn't it means that + * it's a duplicate or late frame. In that case the following will lead to + * a decryption that fails sanity checks which is OK because the frame will + * be correctly rejected. + */ + locCnt = frameCnt; + } + else + { + /* It's either a rogue or a really old duplicate packet. In either case + * we dismiss the frame. + */ + rc = 0; + done = 1; + } + } + else + { + /* locCnt is bigger. The only way the frame can be valid is if the + * counter wrapped causing frameCnt to appear to be smaller. Wrap the + * counter and decrypt. If the frame isn't valid, i.e., it's late, + * a duplicate, or a rogue, the decryption will fail sanity checks and + * the frame will be correctly rejected. The following arithmetic works + * correctly without a special test for the complete counter wrap case. + */ + frameCnt += 0x100; /* wrap the hint-based counter */ + if (((frameCnt-CTR_WINDOW) <= locCnt)) + { + /* An lsb wrap but still within window. We probably missed something. + * Adjust (with wrap) and decrypt. + */ + locCnt = frameCnt; + } + else + { + /* rogue frame */ + rc = 0; + done = 1; + } + } + } + } while (!done); + + if (ctr && rc) + { + /* Only update the counter if the count was a "real" one and the + * decryption succeeded. + */ + *ctr = locCnt; + } + + return rc; +} + +#endif /* SMPL_SECURE */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_security.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_security.h new file mode 100755 index 0000000..212ce8f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/Components/nwk_applications/nwk_security.h @@ -0,0 +1,48 @@ +/************************************************************************************************** + Filename: nwk_security.h + Revised: $Date: 2009-01-09 15:02:17 -0800 (Fri, 09 Jan 2009) $ + Revision: $Revision: 18728 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Security network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_SECURITY_H +#define NWK_SECURITY_H + +/* change the following as Security application is developed */ +#define MAX_SEC_APP_FRAME 0 + +/* prototypes */ +void nwk_securityInit(void); +fhStatus_t nwk_processSecurity(mrfiPacket_t *); +void nwk_setSecureFrame(mrfiPacket_t *, uint8_t, uint32_t *); +uint8_t nwk_getSecureFrame(mrfiPacket_t *, uint8_t, uint32_t *); +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/simpliciti.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/simpliciti.h new file mode 100755 index 0000000..f528db8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/simpliciti.h @@ -0,0 +1,163 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// +// SimpliciTI packet size (TX only mode) +// ------------------------------------- +// +// * packet rate (100/3) packets/second = 33.3 packets/second +// * packet length 28 bytes +// * packet structure 4 bytes preamble +// 4 bytes sync +// 1 bytes length +// 1 bytes address +// 16 bytes data +// 12 byte network data +// 4 byte user data +// 2 bytes crc +// +// SimpliciTI frequency overview +// ----------------------------- +// +// CC430_End_Device_433MHz.lib (433MHz ISM band) +// +// * base frequency 433.92 MHz +// * deviation 32 kHz +// * channel spacing 25 kHz +// * used channel number 0 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.4 dBm +// * duty 9,6% (TX only mode, 32 packets / second) +// +// CC430_End_Device_868MHz.lib (868MHz ISM band) +// +// * base frequency 869.525 MHz +// * deviation 32 kHz +// * channel spacing 25 kHz +// * used channel number 0 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.1 dBm +// * duty 9,6% (TX only mode, 32 packets / second) +// +// CC430_End_Device_915MHz.lib (915MHz ISM band) +// +// * base frequency 902.000 MHz +// * deviation 32 kHz +// * channel spacing 200 kHz +// * used channel number 20 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.3 dBm +// * duty 9.6% (TX only mode, 32 packets / second) +// +// ************************************************************************************************* + +// --------------------------------------------------------------- +// Generic defines and variables + +// Entry point into SimpliciTI library +extern unsigned char simpliciti_link(void); + +// 4 byte device address overrides device address set during compile time +extern unsigned char simpliciti_ed_address[4]; + +// Maximum data length +#define SIMPLICITI_MAX_PAYLOAD_LENGTH (32u) + +// Data to send / receive +extern unsigned char simpliciti_data[SIMPLICITI_MAX_PAYLOAD_LENGTH]; + +// Flag contains status information and triggers to send data or to exit SimpliciTI library +// Control is done from outside SimpliciTI library +extern unsigned char simpliciti_flag; +#define SIMPLICITI_STATUS_LINKING (BIT0) +#define SIMPLICITI_STATUS_LINKED (BIT1) +#define SIMPLICITI_STATUS_ERROR (BIT2) +#define SIMPLICITI_TRIGGER_SEND_DATA (BIT3) +#define SIMPLICITI_TRIGGER_RECEIVED_DATA (BIT4) +#define SIMPLICITI_TRIGGER_STOP (BIT5) + +// Radio frequency offset read from calibration memory +// Compensates crystal deviation from 26MHz nominal value +extern unsigned char rf_frequoffset; + +// Macros +#define getFlag(val, flag) ((val&flag)==flag) +#define setFlag(val, flag) (val|=flag) +#define clearFlag(val, flag) (val&=(~flag)) +#define toggleFlag(val, flag) (val^=flag) + + +// --------------------------------------------------------------- +// SimpliciTI RX only + +// Entry point into SimpliciTI library +extern void simpliciti_main_tx_only(void); + +// Callback function to read data from acceleration sensor or buttons and trigger sending +extern void simpliciti_get_ed_data_callback(void); + + +// --------------------------------------------------------------- +// SimpliciTI Sync + +// Sync data length +#define BM_SYNC_DATA_LENGTH (19u) + +// Device data (0)TYPE (1) - (18) DATA +#define SYNC_ED_TYPE_R2R (1u) +#define SYNC_ED_TYPE_MEMORY (2u) +#define SYNC_ED_TYPE_STATUS (3u) + +// Host data (0)CMD (1) - (18) DATA +#define SYNC_AP_CMD_NOP (1u) +#define SYNC_AP_CMD_GET_STATUS (2u) +#define SYNC_AP_CMD_SET_WATCH (3u) +#define SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_1 (4u) +#define SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_2 (5u) +#define SYNC_AP_CMD_ERASE_MEMORY (6u) +#define SYNC_AP_CMD_EXIT (7u) + + +// Entry point into SimpliciTI library +extern void simpliciti_main_sync(void); + +// Callback function to decode access point command +extern void simpliciti_sync_decode_ap_cmd_callback(void); + +// Callback function to read data from application and trigger sending +extern void simpliciti_sync_get_data_callback(unsigned int index); + +// Send reply packets (>0), 0=no need to reply +extern unsigned char simpliciti_reply_count; + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/simpliciti_readme.txt b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/simpliciti_readme.txt new file mode 100755 index 0000000..d1ff81d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Data Logger/simpliciti/simpliciti_readme.txt @@ -0,0 +1,46 @@ +Some notes about the SimpliciTI configuration used in this project + +- The source code is based on the SimpliciTI 1.1.1 release. + +- A full SimpliciTI installation contains configurations for many targets and device types. To avoid confusion, + only the configuration (End Device) and target files (CC430EM) required for the eZ430-Chronos have been used. + +- All source code files have been copied into the project physically. Symbolic links have been replaced with + the real source code file. + +- Due to the indirect inclusion scheme of hardware-dependent source code, some source code files have been + excluded from build. However, they will be included through higher level source code. + +- Some modifications where required to the original source code. All these changes have been marked with [BM]. + + bsp_board.c/BSP_InitBoard(void) Changed from TA0 to TA1 for delay function, because TA0 is already occupied. + + bsp_msp430_defs.h/BSP_EarlyInit(void) Function removed, because SimpliciTI must run in watch context + + mrfi_radio_interface.c/mrfiRadioInterfaceCmdStrobe(uint8_t addr) + Added code to properly synchronize with radio interface. Otherwise + interface could get stuck. + + mrfi_radio.c Changed channel assignment (mrfiLogicalChanTable) for three ISM bands + Changed power output settings (mrfiRFPowerTable) for three ISM bands + + mrfi_radio.c/MRFI_Init(void) Added frequency offset correction to use calibrated frequency offset + when starting RF communication + + mrfi_radio.c/MRFI_RadioIsr(void) Changed radio ISR to normal function, since we have a shared radio ISR + + nwk_api.c Made variable sInit_done globally available to allow SimpliciTI to shutdown + and restart multiple times + + nwk.c/nwk_nwkInit Added workaround to allow allow SimpliciTI to shutdown + and restart multiple times + +- If you (for whatever reason) want to upgrade to a newer version of SimpliciTI, please bear in mind that + + a) the access point SimpliciTI version is 1.1.1 (and cannot be updated) + + b) the workarounds used here to enable SimpliciTI to shutdown and restart multiple times might not necessarily + work when used with later revisions + + + \ No newline at end of file diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_433MHz.r43 b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_433MHz.r43 new file mode 100755 index 0000000..6bc0263 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_433MHz.r43 differ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_868MHz.r43 b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_868MHz.r43 new file mode 100755 index 0000000..beb04a4 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_868MHz.r43 differ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_915MHz.r43 b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_915MHz.r43 new file mode 100755 index 0000000..17a47b4 Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_915MHz.r43 differ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_API.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_API.h new file mode 100755 index 0000000..049c99f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/BlueRobin_RX_API.h @@ -0,0 +1,157 @@ +// ************************************************************************************************* +// +// Copyright 2009 BM innovations GmbH (www.bm-innovations.com), all rights reserved. +// +// This trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC" may be used for non-profit non-commercial purposes only. If you want to use +// BlueRobin(TM) in a commercial project, please contact the copyright holder for a +// separate license agreement. +// +// By using this trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC", you implicitly agree that you will not modify, adapt, disassemble, decompile, +// reverse engineer, translate or otherwise attempt to discover the source code of the +// "BlueRobin(TM) receiver library for the Texas Instruments CC430 SoC". +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// +// Public header for eZ430-Chronos specific BlueRobin(TM) receiver library. +// +// The following BlueRobin(TM) profiles are supported by this build +// - heart rate (HR) transmitter +// +// The following number of channels is supported: 1 +// +// ************************************************************************************************* +// +// BlueRobin(TM) packet size +// ------------------------- +// +// * average packet rate 1 packet/875 msec = ~1.14 packets/second +// * payload per packet 5 bytes +// +// BlueRobin(TM) frequency overview +// (Please note: Settings apply for the transmitter side, i.e. the USB dongle) +// ---------------------------------------------------------------------- +// +// Bluerobin_RX_433MHz.lib (433MHz ISM band) +// +// * frequency 433.30 MHz - 434.00 MHz +// * deviation 95 kHz +// * channels 3 +// * data rate 250 kBaud +// +// Bluerobin_RX_868MHz.lib (868MHz ISM band) +// +// * frequency 868.25 MHz - 868.95 MHz +// * deviation 95 kHz +// * channels 3 +// * data rate 250 kBaud +// +// +// Bluerobin_RX_915MHz.lib (915MHz ISM band) +// +// * frequency 914.35 MHz - 917.75 MHz +// * deviation 95 kHz +// * channels 34 +// * data rate 250 kBaud +// +// ************************************************************************************************* + +#ifndef BRRX_API_H_ +#define BRRX_API_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Defines section + +// List of all possible channel states +typedef enum +{ + TX_OFF = 0, // Powerdown mode + TX_ACTIVE, // Active mode + TX_SEARCH // Search mode +} brtx_state_t; + +// Transmitter to channel assignment +#define HR_CHANNEL (0) + +// ************************************************************************************************* +// API section + +// ---------------------------------------------------------- +// Functions for initializing and controlling the library + +// Initialize several global variables. +void BRRX_Init_v(void); + +// Set delay after which a channel will be switched off if no new data can be received. +// Param1: Powerdown delay in packet intervals (875 ms) +void BRRX_SetPowerdownDelay_v(u8 Delay_u8); + +// Set timeout when searching for a transmitter +// Param1: Search timeout in seconds +void BRRX_SetSearchTimeout_v(u8 Timeout_u8); + +// Set reduction of valid signal level in learn mode. +// Param1: Reduction of signal level +void BRRX_SetSignalLevelReduction_v(u8 Reduction_u8); + +// Set ID for a channel. To search for an unknown transmitter the ID has to be set to 0. +// Can be only executed on channels currently in powerdown mode. +// Param1: Channel index +// Param2: New ID +void BRRX_SetID_v(u8 Index_u8, u32 ID_u32); + +// Get current ID of channel. +// Return: Current ID of channel +// Param1: Channel index +u32 BRRX_GetID_u32(u8 Index_u8); + +// Start reception on one or all channels. +// Param1: Channel index (use 0xFF to start all channels) +void BRRX_Start_v(u8 Index_u8); + +// Stop reception on one or all channels. +// Param1: Channel index (0xFF for all channels) +void BRRX_Stop_v(u8 Index_u8); + +// Get current state of a channel +// Param1: Channel index +brtx_state_t BRRX_GetState_t(u8 Index_u8); + +// ---------------------------------------------------------- +// eZ430-Chronos specific functions + +// Get current heart rate. +// Return: Heart rate in bpm +u8 BRRX_GetHeartRate_u8(void); + +// Get current distance. +// Return: Distance in 10m steps. +u16 BRRX_GetDistance_u16(void); + +// Get current speed. +// Return: Speed in 0.1km/h steps. Trial version is limited to 25.5km/h. +u8 BRRX_GetSpeed_u8(void); + +// ---------------------------------------------------------- +// Radio-related functions + +// RX packet end service function +// Must be called by CC1101_VECTOR ISR +void BlueRobin_RadioISR_v(void); + +#endif /*BRRX_API_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/bm.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/bm.h new file mode 100755 index 0000000..781b1e1 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/bluerobin/bm.h @@ -0,0 +1,480 @@ +// ************************************************************************************************* +// +// Copyright 2009 BM innovations GmbH (www.bm-innovations.com), all rights reserved. +// +// This trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC" may be used for non-profit non-commercial purposes only. If you want to use +// BlueRobin(TM) in a commercial project, please contact the copyright holder for a +// separate license agreement. +// +// By using this trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC", you implicitly agree that you will not modify, adapt, disassemble, decompile, +// reverse engineer, translate or otherwise attempt to discover the source code of the +// "BlueRobin(TM) receiver library for the Texas Instruments CC430 SoC". +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Standard definitions, have to be included in every source and header file. +// ************************************************************************************************* + +#ifndef __BM_H +#define __BM_H + +#if (defined __IAR_SYSTEMS_ASM) || (defined __IAR_SYSTEMS_ASM__) +# define _ASSEMBLER_USED_ +#endif + +#ifndef _ASSEMBLER_USED_ +# include +#endif + +#ifndef FALSE +// the classic false +# define FALSE (0 == 1) +#endif + +#ifndef TRUE +// the classic true +# define TRUE (1 == 1) +#endif + +#ifndef USE_RAW_ATTR +// per default this feature is disabled +# define USE_RAW_ATTR FALSE +#endif + +// ************************************************************************************************* +// First Section: Basic Data Types +// ************************************************************************************************* + +// Fundamental #definitions +// CPU target idents are used for target dependent compilations + +// Texas Instruments MSP430 +#define _TI_MSP430_ (16) + +// Find the currently running compiler +// and make the related #define's + +// _IAR_TID_ target ID from IAR compilers +// _CPU_TID_ remap to enum of processor target numbers +// _CPU_8BIT_INT_ type for 8 bit int +// _CPU_16BIT_INT_ type for 16 bit int +// _CPU_32BIT_INT_ type for 32 bit int +// _CPU_32BIT_FLOAT_ type for 32 bit float +// _CPU_64BIT_FLOAT_ type for 64 bit float +// INTERRUPT declares an interrupt service routine without an entry in the vector +// table +// ISR(vector) declares an interrupt service routine which is added in vector table at +// offset vector +// MONITOR declares a function atomic +// INTERRUPTS_ENABLE remap to the intrinsic for enable interrupts +// INTERRUPTS_DISABLE remap to the intrinsic for disable interrupts +// NO_OPERATION remap to the intrinsic for no operation +// _CPU_DIRECTION_OUT_1_ if TRUE the direction register indicates with an 1: direction is output +// _CPU_EDGE_HIGH_LOW_1_ if TRUE the edge select register indicates with an 1: trigger on high +// low +// NO_INIT declare a variable as not initialized +// INLINE_FUNC declare a function as inline for release builds + +#if ((defined __IAR_SYSTEMS_ICC) || (defined __IAR_SYSTEMS_ASM)) && (__IAR_SYSTEMS_ICC__ < 2) +// Found IAR Compiler with classic IAR frontend +# ifndef _IAR_TID_ +# define _IAR_TID_ ((__TID__ >> 8) & 0x7f) +# endif + +# define INTERRUPT interrupt +# define ISR(vector) interrupt[(vector)] +# define MONITOR monitor + +# if ((_IAR_TID_) == 43) +// Found Texas Instruments MSP430 CPU +# define _CPU_TID_ _TI_MSP430_ +# define _CPU_DIRECTION_OUT_1_ TRUE +# define _CPU_EDGE_HIGH_LOW_1_ TRUE +# define INTERRUPTS_ENABLE() _EINT() +// WA for HW bug, add a NOP +# define INTERRUPTS_DISABLE() { _DINT(); _NOP(); } +# define NO_OPERATION() _NOP() + +# else +# error "Unknown IAR Compiler, the file bm.h has to be expanded !" +# endif + +#elif defined __IAR_SYSTEMS_ICC__ +// Found IAR Compiler with EDG frontend +# define _IAR_TID_ ((__TID__ >> 8) & 0x7f) + +# if USE_RAW_ATTR == TRUE +// Use the raw attribute in ISR's +# define _RAW __raw +# else +// Empty define RAW as it is not used +# define _RAW +# endif +# define INTERRUPT _RAW __interrupt +# define MONITOR __monitor +# define NO_INIT __no_init +# define INTERRUPTS_ENABLE() __enable_interrupt() +# define INTERRUPTS_DISABLE() __disable_interrupt() +# define NO_OPERATION() __no_operation() + +# ifndef DEBUG +// Force inlining of function in release builds +# define INLINE_FUNC PRAGMA(inline = forced) +# else +// Do not force inlining of function in debug builds +# define INLINE_FUNC +# endif + +# if (!defined CODECHECK) && (!defined __DA_C__) +// Define to a new way of using #pragmas in preprocessor +# define PRAGMA(x) _Pragma(# x) +# define ISR(x) PRAGMA(vector = (x)) INTERRUPT +# endif + +# if ((_IAR_TID_) == 43) +// Found Texas Instruments MSP430 CPU (V2) +# define _CPU_TID_ _TI_MSP430_ +# define _CPU_DIRECTION_OUT_1_ TRUE +# define _CPU_EDGE_HIGH_LOW_1_ TRUE +# define _CPU_64BIT_INT_ long long +# if __VER__ < 220 +// WA for HW bug, add a nop after DINT, Compiler has a bugfix since version 2.20 +# undef INTERRUPTS_DISABLE +# define INTERRUPTS_DISABLE() { __disable_interrupt(); __no_operation(); } +# endif + +# else +# error "Unknown new IAR Compiler, the file bm.h has to be expanded !" +# endif + +#elif defined __CCE__ +// Found CCE Compiler +# define INTERRUPT __interrupt +# define MONITOR // __monitor +# define NO_INIT __no_init +# define INTERRUPTS_ENABLE() __enable_interrupt() +# define INTERRUPTS_DISABLE() __disable_interrupt() +# define NO_OPERATION() __no_operation() + +# ifndef DEBUG +// Force inlining of function in release builds +# define INLINE_FUNC PRAGMA(inline = forced) +# else +// Do not force inlining of function in debug builds +# define INLINE_FUNC +# endif + +// Found Texas Instruments MSP430 CPU (V2) +# define _CPU_TID_ _TI_MSP430_ +# define _CPU_DIRECTION_OUT_1_ TRUE +# define _CPU_EDGE_HIGH_LOW_1_ TRUE +//#define _CPU_64BIT_INT_ long long + +// #endif + +#else +# error "Unknown Compiler, the file bm.h has to be expanded !" +#endif + +#ifndef _ASSEMBLER_USED_ +// Get the limits to autodetect the size of integral types +# include +// Get floats to autodetect the size of float types +# include + +// *********************************************************************************************** +// +// Common basic data types +// +// *********************************************************************************************** +# if UCHAR_MAX == 0xFFu +# define _CPU_8BIT_INT_ char +# else +# error "unable to get size of u8 automatically" +# endif + +# if USHRT_MAX == 0xFFFFu +# define _CPU_16BIT_INT_ short +# elif UINT_MAX == 0xFFFFu +# define _CPU_16BIT_INT_ int +# else +# error "unable to get size of u16 automatically" +# endif + +# if USHRT_MAX == 0xFFFFFFFFu +# define _CPU_32BIT_INT_ short +# elif UINT_MAX == 0xFFFFFFFFu +# define _CPU_32BIT_INT_ int +# elif ULONG_MAX == 0xFFFFFFFFu +# define _CPU_32BIT_INT_ long +# else +# error "unable to get size of u32 automatically" +# endif + +# ifdef __IAR_SYSTEMS_ICC__ +# if __IAR_SYSTEMS_ICC__ > 1 +# define _CPU_32BIT_FLOAT_ float +# if __DOUBLE_SIZE__ == 8 +# define _CPU_64BIT_FLOAT_ double +# endif +# endif +# endif + +# ifndef _CPU_32BIT_FLOAT_ +# if FLT_MANT_DIG == 24 +# define _CPU_32BIT_FLOAT_ float +# elif DBL_MANT_DIG == 24 +# define _CPU_32BIT_FLOAT_ double +# else +# error "unable to get size of f32 automatically" +# endif + +# if DBL_MANT_DIG == 53 +# define _CPU_64BIT_FLOAT_ double +# endif +# endif + +// *********************************************************************************************** +// +// Following lines #typedef the basic data types in a compiler independent way. +// +// *********************************************************************************************** + +# ifdef _CPU_8BIT_INT_ +// unsigned 8 bit +typedef unsigned _CPU_8BIT_INT_ u8; +// unsigned 8 bit max value +# define U8_MAX (0xFFU) +// signed 8 bit max value +typedef signed _CPU_8BIT_INT_ s8; +// signed 8 bit min value +# define S8_MIN (-127 - 1) +// signed 8 bit max value +# define S8_MAX (127) +# endif + +# ifdef _CPU_16BIT_INT_ +// unsigned 16 bit +typedef unsigned _CPU_16BIT_INT_ u16; +// unsigned 16 bit max value +# define U16_MAX (0xFFFFU) +// signed 16 bit +typedef signed _CPU_16BIT_INT_ s16; +// signed 16 bit min value +# define S16_MIN (-32767 - 1) +// signed 16 bit max value +# define S16_MAX (32767) +# endif + +# ifdef _CPU_32BIT_INT_ +// unsigned 32 bit +typedef unsigned _CPU_32BIT_INT_ u32; +// unsigned 32 bit max value +# define U32_MAX (0xFFFFFFFFUL) +// signed 32 bit +typedef signed _CPU_32BIT_INT_ s32; +// signed 32 bit min value +# define S32_MIN (-2147483647L - 1L) +// signed 32 bit max value +# define S32_MAX (2147483647L) +# endif + +# ifdef _CPU_64BIT_INT_ +// unsigned 64 bit +typedef unsigned _CPU_64BIT_INT_ u64; +// signed 64 bit +typedef signed _CPU_64BIT_INT_ s64; +# endif + +# ifdef _CPU_32BIT_FLOAT_ +// float 32 bit +typedef _CPU_32BIT_FLOAT_ f32; +// number of digits in mantissa of f32 +# define F32_MANT_DIG (24) +// epsilon for f32 +# define F32_EPSILON (1.192092896e-07) +// number of digits of precision of f32 +# define F32_DIG (6) +// exponent min of f32 +# define F32_MIN_EXP (-125) +// min positive value of f32 +# define F32_MIN (1.175494351e-38) +// decimal exponent min of f32 +# define F32_MIN_10_EXP (-37) +// exponent max of f32 +# define F32_MAX_EXP (128) +// max value of f32 +# define F32_MAX (3.402823466e+38) +// decimal exponent max of f32 +# define F32_MAX_10_EXP (38) +# endif + +# ifdef _CPU_64BIT_FLOAT_ +// float 64 bit +typedef _CPU_64BIT_FLOAT_ f64; +// number of digits in mantissa of f64 +# define F64_MANT_DIG (53) +// epsilon for f64 +# define F64_EPSILON (2.2204460492503131e-016) +// number of digits of precision of f64 +# define F64_DIG (15) +// exponent min of f64 +# define F64_MIN_EXP (-1021) +// min positive value of f64 +# define F64_MIN (2.2250738585072014e-308) +// decimal exponent min of f64 +# define F64_MIN_10_EXP (-307) +// exponent max of f64 +# define F64_MAX_EXP (1024) +// max value of f64 +# define F64_MAX (1.7976931348623158e+308) +// decimal exponent max of f64 +# define F64_MAX_10_EXP (308) +# endif + +typedef unsigned char BYTE; +typedef unsigned int WORD; +typedef unsigned long DWORD; + +#endif // _ASSMEBLER_USED_ + +// A macro that calculates the number of bits of a given type +#ifndef BITSIZEOF +# define BITSIZEOF(type) (sizeof(type) * CHAR_BIT) +#endif + +/* A macro that generates a bit mask according to a given bit number. + * Example: + * - BIT(0) expands to 1 (== 0x01) + * - BIT(3) expands to 8 (== 0x08) + */ +#define BIT(x) (1uL << (x)) + +/* A macro that generates a bit mask according to a given bit number with a cast to type. + * The difference to BIT(X) is the additional type argument T that is used to cast the type of the + * constant 1 and the type of the result as well. + * Example: + * - BIT_T(u8,0) expands to (u8)1 (== 0x01) + * - BIT_T(u32,3) expands to (u32)8 (== 0x08L) + */ +#define BIT_T(t, x) ((t)((t)1 << (x))) + +/* A macro to calculate the position of the highest bit. + * The result is same as LOG2 in case only one bit is set. Use with constant values only because + * of code size. + */ +#define BIT_HIGHEST(Input_u32) ( \ + ((Input_u32) & BIT(31)) ? 31 : ( \ + ((Input_u32) & BIT(30)) ? 30 : ( \ + ((Input_u32) & BIT(29)) ? 29 : ( \ + ((Input_u32) & BIT(28)) ? 28 : ( \ + ((Input_u32) & BIT(27)) ? 27 : ( \ + ((Input_u32) & BIT(26)) ? 26 : ( \ + ((Input_u32) & BIT(25)) ? 25 : ( \ + ((Input_u32) & BIT(24)) ? 24 : ( \ + ((Input_u32) & BIT(23)) ? 23 : ( \ + ((Input_u32) & BIT(22)) ? 22 : ( \ + ((Input_u32) & BIT(21)) ? 21 : ( \ + ((Input_u32) & BIT(20)) ? 20 : ( \ + ((Input_u32) & BIT(19)) ? 19 : ( \ + ((Input_u32) & BIT(18)) ? 18 : ( \ + ((Input_u32) & BIT(17)) ? 17 : ( \ + ((Input_u32) & BIT(16)) ? 16 : ( \ + ((Input_u32) & \ + BIT(15)) ? 15 : ( \ + ((Input_u32) & \ + BIT(14)) ? 14 : ( \ + ((Input_u32) & \ + BIT(13)) ? 13 : ( \ + ((Input_u32) & \ + BIT(12)) ? 12 \ + : ( \ + ((Input_u32) \ + & BIT(11)) \ + ? 11 : ( \ + (( \ + Input_u32) \ + & BIT( \ + 10)) ? 10 : ( \ + (( \ + Input_u32) \ + & \ + BIT(9)) ? 9 : ( \ + (( \ + Input_u32) \ + & \ + BIT(8)) ? 8 : ( \ + (( \ + Input_u32) \ + & \ + BIT(7)) ? 7 : ( \ + (( \ + Input_u32) \ + & \ + BIT(6)) ? 6 : ( \ + (( \ + Input_u32) \ + & \ + BIT(5)) ? 5 : ( \ + (( \ + Input_u32) \ + & \ + BIT(4)) ? 4 : ( \ + (( \ + Input_u32) \ + & \ + BIT(3)) ? 3 : ( \ + (( \ + Input_u32) \ + & \ + BIT(2)) ? 2 : ( \ + (( \ + Input_u32) \ + & \ + BIT(1)) ? 1 : ( \ + (( \ + Input_u32) \ + & \ + BIT(0)) ? 0 : -1uL)))))))))))))))))))))))))))))))) + +#ifndef MONITOR +# define MONITOR +#endif + +#ifndef NO_INIT +# define NO_INIT +#endif + +#ifndef INTERRUPT +# define INTERRUPT +#endif + +#ifndef ISR +# define ISR(ignore) +#endif + +#ifndef INLINE_FUNC +# define INLINE_FUNC +#endif + +#ifndef INTERRUPTS_ENABLE +# define INTERRUPTS_ENABLE() +#endif + +#ifndef INTERRUPTS_DISABLE +# define INTERRUPTS_DISABLE() +#endif + +#endif // __BM_H diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/change_record.txt b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/change_record.txt new file mode 100755 index 0000000..37f7597 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/change_record.txt @@ -0,0 +1,38 @@ +V1.6 (21.11.2010) +Fixed following bugs +- rfsimpliciti.c/simpliciti_sync_decode_ap_cmd_callback(), +- timer.c/TIMER0_A0_ISR(), LCD shows "done" after successfully received data +- main.c/wakeup_event(), +- rfbsl.c/sx_rfbsl() rfBSL requires two button presses in order to update watch +- timer.c/Timer0_A3_Start() Fixed register read (Asynchronous) +- timer.c/Timer0_A4_Delay() Fixed register read (Asynchronous) + Avoid unwanted flag changes caused by interrupt methods + After timeout the accelerometer menu shows "----" +- port.c/PORT2_ISR() and timer.c/TIMER0_A0_ISR() Changes the menu if the pressed time from STAR or NUM button are between "short(50ms)" and "long(3s)" + The backlight stays 3 seconds on +- display.c Removed file display1.c. The content is now in display.c +- display.h Fixed LCD_UNIT_L1_PER_S_MASK bit + +Other changes: +- adc12.c and adc12.h Removed commented function and #defines +- battery.c Removed commented function +- DCO settling time Set to 375000 cycles +________________________________________________________________________________________________________________________________________________ +V1.5 (16.03.2010) +Fixed following bugs +- main.c/init_application() Changed XT1 drive level to highest to avoid ACLK noise when turning on backlight. +- main.c/wakeup_event(), timer.c/TIMER0_A0_ISR() Modified key lock procedure. +- vti_ps.c/ps_get_temp() Negative °C are now converted correctly to Kelvin +- altitude.c/mx_altitude() Enabled fast mode when changing altitude offset +- ports.c/PORT2_ISR() Disabled stopwatch stop when watch buttons are locked + +Other changes +- main.c/read_calibration_values() Added range check for rf_frequoffset variable + Added bytes for altitude offset correction and s/w version +- altitude.h, altitude.c Added initial altitude offset correction +- SimpliciTI Added SimpliciTI sources to project. Upgraded to Version 1.1.1. +- RFBSL Added wireless update support +- Button names Changed button names from M1/M2/S1/S2/BL to STAR/NUM/UP/DOWN/BACKLIGHT +__________________________________________________________________________________________________________________________________________________ +V1.4 (22.11.2009) +First version released to manufacturing. \ No newline at end of file diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/adc12.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/adc12.c new file mode 100755 index 0000000..07f13cc --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/adc12.c @@ -0,0 +1,164 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// ADC12 functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include + +// driver +#include "adc12.h" +#include "timer.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +u16 adc12_result; +u8 adc12_data_ready; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn adc12_single_conversion +// @brief Init ADC12. Do single conversion. Turn off ADC12. +// @param u16 ref Select reference +// u16 sht Sample-and-hold time +// u16 channel Channel of the conversion +// @return u16 adc12_result Return ADC result +// ************************************************************************************************* +u16 adc12_single_conversion(u16 ref, u16 sht, u16 channel) +{ + // Initialize the shared reference module + REFCTL0 |= REFMSTR + ref + REFON; // Enable internal reference (1.5V or 2.5V) + + // Initialize ADC12_A + ADC12CTL0 = sht + ADC12ON; // Set sample time + ADC12CTL1 = ADC12SHP; // Enable sample timer + ADC12MCTL0 = ADC12SREF_1 + channel; // ADC input channel + ADC12IE = 0x001; // ADC_IFG upon conv result-ADCMEMO + + // Wait 2 ticks (66us) to allow internal reference to settle + Timer0_A4_Delay(2); + + // Start ADC12 + ADC12CTL0 |= ADC12ENC; + + // Clear data ready flag + adc12_data_ready = 0; + + // Sampling and conversion start + ADC12CTL0 |= ADC12SC; + + // Delay to get next ADC value + Timer0_A4_Delay(5); + while (!adc12_data_ready) ; + + // Shut down ADC12 + ADC12CTL0 &= ~(ADC12ENC | ADC12SC | sht); + ADC12CTL0 &= ~ADC12ON; + + // Shut down reference voltage + REFCTL0 &= ~(REFMSTR + ref + REFON); + + ADC12IE = 0; + + // Return ADC result + return (adc12_result); +} + +// ************************************************************************************************* +// @fn ADC12ISR +// @brief Store ADC12 conversion result. Set flag to indicate data ready. +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=ADC12_VECTOR +__interrupt void ADC12ISR(void) +{ + switch (__even_in_range(ADC12IV, 34)) + { + case 0: + break; // Vector 0: No interrupt + case 2: + break; // Vector 2: ADC overflow + case 4: + break; // Vector 4: ADC timing overflow + case 6: // Vector 6: ADC12IFG0 + adc12_result = ADC12MEM0; // Move results, IFG is cleared + adc12_data_ready = 1; + _BIC_SR_IRQ(LPM3_bits); // Exit active CPU + break; + case 8: + break; // Vector 8: ADC12IFG1 + case 10: + break; // Vector 10: ADC12IFG2 + case 12: + break; // Vector 12: ADC12IFG3 + case 14: + break; // Vector 14: ADC12IFG4 + case 16: + break; // Vector 16: ADC12IFG5 + case 18: + break; // Vector 18: ADC12IFG6 + case 20: + break; // Vector 20: ADC12IFG7 + case 22: + break; // Vector 22: ADC12IFG8 + case 24: + break; // Vector 24: ADC12IFG9 + case 26: + break; // Vector 26: ADC12IFG10 + case 28: + break; // Vector 28: ADC12IFG11 + case 30: + break; // Vector 30: ADC12IFG12 + case 32: + break; // Vector 32: ADC12IFG13 + case 34: + break; // Vector 34: ADC12IFG14 + default: + break; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/adc12.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/adc12.h new file mode 100755 index 0000000..90fc327 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/adc12.h @@ -0,0 +1,57 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ADC12_H_ +#define ADC12_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern u16 adc12_single_conversion(u16 ref, u16 sht, u16 channel); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +extern u16 adc12_result; +extern u8 adc12_data_ready; + +// ************************************************************************************************* +// Extern section + +#endif /*ADC12_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/buzzer.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/buzzer.c new file mode 100755 index 0000000..9ac581a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/buzzer.c @@ -0,0 +1,220 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Buzzer functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "buzzer.h" +#include "timer.h" +#include "display.h" + +// logic +#include "alarm.h" + +// ************************************************************************************************* +// Prototypes section +void toggle_buzzer(void); +void countdown_buzzer(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct buzzer sBuzzer; + +// ************************************************************************************************* +// Extern section +//extern u16 timer0_A3_ticks_g; + +// ************************************************************************************************* +// @fn reset_buzzer +// @brief Init buzzer variables +// @param none +// @return none +// ************************************************************************************************* +void reset_buzzer(void) +{ + sBuzzer.time = 0; + sBuzzer.state = BUZZER_OFF; +} + +// ************************************************************************************************* +// @fn start_buzzer +// @brief Start buzzer output for a number of cylces +// @param u8 cycles Keep buzzer output for number of cycles +// u16 on_time Output buzzer for "on_time" ACLK ticks +// u16 off_time Do not output buzzer for "off_time" ACLK ticks +// @return none +// ************************************************************************************************* +void start_buzzer(u8 cycles, u16 on_time, u16 off_time) +{ + // Store new buzzer duration while buzzer is off + if (sBuzzer.time == 0) + { + sBuzzer.time = cycles; + sBuzzer.on_time = on_time; + sBuzzer.off_time = off_time; + + // Need to init every time, because SimpliciTI claims same timer + // Reset TA1R, set up mode, TA1 runs from 32768Hz ACLK + TA1CTL = TACLR | MC_1 | TASSEL__ACLK; + + // Set PWM frequency + TA1CCR0 = BUZZER_TIMER_STEPS; + + // Enable IRQ, set output mode "toggle" + TA1CCTL0 = OUTMOD_4; + + // Allow buzzer PWM output on P2.7 + P2SEL |= BIT7; + + // Activate Timer0_A3 periodic interrupts + fptr_Timer0_A3_function = toggle_buzzer; + Timer0_A3_Start(sBuzzer.on_time); + + // Preload timer advance variable + sTimer.timer0_A3_ticks = sBuzzer.off_time; + + // Start with buzzer output on + sBuzzer.state = BUZZER_ON_OUTPUT_ENABLED; + } +} + +// ************************************************************************************************* +// @fn toggle_buzzer +// @brief Keeps track of buzzer on/off duty cycle +// @param none +// @return none +// ************************************************************************************************* +void toggle_buzzer(void) +{ + // Turn off buzzer + if (sBuzzer.state == BUZZER_ON_OUTPUT_ENABLED) + { + // Stop PWM timer + TA1CTL &= ~(BIT4 | BIT5); + + // Reset and disable buzzer PWM output + P2OUT &= ~BIT7; + P2SEL &= ~BIT7; + + // Update buzzer state + sBuzzer.state = BUZZER_ON_OUTPUT_DISABLED; + + // Reload Timer0_A4 IRQ to restart output + sTimer.timer0_A3_ticks = sBuzzer.on_time; + } + else // Turn on buzzer + { + // Decrement buzzer total cycles + countdown_buzzer(); + + // Reload Timer0_A4 to stop output if sBuzzer.time > 0 + if (sBuzzer.state != BUZZER_OFF) + { + // Reset timer TA1 + TA1R = 0; + TA1CTL |= MC_1; + + // Enable buzzer PWM output + P2SEL |= BIT7; + + // Update buzzer state + sBuzzer.state = BUZZER_ON_OUTPUT_ENABLED; + + // Reload Timer0_A4 IRQ to turn off output + sTimer.timer0_A3_ticks = sBuzzer.off_time; + } + } +} + +// ************************************************************************************************* +// @fn stop_buzzer +// @brief Stop buzzer output +// @param none +// @return none +// ************************************************************************************************* +void stop_buzzer(void) +{ + // Stop PWM timer + TA1CTL &= ~(BIT4 | BIT5); + + // Disable buzzer PWM output + P2OUT &= ~BIT7; + P2SEL &= ~BIT7; + + // Clear PWM timer interrupt + TA1CCTL0 &= ~CCIE; + + // Disable periodic start/stop interrupts + Timer0_A3_Stop(); + + // Clear variables + reset_buzzer(); +} + +// ************************************************************************************************* +// @fn is_buzzer +// @brief Check if buzzer is operating +// @param none +// @return u8 1 = Buzzer is operating, 0 = Buzzer is off +// ************************************************************************************************* +u8 is_buzzer(void) +{ + return (sBuzzer.state != BUZZER_OFF); +} + +// ************************************************************************************************* +// @fn countdown_buzzer +// @brief Decrement active buzzer time. Turn off buzzer if cycle end reached. +// @param none +// @return none +// ************************************************************************************************* +void countdown_buzzer(void) +{ + // Stop buzzer when reaching 0 cycles + if (--sBuzzer.time == 0) + { + stop_buzzer(); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/buzzer.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/buzzer.h new file mode 100755 index 0000000..59fbba9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/buzzer.h @@ -0,0 +1,87 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BUZZER_H_ +#define BUZZER_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_buzzer(void); +extern void start_buzzer(u8 cycles, u16 on_time, u16 off_time); +extern void stop_buzzer(void); +extern void toggle_buzzer(void); +extern u8 is_buzzer(void); +extern void countdown_buzzer(void); + +// ************************************************************************************************* +// Defines section + +// Buzzer states +#define BUZZER_OFF (0u) +#define BUZZER_ON_OUTPUT_DISABLED (1u) +#define BUZZER_ON_OUTPUT_ENABLED (2u) + +// Buzzer output signal frequency = 32,768kHz/(BUZZER_TIMER_STEPS+1)/2 = 2.7kHz +#define BUZZER_TIMER_STEPS (5u) + +// Buzzer on time +#define BUZZER_ON_TICKS (CONV_MS_TO_TICKS(20)) + +// Buzzer off time +#define BUZZER_OFF_TICKS (CONV_MS_TO_TICKS(200)) + +// ************************************************************************************************* +// Global Variable section +struct buzzer +{ + // Keep output for "time" seconds + u8 time; + + // On/off duty + u16 on_time; + u16 off_time; + + // Current buzzer output state + u8 state; +}; +extern struct buzzer sBuzzer; + +// ************************************************************************************************* +// Extern section + +#endif /*BUZZER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/display.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/display.c new file mode 100755 index 0000000..46a5d70 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/display.c @@ -0,0 +1,759 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Display functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include +#include + +// driver +#include "display.h" + +// logic +#include "clock.h" +#include "user.h" +#include "date.h" +#include "stopwatch.h" +#include "temperature.h" + +// ************************************************************************************************* +// Prototypes section +void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state); +void clear_line(u8 line); +void display_symbol(u8 symbol, u8 mode); +void display_char(u8 segment, u8 chr, u8 mode); +void display_chars(u8 segments, u8 * str, u8 mode); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// Table with memory bit assignment for digits "0" to "9" and characters "A" to "Z" +const u8 lcd_font[] = { + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F, // Displays "0" + SEG_B + SEG_C, // Displays "1" + SEG_A + SEG_B + SEG_D + SEG_E + SEG_G, // Displays "2" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_G, // Displays "3" + SEG_B + SEG_C + SEG_F + SEG_G, // Displays "4" + SEG_A + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "5" + SEG_A + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "6" + SEG_A + SEG_B + SEG_C, // Displays "7" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "8" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "9" + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + SEG_D + SEG_E + SEG_G, // Displays "c" + 0, // Displays " " + SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G, // Displays "A" + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "b" + SEG_A + SEG_D + SEG_E + SEG_F, // Displays "C" + SEG_B + SEG_C + SEG_D + SEG_E + SEG_G, // Displays "d" + SEG_A + +SEG_D + SEG_E + SEG_F + SEG_G, // Displays "E" + SEG_A + SEG_E + SEG_F + SEG_G, // Displays "F" + // SEG_A+ SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "G" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "g" + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G, // Displays "H" + SEG_E + SEG_F, // Displays "I" + SEG_A + SEG_B + SEG_C + SEG_D, // Displays "J" + // SEG_B+SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "k" + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "k" + SEG_D + SEG_E + SEG_F, // Displays "L" + SEG_A + SEG_B + SEG_C + SEG_E + SEG_F, // Displays "M" + SEG_C + SEG_E + SEG_G, // Displays "n" + SEG_C + SEG_D + SEG_E + SEG_G, // Displays "o" + SEG_A + SEG_B + SEG_E + SEG_F + SEG_G, // Displays "P" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F, // Displays "Q" + SEG_E + SEG_G, // Displays "r" + SEG_A + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "S" + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "t" + SEG_C + SEG_D + SEG_E, // Displays "u" + SEG_C + SEG_D + SEG_E, // Displays "u" + SEG_G, // Displays "-" + SEG_B + SEG_C + +SEG_E + SEG_F + SEG_G, // Displays "X" + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "Y" + SEG_A + SEG_B + SEG_D + SEG_E + SEG_G, // Displays "Z" +}; + +// Table with memory address for each display element +const u8 *segments_lcdmem[] = { + LCD_SYMB_AM_MEM, + LCD_SYMB_PM_MEM, + LCD_SYMB_ARROW_UP_MEM, + LCD_SYMB_ARROW_DOWN_MEM, + LCD_SYMB_PERCENT_MEM, + LCD_SYMB_TOTAL_MEM, + LCD_SYMB_AVERAGE_MEM, + LCD_SYMB_MAX_MEM, + LCD_SYMB_BATTERY_MEM, + LCD_UNIT_L1_FT_MEM, + LCD_UNIT_L1_K_MEM, + LCD_UNIT_L1_M_MEM, + LCD_UNIT_L1_I_MEM, + LCD_UNIT_L1_PER_S_MEM, + LCD_UNIT_L1_PER_H_MEM, + LCD_UNIT_L1_DEGREE_MEM, + LCD_UNIT_L2_KCAL_MEM, + LCD_UNIT_L2_KM_MEM, + LCD_UNIT_L2_MI_MEM, + LCD_ICON_HEART_MEM, + LCD_ICON_STOPWATCH_MEM, + LCD_ICON_RECORD_MEM, + LCD_ICON_ALARM_MEM, + LCD_ICON_BEEPER1_MEM, + LCD_ICON_BEEPER2_MEM, + LCD_ICON_BEEPER3_MEM, + LCD_SEG_L1_3_MEM, + LCD_SEG_L1_2_MEM, + LCD_SEG_L1_1_MEM, + LCD_SEG_L1_0_MEM, + LCD_SEG_L1_COL_MEM, + LCD_SEG_L1_DP1_MEM, + LCD_SEG_L1_DP0_MEM, + LCD_SEG_L2_5_MEM, + LCD_SEG_L2_4_MEM, + LCD_SEG_L2_3_MEM, + LCD_SEG_L2_2_MEM, + LCD_SEG_L2_1_MEM, + LCD_SEG_L2_0_MEM, + LCD_SEG_L2_COL1_MEM, + LCD_SEG_L2_COL0_MEM, + LCD_SEG_L2_DP_MEM, +}; + +// Table with bit mask for each display element +const u8 segments_bitmask[] = { + LCD_SYMB_AM_MASK, + LCD_SYMB_PM_MASK, + LCD_SYMB_ARROW_UP_MASK, + LCD_SYMB_ARROW_DOWN_MASK, + LCD_SYMB_PERCENT_MASK, + LCD_SYMB_TOTAL_MASK, + LCD_SYMB_AVERAGE_MASK, + LCD_SYMB_MAX_MASK, + LCD_SYMB_BATTERY_MASK, + LCD_UNIT_L1_FT_MASK, + LCD_UNIT_L1_K_MASK, + LCD_UNIT_L1_M_MASK, + LCD_UNIT_L1_I_MASK, + LCD_UNIT_L1_PER_S_MASK, + LCD_UNIT_L1_PER_H_MASK, + LCD_UNIT_L1_DEGREE_MASK, + LCD_UNIT_L2_KCAL_MASK, + LCD_UNIT_L2_KM_MASK, + LCD_UNIT_L2_MI_MASK, + LCD_ICON_HEART_MASK, + LCD_ICON_STOPWATCH_MASK, + LCD_ICON_RECORD_MASK, + LCD_ICON_ALARM_MASK, + LCD_ICON_BEEPER1_MASK, + LCD_ICON_BEEPER2_MASK, + LCD_ICON_BEEPER3_MASK, + LCD_SEG_L1_3_MASK, + LCD_SEG_L1_2_MASK, + LCD_SEG_L1_1_MASK, + LCD_SEG_L1_0_MASK, + LCD_SEG_L1_COL_MASK, + LCD_SEG_L1_DP1_MASK, + LCD_SEG_L1_DP0_MASK, + LCD_SEG_L2_5_MASK, + LCD_SEG_L2_4_MASK, + LCD_SEG_L2_3_MASK, + LCD_SEG_L2_2_MASK, + LCD_SEG_L2_1_MASK, + LCD_SEG_L2_0_MASK, + LCD_SEG_L2_COL1_MASK, + LCD_SEG_L2_COL0_MASK, + LCD_SEG_L2_DP_MASK, +}; + +// Quick integer to array conversion table for most common integer values +const u8 int_to_array_conversion_table[][3] = { + "000", "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", + "013", "014", "015", + "016", "017", "018", "019", "020", "021", "022", "023", "024", "025", "026", "027", "028", + "029", "030", "031", + "032", "033", "034", "035", "036", "037", "038", "039", "040", "041", "042", "043", "044", + "045", "046", "047", + "048", "049", "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", "060", + "061", "062", "063", + "064", "065", "066", "067", "068", "069", "070", "071", "072", "073", "074", "075", "076", + "077", "078", "079", + "080", "081", "082", "083", "084", "085", "086", "087", "088", "089", "090", "091", "092", + "093", "094", "095", + "096", "097", "098", "099", "100", "101", "102", "103", "104", "105", "106", "107", "108", + "109", "110", "111", + "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", + "125", "126", "127", + "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", + "141", "142", "143", + "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", + "157", "158", "159", + "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", + "173", "174", "175", + "176", "177", "178", "179", "180", +}; + +// Display flags +volatile s_display_flags display; + +// Global return string for int_to_array function +u8 int_to_array_str[8]; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); +extern void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn lcd_init +// @brief Erase LCD memory. Init LCD peripheral. +// @param none +// @return none +// ************************************************************************************************* +void lcd_init(void) +{ + // Clear entire display memory + LCDBMEMCTL |= LCDCLRBM + LCDCLRM; + + // LCD_FREQ = ACLK/16/8 = 256Hz + // Frame frequency = 256Hz/4 = 64Hz, LCD mux 4, LCD on + LCDBCTL0 = (LCDDIV0 + LCDDIV1 + LCDDIV2 + LCDDIV3) | (LCDPRE0 + LCDPRE1) | LCD4MUX | LCDON; + + // LCB_BLK_FREQ = ACLK/8/4096 = 1Hz + LCDBBLKCTL = LCDBLKPRE0 | LCDBLKPRE1 | LCDBLKDIV0 | LCDBLKDIV1 | LCDBLKDIV2 | LCDBLKMOD0; + + // I/O to COM outputs + P5SEL |= (BIT5 | BIT6 | BIT7); + P5DIR |= (BIT5 | BIT6 | BIT7); + + // Activate LCD output + LCDBPCTL0 = 0xFFFF; // Select LCD segments S0-S15 + LCDBPCTL1 = 0x00FF; // Select LCD segments S16-S22 + +#ifdef USE_LCD_CHARGE_PUMP + // Charge pump voltage generated internally, internal bias (V2-V4) generation + LCDBVCTL = LCDCPEN | VLCD_2_72; +#endif +} + +// ************************************************************************************************* +// @fn clear_display_all +// @brief Erase LINE1 and LINE2 segments. Clear also function-specific content. +// @param none +// @return none +// ************************************************************************************************* +void clear_display_all(void) +{ + // Clear generic content + clear_line(LINE1); + clear_line(LINE2); + + // Clean up function-specific content + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_CLEAR); +} + +// ************************************************************************************************* +// @fn clear_display +// @brief Erase LINE1 and LINE2 segments. Keep icons. +// @param none +// @return none +// ************************************************************************************************* +void clear_display(void) +{ + clear_line(LINE1); + clear_line(LINE2); +} + +// ************************************************************************************************* +// @fn clear_line +// @brief Erase segments of a given line. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void clear_line(u8 line) +{ + display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_5_0), NULL, SEG_OFF); + if (line == LINE1) + { + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + display_symbol(LCD_SEG_L1_DP0, SEG_OFF); + display_symbol(LCD_SEG_L1_COL, SEG_OFF); + } + else // line == LINE2 + { + display_symbol(LCD_SEG_L2_DP, SEG_OFF); + display_symbol(LCD_SEG_L2_COL1, SEG_OFF); + display_symbol(LCD_SEG_L2_COL0, SEG_OFF); + } +} + +// ************************************************************************************************* +// @fn write_segment +// @brief Write to one or multiple LCD segments +// @param lcdmem Pointer to LCD byte memory +// bits Segments to address +// bitmask Bitmask for particular display item +// mode On, off or blink segments +// @return +// ************************************************************************************************* +void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state) +{ + if (state == SEG_ON) + { + // Clear segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (u8) (*lcdmem | bits); + } + else if (state == SEG_OFF) + { + // Clear segments + *lcdmem = (u8) (*lcdmem & ~bitmask); + } + else if (state == SEG_ON_BLINK_ON) + { + // Clear visible / blink segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + + // Set visible / blink segments + *lcdmem = (u8) (*lcdmem | bits); + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) | bits); + } + else if (state == SEG_ON_BLINK_OFF) + { + // Clear visible segments before writing + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (u8) (*lcdmem | bits); + + // Clear blink segments + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + } + else if (state == SEG_OFF_BLINK_OFF) + { + // Clear segments + *lcdmem = (u8) (*lcdmem & ~bitmask); + + // Clear blink segments + *(lcdmem + 0x20) = (u8) (*(lcdmem + 0x20) & ~bitmask); + } +} + +// ************************************************************************************************* +// @fn int_to_array +// @brief Generic integer to array routine. Converts integer n to string. +// Default conversion result has leading zeros, e.g. "00123" +// Option to convert leading '0' into whitespace (blanks) +// @param u32 n integer to convert +// u8 digits number of digits +// u8 blanks fill up result string with number of +// whitespaces instead of leading zeros +// @return u8 string +// ************************************************************************************************* +u8 *int_to_array(u32 n, u8 digits, u8 blanks) +{ + u8 i; + u8 digits1 = digits; + + // Preset result string + memcpy(int_to_array_str, "0000000", 7); + + // Return empty string if number of digits is invalid (valid range for digits: 1-7) + if ((digits == 0) || (digits > 7)) + return (int_to_array_str); + + // Numbers 0 .. 180 can be copied from int_to_array_conversion_table without conversion + if (n <= 180) + { + if (digits >= 3) + { + memcpy(int_to_array_str + (digits - 3), int_to_array_conversion_table[n], 3); + } + else // digits == 1 || 2 + { + memcpy(int_to_array_str, int_to_array_conversion_table[n] + (3 - digits), digits); + } + } + else // For n > 180 need to calculate string content + { + // Calculate digits from least to most significant number + do + { + int_to_array_str[digits - 1] = n % 10 + '0'; + n /= 10; + } + while (--digits > 0); + } + + // Remove specified number of leading '0', always keep last one + i = 0; + while ((int_to_array_str[i] == '0') && (i < digits1 - 1)) + { + if (blanks > 0) + { + // Convert only specified number of leading '0' + int_to_array_str[i] = ' '; + blanks--; + } + i++; + } + + return (int_to_array_str); +} + +// ************************************************************************************************* +// @fn display_value +// @brief Generic decimal display routine. Used exclusively by set_value function. +// @param u8 segments LCD segments where value is displayed +// u32 value Integer value to be displayed +// u8 digits Number of digits to convert +// u8 blanks Number of leadings blanks in +// int_to_array result string +// @return none +// ************************************************************************************************* +void display_value(u8 segments, u32 value, u8 digits, u8 blanks) +{ + u8 *str; + + str = int_to_array(value, digits, blanks); + + // Display string in blink mode + display_chars(segments, str, SEG_ON_BLINK_ON); +} + +// ************************************************************************************************* +// @fn display_hours +// @brief Display hours in 24H / 12H time format. +// @param u8 segments Segments where to display hour data +// u32 value Hour data +// u8 digits Must be "2" +// u8 blanks Must be "0" +// @return none +// ************************************************************************************************* +void display_hours(u8 segments, u32 value, u8 digits, u8 blanks) +{ + u8 hours; + + if (sys.flag.use_metric_units) + { + // Display hours in 24H time format + display_value(segments, (u16) value, digits, blanks); + } + else + { + // convert internal 24H time format to 12H time format + hours = convert_hour_to_12H_format(value); + + // display hours in 12H time format + display_value(segments, hours, digits, blanks); + display_am_pm_symbol(value); + } +} + +// ************************************************************************************************* +// @fn display_am_pm_symbol +// @brief Display AM or PM symbol. +// @param u8 hour 24H internal time format +// @return none +// ************************************************************************************************* +void display_am_pm_symbol(u8 hour) +{ + // Display AM/PM symbol + if (is_hour_am(hour)) + { + display_symbol(LCD_SYMB_AM, SEG_ON); + } + else + { + // Clear AM segments first - required when changing from AM to PM + display_symbol(LCD_SYMB_AM, SEG_OFF); + display_symbol(LCD_SYMB_PM, SEG_ON); + } +} + +// ************************************************************************************************* +// @fn display_symbol +// @brief Switch symbol on or off on LCD. +// @param u8 symbol A valid LCD symbol (index 0..42) +// u8 state SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_symbol(u8 symbol, u8 mode) +{ + u8 *lcdmem; + u8 bits; + u8 bitmask; + + if (symbol <= LCD_SEG_L2_DP) + { + // Get LCD memory address for symbol from table + lcdmem = (u8 *) segments_lcdmem[symbol]; + + // Get bits for symbol from table + bits = segments_bitmask[symbol]; + + // Bitmask for symbols equals bits + bitmask = bits; + + // Write LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + +// ************************************************************************************************* +// @fn display_char +// @brief Write to 7-segment characters. +// @param u8 segment A valid LCD segment +// u8 chr Character to display +// u8 mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_char(u8 segment, u8 chr, u8 mode) +{ + u8 *lcdmem; // Pointer to LCD memory + u8 bitmask; // Bitmask for character + u8 bits, bits1; // Bits to write + + // Write to single 7-segment character + if ((segment >= LCD_SEG_L1_3) && (segment <= LCD_SEG_L2_DP)) + { + // Get LCD memory address for segment from table + lcdmem = (u8 *) segments_lcdmem[segment]; + + // Get bitmask for character from table + bitmask = segments_bitmask[segment]; + + // Get bits from font set + if ((chr >= 0x30) && (chr <= 0x5A)) + { + // Use font set + bits = lcd_font[chr - 0x30]; + } + else if (chr == 0x2D) + { + // '-' not in font set + bits = BIT1; + } + else + { + // Other characters map to ' ' (blank) + bits = 0; + } + + // When addressing LINE2 7-segment characters need to swap high- and low-nibble, + // because LCD COM/SEG assignment is mirrored against LINE1 + if (segment >= LCD_SEG_L2_5) + { + bits1 = ((bits << 4) & 0xF0) | ((bits >> 4) & 0x0F); + bits = bits1; + + // When addressing LCD_SEG_L2_5, need to convert ASCII '1' and 'L' to 1 bit, + // because LCD COM/SEG assignment is special for this incomplete character + if (segment == LCD_SEG_L2_5) + { + if ((chr == '1') || (chr == 'L')) + bits = BIT7; + } + } + + // Physically write to LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + +// ************************************************************************************************* +// @fn display_chars +// @brief Write to consecutive 7-segment characters. +// @param u8 segments LCD segment array +// u8 * str Pointer to a string +// u8 mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_chars(u8 segments, u8 * str, u8 mode) +{ + u8 i; + u8 length = 0; // Write length + u8 char_start; // Starting point for consecutive write + + switch (segments) + { + // LINE1 + case LCD_SEG_L1_3_0: + length = 4; + char_start = LCD_SEG_L1_3; + break; + case LCD_SEG_L1_2_0: + length = 3; + char_start = LCD_SEG_L1_2; + break; + case LCD_SEG_L1_1_0: + length = 2; + char_start = LCD_SEG_L1_1; + break; + case LCD_SEG_L1_3_1: + length = 3; + char_start = LCD_SEG_L1_3; + break; + case LCD_SEG_L1_3_2: + length = 2; + char_start = LCD_SEG_L1_3; + break; + + // LINE2 + case LCD_SEG_L2_5_0: + length = 6; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_4_0: + length = 5; + char_start = LCD_SEG_L2_4; + break; + case LCD_SEG_L2_3_0: + length = 4; + char_start = LCD_SEG_L2_3; + break; + case LCD_SEG_L2_2_0: + length = 3; + char_start = LCD_SEG_L2_2; + break; + case LCD_SEG_L2_1_0: + length = 2; + char_start = LCD_SEG_L2_1; + break; + case LCD_SEG_L2_5_4: + length = 2; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_5_2: + length = 4; + char_start = LCD_SEG_L2_5; + break; + case LCD_SEG_L2_3_2: + length = 2; + char_start = LCD_SEG_L2_3; + break; + case LCD_SEG_L2_4_2: + length = 3; + char_start = LCD_SEG_L2_4; + break; + } + + // Write to consecutive digits + for (i = 0; i < length; i++) + { + // Use single character routine to write display memory + display_char(char_start + i, *(str + i), mode); + } +} + +// ************************************************************************************************* +// @fn switch_seg +// @brief Returns index of 7-segment character. Required for display routines that can draw +// information on both lines. +// @param u8 line LINE1 or LINE2 +// u8 index1 Index of LINE1 +// u8 index2 Index of LINE2 +// @return uint8 +// ************************************************************************************************* +u8 switch_seg(u8 line, u8 index1, u8 index2) +{ + if (line == LINE1) + { + return index1; + } + else // line == LINE2 + { + return index2; + } +} + +// ************************************************************************************************* +// @fn start_blink +// @brief Start blinking. +// @param none +// @return none +// ************************************************************************************************* +void start_blink(void) +{ + LCDBBLKCTL |= LCDBLKMOD0; +} + +// ************************************************************************************************* +// @fn stop_blink +// @brief Stop blinking. +// @param none +// @return none +// ************************************************************************************************* +void stop_blink(void) +{ + LCDBBLKCTL &= ~LCDBLKMOD0; +} + +// ************************************************************************************************* +// @fn stop_blink +// @brief Clear blinking memory. +// @param none +// @return none +// ************************************************************************************************* +void clear_blink_mem(void) +{ + LCDBMEMCTL |= LCDCLRBM; +} + +// ************************************************************************************************* +// @fn set_blink_rate +// @brief Set blink rate register bits. +// @param none +// @return none +// ************************************************************************************************* +void set_blink_rate(u8 bits) +{ + LCDBBLKCTL &= ~(BIT7 | BIT6 | BIT5); + LCDBBLKCTL |= bits; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/display.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/display.h new file mode 100755 index 0000000..3674a4e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/display.h @@ -0,0 +1,338 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef __DISPLAY_H +#define __DISPLAY_H + +// ************************************************************************************************* +// Include section + +#include + +// ************************************************************************************************* +// Extern section + +// Constants defined in library +extern const u8 lcd_font[]; +extern const u8 *segments_lcdmem[]; +extern const u8 segments_bitmask[]; +extern const u8 int_to_array_conversion_table[][3]; + +// ************************************************************************************************* +// Global Variable section + +// Set of display flags +typedef union +{ + struct + { + // Line1 + Line2 + Icons + u16 full_update : 1; // 1 = Redraw all content + u16 partial_update : 1; // 1 = Update changes + + // Line only + u16 line1_full_update : 1; // 1 = Redraw Line1 content + u16 line2_full_update : 1; // 1 = Redraw Line2 content + + // Logic module data update flags + u16 update_time : 1; // 1 = Time was updated + u16 update_stopwatch : 1; // 1 = Stopwatch was updated + u16 update_temperature : 1; // 1 = Temperature was updated + u16 update_battery_voltage : 1; // 1 = Battery voltage was updated + u16 update_date : 1; // 1 = Date was updated + u16 update_alarm : 1; // 1 = Alarm time was updated + u16 update_acceleration : 1; // 1 = Acceleration data was updated + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_display_flags; + +extern volatile s_display_flags display; + +// ************************************************************************************************* +// Defines section + +// Display function modes +#define DISPLAY_LINE_UPDATE_FULL (BIT0) +#define DISPLAY_LINE_UPDATE_PARTIAL (BIT1) +#define DISPLAY_LINE_CLEAR (BIT2) + +// Definitions for line view style +#define DISPLAY_DEFAULT_VIEW (0u) +#define DISPLAY_ALTERNATIVE_VIEW (1u) + +// Definitions for line access +#define LINE1 (1u) +#define LINE2 (2u) + +// LCD display modes +#define SEG_OFF (0u) +#define SEG_ON (1u) +#define SEG_ON_BLINK_ON (2u) +#define SEG_ON_BLINK_OFF (3u) +#define SEG_OFF_BLINK_OFF (4u) + +// 7-segment character bit assignments +#define SEG_A (BIT4) +#define SEG_B (BIT5) +#define SEG_C (BIT6) +#define SEG_D (BIT7) +#define SEG_E (BIT2) +#define SEG_F (BIT0) +#define SEG_G (BIT1) + +// ------------------------------------------ +// LCD symbols for easier access +// +// xxx_SEG_xxx = Seven-segment character (sequence 5-4-3-2-1-0) +// xxx_SYMB_xxx = Display symbol, e.g. "AM" for ante meridiem +// xxx_UNIT_xxx = Display unit, e.g. "km/h" for kilometers per hour +// xxx_ICON_xxx = Display icon, e.g. heart to indicate reception of heart rate data +// xxx_L1_xxx = Item is part of Line1 information +// xxx_L2_xxx = Item is part of Line2 information + +// Symbols for Line1 +#define LCD_SYMB_AM 0 +#define LCD_SYMB_PM 1 +#define LCD_SYMB_ARROW_UP 2 +#define LCD_SYMB_ARROW_DOWN 3 +#define LCD_SYMB_PERCENT 4 + +// Symbols for Line2 +#define LCD_SYMB_TOTAL 5 +#define LCD_SYMB_AVERAGE 6 +#define LCD_SYMB_MAX 7 +#define LCD_SYMB_BATTERY 8 + +// Units for Line1 +#define LCD_UNIT_L1_FT 9 +#define LCD_UNIT_L1_K 10 +#define LCD_UNIT_L1_M 11 +#define LCD_UNIT_L1_I 12 +#define LCD_UNIT_L1_PER_S 13 +#define LCD_UNIT_L1_PER_H 14 +#define LCD_UNIT_L1_DEGREE 15 + +// Units for Line2 +#define LCD_UNIT_L2_KCAL 16 +#define LCD_UNIT_L2_KM 17 +#define LCD_UNIT_L2_MI 18 + +// Icons +#define LCD_ICON_HEART 19 +#define LCD_ICON_STOPWATCH 20 +#define LCD_ICON_RECORD 21 +#define LCD_ICON_ALARM 22 +#define LCD_ICON_BEEPER1 23 +#define LCD_ICON_BEEPER2 24 +#define LCD_ICON_BEEPER3 25 + +// Line1 7-segments +#define LCD_SEG_L1_3 26 +#define LCD_SEG_L1_2 27 +#define LCD_SEG_L1_1 28 +#define LCD_SEG_L1_0 29 +#define LCD_SEG_L1_COL 30 +#define LCD_SEG_L1_DP1 31 +#define LCD_SEG_L1_DP0 32 + +// Line2 7-segments +#define LCD_SEG_L2_5 33 +#define LCD_SEG_L2_4 34 +#define LCD_SEG_L2_3 35 +#define LCD_SEG_L2_2 36 +#define LCD_SEG_L2_1 37 +#define LCD_SEG_L2_0 38 +#define LCD_SEG_L2_COL1 39 +#define LCD_SEG_L2_COL0 40 +#define LCD_SEG_L2_DP 41 + +// Line1 7-segment arrays +#define LCD_SEG_L1_3_0 70 +#define LCD_SEG_L1_2_0 71 +#define LCD_SEG_L1_1_0 72 +#define LCD_SEG_L1_3_1 73 +#define LCD_SEG_L1_3_2 74 + +// Line2 7-segment arrays +#define LCD_SEG_L2_5_0 90 +#define LCD_SEG_L2_4_0 91 +#define LCD_SEG_L2_3_0 92 +#define LCD_SEG_L2_2_0 93 +#define LCD_SEG_L2_1_0 94 +#define LCD_SEG_L2_5_2 95 +#define LCD_SEG_L2_3_2 96 +#define LCD_SEG_L2_5_4 97 +#define LCD_SEG_L2_4_2 98 + +// LCD controller memory map +#define LCD_MEM_1 ((u8*)0x0A20) +#define LCD_MEM_2 ((u8*)0x0A21) +#define LCD_MEM_3 ((u8*)0x0A22) +#define LCD_MEM_4 ((u8*)0x0A23) +#define LCD_MEM_5 ((u8*)0x0A24) +#define LCD_MEM_6 ((u8*)0x0A25) +#define LCD_MEM_7 ((u8*)0x0A26) +#define LCD_MEM_8 ((u8*)0x0A27) +#define LCD_MEM_9 ((u8*)0x0A28) +#define LCD_MEM_10 ((u8*)0x0A29) +#define LCD_MEM_11 ((u8*)0x0A2A) +#define LCD_MEM_12 ((u8*)0x0A2B) + +// Memory assignment +#define LCD_SEG_L1_0_MEM (LCD_MEM_6) +#define LCD_SEG_L1_1_MEM (LCD_MEM_4) +#define LCD_SEG_L1_2_MEM (LCD_MEM_3) +#define LCD_SEG_L1_3_MEM (LCD_MEM_2) +#define LCD_SEG_L1_COL_MEM (LCD_MEM_1) +#define LCD_SEG_L1_DP1_MEM (LCD_MEM_1) +#define LCD_SEG_L1_DP0_MEM (LCD_MEM_5) +#define LCD_SEG_L2_0_MEM (LCD_MEM_8) +#define LCD_SEG_L2_1_MEM (LCD_MEM_9) +#define LCD_SEG_L2_2_MEM (LCD_MEM_10) +#define LCD_SEG_L2_3_MEM (LCD_MEM_11) +#define LCD_SEG_L2_4_MEM (LCD_MEM_12) +#define LCD_SEG_L2_5_MEM (LCD_MEM_12) +#define LCD_SEG_L2_COL1_MEM (LCD_MEM_1) +#define LCD_SEG_L2_COL0_MEM (LCD_MEM_5) +#define LCD_SEG_L2_DP_MEM (LCD_MEM_9) +#define LCD_SYMB_AM_MEM (LCD_MEM_1) +#define LCD_SYMB_PM_MEM (LCD_MEM_1) +#define LCD_SYMB_ARROW_UP_MEM (LCD_MEM_1) +#define LCD_SYMB_ARROW_DOWN_MEM (LCD_MEM_1) +#define LCD_SYMB_PERCENT_MEM (LCD_MEM_5) +#define LCD_SYMB_TOTAL_MEM (LCD_MEM_11) +#define LCD_SYMB_AVERAGE_MEM (LCD_MEM_10) +#define LCD_SYMB_MAX_MEM (LCD_MEM_8) +#define LCD_SYMB_BATTERY_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_FT_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_K_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_M_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_I_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_PER_S_MEM (LCD_MEM_5) +#define LCD_UNIT_L1_PER_H_MEM (LCD_MEM_7) +#define LCD_UNIT_L1_DEGREE_MEM (LCD_MEM_5) +#define LCD_UNIT_L2_KCAL_MEM (LCD_MEM_7) +#define LCD_UNIT_L2_KM_MEM (LCD_MEM_7) +#define LCD_UNIT_L2_MI_MEM (LCD_MEM_7) +#define LCD_ICON_HEART_MEM (LCD_MEM_2) +#define LCD_ICON_STOPWATCH_MEM (LCD_MEM_3) +#define LCD_ICON_RECORD_MEM (LCD_MEM_1) +#define LCD_ICON_ALARM_MEM (LCD_MEM_4) +#define LCD_ICON_BEEPER1_MEM (LCD_MEM_5) +#define LCD_ICON_BEEPER2_MEM (LCD_MEM_6) +#define LCD_ICON_BEEPER3_MEM (LCD_MEM_7) + +// Bit masks for write access +#define LCD_SEG_L1_0_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_1_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_2_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_3_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L1_COL_MASK (BIT5) +#define LCD_SEG_L1_DP1_MASK (BIT6) +#define LCD_SEG_L1_DP0_MASK (BIT2) +#define LCD_SEG_L2_0_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_1_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_2_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_3_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_4_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +#define LCD_SEG_L2_5_MASK (BIT7) +#define LCD_SEG_L2_COL1_MASK (BIT4) +#define LCD_SEG_L2_COL0_MASK (BIT0) +#define LCD_SEG_L2_DP_MASK (BIT7) +#define LCD_SYMB_AM_MASK (BIT1 + BIT0) +#define LCD_SYMB_PM_MASK (BIT0) +#define LCD_SYMB_ARROW_UP_MASK (BIT2) +#define LCD_SYMB_ARROW_DOWN_MASK (BIT3) +#define LCD_SYMB_PERCENT_MASK (BIT4) +#define LCD_SYMB_TOTAL_MASK (BIT7) +#define LCD_SYMB_AVERAGE_MASK (BIT7) +#define LCD_SYMB_MAX_MASK (BIT7) +#define LCD_SYMB_BATTERY_MASK (BIT7) +#define LCD_UNIT_L1_FT_MASK (BIT5) +#define LCD_UNIT_L1_K_MASK (BIT6) +#define LCD_UNIT_L1_M_MASK (BIT1) +#define LCD_UNIT_L1_I_MASK (BIT0) +#define LCD_UNIT_L1_PER_S_MASK (BIT7) +#define LCD_UNIT_L1_PER_H_MASK (BIT2) +#define LCD_UNIT_L1_DEGREE_MASK (BIT1) +#define LCD_UNIT_L2_KCAL_MASK (BIT4) +#define LCD_UNIT_L2_KM_MASK (BIT5) +#define LCD_UNIT_L2_MI_MASK (BIT6) +#define LCD_ICON_HEART_MASK (BIT3) +#define LCD_ICON_STOPWATCH_MASK (BIT3) +#define LCD_ICON_RECORD_MASK (BIT7) +#define LCD_ICON_ALARM_MASK (BIT3) +#define LCD_ICON_BEEPER1_MASK (BIT3) +#define LCD_ICON_BEEPER2_MASK (BIT3) +#define LCD_ICON_BEEPER3_MASK (BIT3) + +// ************************************************************************************************* +// API section + +// Physical LCD memory write +extern void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state); + +// Display init / clear +extern void lcd_init(void); +extern void clear_display(void); +extern void clear_display_all(void); +extern void clear_line(u8 line); + +// Blinking function +extern void start_blink(void); +extern void stop_blink(void); +extern void clear_blink_mem(void); +extern void set_blink_rate(u8 bits); + +// Character / symbol draw functions +extern void display_char(u8 segment, u8 chr, u8 mode); +extern void display_chars(u8 segments, u8 * str, u8 mode); +extern void display_symbol(u8 symbol, u8 mode); + +// Time display function +extern void DisplayTime(u8 updateMode); +extern void display_am_pm_symbol(u8 timeAM); + +// Set_value display functions +extern void display_value(u8 segments, u32 value, u8 digits, u8 blanks); +extern void display_hours(u8 segments, u32 value, u8 digits, u8 blanks); + +// Integer to string conversion +extern u8 *int_to_array(u32 n, u8 digits, u8 blanks); + +// Segment index helper function +extern u8 switch_seg(u8 line, u8 index1, u8 index2); + +#endif /*DISPLAY_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/ez430_chronos_drivers.r43 b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/ez430_chronos_drivers.r43 new file mode 100755 index 0000000..45b9a2a Binary files /dev/null and b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/ez430_chronos_drivers.r43 differ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/pmm.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/pmm.c new file mode 100755 index 0000000..6d53a7c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/pmm.c @@ -0,0 +1,78 @@ +//****************************************************************************// +// Function Library for setting the PMM +// +// This file is used in conjunction with PMM.c to set the core +// voltage level of a device. To set a core voltage level, call +// SetVCore(level). See RF project(s) for example usage. +// +// Original programm Stefan Schauer +// Rev 1.1: changed VCoreUp to fit with recommended flow (09/04/2008) +// +//****************************************************************************// +#include "cc430x613x.h" +#include "pmm.h" + +//****************************************************************************// +// Set VCore level +// SetVCore level is called from the user API +//****************************************************************************// +void SetVCore(unsigned char level) // Note: change level by one + // step only +{ + unsigned char actLevel; + + do + { + actLevel = PMMCTL0_L & PMMCOREV_3; + if (actLevel < level) + SetVCoreUp(++actLevel); // Set VCore (step by step) + if (actLevel > level) + SetVCoreDown(--actLevel); // Set VCore (step by step) + } + while (actLevel != level); +} + +//****************************************************************************// +// Set VCore up +//****************************************************************************// +void SetVCoreUp(unsigned char level) // Note: change level by one + // step only +{ + // Open PMM module registers for write access + PMMCTL0_H = 0xA5; + + // Set SVS/M high side to new level + SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; + + SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; // Set SVM new Level + while ((PMMIFG & SVSMLDLYIFG) == 0) ; // Wait till SVM is settled + // (Delay) + PMMCTL0_L = PMMCOREV0 * level; // Set VCore to x + PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); // Clear already set flags + if ((PMMIFG & SVMLIFG)) + while ((PMMIFG & SVMLVLRIFG) == 0) ; // Wait till level is reached + + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Set SVS/M Low side to new + // level + PMMCTL0_H = 0x00; // Lock PMM module registers + // for write access +} + +//****************************************************************************// +// Set VCore down +//****************************************************************************// +void SetVCoreDown(unsigned char level) +{ + PMMCTL0_H = 0xA5; // Open PMM module registers + // for write access + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Set SVS/M Low side to new + // level + while ((PMMIFG & SVSMLDLYIFG) == 0) ; // Wait till SVM is settled + // (Delay) + PMMCTL0_L = (level * PMMCOREV0); // Set VCore to 1.85 V for Max + // Speed. + PMMCTL0_H = 0x00; // Lock PMM module registers + // for write access +} + +//****************************************************************************// diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/pmm.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/pmm.h new file mode 100755 index 0000000..170008f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/pmm.h @@ -0,0 +1,43 @@ +//==================================================================== +// File: PMM.h +// +// This file is used in conjunction with PMM.c to set the core +// voltage level of a device. To set a core voltage level, call +// SetVCore(level). See RF project(s) for example usage. +// +// Version 1.0 first +// 07/14/07 +// +//==================================================================== + +#ifndef __PMM +#define __PMM + +//==================================================================== + +/** + * Set the VCore to a new level + * + * \param level PMM level ID + */ +void SetVCore(unsigned char level); + +//==================================================================== + +/** + * Set the VCore to a new higher level + * + * \param level PMM level ID + */ +void SetVCoreUp(unsigned char level); + +//==================================================================== + +/** + * Set the VCore to a new Lower level + * + * \param level PMM level ID + */ +void SetVCoreDown(unsigned char level); + +#endif /* __PMM */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/ports.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/ports.c new file mode 100755 index 0000000..cd086c3 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/ports.c @@ -0,0 +1,455 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Button entry functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "ports.h" +#include "buzzer.h" +#include "vti_as.h" +#include "vti_ps.h" +#include "timer.h" +#include "display.h" + +// logic +#include "clock.h" +#include "alarm.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "altitude.h" +#include "stopwatch.h" + +// ************************************************************************************************* +// Prototypes section +void button_repeat_on(u16 msec); +void button_repeat_off(void); +void button_repeat_function(void); + +// ************************************************************************************************* +// Defines section + +// Macro for button IRQ +#define IRQ_TRIGGERED(flags, bit) ((flags & bit) == bit) + +// ************************************************************************************************* +// Global Variable section +volatile s_button_flags button; +volatile struct struct_button sButton; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// @fn init_buttons +// @brief Init and enable button interrupts. +// @param none +// @return none +// ************************************************************************************************* +void init_buttons(void) +{ + // Set button ports to input + BUTTONS_DIR &= ~ALL_BUTTONS; + + // Enable internal pull-downs + BUTTONS_OUT &= ~ALL_BUTTONS; + BUTTONS_REN |= ALL_BUTTONS; + + // IRQ triggers on rising edge + BUTTONS_IES &= ~ALL_BUTTONS; + + // Reset IRQ flags + BUTTONS_IFG &= ~ALL_BUTTONS; + + // Enable button interrupts + BUTTONS_IE |= ALL_BUTTONS; +} + +// ************************************************************************************************* +// @fn PORT2_ISR +// @brief Interrupt service routine for +// - buttons +// - acceleration sensor CMA_INT +// - pressure sensor DRDY +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=PORT2_VECTOR +__interrupt void PORT2_ISR(void) +{ + // Clear flags + u8 int_flag, int_enable; + u8 buzzer = 0; + u8 simpliciti_button_event = 0; + static u8 simpliciti_button_repeat = 0; + + // Remember interrupt enable bits + int_enable = BUTTONS_IE; + + if ((!button.flag.star_long) && (!button.flag.num_long)) + { + // Clear button flags + button.all_flags = 0; + + // Store valid button interrupt flag + int_flag = BUTTONS_IFG & int_enable; + + // --------------------------------------------------- + // While SimpliciTI stack is active, buttons behave differently: + // - Store button events in SimpliciTI packet data + // - Exit SimpliciTI when button DOWN was pressed + if (is_rf()) + { + // Erase previous button press after a number of resends (increase number if link + // quality is low) + // This will create a series of packets containing the same button press + // Necessary because we have no acknowledge + // Filtering (edge detection) will be done by receiver software + if (simpliciti_button_repeat++ > 6) + { + simpliciti_data[0] &= ~0xF0; + simpliciti_button_repeat = 0; + } + + if ((int_flag & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_STAR; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_NUM; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_UP_PIN) == BUTTON_UP_PIN) + { + simpliciti_data[0] |= SIMPLICITI_BUTTON_UP; + simpliciti_button_event = 1; + } + else if ((int_flag & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN) + { + simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; + } + + // Trigger packet sending inside SimpliciTI stack + if (simpliciti_button_event) + simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; + } + else // Normal operation + { + // Debounce buttons + if ((int_flag & ALL_BUTTONS) != 0) + { + // Disable PORT2 IRQ + __disable_interrupt(); + BUTTONS_IE = 0x00; + __enable_interrupt(); + + // Debounce delay 1 + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN)); + + // Reset inactivity detection + sTime.last_activity = sTime.system_time; + } + + // --------------------------------------------------- + // STAR button IRQ + if (IRQ_TRIGGERED(int_flag, BUTTON_STAR_PIN)) + { + // Filter bouncing noise + if (BUTTON_STAR_IS_PRESSED) + { + button.flag.star = 1; + button.flag.star_not_long = 0; + // Generate button click + buzzer = 1; + } + else if ((BUTTONS_IES & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) + { + button.flag.star = 1; + button.flag.star_not_long = 0; + BUTTONS_IES &= ~BUTTON_STAR_PIN; + } + } + // --------------------------------------------------- + // NUM button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN)) + { + // Filter bouncing noise + if (BUTTON_NUM_IS_PRESSED) + { + button.flag.num = 1; + button.flag.num_not_long = 0; + // Generate button click + buzzer = 1; + } + else if ((BUTTONS_IES & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) + { + button.flag.num = 1; + button.flag.num_not_long = 0; + BUTTONS_IES &= ~BUTTON_NUM_PIN; + } + } + // --------------------------------------------------- + // UP button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_UP_PIN)) + { + // Filter bouncing noise + if (BUTTON_UP_IS_PRESSED) + { + button.flag.up = 1; + + // Generate button click + buzzer = 1; + } + } + // --------------------------------------------------- + // DOWN button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_DOWN_PIN)) + { + // Filter bouncing noise + if (BUTTON_DOWN_IS_PRESSED) + { + button.flag.down = 1; + + // Generate button click + buzzer = 1; + + // Faster reaction for stopwatch stop button press + if (is_stopwatch() && !sys.flag.lock_buttons) + { + stop_stopwatch(); + button.flag.down = 0; + } + } + } + // --------------------------------------------------- + // B/L button IRQ + else if (IRQ_TRIGGERED(int_flag, BUTTON_BACKLIGHT_PIN)) + { + // Filter bouncing noise + if (BUTTON_BACKLIGHT_IS_PRESSED) + { + sButton.backlight_status = 1; + sButton.backlight_timeout = 0; + P2OUT |= BUTTON_BACKLIGHT_PIN; + P2DIR |= BUTTON_BACKLIGHT_PIN; + } + } + } + + // Trying to lock/unlock buttons? + if (button.flag.num && button.flag.down) + { + // No buzzer output + buzzer = 0; + button.all_flags = 0; + } + + // Generate button click when button was activated + if (buzzer) + { + // Any button event stops active alarm + if (sAlarm.state == ALARM_ON) + { + stop_alarm(); + button.all_flags = 0; + } + else if (!sys.flag.up_down_repeat_enabled) + { + start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150)); + } + + // Debounce delay 2 + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + } + + // --------------------------------------------------- + // Acceleration sensor IRQ + if (IRQ_TRIGGERED(int_flag, AS_INT_PIN)) + { + // Get data from sensor + request.flag.acceleration_measurement = 1; + } + + // --------------------------------------------------- + // Pressure sensor IRQ + if (IRQ_TRIGGERED(int_flag, PS_INT_PIN)) + { + // Get data from sensor + request.flag.altitude_measurement = 1; + } + + // --------------------------------------------------- + // Safe long button event detection + if (button.flag.star || button.flag.num) + { + // Additional debounce delay to enable safe high detection - 50ms + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT)); + + // Check if this button event is short enough + if (BUTTON_STAR_IS_PRESSED) + { + // Change interrupt edge to detect button release + BUTTONS_IES |= BUTTON_STAR_PIN; + button.flag.star = 0; + // This flag is used to detect if the user released the button before the + // time for a long button press (3s) + button.flag.star_not_long = 1; + } + if (BUTTON_NUM_IS_PRESSED) + { + // Change interrupt edge to detect button release + BUTTONS_IES |= BUTTON_NUM_PIN; + button.flag.num = 0; + // This flag is used to detect if the user released the button before the + // time for a long button press (3s) + button.flag.num_not_long = 1; + } + } + + } + // Reenable PORT2 IRQ + __disable_interrupt(); + BUTTONS_IFG = 0x00; + BUTTONS_IE = int_enable; + __enable_interrupt(); + + // Exit from LPM3/LPM4 on RETI + __bic_SR_register_on_exit(LPM4_bits); +} + +// ************************************************************************************************* +// @fn button_repeat_on +// @brief Start button auto repeat timer. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_on(u16 msec) +{ + // Set button repeat flag + sys.flag.up_down_repeat_enabled = 1; + + // Set Timer0_A3 function pointer to button repeat function + fptr_Timer0_A3_function = button_repeat_function; + + // Timer0_A3 IRQ triggers every 200ms + Timer0_A3_Start(CONV_MS_TO_TICKS(msec)); +} + +// ************************************************************************************************* +// @fn button_repeat_off +// @brief Stop button auto repeat timer. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_off(void) +{ + // Clear button repeat flag + sys.flag.up_down_repeat_enabled = 0; + + // Timer0_A3 IRQ repeats with 4Hz + Timer0_A3_Stop(); +} + +// ************************************************************************************************* +// @fn button_repeat_function +// @brief Check at regular intervals if button is pushed continuously +// and trigger virtual button event. +// @param none +// @return none +// ************************************************************************************************* +void button_repeat_function(void) +{ + static u8 start_delay = 10; // Wait for 2 seconds before starting auto up/down + u8 repeat = 0; + + // If buttons UP or DOWN are continuously high, repeatedly set button flag + if (BUTTON_UP_IS_PRESSED) + { + if (start_delay == 0) + { + // Generate a virtual button event + button.flag.up = 1; + repeat = 1; + } + else + { + start_delay--; + } + } + else if (BUTTON_DOWN_IS_PRESSED) + { + if (start_delay == 0) + { + // Generate a virtual button event + button.flag.down = 1; + repeat = 1; + } + else + { + start_delay--; + } + } + else + { + // Reset repeat counter + sButton.repeats = 0; + start_delay = 10; + + // Enable blinking + start_blink(); + } + + // If virtual button event is generated, stop blinking and reset timeout counter + if (repeat) + { + // Increase repeat counter + sButton.repeats++; + + // Reset inactivity detection counter + sTime.last_activity = sTime.system_time; + + // Disable blinking + stop_blink(); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/ports.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/ports.h new file mode 100755 index 0000000..fcb731f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/ports.h @@ -0,0 +1,130 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef PORTS_H_ +#define PORTS_H_ + +// ************************************************************************************************* +// Defines section + +// Port, pins and interrupt resources for buttons +#define BUTTONS_IN (P2IN) +#define BUTTONS_OUT (P2OUT) +#define BUTTONS_DIR (P2DIR) +#define BUTTONS_REN (P2REN) +#define BUTTONS_IE (P2IE) +#define BUTTONS_IES (P2IES) +#define BUTTONS_IFG (P2IFG) +#define BUTTONS_IRQ_VECT2 (PORT2_VECTOR) + +// Button ports +#define BUTTON_STAR_PIN (BIT2) +#define BUTTON_NUM_PIN (BIT1) +#define BUTTON_UP_PIN (BIT4) +#define BUTTON_DOWN_PIN (BIT0) +#define BUTTON_BACKLIGHT_PIN (BIT3) +#define ALL_BUTTONS (BUTTON_STAR_PIN + BUTTON_NUM_PIN + BUTTON_UP_PIN + \ + BUTTON_DOWN_PIN + BUTTON_BACKLIGHT_PIN) + +// Macros for button press detection +#define BUTTON_STAR_IS_PRESSED ((BUTTONS_IN & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) +#define BUTTON_NUM_IS_PRESSED ((BUTTONS_IN & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) +#define BUTTON_UP_IS_PRESSED ((BUTTONS_IN & BUTTON_UP_PIN) == BUTTON_UP_PIN) +#define BUTTON_DOWN_IS_PRESSED ((BUTTONS_IN & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN) +#define BUTTON_BACKLIGHT_IS_PRESSED ((BUTTONS_IN & BUTTON_BACKLIGHT_PIN) == \ + BUTTON_BACKLIGHT_PIN) +#define NO_BUTTON_IS_PRESSED ((BUTTONS_IN & ALL_BUTTONS) == 0) + +// Macros for button release detection +#define BUTTON_STAR_IS_RELEASED ((BUTTONS_IN & BUTTON_STAR_PIN) == 0) +#define BUTTON_NUM_IS_RELEASED ((BUTTONS_IN & BUTTON_NUM_PIN) == 0) +#define BUTTON_UP_IS_RELEASED (BUTTONS_IN & BUTTON_UP_PIN) == 0) +#define BUTTON_DOWN_IS_RELEASED ((BUTTONS_IN & BUTTON_DOWN_PIN) == 0) +#define BUTTON_BACKLIGHT_IS_RELEASED ((BUTTONS_IN & BUTTON_BACKLIGHT_PIN) == 0) + +// Button debounce time (msec) +#define BUTTONS_DEBOUNCE_TIME_IN (5u) +#define BUTTONS_DEBOUNCE_TIME_OUT (250u) +#define BUTTONS_DEBOUNCE_TIME_LEFT (50u) + +// Detect if STAR / NUM button is held low continuously +#define LEFT_BUTTON_LONG_TIME (2u) + +// Backlight time (sec) +#define BACKLIGHT_TIME_ON (3u) + +// Leave set_value() function after some seconds of user inactivity +#define INACTIVITY_TIME (30u) + +// Set of button flags +typedef union +{ + struct + { + // Manual button events + u16 star : 1; // Short STAR button press + u16 num : 1; // Short NUM button press + u16 up : 1; // Short UP button press + u16 down : 1; // Short DOWN button press + u16 backlight : 1; // Short BACKLIGHT button press + u16 star_long : 1; // Long STAR button press + u16 num_long : 1; // Long NUM button press + u16 star_not_long : 1; // Between short and long STAR button press + u16 num_not_long : 1; // Between short and long NUM button press + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_button_flags; +extern volatile s_button_flags button; + +struct struct_button +{ + u8 star_timeout; // this variable is incremented each second if STAR button is still + // pressed + u8 num_timeout; // this variable is incremented each second if NUM button is still + // pressed + u8 backlight_timeout; // controls the timeout for the backlight + u8 backlight_status; // 1 case backlight is on + s16 repeats; +}; +extern volatile struct struct_button sButton; + +// ************************************************************************************************* +// Extern section +extern void button_repeat_on(u16 msec); +extern void button_repeat_off(void); +extern void button_repeat_function(void); +extern void init_buttons(void); + +#endif /*PORTS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/radio.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/radio.c new file mode 100755 index 0000000..276d929 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/radio.c @@ -0,0 +1,187 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// system +#include "project.h" + +// driver +#include "rf1a.h" +#include "timer.h" + +// logic +#include "rfsimpliciti.h" +#include "bluerobin.h" + +// ************************************************************************************************* +// Extern section + +// SimpliciTI CC430 radio ISR - located in SimpliciTi library +extern void MRFI_RadioIsr(void); + +// BlueRobin CC430 radio ISR - located in BlueRobin library +extern void BlueRobin_RadioISR_v(void); + +// ************************************************************************************************* +// @fn radio_reset +// @brief Reset radio core. +// @param none +// @return none +// ************************************************************************************************* +void radio_reset(void) +{ + volatile u16 i; + u8 x; + + // Reset radio core + Strobe(RF_SRES); + // Wait before checking IDLE + for (i = 0; i < 100; i++) ; + do + { + x = Strobe(RF_SIDLE); + } + while ((x & 0x70) != 0x00); + + // Clear radio error register + RF1AIFERR = 0; +} + +// ************************************************************************************************* +// @fn radio_powerdown +// @brief Put radio to SLEEP mode. +// @param none +// @return none +// ************************************************************************************************* +void radio_powerdown(void) +{ + // Chip bug: Radio does not come out of this SLEEP when put to sleep + // using the SPWD cmd. However, it does wakes up if SXOFF was used to + // put it to sleep. + + // Powerdown radio + Strobe(RF_SIDLE); + Strobe(RF_SPWD); +} + +// ************************************************************************************************* +// @fn radio_sxoff +// @brief Put radio to SLEEP mode (XTAL off only). +// @param none +// @return none +// ************************************************************************************************* +void radio_sxoff(void) +{ + // Chip bug: Radio does not come out of this SLEEP when put to sleep + // using the SPWD cmd. However, it does wakes up if SXOFF was used to + // put it to sleep. + + // Powerdown radio + Strobe(RF_SIDLE); + Strobe(RF_SXOFF); +} + +// ************************************************************************************************* +// @fn open_radio +// @brief Prepare radio for RF communication. +// @param none +// @return none +// ************************************************************************************************* +void open_radio(void) +{ + // Reset radio core + radio_reset(); + + // Enable radio IRQ + RF1AIFG &= ~BIT4; // Clear a pending interrupt + RF1AIE |= BIT4; // Enable the interrupt +} + +// ************************************************************************************************* +// @fn close_radio +// @brief Shutdown radio for RF communication. +// @param none +// @return none +// ************************************************************************************************* +void close_radio(void) +{ + // Disable radio IRQ + RF1AIFG = 0; + RF1AIE = 0; + + // Reset radio core + radio_reset(); + + // Put radio to sleep + radio_powerdown(); +} + +// ************************************************************************************************* +// @fn GDOx_ISR +// @brief GDO0/2 ISR to detect received packet. +// In BlueRobin mode: capture packet end time and decode received +// packet +// In SimpliciTI mode: go to SimpliciTI handler +// @param none +// @return none +// ************************************************************************************************* +#pragma vector=CC1101_VECTOR +__interrupt void radio_ISR(void) +{ + u8 rf1aivec = RF1AIV; + + // Forward to SimpliciTI interrupt service routine + if (is_rf()) + { + MRFI_RadioIsr(); + } + else // BlueRobin packet end interrupt service routine + { + if (rf1aivec == RF1AIV_RFIFG9) + { + if ((sBlueRobin.state == BLUEROBIN_SEARCHING) || + (sBlueRobin.state == BLUEROBIN_CONNECTED)) + { + BlueRobin_RadioISR_v(); + } + } + else if (rf1aivec == RF1AIV_NONE) // RF1A interface interrupt (error etc.) + { + asm (" nop"); // break here + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/radio.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/radio.h new file mode 100755 index 0000000..f4c1bb9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/radio.h @@ -0,0 +1,48 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RADIO_H_ +#define RADIO_H_ + +extern void radio_reset(void); +extern void radio_powerdown(void); +extern void radio_sxoff(void); +extern void radio_idle(void); +extern void open_radio(void); +extern void close_radio(void); +extern void pmm_set_high_current_mode(void); +extern void pmm_set_low_current_mode(void); + +#endif /*RADIO_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/rf1a.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/rf1a.c new file mode 100755 index 0000000..9f3b5be --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/rf1a.c @@ -0,0 +1,233 @@ +// ************************************************************************************************* +// +// Actual revision: $Revision: $ +// Revision label: $Name: $ +// Revision state: $State: $ +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include + +// driver +#include "rf1a.h" + +// ************************************************************************************************* +// Global section + +// ************************************************************************************************* +// Define section +#define st(x) do { x } while (__LINE__ == -1) +#define ENTER_CRITICAL_SECTION(x) st(x = __get_interrupt_state(); __disable_interrupt(); ) +#define EXIT_CRITICAL_SECTION(x) __set_interrupt_state(x) + +// ************************************************************************************************* +// @fn Strobe +// @brief Send command to radio. +// @param unsigned char strobe Command to radio +// @return statusByte Radio core status +// ************************************************************************************************* +unsigned char Strobe(unsigned char strobe) +{ + u8 statusByte = 0; + u16 int_state, gdo_state; + + // Check for valid strobe command + if ((strobe == 0xBD) || ((strobe > RF_SRES) && (strobe < RF_SNOP))) + { + ENTER_CRITICAL_SECTION(int_state); + + // Clear the Status read flag + RF1AIFCTL1 &= ~(RFSTATIFG); + + // Wait for radio to be ready for next instruction + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + + // Write the strobe instruction + if ((strobe > RF_SRES) && (strobe < RF_SNOP)) + { + + gdo_state = ReadSingleReg(IOCFG2); // buffer IOCFG2 state + WriteSingleReg(IOCFG2, 0x29); // c-ready to GDO2 + + RF1AINSTRB = strobe; + if ((RF1AIN & 0x04) == 0x04) // chip at sleep mode + { + if ((strobe == RF_SXOFF) || (strobe == RF_SPWD) || (strobe == RF_SWOR)) + { + } + else + { + while ((RF1AIN & 0x04) == 0x04) ; // c-ready ? + __delay_cycles(9800); // Delay for ~810usec at 12MHz CPU clock + } + } + WriteSingleReg(IOCFG2, gdo_state); // restore IOCFG2 setting + } + else // chip active mode + { + RF1AINSTRB = strobe; + } + statusByte = RF1ASTATB; + while (!(RF1AIFCTL1 & RFSTATIFG)) ; + EXIT_CRITICAL_SECTION(int_state); + } + return statusByte; +} + +// ************************************************************************************************* +// @fn ResetRadioCore +// @brief Software reset radio core. +// @param none +// @return none +// ************************************************************************************************* +void ResetRadioCore(void) +{ + Strobe(RF_SRES); // Reset the Radio Core + Strobe(RF_SNOP); // Reset Radio Pointer +} + +// ************************************************************************************************* +// @fn ReadSingleReg +// @brief Read byte from register. +// @param none +// @return none +// ************************************************************************************************* +unsigned char ReadSingleReg(unsigned char addr) +{ + unsigned char x; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + RF1AINSTR1B = (addr | RF_REGRD); + x = RF1ADOUT1B; + + EXIT_CRITICAL_SECTION(int_state); + + return x; +} + +// ************************************************************************************************* +// @fn WriteSingleReg +// @brief Write byte to register. +// @param none +// @return none +// ************************************************************************************************* +void WriteSingleReg(unsigned char addr, unsigned char value) +{ + volatile unsigned int i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for the next + // instruction + + RF1AINSTRW = ((addr | RF_REGWR) << 8) + value; // Send address + Instruction + while (!(RFDINIFG & RF1AIFCTL1)) ; + + i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status + // byte + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn ReadBurstReg +// @brief Read sequence of bytes from register. +// @param none +// @return none +// ************************************************************************************************* +void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) +{ + unsigned int i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for next instruction + RF1AINSTR1B = (addr | RF_REGRD); // Send address + Instruction + + for (i = 0; i < (count - 1); i++) + { + while (!(RFDOUTIFG & RF1AIFCTL1)) ; // Wait for the Radio Core to update the RF1ADOUTB reg + buffer[i] = RF1ADOUT1B; // Read DOUT from Radio Core + clears RFDOUTIFG + // Also initiates auo-read for next DOUT byte + } + buffer[count - 1] = RF1ADOUT0B; // Store the last DOUT from Radio Core + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn WriteBurstReg +// @brief Write sequence of bytes to register. +// @param none +// @return none +// ************************************************************************************************* +void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count) +{ + // Write Burst works wordwise not bytewise - bug known already + unsigned char i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for next + // instruction + RF1AINSTRW = ((addr | RF_REGWR) << 8) + buffer[0]; // Send address + Instruction + + for (i = 1; i < count; i++) + { + RF1ADINB = buffer[i]; // Send data + while (!(RFDINIFG & RF1AIFCTL1)) ; // Wait for TX to finish + } + i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status + // byte + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn WritePATable +// @brief Write data to power table +// @param unsigned char value Value to write +// @return none +// ************************************************************************************************* +void WritePATable(unsigned char value) +{ + unsigned char readbackPATableValue = 0; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (readbackPATableValue != value) + { + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRW = 0x7E00 + value; // PA Table write (burst) + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; // reset pointer + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = 0xFE; // PA Table read (burst) + + while (!(RF1AIFCTL1 & RFDINIFG)) ; + RF1ADINB = 0x00; //dummy write + + while (!(RF1AIFCTL1 & RFDOUTIFG)) ; + readbackPATableValue = RF1ADOUT0B; + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; + } + + EXIT_CRITICAL_SECTION(int_state); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/rf1a.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/rf1a.h new file mode 100755 index 0000000..f1acd1c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/rf1a.h @@ -0,0 +1,20 @@ +// ************************************************************************************************* +// +// Actual revision: $Revision: $ +// Revision label: $Name: $ +// Revision state: $State: $ +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// ************************************************************************************************* +// Prototype section +unsigned char Strobe(unsigned char strobe); +unsigned char ReadSingleReg(unsigned char addr); +void WriteSingleReg(unsigned char addr, unsigned char value); +void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count); +void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count); +void ResetRadioCore(void); +void WritePATable(unsigned char value); +void WaitForXT2(void); diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/timer.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/timer.c new file mode 100755 index 0000000..8cd2811 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/timer.c @@ -0,0 +1,576 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Timer service routines. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "timer.h" +#include "ports.h" +#include "buzzer.h" +#include "vti_ps.h" +#include "vti_as.h" +#include "display.h" + +// logic +#include "clock.h" +#include "battery.h" +#include "stopwatch.h" +#include "alarm.h" +#include "altitude.h" +#include "display.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "acceleration.h" +#include "bluerobin.h" +#include "temperature.h" + +// ************************************************************************************************* +// Prototypes section +void Timer0_Init(void); +void Timer0_Stop(void); +void Timer0_A1_Start(void); +void Timer0_A1_Stop(void); +void Timer0_A3_Start(u16 ticks); +void Timer0_A3_Stop(void); +void Timer0_A4_Delay(u16 ticks); + +void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct timer sTimer; + +// ************************************************************************************************* +// Extern section +extern void BRRX_TimerTask_v(void); +extern void to_lpm(void); + +// ************************************************************************************************* +// @fn Timer0_Init +// @brief Set Timer0 to a period of 1 or 2 sec. IRQ TACCR0 is asserted when timer overflows. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Init(void) +{ + // Set interrupt frequency to 1Hz + TA0CCR0 = 32768 - 1; + + // Enable timer interrupt + TA0CCTL0 |= CCIE; + + // Clear and start timer now + // Continuous mode: Count to 0xFFFF and restart from 0 again - 1sec timing will be generated by + // ISR + TA0CTL |= TASSEL0 + MC1 + TACLR; +} + +// ************************************************************************************************* +// @fn Timer0_Start +// @brief Start Timer0. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Start(void) +{ + // Start Timer0 in continuous mode + TA0CTL |= MC_2; +} + +// ************************************************************************************************* +// @fn Timer0_Stop +// @brief Stop and reset Timer0. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_Stop(void) +{ + // Stop Timer0 + TA0CTL &= ~MC_2; + + // Set Timer0 count register to 0x0000 + TA0R = 0; +} + +// ************************************************************************************************* +// @fn Timer0_A3_Start +// @brief Trigger IRQ every "ticks" microseconds +// @param ticks (1 tick = 1/32768 sec) +// @return none +// ************************************************************************************************* +void Timer0_A3_Start(u16 ticks) +{ + u16 value = 0; + + // Store timer ticks in global variable + sTimer.timer0_A3_ticks = ticks; + + // Delay based on current counter value + // To make sure this value is correctly read + while (value != TA0R) + value = TA0R; + value += ticks; + + // Update CCR + TA0CCR3 = value; + + // Reset IRQ flag + TA0CCTL3 &= ~CCIFG; + + // Enable timer interrupt + TA0CCTL3 |= CCIE; +} + +// ************************************************************************************************* +// @fn Timer0_A3_Stop +// @brief Stop Timer0_A3. +// @param none +// @return none +// ************************************************************************************************* +void Timer0_A3_Stop(void) +{ + // Clear timer interrupt + TA0CCTL3 &= ~CCIE; +} + +// ************************************************************************************************* +// @fn Timer0_A4_Delay +// @brief Wait for some microseconds +// @param ticks (1 tick = 1/32768 sec) +// @return none +// ************************************************************************************************* +void Timer0_A4_Delay(u16 ticks) +{ + u16 value = 0; + + // Exit immediately if Timer0 not running - otherwise we'll get stuck here + if ((TA0CTL & (BIT4 | BIT5)) == 0) + return; + + // Disable timer interrupt + TA0CCTL4 &= ~CCIE; + + // Clear delay_over flag + sys.flag.delay_over = 0; + + // Add delay to current timer value + // To make sure this value is correctly read + while (value != TA0R) + value = TA0R; + value += ticks; + + // Update CCR + TA0CCR4 = value; + + // Reset IRQ flag + TA0CCTL4 &= ~CCIFG; + + // Enable timer interrupt + TA0CCTL4 |= CCIE; + + // Wait for timer IRQ + while (1) + { + // Delay in LPM + to_lpm(); // will also set GIE again + +#ifdef USE_WATCHDOG + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; +#endif + // Redraw stopwatch display + if (is_stopwatch()) + display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_PARTIAL); + + // Check stop condition + // disable interrupt to prevent flag's change caused by interrupt methods + __disable_interrupt(); + if (sys.flag.delay_over) + break; + } + __enable_interrupt(); +} + +// ************************************************************************************************* +// @fn TIMER0_A0_ISR +// @brief IRQ handler for TIMER0_A0 IRQ +// Timer0_A0 1/1sec clock tick (serviced by +// function TIMER0_A0_ISR) +// Timer0_A1 +// (serviced by function +// TIMER0_A1_5_ISR) +// Timer0_A2 1/100 sec Stopwatch (serviced by +// function TIMER0_A1_5_ISR) +// Timer0_A3 Configurable periodic IRQ (serviced by +// function TIMER0_A1_5_ISR) +// Timer0_A4 One-time delay (serviced by +// function TIMER0_A1_5_ISR) +// @param none +// @return none +// ************************************************************************************************* +#pragma vector = TIMER0_A0_VECTOR +__interrupt void TIMER0_A0_ISR(void) +{ + static u8 button_lock_counter = 0; + + // Disable IE + TA0CCTL0 &= ~CCIE; + // Reset IRQ flag + TA0CCTL0 &= ~CCIFG; + // Add 1 sec to TACCR0 register (IRQ will be asserted at 0x7FFF and 0xFFFF = 1 sec intervals) + TA0CCR0 += 32768; + // Enable IE + TA0CCTL0 |= CCIE; + + // Add 1 second to global time + clock_tick(); + + // Set clock update flag + display.flag.update_time = 1; + + // While SimpliciTI stack operates or BlueRobin searches, freeze system state + if (is_rf() || is_bluerobin_searching()) + { + // SimpliciTI automatic timeout + if (sRFsmpl.timeout == 0) + { + simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; + } + else + { + sRFsmpl.timeout--; + } + + // switch message after received packet + if (sRFsmpl.mode == SIMPLICITI_SYNC) + { + if (sRFsmpl.display_sync_done == 0) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " SYNC", SEG_ON); + } + else + { + sRFsmpl.display_sync_done--; + } + } + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); + return; + } + + // ------------------------------------------------------------------- + // Service modules that require 1/min processing + if (sTime.drawFlag >= 2) + { + // Measure battery voltage to keep track of remaining battery life + request.flag.voltage_measurement = 1; + + // Check if alarm needs to be turned on + check_alarm(); + } + + // ------------------------------------------------------------------- + // Service active modules that require 1/s processing + + // Generate alarm signal + if (sAlarm.state == ALARM_ON) + { + // Decrement alarm duration counter + if (sAlarm.duration-- > 0) + { + request.flag.buzzer = 1; + } + else + { + sAlarm.duration = ALARM_ON_DURATION; + stop_alarm(); + } + } + + // Do a temperature measurement each second while menu item is active + if (is_temp_measurement()) + request.flag.temperature_measurement = 1; + + // Do a pressure measurement each second while menu item is active + if (is_altitude_measurement()) + { + // Countdown altitude measurement timeout while menu item is active + sAlt.timeout--; + + // Stop measurement when timeout has elapsed + if (sAlt.timeout == 0) + { + stop_altitude_measurement(); + // Show ---- m/ft + display_chars(LCD_SEG_L1_3_0, (u8 *) "----", SEG_ON); + // Clear up/down arrow + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + + // In case we missed the IRQ due to debouncing, get data now + if ((PS_INT_IN & PS_INT_PIN) == PS_INT_PIN) + request.flag.altitude_measurement = 1; + } + + // Count down timeout + if (is_acceleration_measurement()) + { + // Countdown acceleration measurement timeout + sAccel.timeout--; + + // Stop measurement when timeout has elapsed + if (sAccel.timeout == 0) + { + as_stop(); + // Show ---- + display_chars(LCD_SEG_L1_3_0, (u8 *) "----", SEG_ON); + // Clear up/down arrow + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + } + + // If DRDY is (still) high, request data again + if ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN) + request.flag.acceleration_measurement = 1; + } + + // If BlueRobin transmitter is connected, get data from API + if (is_bluerobin()) + get_bluerobin_data(); + + // If battery is low, decrement display counter + if (sys.flag.low_battery) + { + if (sBatt.lobatt_display-- == 0) + { + message.flag.prepare = 1; + message.flag.type_lobatt = 1; + sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE; + } + } + + // If a message has to be displayed, set display flag + if (message.all_flags) + { + if (message.flag.prepare) + { + message.flag.prepare = 0; + message.flag.show = 1; + } + else if (message.flag.erase) // message cycle is over, so erase it + { + message.flag.erase = 0; + display.flag.full_update = 1; + } + } + + // ------------------------------------------------------------------- + // Check idle timeout, set timeout flag + if (sys.flag.idle_timeout_enabled) + { + if (sTime.system_time - sTime.last_activity > INACTIVITY_TIME) + sys.flag.idle_timeout = 1; //setFlag(sysFlag_g, SYS_TIMEOUT_IDLE); + } + + // ------------------------------------------------------------------- + // Turn the Backlight off after timeout + if (sButton.backlight_status == 1) + { + if (sButton.backlight_timeout > BACKLIGHT_TIME_ON) + { + //turn off Backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + sButton.backlight_timeout = 0; + sButton.backlight_status = 0; + } + else + { + sButton.backlight_timeout++; + } + } + + // ------------------------------------------------------------------- + // Detect continuous button high states + + // Trying to lock/unlock buttons? + if (BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED) + { + if (button_lock_counter++ > LEFT_BUTTON_LONG_TIME) + { + // Toggle lock / unlock buttons flag + sys.flag.lock_buttons = ~sys.flag.lock_buttons; + + // Show "buttons are locked/unlocked" message synchronously with next second tick + message.flag.prepare = 1; + if (sys.flag.lock_buttons) + message.flag.type_locked = 1; + else + message.flag.type_unlocked = 1; + + // Reset button lock counter + button_lock_counter = 0; + } + } + else // Trying to create a long button press? + { + // Reset button lock counter + button_lock_counter = 0; + + if (BUTTON_STAR_IS_PRESSED) + { + sButton.star_timeout++; + + // Check if button was held low for some seconds + if (sButton.star_timeout > LEFT_BUTTON_LONG_TIME) + { + button.flag.star_long = 1; + button.flag.star_not_long = 0; + sButton.star_timeout = 0; + // Return interrupt edge to normal value + BUTTONS_IES &= ~BUTTON_STAR_PIN; + } + } + else // there was a button press not long enough + { + sButton.star_timeout = 0; + } + + if (BUTTON_NUM_IS_PRESSED) + { + sButton.num_timeout++; + + // Check if button was held low for some seconds + if (sButton.num_timeout > LEFT_BUTTON_LONG_TIME) + { + button.flag.num_long = 1; + button.flag.num_not_long = 0; + sButton.num_timeout = 0; + // Return interrupt edge to normal value + BUTTONS_IES &= ~BUTTON_NUM_PIN; + } + } + else // there was a button press not long enough + { + sButton.num_timeout = 0; + } + } + + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); +} + +// ************************************************************************************************* +// @fn Timer0_A1_5_ISR +// @brief IRQ handler for timer IRQ. +// Timer0_A0 1/1sec clock tick (serviced by function +// TIMER0_A0_ISR) +// Timer0_A1 BlueRobin timer +// Timer0_A2 1/100 sec Stopwatch +// Timer0_A3 Configurable periodic IRQ (used by button_repeat and +// buzzer) +// Timer0_A4 One-time delay +// @param none +// @return none +// ************************************************************************************************* +#pragma vector = TIMER0_A1_VECTOR +__interrupt void TIMER0_A1_5_ISR(void) +{ + u16 value = 0; + + switch (TA0IV) + { + // Timer0_A1 BlueRobin timer + case 0x02: // Timer0_A1 handler + BRRX_TimerTask_v(); + break; + + // Timer0_A2 1/1 or 1/100 sec Stopwatch + case 0x04: // Timer0_A2 handler + // Disable IE + TA0CCTL2 &= ~CCIE; + // Reset IRQ flag + TA0CCTL2 &= ~CCIFG; + // Load CCR register with next capture point + update_stopwatch_timer(); + // Enable timer interrupt + TA0CCTL2 |= CCIE; + // Increase stopwatch counter + stopwatch_tick(); + break; + + // Timer0_A3 Configurable periodic IRQ (used by button_repeat and buzzer) + case 0x06: // Disable IE + TA0CCTL3 &= ~CCIE; + // Reset IRQ flag + TA0CCTL3 &= ~CCIFG; + // Store new value in CCR + // To make sure this value is correctly read + while (value != TA0R) + value = TA0R; + value += sTimer.timer0_A3_ticks; + // Load CCR register with next capture point + TA0CCR3 = value; + // Enable timer interrupt + TA0CCTL3 |= CCIE; + // Call function handler + fptr_Timer0_A3_function(); + break; + + // Timer0_A4 One-time delay + case 0x08: // Disable IE + TA0CCTL4 &= ~CCIE; + // Reset IRQ flag + TA0CCTL4 &= ~CCIFG; + // Set delay over flag + sys.flag.delay_over = 1; + break; + } + + // Exit from LPM3 on RETI + _BIC_SR_IRQ(LPM3_bits); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/timer.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/timer.h new file mode 100755 index 0000000..89e0e53 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/timer.h @@ -0,0 +1,71 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef TIMER_H_ +#define TIMER_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void Timer0_Init(void); +extern void Timer0_Start(void); +extern void Timer0_Stop(void); +extern void Timer0_A3_Start(u16 ticks); +extern void Timer0_A3_Stop(void); +extern void Timer0_A4_Delay(u16 ticks); + +extern void (*fptr_Timer0_A3_function)(void); + +// ************************************************************************************************* +// Defines section +struct timer +{ + // Timer0_A3 periodic delay + u16 timer0_A3_ticks; +}; +extern struct timer sTimer; + +// Trigger reset when all buttons are pressed +#define BUTTON_RESET_SEC (3u) + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*TIMER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_as.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_as.c new file mode 100755 index 0000000..bede10d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_as.c @@ -0,0 +1,360 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// VTI CMA3000-D0x acceleration sensor driver functions +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// logic +#include "simpliciti.h" + +// driver +#include "vti_as.h" +#include "timer.h" +#include "display.h" + +// ************************************************************************************************* +// Prototypes section +void as_start(void); +void as_stop(void); +u8 as_read_register(u8 bAddress); +u8 as_write_register(u8 bAddress, u8 bData); + +// ************************************************************************************************* +// Defines section + +// ================================================================================================= +// CMA3000-D0x acceleration sensor configuration +// ================================================================================================= +// DCO frequency division factor determining speed of the acceleration sensor SPI interface +// Speed in Hz = 12MHz / AS_BR_DIVIDER (max. 500kHz) +#define AS_BR_DIVIDER (30u) + +// Acceleration measurement range in g +// Valid ranges are: 2 and 8 +#define AS_RANGE (2u) + +// Sample rate for acceleration values in Hz +// Valid sample rates for 2g range are: 100, 400 +// Valid sample rates for 8g range are: 40, 100, 400 +#define AS_SAMPLE_RATE (100u) + +// ************************************************************************************************* +// Global Variable section + +// Global flag for proper acceleration sensor operation +u8 as_ok; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn as_init +// @brief Setup acceleration sensor connection, do not power up yet +// @param none +// @return none +// ************************************************************************************************* +void as_init(void) +{ +#ifdef AS_DISCONNECT + // Deactivate connection to acceleration sensor + AS_PWR_OUT &= ~AS_PWR_PIN; // Power off + AS_INT_OUT &= ~AS_INT_PIN; // Pin to low to avoid floating pins + AS_SPI_OUT &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Pin to low to avoid floating pins + AS_CSN_OUT &= ~AS_CSN_PIN; // Pin to low to avoid floating pins + AS_INT_DIR |= AS_INT_PIN; // Pin to output to avoid floating pins + AS_SPI_DIR |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Pin to output to avoid floating pins + AS_CSN_DIR |= AS_CSN_PIN; // Pin to output to avoid floating pins + AS_PWR_DIR |= AS_PWR_PIN; // Power pin to output direction +#else + AS_INT_DIR &= ~AS_INT_PIN; // Input + AS_SPI_DIR &= ~AS_SDI_PIN; // Input + AS_SPI_DIR |= AS_SDO_PIN + AS_SCK_PIN; // Output + AS_SPI_SEL |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Port pins to SDO, SDI and SCK function + AS_CSN_OUT |= AS_CSN_PIN; // CSN=1 + AS_CSN_DIR |= AS_CSN_PIN; // + AS_PWR_OUT |= AS_PWR_PIN; // VDD=1 + AS_PWR_DIR |= AS_PWR_PIN; // +#endif + + // Reset global sensor flag + as_ok = 1; +} + +// ************************************************************************************************* +// @fn as_start +// @brief Power-up and initialize acceleration sensor +// @param none +// @return none +// ************************************************************************************************* +void as_start(void) +{ + volatile u16 Counter_u16; + u8 bConfig; //, bStatus; + + // Initialize SPI interface to acceleration sensor + AS_SPI_CTL0 |= UCSYNC | UCMST | UCMSB // SPI master, 8 data bits, MSB first, + | UCCKPH; // clock idle low, data output on falling + // edge + AS_SPI_CTL1 |= UCSSEL1; // SMCLK as clock source + AS_SPI_BR0 = AS_BR_DIVIDER; // Low byte of division factor for baud rate + AS_SPI_BR1 = 0x00; // High byte of division factor for baud + // rate + AS_SPI_CTL1 &= ~UCSWRST; // Start SPI hardware + + // Initialize interrupt pin for data read out from acceleration sensor + AS_INT_IES &= ~AS_INT_PIN; // Interrupt on rising edge + +#ifdef AS_DISCONNECT + // Enable interrupt + AS_INT_DIR &= ~AS_INT_PIN; // Switch INT pin to input + AS_SPI_DIR &= ~AS_SDI_PIN; // Switch SDI pin to input + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin + AS_SPI_SEL |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Port pins to SDO, SDI and SCK function + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_PWR_OUT |= AS_PWR_PIN; // Power on active high +#endif + + // Delay of >5ms required between switching on power and configuring sensor + Timer0_A4_Delay(CONV_MS_TO_TICKS(10)); + + // Initialize interrupt pin for data read out from acceleration sensor + AS_INT_IFG &= ~AS_INT_PIN; // Reset flag + AS_INT_IE |= AS_INT_PIN; // Enable interrupt + + // Configure sensor and start to sample data +#if (AS_RANGE == 2) + bConfig = 0x80; +# if (AS_SAMPLE_RATE == 100) + bConfig |= 0x02; +# elif (AS_SAMPLE_RATE == 400) + bConfig |= 0x04; +# else +# error "Sample rate not supported" +# endif +#elif (AS_RANGE == 8) + bConfig = 0x00; +# if (AS_SAMPLE_RATE == 40) + bConfig |= 0x06; +# elif (AS_SAMPLE_RATE == 100) + bConfig |= 0x02; +# elif (AS_SAMPLE_RATE == 400) + bConfig |= 0x04; +# else +# error "Sample rate not supported" +# endif +#else +# error "Measurement range not supported" +#endif + + // Reset sensor + as_write_register(0x04, 0x02); + as_write_register(0x04, 0x0A); + as_write_register(0x04, 0x04); + + // Wait 5 ms before starting sensor output + Timer0_A4_Delay(CONV_MS_TO_TICKS(5)); + + // Set 2g measurement range, start to output data with 100Hz rate + as_write_register(0x02, bConfig); +} + +// ************************************************************************************************* +// @fn as_stop +// @brief Power down acceleration sensor +// @param none +// @return none +// ************************************************************************************************* +void as_stop(void) +{ + // Disable interrupt + AS_INT_IE &= ~AS_INT_PIN; // Disable interrupt + +#ifdef AS_DISCONNECT + // Power-down sensor + AS_PWR_OUT &= ~AS_PWR_PIN; // Power off + AS_INT_OUT &= ~AS_INT_PIN; // Pin to low to avoid floating pins + AS_SPI_OUT &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Pins to low to avoid floating pins + AS_SPI_SEL &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Port pins to I/O function + AS_CSN_OUT &= ~AS_CSN_PIN; // Pin to low to avoid floating pins + AS_INT_DIR |= AS_INT_PIN; // Pin to output to avoid floating pins + AS_SPI_DIR |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Pins to output to avoid floating pins + AS_CSN_DIR |= AS_CSN_PIN; // Pin to output to avoid floating pins +#else + // Reset sensor -> sensor to powerdown + as_write_register(0x04, 0x02); + as_write_register(0x04, 0x0A); + as_write_register(0x04, 0x04); +#endif +} + +// ************************************************************************************************* +// @fn as_read_register +// @brief Read a byte from the acceleration sensor +// @param u8 bAddress Register address +// @return u8 bResult Register content +// If the returned value is 0, +// there was an error. +// ************************************************************************************************* +u8 as_read_register(u8 bAddress) +{ + u8 bResult; + u16 timeout; + + // Exit function if an error was detected previously + if (!as_ok) + return (0); + + bAddress <<= 2; // Address to be shifted left by 2 and + // RW bit to be reset + + AS_SPI_REN &= ~AS_SDI_PIN; // Pulldown on SDI pin not required + AS_CSN_OUT &= ~AS_CSN_PIN; // Select acceleration sensor + + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bAddress; // Write address to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = 0; // Write dummy data to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer + + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin required again + + // Return new data from RX buffer + return bResult; +} + +// ************************************************************************************************* +// @fn as_write_register +// @brief Write a byte to the acceleration sensor +// @param u8 bAddress Register address +// u8 bData Data to write +// @return u8 0 or bResult Register content. +// If the returned value is 0, +// there was an error. +// ************************************************************************************************* +u8 as_write_register(u8 bAddress, u8 bData) +{ + u8 bResult; + u16 timeout; + + // Exit function if an error was detected previously + if (!as_ok) + return (0); + + bAddress <<= 2; // Address to be shifted left by 1 + bAddress |= BIT1; // RW bit to be set + + AS_SPI_REN &= ~AS_SDI_PIN; // Pulldown on SDI pin not required + AS_CSN_OUT &= ~AS_CSN_PIN; // Select acceleration sensor + + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bAddress; // Write address to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer just to clear + // interrupt flag + + AS_TX_BUFFER = bData; // Write data to TX buffer + + timeout = SPI_TIMEOUT; + while (!(AS_IRQ_REG & AS_RX_IFG) && (--timeout > 0)) ; // Wait until new data was written into + // RX buffer + if (timeout == 0) + { + as_ok = 0; + return (0); + } + bResult = AS_RX_BUFFER; // Read RX buffer + + AS_CSN_OUT |= AS_CSN_PIN; // Deselect acceleration sensor + AS_SPI_REN |= AS_SDI_PIN; // Pulldown on SDI pin required again + + return bResult; +} + +// ************************************************************************************************* +// @fn as_get_data +// @brief Service routine to read acceleration values. +// @param none +// @return none +// ************************************************************************************************* +void as_get_data(u8 * data) +{ + // Exit if sensor is not powered up + if ((AS_PWR_OUT & AS_PWR_PIN) != AS_PWR_PIN) + return; + + // Store X/Y/Z acceleration data in buffer + *(data + 0) = as_read_register(0x06); + *(data + 1) = as_read_register(0x07); + *(data + 2) = as_read_register(0x08); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_as.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_as.h new file mode 100755 index 0000000..358a948 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_as.h @@ -0,0 +1,106 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef VTI_AS_H_ +#define VTI_AS_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void as_init(void); +extern void as_start(void); +extern void as_stop(void); +extern u8 as_read_register(u8 bAddress); +extern u8 as_write_register(u8 bAddress, u8 bData); +extern void as_get_data(u8 * data); + +// ************************************************************************************************* +// Defines section + +// Disconnect power supply for acceleration sensor when not used +#define AS_DISCONNECT + +// Port and pin resource for SPI interface to acceleration sensor +// SDO=MOSI=P1.6, SDI=MISO=P1.5, SCK=P1.7 +#define AS_SPI_IN (P1IN) +#define AS_SPI_OUT (P1OUT) +#define AS_SPI_DIR (P1DIR) +#define AS_SPI_SEL (P1SEL) +#define AS_SPI_REN (P1REN) +#define AS_SDO_PIN (BIT6) +#define AS_SDI_PIN (BIT5) +#define AS_SCK_PIN (BIT7) + +// CSN=PJ.1 +#define AS_CSN_OUT (PJOUT) +#define AS_CSN_DIR (PJDIR) +#define AS_CSN_PIN (BIT1) + +#define AS_TX_BUFFER (UCA0TXBUF) +#define AS_RX_BUFFER (UCA0RXBUF) +#define AS_TX_IFG (UCTXIFG) +#define AS_RX_IFG (UCRXIFG) +#define AS_IRQ_REG (UCA0IFG) +#define AS_SPI_CTL0 (UCA0CTL0) +#define AS_SPI_CTL1 (UCA0CTL1) +#define AS_SPI_BR0 (UCA0BR0) +#define AS_SPI_BR1 (UCA0BR1) + +// Port and pin resource for power-up of acceleration sensor, VDD=PJ.0 +#define AS_PWR_OUT (PJOUT) +#define AS_PWR_DIR (PJDIR) +#define AS_PWR_PIN (BIT0) + +// Port, pin and interrupt resource for interrupt from acceleration sensor, CMA_INT=P2.5 +#define AS_INT_IN (P2IN) +#define AS_INT_OUT (P2OUT) +#define AS_INT_DIR (P2DIR) +#define AS_INT_IE (P2IE) +#define AS_INT_IES (P2IES) +#define AS_INT_IFG (P2IFG) +#define AS_INT_PIN (BIT5) + +// SPI timeout to detect sensor failure +#define SPI_TIMEOUT (1000u) + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*VTI_AS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_ps.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_ps.c new file mode 100755 index 0000000..645f17e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_ps.c @@ -0,0 +1,559 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// VTI SCP1000-D0x pressure sensor driver functions +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "vti_ps.h" +#include "timer.h" + +// ************************************************************************************************* +// Prototypes section +u16 ps_read_register(u8 address, u8 mode); +u8 ps_write_register(u8 address, u8 data); +u8 ps_twi_read(u8 ack); +void twi_delay(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// VTI pressure (hPa) to altitude (m) conversion tables +const s16 h0[17] = +{ -153, 0, 111, 540, 989, 1457, 1949, 2466, 3012, 3591, 4206, 4865, 5574, 6344, 7185, 8117, 9164 }; +const u16 p0[17] = +{ 1031, 1013, 1000, 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300 }; + +float p[17]; + +// Global flag for proper pressure sensor operation +u8 ps_ok; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn ps_init +// @brief Init pressure sensor I/O +// @param none +// @return none +// ************************************************************************************************* +void ps_init(void) +{ + volatile u8 success, status, eeprom, timeout; + + PS_INT_DIR &= ~PS_INT_PIN; // DRDY is input + PS_INT_IES &= ~PS_INT_PIN; // Interrupt on DRDY rising edge + PS_TWI_OUT |= PS_SCL_PIN + PS_SDA_PIN; // SCL and SDA are outputs by default + PS_TWI_DIR |= PS_SCL_PIN + PS_SDA_PIN; // SCL and SDA are outputs by default + + // Reset global ps_ok flag + ps_ok = 0; + + // 100msec delay to allow VDD stabilisation + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + + // Reset pressure sensor -> powerdown sensor + success = ps_write_register(0x06, 0x01); + + // 100msec delay + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + + // Check if STATUS register BIT0 is cleared + status = ps_read_register(0x07, PS_TWI_8BIT_ACCESS); + if (((status & BIT0) == 0) && (status != 0)) + { + // Check EEPROM checksum in DATARD8 register + eeprom = ps_read_register(0x7F, PS_TWI_8BIT_ACCESS); + if (eeprom == 0x01) + ps_ok = 1; + else + ps_ok = 0; + } +} + +// ************************************************************************************************* +// @fn ps_start +// @brief Init pressure sensor registers and start sampling +// @param none +// @return u8 1=Sensor started, 0=Sensor did not start +// ************************************************************************************************* +void ps_start(void) +{ + // Start sampling data in ultra low power mode + ps_write_register(0x03, 0x0B); +} + +// ************************************************************************************************* +// @fn ps_stop +// @brief Power down pressure sensor +// @param none +// @return none +// ************************************************************************************************* +void ps_stop(void) +{ + // Put sensor to standby + ps_write_register(0x03, 0x00); +} + +// ************************************************************************************************* +// @fn ps_twi_sda +// @brief Control SDA line +// @param u8 condition PS_TWI_SEND_START, PS_TWI_SEND_RESTART, PS_TWI_SEND_STOP +// PS_TWI_CHECK_ACK +// @return u8 1=ACK, 0=NACK +// ************************************************************************************************* +u8 ps_twi_sda(u8 condition) +{ + u8 sda = 0; + + if (condition == PS_TWI_SEND_START) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; // SCL 1-0 transition while SDA=0 + twi_delay(); + } + else if (condition == PS_TWI_SEND_RESTART) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SCL_LO; + PS_TWI_SDA_HI; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; + twi_delay(); + } + else if (condition == PS_TWI_SEND_STOP) + { + PS_TWI_SDA_OUT; // SDA is output + PS_TWI_SDA_LO; + twi_delay(); + PS_TWI_SCL_LO; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + PS_TWI_SDA_HI; // SDA 0-1 transition while SCL=1 + twi_delay(); + } + else if (condition == PS_TWI_CHECK_ACK) + { + PS_TWI_SDA_IN; // SDA is input + PS_TWI_SCL_LO; + twi_delay(); + PS_TWI_SCL_HI; + twi_delay(); + sda = PS_TWI_IN & PS_SDA_PIN; + PS_TWI_SCL_LO; + } + + // Return value will only be evaluated when checking device ACK + return (sda == 0); +} + +// ************************************************************************************************* +// @fn twi_delay +// @brief Delay between TWI signal edges. +// @param none +// @return none +// ************************************************************************************************* +void twi_delay(void) +{ + asm (" nop"); +} + +// ************************************************************************************************* +// @fn ps_twi_write +// @brief Clock out bits through SDA. +// @param u8 data Byte to send +// @return none +// ************************************************************************************************* +void ps_twi_write(u8 data) +{ + u8 i, mask; + + // Set mask byte to 10000000b + mask = BIT0 << 7; + + PS_TWI_SDA_OUT; // SDA is output + + for (i = 8; i > 0; i--) + { + PS_TWI_SCL_LO; // SCL=0 + if ((data & mask) == mask) + { + PS_TWI_SDA_HI; // SDA=1 + } + else + { + PS_TWI_SDA_LO; // SDA=0 + } + mask = mask >> 1; + twi_delay(); + PS_TWI_SCL_HI; // SCL=1 + twi_delay(); + } + + PS_TWI_SCL_LO; // SCL=0 + PS_TWI_SDA_IN; // SDA is input +} + +// ************************************************************************************************* +// @fn ps_twi_read +// @brief Read bits from SDA +// @param u8 ack 1=Send ACK after read, 0=Send NACK after read +// @return u8 Bits read +// ************************************************************************************************* +u8 ps_twi_read(u8 ack) +{ + u8 i; + u8 data = 0; + + PS_TWI_SDA_IN; // SDA is input + + for (i = 0; i < 8; i++) + { + PS_TWI_SCL_LO; // SCL=0 + twi_delay(); + PS_TWI_SCL_HI; // SCL=0 + twi_delay(); + + // Shift captured bits to left + data = data << 1; + + // Capture new bit + if ((PS_TWI_IN & PS_SDA_PIN) == PS_SDA_PIN) + data |= BIT0; + } + + PS_TWI_SDA_OUT; // SDA is output + + // 1 aditional clock phase to generate master ACK + PS_TWI_SCL_LO; // SCL=0 + if (ack == 1) + PS_TWI_SDA_LO // Send ack -> continue read + else + PS_TWI_SDA_HI // Send nack -> stop read + twi_delay(); + PS_TWI_SCL_HI; // SCL=0 + twi_delay(); + PS_TWI_SCL_LO; + + return (data); +} + +// ************************************************************************************************* +// @fn as_write_register +// @brief Write a byte to the pressure sensor +// @param u8 address Register address +// u8 data Data to write +// @return u8 +// ************************************************************************************************* +u8 ps_write_register(u8 address, u8 data) +{ + volatile u8 success; + + ps_twi_sda(PS_TWI_SEND_START); // Generate start condition + + ps_twi_write((0x11 << 1) | PS_TWI_WRITE); // Send 7bit device address 0x11 + write bit '0' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(address); // Send 8bit register address + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(data); // Send 8bit data to register + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + // Slave does not send this ACK + // if (!success) return (0); + + ps_twi_sda(PS_TWI_SEND_STOP); // Generate stop condition + + return (1); +} + +// ************************************************************************************************* +// @fn ps_read_register +// @brief Read a byte from the pressure sensor +// @param u8 address Register address +// u8 mode PS_TWI_8BIT_ACCESS, PS_TWI_16BIT_ACCESS +// @return u16 Register content +// ************************************************************************************************* +u16 ps_read_register(u8 address, u8 mode) +{ + u8 success; + u16 data = 0; + + ps_twi_sda(PS_TWI_SEND_START); // Generate start condition + + ps_twi_write((0x11 << 1) | PS_TWI_WRITE); // Send 7bit device address 0x11 + write bit '0' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_write(address); // Send 8bit register address + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + ps_twi_sda(PS_TWI_SEND_RESTART); // Generate restart condition + + ps_twi_write((0x11 << 1) | PS_TWI_READ); // Send 7bit device address 0x11 + read bit '1' + success = ps_twi_sda(PS_TWI_CHECK_ACK); // Check ACK from device + if (!success) + return (0); + + if (mode == PS_TWI_16BIT_ACCESS) + { + data = ps_twi_read(1) << 8; // Read MSB 8bit data from register + data |= ps_twi_read(0); // Read LSB 8bit data from register + } + else + { + data = ps_twi_read(0); // Read 8bit data from register + } + + ps_twi_sda(PS_TWI_SEND_STOP); // Generate stop condition + + return (data); +} + +// ************************************************************************************************* +// @fn ps_get_pa +// @brief Read out pressure. Format is Pa. Range is 30000 .. 120000 Pa. +// @param none +// @return u32 15-bit pressure sensor value (Pa) +// ************************************************************************************************* +u32 ps_get_pa(void) +{ + volatile u32 data = 0; + + // Get 3 MSB from DATARD8 register + data = ps_read_register(0x7F, PS_TWI_8BIT_ACCESS); + data = ((data & 0x07) << 8) << 8; + + // Get 16 LSB from DATARD16 register + data |= ps_read_register(0x80, PS_TWI_16BIT_ACCESS); + + // Convert decimal value to Pa + data = (data >> 2); + + return (data); +} + +// ************************************************************************************************* +// @fn ps_get_temp +// @brief Read out temperature. +// @param none +// @return u16 13-bit temperature value in xx.x K format +// ************************************************************************************************* +u16 ps_get_temp(void) +{ + volatile u16 data = 0; + u16 temp = 0; + u8 is_negative = 0; + u16 kelvin; + + // Get 13 bit from TEMPOUT register + data = ps_read_register(0x81, PS_TWI_16BIT_ACCESS); + + // Convert negative temperatures + if ((data & BIT(13)) == BIT(13)) + { + // Sign extend temperature + data |= 0xC000; + // Convert two's complement + data = ~data; + data += 1; + is_negative = 1; + } + + temp = data / 2; + + // Convert from °C to K + if (is_negative) + kelvin = 2732 - temp; + else + kelvin = temp + 2732; + + return (kelvin); +} + +// ************************************************************************************************* +// @fn init_pressure_table +// @brief Init pressure table with constants +// @param u32 p Pressure (Pa) +// @return u16 Altitude (m) +// ************************************************************************************************* +void init_pressure_table(void) +{ + u8 i; + + for (i = 0; i < 17; i++) + p[i] = p0[i]; +} + +// ************************************************************************************************* +// @fn update_pressure_table +// @brief Calculate pressure table for reference altitude. +// Implemented straight from VTI reference code. +// @param s16 href Reference height +// u32 p_meas Pressure (Pa) +// u16 t_meas Temperature (10*K) +// @return none +// ************************************************************************************************* +void update_pressure_table(s16 href, u32 p_meas, u16 t_meas) +{ + const float Invt00 = 0.003470415; + const float coefp = 0.00006; + volatile float p_fact; + volatile float p_noll; + volatile float hnoll; + volatile float h_low = 0; + volatile float t0; + u8 i; + + // Typecast arguments + volatile float fl_href = href; + volatile float fl_p_meas = (float)p_meas / 100; // Convert from Pa to hPa + volatile float fl_t_meas = (float)t_meas / 10; // Convert from 10 K to 1 K + + t0 = fl_t_meas + (0.0065 * fl_href); + + hnoll = fl_href / (t0 * Invt00); + + for (i = 0; i <= 15; i++) + { + if (h0[i] > hnoll) + break; + h_low = h0[i]; + } + + p_noll = + (float)(hnoll - + h_low) * + (1 - + (hnoll - + (float)h0[i]) * + coefp) * ((float)p0[i] - (float)p0[i - 1]) / ((float)h0[i] - h_low) + (float)p0[i - 1]; + + // Calculate multiplicator + p_fact = fl_p_meas / p_noll; + + // Apply correction factor to pressure table + for (i = 0; i <= 16; i++) + { + p[i] = p0[i] * p_fact; + } +} + +// ************************************************************************************************* +// @fn conv_pa_to_meter +// @brief Convert pressure (Pa) to altitude (m) using a conversion table +// Implemented straight from VTI reference code. +// @param u32 p_meas Pressure (Pa) +// u16 t_meas Temperature (10*K) +// @return s16 Altitude (m) +// ************************************************************************************************* +s16 conv_pa_to_meter(u32 p_meas, u16 t_meas) +{ + const float coef2 = 0.0007; + const float Invt00 = 0.003470415; + volatile float hnoll; + volatile float t0; + volatile float p_low; + volatile float fl_h; + volatile s16 h; + u8 i; + + // Typecast arguments + volatile float fl_p_meas = (float)p_meas / 100; // Convert from Pa to hPa + volatile float fl_t_meas = (float)t_meas / 10; // Convert from 10 K to 1 K + + for (i = 0; i <= 16; i++) + { + if (p[i] < fl_p_meas) + break; + p_low = p[i]; + } + + if (i == 0) + { + hnoll = (float)(fl_p_meas - p[0]) / (p[1] - p[0]) * ((float)(h0[1] - h0[0])); + } + else if (i < 15) + { + hnoll = + (float)(fl_p_meas - + p_low) * + (1 - + (fl_p_meas - + p[i]) * coef2) / (p[i] - p_low) * ((float)(h0[i] - h0[i - 1])) + h0[i - 1]; + } + else if (i == 15) + { + hnoll = + (float)(fl_p_meas - p_low) / (p[i] - p_low) * ((float)(h0[i] - h0[i - 1])) + h0[i - 1]; + } + else // i==16 + { + hnoll = (float)(fl_p_meas - p[16]) / (p[16] - p[15]) * ((float)(h0[16] - h0[15])) + h0[16]; + } + + // Compensate temperature error + t0 = fl_t_meas / (1 - hnoll * Invt00 * 0.0065); + fl_h = Invt00 * t0 * hnoll; + h = (u16) fl_h; + + return (h); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_ps.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_ps.h new file mode 100755 index 0000000..e044695 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/driver/vti_ps.h @@ -0,0 +1,99 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef VTI_PS_H_ +#define VTI_PS_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void ps_init(void); +extern void ps_start(void); +extern void ps_stop(void); +extern u32 ps_get_pa(void); +extern u16 ps_get_temp(void); +extern void init_pressure_table(void); +extern void update_pressure_table(s16 href, u32 p_meas, u16 t_meas); +extern s16 conv_pa_to_meter(u32 p_meas, u16 t_meas); + +// ************************************************************************************************* +// Defines section + +// Port and pin resource for TWI interface to pressure sensor +// SCL=PJ.3, SDA=PJ.2, DRDY=P2.6 +#define PS_TWI_IN (PJIN) +#define PS_TWI_OUT (PJOUT) +#define PS_TWI_DIR (PJDIR) +#define PS_TWI_REN (PJREN) +#define PS_SCL_PIN (BIT3) +#define PS_SDA_PIN (BIT2) + +// Port, pin and interrupt resource for interrupt from acceleration sensor, DRDY=P2.6 +#define PS_INT_IN (P2IN) +#define PS_INT_OUT (P2OUT) +#define PS_INT_DIR (P2DIR) +#define PS_INT_IE (P2IE) +#define PS_INT_IES (P2IES) +#define PS_INT_IFG (P2IFG) +#define PS_INT_PIN (BIT6) + +// TWI defines +#define PS_TWI_WRITE (0u) +#define PS_TWI_READ (1u) + +#define PS_TWI_SEND_START (0u) +#define PS_TWI_SEND_RESTART (1u) +#define PS_TWI_SEND_STOP (2u) +#define PS_TWI_CHECK_ACK (3u) + +#define PS_TWI_8BIT_ACCESS (0u) +#define PS_TWI_16BIT_ACCESS (1u) + +#define PS_TWI_SCL_HI { PS_TWI_OUT |= PS_SCL_PIN; } +#define PS_TWI_SCL_LO { PS_TWI_OUT &= ~PS_SCL_PIN; } +#define PS_TWI_SDA_HI { PS_TWI_OUT |= PS_SDA_PIN; } +#define PS_TWI_SDA_LO { PS_TWI_OUT &= ~PS_SDA_PIN; } +#define PS_TWI_SDA_IN { PS_TWI_OUT |= PS_SDA_PIN; PS_TWI_DIR &= ~PS_SDA_PIN; } +#define PS_TWI_SDA_OUT { PS_TWI_DIR |= PS_SDA_PIN; } + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +#endif /*VTI_PS_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/ez430_chronos.ewd b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/ez430_chronos.ewd new file mode 100755 index 0000000..7fdec66 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/ez430_chronos.ewd @@ -0,0 +1,2107 @@ + + + + 2 + + 915MHz - Limited IAR Kickstart (USA) + + MSP430 + + 1 + + C-SPY + 4 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 868MHz - Limited IAR Kickstart (Europe) + + MSP430 + + 1 + + C-SPY + 4 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 433MHz - Limited IAR Kickstart (Other regions) + + MSP430 + + 1 + + C-SPY + 4 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 915MHz - Unrestricted IAR Workbench (USA) + + MSP430 + + 1 + + C-SPY + 4 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 868MHz - Unrestricted IAR Workbench (Europe) + + MSP430 + + 1 + + C-SPY + 4 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 433MHz - Unrestricted IAR Workbench (Other regions) + + MSP430 + + 1 + + C-SPY + 4 + + 25 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/ez430_chronos.ewp b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/ez430_chronos.ewp new file mode 100755 index 0000000..6e63043 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/ez430_chronos.ewp @@ -0,0 +1,6028 @@ + + + + 2 + + 915MHz - Limited IAR Kickstart (USA) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 868MHz - Limited IAR Kickstart (Europe) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 433MHz - Limited IAR Kickstart (Other regions) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 915MHz - Unrestricted IAR Workbench (USA) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 868MHz - Unrestricted IAR Workbench (Europe) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 433MHz - Unrestricted IAR Workbench (Other regions) + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + bluerobin + + $PROJ_DIR$\bluerobin\BlueRobin_RX_433MHz.r43 + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + + + + $PROJ_DIR$\bluerobin\BlueRobin_RX_868MHz.r43 + + 915MHz - Limited IAR Kickstart (USA) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\bluerobin\BlueRobin_RX_915MHz.r43 + + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\bluerobin\BlueRobin_RX_API.h + + + $PROJ_DIR$\bluerobin\bm.h + + + + driver + + $PROJ_DIR$\driver\adc12.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\adc12.h + + + $PROJ_DIR$\driver\buzzer.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\buzzer.h + + + $PROJ_DIR$\driver\display.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\display.h + + + $PROJ_DIR$\driver\ez430_chronos_drivers.r43 + + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\driver\pmm.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\pmm.h + + + $PROJ_DIR$\driver\ports.c + + + $PROJ_DIR$\driver\ports.h + + + $PROJ_DIR$\driver\radio.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\radio.h + + + $PROJ_DIR$\driver\rf1a.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\rf1a.h + + + $PROJ_DIR$\driver\timer.c + + + $PROJ_DIR$\driver\timer.h + + + $PROJ_DIR$\driver\vti_as.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\vti_as.h + + + $PROJ_DIR$\driver\vti_ps.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\driver\vti_ps.h + + + + include + + $PROJ_DIR$\include\project.h + + + + logic + + $PROJ_DIR$\logic\acceleration.c + + + $PROJ_DIR$\logic\acceleration.h + + + $PROJ_DIR$\logic\alarm.c + + + $PROJ_DIR$\logic\alarm.h + + + $PROJ_DIR$\logic\altitude.c + + + $PROJ_DIR$\logic\altitude.h + + + $PROJ_DIR$\logic\battery.c + + + $PROJ_DIR$\logic\battery.h + + + $PROJ_DIR$\logic\bluerobin.c + + + $PROJ_DIR$\logic\bluerobin.h + + + $PROJ_DIR$\logic\clock.c + + + $PROJ_DIR$\logic\clock.h + + + $PROJ_DIR$\logic\date.c + + + $PROJ_DIR$\logic\date.h + + + $PROJ_DIR$\logic\menu.c + + + $PROJ_DIR$\logic\menu.h + + + $PROJ_DIR$\logic\rfbsl.c + + + $PROJ_DIR$\logic\rfbsl.h + + + $PROJ_DIR$\logic\rfsimpliciti.c + + + $PROJ_DIR$\logic\rfsimpliciti.h + + + $PROJ_DIR$\logic\stopwatch.c + + + $PROJ_DIR$\logic\stopwatch.h + + + $PROJ_DIR$\logic\temperature.c + + + $PROJ_DIR$\logic\temperature.h + + + $PROJ_DIR$\logic\test.c + + + $PROJ_DIR$\logic\test.h + + + $PROJ_DIR$\logic\user.c + + + $PROJ_DIR$\logic\user.h + + + + simpliciti + + Applications + + application + + End Device + + $PROJ_DIR$\simpliciti\Applications\application\End Device\main_ED_BM.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + + + configuration + + End Device + + $PROJ_DIR$\simpliciti\Applications\configuration\End Device\smpl_config.dat + + + + $PROJ_DIR$\simpliciti\Applications\configuration\smpl_nwk_config.dat + + + + + Components + + bsp + + boards + + CC430EM + + bsp_external + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_external\mrfi_board_defs.h + + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_board.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_board_defs.h + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_button_defs.h + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_config.h + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_driver_defs.h + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_drivers.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\CC430EM\bsp_led_defs.h + + + + + drivers + + code + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_buttons.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_generic_buttons.h + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_generic_leds.h + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_leds.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\bsp_buttons.h + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\bsp_leds.h + + + + mcus + + $PROJ_DIR$\simpliciti\Components\bsp\mcus\bsp_msp430_defs.h + + + + $PROJ_DIR$\simpliciti\Components\bsp\bsp.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\bsp.h + + + $PROJ_DIR$\simpliciti\Components\bsp\bsp_macros.h + + + + mrfi + + radios + + family5 + + $PROJ_DIR$\simpliciti\Components\mrfi\radios\family5\mrfi_radio.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\mrfi\radios\family5\mrfi_radio_interface.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\mrfi\radios\family5\mrfi_radio_interface.h + + + + + smartrf + + CC1101 + + $PROJ_DIR$\simpliciti\Components\mrfi\smartrf\CC1101\smartrf_CC1101.h + + + + + $PROJ_DIR$\simpliciti\Components\mrfi\mrfi.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\mrfi\mrfi.h + + + $PROJ_DIR$\simpliciti\Components\mrfi\mrfi_defs.h + + + + nwk + + $PROJ_DIR$\simpliciti\Components\nwk\nwk.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_api.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_api.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_app.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_frame.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_frame.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_globals.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_globals.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_QMgmt.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_QMgmt.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_types.h + + + + nwk_applications + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_freq.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_freq.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ioctl.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ioctl.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_join.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_join.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_link.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_link.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_mgmt.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_mgmt.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ping.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ping.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_security.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_security.h + + + + + $PROJ_DIR$\simpliciti\CC430_End_Device_433MHz.r43 + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\CC430_End_Device_868MHz.r43 + + 915MHz - Limited IAR Kickstart (USA) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\CC430_End_Device_915MHz.r43 + + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\simpliciti.h + + + $PROJ_DIR$\simpliciti\simpliciti_readme.txt + + + + $PROJ_DIR$\change_record.txt + + + $PROJ_DIR$\main.c + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/ez430_chronos.eww b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/ez430_chronos.eww new file mode 100755 index 0000000..307ee06 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/ez430_chronos.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\ez430_chronos.ewp + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/include/project.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/include/project.h new file mode 100755 index 0000000..73eb8a0 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/include/project.h @@ -0,0 +1,129 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef PROJECT_H_ +#define PROJECT_H_ + +// ************************************************************************************************* +// Include section +#include +#include + +// ************************************************************************************************* +// Defines section + +// Comment this to not use the LCD charge pump +//#define USE_LCD_CHARGE_PUMP + +// Comment this define to build the application without watchdog support +#define USE_WATCHDOG + +// Use/not use filter when measuring physical values +#define FILTER_OFF (0u) +#define FILTER_ON (1u) + +// ************************************************************************************************* +// Macro section + +// Conversion from usec to ACLK timer ticks +#define CONV_US_TO_TICKS(usec) (((usec) * 32768) / 1000000) + +// Conversion from msec to ACLK timer ticks +#define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000) + +// ************************************************************************************************* +// Typedef section + +typedef enum +{ + MENU_ITEM_NOT_VISIBLE = 0, // Menu item is not visible + MENU_ITEM_VISIBLE // Menu item is visible +} menu_t; + +// Set of system flags +typedef union +{ + struct + { + u16 idle_timeout:1; // Timeout after inactivity + u16 idle_timeout_enabled:1; // When in set mode, timeout after a given period + u16 lock_buttons:1; // Lock buttons + u16 mask_buzzer:1; // Do not output buzz for next button event + u16 up_down_repeat_enabled:1; // While in set_value(), create virtual UP/DOWN button events + u16 low_battery:1; // 1 = Battery is low + u16 use_metric_units:1; // 1 = Use metric units, 0 = use English units + u16 delay_over:1; // 1 = Timer delay over + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_system_flags; +extern volatile s_system_flags sys; + +// Set of request flags +typedef union +{ + struct + { + u16 temperature_measurement:1; // 1 = Measure temperature + u16 voltage_measurement:1; // 1 = Measure voltage + u16 altitude_measurement:1; // 1 = Measure air pressure + u16 acceleration_measurement:1; // 1 = Measure acceleration + u16 buzzer:1; // 1 = Output buzzer + } flag; + u16 all_flags; // Shortcut to all display flags (for reset) +} s_request_flags; +extern volatile s_request_flags request; + +// Set of message flags +typedef union +{ + struct + { + u16 prepare:1; // 1 = Wait for clock tick, then set display.flag.show_message flag + u16 show:1; // 1 = Display message now + u16 erase:1; // 1 = Erase message + u16 type_locked:1; // 1 = Show "buttons are locked" in Line2 + u16 type_unlocked:1; // 1 = Show "buttons are unlocked" in Line2 + u16 type_lobatt:1; // 1 = Show "lobatt" text in Line2 + u16 type_alarm_on:1; // 1 = Show " on" text in Line1 + u16 type_alarm_off:1; // 1 = Show " off" text in Line1 + } flag; + u16 all_flags; // Shortcut to all message flags (for reset) +} s_message_flags; +extern volatile s_message_flags message; + +// ************************************************************************************************* +// Global Variable section + +#endif /*PROJECT_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/acceleration.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/acceleration.c new file mode 100755 index 0000000..41db976 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/acceleration.c @@ -0,0 +1,270 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Temperature measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "vti_as.h" + +// logic +#include "acceleration.h" +#include "simpliciti.h" +#include "user.h" + +// ************************************************************************************************* +// Global Variable section +struct accel sAccel; + +// Conversion values from data to mgrav taken from CMA3000-D0x datasheet (rev 0.4, table 4) +const u16 mgrav_per_bit[7] = { 18, 36, 71, 143, 286, 571, 1142 }; + +// ************************************************************************************************* +// Extern section + +// Global flag for proper acceleration sensor operation +extern u8 as_ok; + +// ************************************************************************************************* +// @fn reset_acceleration +// @brief Reset acceleration variables. +// @param none +// @return none +// ************************************************************************************************* +void reset_acceleration(void) +{ + // Start with Y-axis display + sAccel.view_style = DISPLAY_ACCEL_Y; + + // Clear timeout counter + sAccel.timeout = 0; + + // Default mode is off + sAccel.mode = ACCEL_MODE_OFF; +} + +// ************************************************************************************************* +// @fn sx_acceleration +// @brief Acceleration direct function. Button UP switches between X/Y/Z values. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_acceleration(u8 line) +{ + if (++sAccel.view_style > 2) + sAccel.view_style = 0; + + // Reset current acceleration value + sAccel.data = 0; + + // Get data from sensor + as_get_data(sAccel.xyz); +} + +// ************************************************************************************************* +// @fn acceleration_value_is_positive +// @brief Returns 1 if 2's complement number is positive +// @param u8 value 2's complement number +// @return u8 1 = number is positive, 0 = number is negavtive +// ************************************************************************************************* +u8 acceleration_value_is_positive(u8 value) +{ + return ((value & BIT7) == 0); +} + +// ************************************************************************************************* +// @fn convert_acceleration_value_to_mgrav +// @brief Converts measured value to mgrav units +// @param u8 value g data from sensor +// @return u16 Acceleration (mgrav) +// ************************************************************************************************* +u16 convert_acceleration_value_to_mgrav(u8 value) +{ + u16 result; + u8 i; + + if (!acceleration_value_is_positive(value)) + { + // Convert 2's complement negative number to positive number + value = ~value; + value += 1; + } + + result = 0; + for (i = 0; i < 7; i++) + { + result += ((value & (BIT(i))) >> i) * mgrav_per_bit[i]; + } + + return (result); +} + +// ************************************************************************************************* +// @fn is_acceleration_measurement +// @brief Returns 1 if acceleration is currently measured. +// @param none +// @return u8 1 = acceleration measurement ongoing +// ************************************************************************************************* +u8 is_acceleration_measurement(void) +{ + return ((sAccel.mode == ACCEL_MODE_ON) && (sAccel.timeout > 0)); +} + +// ************************************************************************************************* +// @fn do_acceleration_measurement +// @brief Get sensor data and store in sAccel struct +// @param none +// @return none +// ************************************************************************************************* +void do_acceleration_measurement(void) +{ + // Get data from sensor + as_get_data(sAccel.xyz); + + // Set display update flag + display.flag.update_acceleration = 1; +} + +// ************************************************************************************************* +// @fn display_acceleration +// @brief Display routine. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_acceleration(u8 line, u8 update) +{ + u8 *str; + u8 raw_data; + u16 accel_data; + + // Show warning if acceleration sensor was not initialised properly + if (!as_ok) + { + display_chars(LCD_SEG_L1_2_0, (u8 *) "ERR", SEG_ON); + } + else + { + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + { + // Start acceleration sensor + if (!is_acceleration_measurement()) + { + // Clear previous acceleration value + sAccel.data = 0; + + // Start sensor + as_start(); + + // Set timeout counter + sAccel.timeout = ACCEL_MEASUREMENT_TIMEOUT; + + // Set mode + sAccel.mode = ACCEL_MODE_ON; + + // Start with Y-axis values + sAccel.view_style = DISPLAY_ACCEL_Y; + } + + // Display decimal point + display_symbol(LCD_SEG_L1_DP1, SEG_ON); + } + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + // Convert X/Y/Z values to mg + switch (sAccel.view_style) + { + case DISPLAY_ACCEL_X: + raw_data = sAccel.xyz[0]; + display_char(LCD_SEG_L1_3, 'X', SEG_ON); + break; + case DISPLAY_ACCEL_Y: + raw_data = sAccel.xyz[1]; + display_char(LCD_SEG_L1_3, 'Y', SEG_ON); + break; + default: + raw_data = sAccel.xyz[2]; + display_char(LCD_SEG_L1_3, 'Z', SEG_ON); + break; + } + accel_data = convert_acceleration_value_to_mgrav(raw_data) / 10; + + // Filter acceleration + accel_data = (u16) ((accel_data * 0.2) + (sAccel.data * 0.8)); + + // Store average acceleration + sAccel.data = accel_data; + + // Display acceleration in x.xx format + str = int_to_array(accel_data, 3, 0); + display_chars(LCD_SEG_L1_2_0, str, SEG_ON); + + // Display sign + if (acceleration_value_is_positive(raw_data)) + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + else + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Stop acceleration sensor + as_stop(); + + // Clear mode + sAccel.mode = ACCEL_MODE_OFF; + + // Clean up display + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/acceleration.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/acceleration.h new file mode 100755 index 0000000..14f3d43 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/acceleration.h @@ -0,0 +1,77 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ACCELERATION_H_ +#define ACCELERATION_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section +#define DISPLAY_ACCEL_X (0u) +#define DISPLAY_ACCEL_Y (1u) +#define DISPLAY_ACCEL_Z (2u) + +#define ACCEL_MODE_OFF (0u) +#define ACCEL_MODE_ON (1u) + +// Stop acceleration measurement after 60 minutes to save battery +#define ACCEL_MEASUREMENT_TIMEOUT (60 * 60u) + +// ************************************************************************************************* +// Global Variable section +struct accel +{ + u8 mode; // ACC_MODE_OFF, ACC_MODE_ON + u8 xyz[3]; // Sensor raw data + u16 data; // Acceleration data in 10 * mgrav + u8 view_style; // Display X/Y/Z values + u16 timeout; // Timeout +}; +extern struct accel sAccel; + +// ************************************************************************************************* +// Extern section +extern void reset_acceleration(void); +extern void sx_acceleration(u8 line); +extern void display_acceleration(u8 line, u8 update); +extern u8 is_acceleration_measurement(void); +extern void do_acceleration_measurement(void); + +#endif /*ACCELERATION_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/alarm.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/alarm.c new file mode 100755 index 0000000..0bfdc94 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/alarm.c @@ -0,0 +1,280 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Alarm routines. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "buzzer.h" +#include "ports.h" + +// logic +#include "alarm.h" +#include "clock.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct alarm sAlarm; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_alarm +// @brief Resets alarmData to 06:30 +// @param none +// @return none +// ************************************************************************************************* +void reset_alarm(void) +{ + // Default alarm time 06:30 + sAlarm.hour = 06; + sAlarm.minute = 30; + + // Alarm is initially off + sAlarm.duration = ALARM_ON_DURATION; + sAlarm.state = ALARM_DISABLED; +} + +// ************************************************************************************************* +// @fn check_alarm +// @brief Check if current time matches alarm time +// @param none +// @return none +// ************************************************************************************************* +void check_alarm(void) +{ + // Return if alarm is not enabled + if (sAlarm.state != ALARM_ENABLED) + return; + + // Compare current time and alarm time + // Start with minutes - only 1/60 probability to match + if (sTime.minute == sAlarm.minute) + { + if (sTime.hour == sAlarm.hour) + { + // Indicate that alarm is on + sAlarm.state = ALARM_ON; + } + } +} + +// ************************************************************************************************* +// @fn stop_alarm +// @brief Stop active alarm +// @param none +// @return none +// ************************************************************************************************* +void stop_alarm(void) +{ + // Indicate that alarm is enabled, but not active + sAlarm.state = ALARM_ENABLED; + + // Stop buzzer + stop_buzzer(); +} + +// ************************************************************************************************* +// @fn sx_alarm +// @brief Sx button turns alarm on/off. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void sx_alarm(u8 line) +{ + // UP: Alarm on, off + if (button.flag.up) + { + // Toggle alarm state + if (sAlarm.state == ALARM_DISABLED) + { + sAlarm.state = ALARM_ENABLED; + + // Show " on" message + message.flag.prepare = 1; + message.flag.type_alarm_on = 1; + } + else if (sAlarm.state == ALARM_ENABLED) + { + sAlarm.state = ALARM_DISABLED; + + // Show " off" message + message.flag.prepare = 1; + message.flag.type_alarm_off = 1; + } + } +} + +// ************************************************************************************************* +// @fn mx_alarm +// @brief Set alarm time. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void mx_alarm(u8 line) +{ + u8 select; + s32 hours; + s32 minutes; + u8 *str; + + // Clear display + clear_display_all(); + + // Keep global values in case new values are discarded + hours = sAlarm.hour; + minutes = sAlarm.minute; + + // Display HH:MM (LINE1) + str = int_to_array(hours, 2, 0); + display_chars(LCD_SEG_L1_3_2, str, SEG_ON); + display_symbol(LCD_SEG_L1_COL, SEG_ON); + + str = int_to_array(minutes, 2, 0); + display_chars(LCD_SEG_L1_1_0, str, SEG_ON); + + // Init value index + select = 0; + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout: exit without saving + if (sys.flag.idle_timeout) + break; + + // STAR (short): save, then exit + if (button.flag.star) + { + // Store local variables in global alarm time + sAlarm.hour = hours; + sAlarm.minute = minutes; + // Set display update flag + display.flag.line1_full_update = 1; + break; + } + + switch (select) + { + case 0: // Set hour + set_value(&hours, 2, 0, 0, 23, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, + display_hours); + select = 1; + break; + + case 1: // Set minutes + set_value(&minutes, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, + display_value); + select = 0; + break; + } + } + + // Clear button flag + button.all_flags = 0; + + // Indicate to display function that new value is available + display.flag.update_alarm = 1; +} + +// ************************************************************************************************* +// @fn display_alarm +// @brief Display alarm time. 24H / 12H time format. +// @param u8 line LINE1, LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_alarm(u8 line, u8 update) +{ + u8 hour12; + + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sys.flag.use_metric_units) + { + // Display 24H alarm time "HH:MM" + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(sAlarm.hour, 2, 0), SEG_ON); + } + else + { + // Display 12H alarm time "HH:MM" + AM/PM + hour12 = convert_hour_to_12H_format(sAlarm.hour); + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(hour12, 2, 0), SEG_ON); + + // Display AM/PM symbol + display_am_pm_symbol(sAlarm.hour); + } + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sAlarm.minute, 2, 0), SEG_ON); + display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_ON); + + // Show blinking alarm icon + display_symbol(LCD_ICON_ALARM, SEG_ON_BLINK_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Clean up function-specific segments before leaving function + display_symbol(LCD_SYMB_AM, SEG_OFF); + + // Clear / set alarm icon + if (sAlarm.state == ALARM_DISABLED) + { + display_symbol(LCD_ICON_ALARM, SEG_OFF_BLINK_OFF); + } + else + { + display_symbol(LCD_ICON_ALARM, SEG_ON_BLINK_OFF); + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/alarm.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/alarm.h new file mode 100755 index 0000000..87b036b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/alarm.h @@ -0,0 +1,75 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// internal functions +extern void reset_alarm(void); +extern void check_alarm(void); +extern void stop_alarm(void); + +// menu functions +extern void sx_alarm(u8 line); +extern void mx_alarm(u8 line); +extern void display_alarm(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// Alarm states +#define ALARM_DISABLED (0u) +#define ALARM_ENABLED (1u) +#define ALARM_ON (2u) + +// Keep alarm for 10 on-off cycles +#define ALARM_ON_DURATION (10u) + +// ************************************************************************************************* +// Global Variable section +struct alarm +{ + u8 state; // ALARM_DISABLED, ALARM_ENABLED, ALARM_ON + u8 duration; // Alarm duration + u8 hour; // Alarm hour + u8 minute; // Alarm minute +}; +extern struct alarm sAlarm; + +// ************************************************************************************************* +// Extern section diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/altitude.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/altitude.c new file mode 100755 index 0000000..8837ea5 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/altitude.c @@ -0,0 +1,420 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Altitude measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "altitude.h" +#include "display.h" +#include "vti_ps.h" +#include "ports.h" +#include "timer.h" + +// logic +#include "user.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct alt sAlt; + +// ************************************************************************************************* +// Extern section + +// Global flag for pressure sensor initialisation status +extern u8 ps_ok; + +// ************************************************************************************************* +// @fn reset_altitude_measurement +// @brief Reset altitude measurement. +// @param none +// @return none +// ************************************************************************************************* +void reset_altitude_measurement(void) +{ + // Menu item is not visible + sAlt.state = MENU_ITEM_NOT_VISIBLE; + + // Clear timeout counter + sAlt.timeout = 0; + + // Set default altitude value + sAlt.altitude = 0; + + // Pressure sensor ok? + if (ps_ok) + { + // Initialise pressure table + init_pressure_table(); + + // Do single conversion + start_altitude_measurement(); + stop_altitude_measurement(); + + // Apply calibration offset and recalculate pressure table + if (sAlt.altitude_offset != 0) + { + sAlt.altitude += sAlt.altitude_offset; + update_pressure_table(sAlt.altitude, sAlt.pressure, sAlt.temperature); + } + } +} + +// ************************************************************************************************* +// @fn conv_m_to_ft +// @brief Convert meters to feet +// @param u16 m Meters +// @return u16 Feet +// ************************************************************************************************* +s16 convert_m_to_ft(s16 m) +{ + return (((s32) 328 * m) / 100); +} + +// ************************************************************************************************* +// @fn conv_ft_to_m +// @brief Convert feet to meters +// @param u16 ft Feet +// @return u16 Meters +// ************************************************************************************************* +s16 convert_ft_to_m(s16 ft) +{ + return (((s32) ft * 61) / 200); +} + +// ************************************************************************************************* +// @fn is_altitude_measurement +// @brief Altitude measurement check +// @param none +// @return u8 1=Measurement ongoing, 0=measurement off +// ************************************************************************************************* +u8 is_altitude_measurement(void) +{ + return ((sAlt.state == MENU_ITEM_VISIBLE) && (sAlt.timeout > 0)); +} + +// ************************************************************************************************* +// @fn start_altitude_measurement +// @brief Start altitude measurement +// @param none +// @return none +// ************************************************************************************************* +void start_altitude_measurement(void) +{ + // Show warning if pressure sensor was not initialised properly + if (!ps_ok) + { + display_chars(LCD_SEG_L1_2_0, (u8 *) "ERR", SEG_ON); + return; + } + + // Start altitude measurement if timeout has elapsed + if (sAlt.timeout == 0) + { + // Enable DRDY IRQ on rising edge + PS_INT_IFG &= ~PS_INT_PIN; + PS_INT_IE |= PS_INT_PIN; + + // Start pressure sensor + ps_start(); + + // Set timeout counter only if sensor status was OK + sAlt.timeout = ALTITUDE_MEASUREMENT_TIMEOUT; + + // Get updated altitude + while ((PS_INT_IN & PS_INT_PIN) == 0) ; + do_altitude_measurement(FILTER_OFF); + } +} + +// ************************************************************************************************* +// @fn stop_altitude_measurement +// @brief Stop altitude measurement +// @param none +// @return none +// ************************************************************************************************* +void stop_altitude_measurement(void) +{ + // Return if pressure sensor was not initialised properly + if (!ps_ok) + return; + + // Stop pressure sensor + ps_stop(); + + // Disable DRDY IRQ + PS_INT_IE &= ~PS_INT_PIN; + PS_INT_IFG &= ~PS_INT_PIN; + + // Clear timeout counter + sAlt.timeout = 0; +} + +// ************************************************************************************************* +// @fn do_altitude_measurement +// @brief Perform single altitude measurement +// @param u8 filter Filter option +// @return none +// ************************************************************************************************* +void do_altitude_measurement(u8 filter) +{ + volatile u32 pressure; + + // If sensor is not ready, skip data read + if ((PS_INT_IN & PS_INT_PIN) == 0) + return; + + // Get temperature (format is *10 K) from sensor + sAlt.temperature = ps_get_temp(); + + // Get pressure (format is 1Pa) from sensor + pressure = ps_get_pa(); + + // Store measured pressure value + if (filter == FILTER_OFF) //sAlt.pressure == 0) + { + sAlt.pressure = pressure; + } + else + { + // Filter current pressure + pressure = (u32) ((pressure * 0.2) + (sAlt.pressure * 0.8)); + + // Store average pressure + sAlt.pressure = pressure; + } + + // Convert pressure (Pa) and temperature (K) to altitude (m) + sAlt.altitude = conv_pa_to_meter(sAlt.pressure, sAlt.temperature); +} + +// ************************************************************************************************* +// @fn sx_altitude +// @brief Altitude direct function. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void sx_altitude(u8 line) +{ + // Function can be empty + // Restarting of altitude measurement will be done by subsequent full display update +} + +// ************************************************************************************************* +// @fn mx_altitude +// @brief Mx button handler to set the altitude offset. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void mx_altitude(u8 line) +{ + s32 altitude; + s32 limit_high, limit_low; + + // Clear display + clear_display_all(); + + // Set lower and upper limits for offset correction + if (sys.flag.use_metric_units) + { + // Display "m" symbol + display_symbol(LCD_UNIT_L1_M, SEG_ON); + + // Convert global variable to local variable + altitude = sAlt.altitude; + + // Limits for set_value function + limit_low = -100; + limit_high = 4000; + } + else // English units + { + // Display "ft" symbol + display_symbol(LCD_UNIT_L1_FT, SEG_ON); + + // Convert altitude in meters to feet + altitude = sAlt.altitude; + + // Convert from meters to feet + altitude = convert_m_to_ft(altitude); + + // Limits for set_value function + limit_low = -500; + limit_high = 9999; + } + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout: exit without saving + if (sys.flag.idle_timeout) + break; + + // Button STAR (short): save, then exit + if (button.flag.star) + { + // When using English units, convert ft back to m before updating pressure table + if (!sys.flag.use_metric_units) + altitude = convert_ft_to_m((s16) altitude); + + // Update pressure table + update_pressure_table((s16) altitude, sAlt.pressure, sAlt.temperature); + + // Set display update flag + display.flag.line1_full_update = 1; + + break; + } + + // Set current altitude - offset is set when leaving function + set_value(&altitude, 4, 3, limit_low, limit_high, SETVALUE_DISPLAY_VALUE + + SETVALUE_FAST_MODE + SETVALUE_DISPLAY_ARROWS, LCD_SEG_L1_3_0, + display_value); + } + + // Clear button flags + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn display_altitude +// @brief Display routine. Supports display in meters and feet. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_altitude(u8 line, u8 update) +{ + u8 *str; + s16 ft; + + // redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Enable pressure measurement + sAlt.state = MENU_ITEM_VISIBLE; + + // Start measurement + start_altitude_measurement(); + + if (sys.flag.use_metric_units) + { + // Display "m" symbol + display_symbol(LCD_UNIT_L1_M, SEG_ON); + } + else + { + // Display "ft" symbol + display_symbol(LCD_UNIT_L1_FT, SEG_ON); + } + + // Display altitude + display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + // Update display only while measurement is active + if (sAlt.timeout > 0) + { + if (sys.flag.use_metric_units) + { + // Display altitude in xxxx m format, allow 3 leading blank digits + if (sAlt.altitude >= 0) + { + str = int_to_array(sAlt.altitude, 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + else + { + str = int_to_array(sAlt.altitude * (-1), 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + } + else + { + // Convert from meters to feet + ft = convert_m_to_ft(sAlt.altitude); + + // Limit to 9999ft (3047m) + if (ft > 9999) + ft = 9999; + + // Display altitude in xxxx ft format, allow 3 leading blank digits + if (ft >= 0) + { + str = int_to_array(ft, 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + else + { + str = int_to_array(ft * (-1), 4, 3); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + } + display_chars(LCD_SEG_L1_3_0, str, SEG_ON); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Disable pressure measurement + sAlt.state = MENU_ITEM_NOT_VISIBLE; + + // Stop measurement + stop_altitude_measurement(); + + // Clean up function-specific segments before leaving function + display_symbol(LCD_UNIT_L1_M, SEG_OFF); + display_symbol(LCD_UNIT_L1_FT, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/altitude.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/altitude.h new file mode 100755 index 0000000..5778d44 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/altitude.h @@ -0,0 +1,76 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef ALTITUDE_H_ +#define ALTITUDE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_altitude_measurement(void); +extern u8 is_altitude_measurement(void); +extern void start_altitude_measurement(void); +extern void stop_altitude_measurement(void); +extern void do_altitude_measurement(u8 filter); + +// menu functions +extern void sx_altitude(u8 line); +extern void mx_altitude(u8 line); +extern void display_altitude(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section +#define ALTITUDE_MEASUREMENT_TIMEOUT (60 * 60u) // Stop altitude measurement after 60 minutes to + // save battery + +// ************************************************************************************************* +// Global Variable section +struct alt +{ + menu_t state; // MENU_ITEM_NOT_VISIBLE, MENU_ITEM_VISIBLE + u32 pressure; // Pressure (Pa) + u16 temperature; // Temperature (K) + s16 altitude; // Altitude (m) + s16 altitude_offset; // Altitude offset stored during calibration + u16 timeout; // Timeout +}; +extern struct alt sAlt; + +// ************************************************************************************************* +// Extern section + +#endif /*ALTITUDE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/battery.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/battery.c new file mode 100755 index 0000000..78e0dcd --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/battery.c @@ -0,0 +1,184 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Battery voltage measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" +#include "adc12.h" + +// logic +#include "menu.h" +#include "battery.h" + +// ************************************************************************************************* +// Prototypes section +void reset_batt_measurement(void); +void battery_measurement(void); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct batt sBatt; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn reset_temp_measurement +// @brief Reset temperature measurement module. +// @param none +// @return none +// ************************************************************************************************* +void reset_batt_measurement(void) +{ + // Set flag to off + sBatt.state = MENU_ITEM_NOT_VISIBLE; + + // Reset lobatt display counter + sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE; + + // Start with battery voltage of 3.00V + sBatt.voltage = 300; +} + +// ************************************************************************************************* +// @fn battery_measurement +// @brief Init ADC12. Do single conversion of AVCC voltage. Turn off ADC12. +// @param none +// @return none +// ************************************************************************************************* +void battery_measurement(void) +{ + u16 voltage; + + // Convert external battery voltage (ADC12INCH_11=AVCC-AVSS/2) + voltage = adc12_single_conversion(REFVSEL_1, ADC12SHT0_10, ADC12INCH_11); + + // Convert ADC value to "x.xx V" + // Ideally we have A11=0->AVCC=0V ... A11=4095(2^12-1)->AVCC=4V + // --> (A11/4095)*4V=AVCC --> AVCC=(A11*4)/4095 + voltage = (voltage * 2 * 2) / 41; + + // Correct measured voltage with calibration value + voltage += sBatt.offset; + + // Discard values that are clearly outside the measurement range + if (voltage > BATTERY_HIGH_THRESHOLD) + { + voltage = sBatt.voltage; + } + + // Filter battery voltage + sBatt.voltage = ((voltage * 2) + (sBatt.voltage * 8)) / 10; + + // If battery voltage falls below low battery threshold, set system flag and modify LINE2 + // display function pointer + if (sBatt.voltage < BATTERY_LOW_THRESHOLD) + { + sys.flag.low_battery = 1; + + // Set sticky battery icon + display_symbol(LCD_SYMB_BATTERY, SEG_ON); + } + else + { + sys.flag.low_battery = 0; + + // Clear sticky battery icon + display_symbol(LCD_SYMB_BATTERY, SEG_OFF); + } + // Update LINE2 + display.flag.line2_full_update = 1; + + // Indicate to display function that new value is available + display.flag.update_battery_voltage = 1; +} + +// ************************************************************************************************* +// @fn display_battery_V +// @brief Display routine for battery voltage. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_battery_V(u8 line, u8 update) +{ + u8 *str; + + // Redraw line + if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Set battery and V icon + display_symbol(LCD_SYMB_BATTERY, SEG_ON); + + // Menu item is visible + sBatt.state = MENU_ITEM_VISIBLE; + + // Display result in xx.x format + str = int_to_array(sBatt.voltage, 3, 0); + + display_chars(LCD_SEG_L2_2_0, str, SEG_ON); + display_symbol(LCD_SEG_L2_DP, SEG_ON); + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + // Display result in xx.x format + str = int_to_array(sBatt.voltage, 3, 0); + + display_chars(LCD_SEG_L2_2_0, str, SEG_ON); + + display.flag.update_battery_voltage = 0; + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Menu item is not visible + sBatt.state = MENU_ITEM_NOT_VISIBLE; + + // Clear function-specific symbols + display_symbol(LCD_SYMB_BATTERY, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/battery.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/battery.h new file mode 100755 index 0000000..baf7608 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/battery.h @@ -0,0 +1,78 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BATTERY_H_ +#define BATTERY_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// Internal functions +extern void reset_batt_measurement(void); +extern void battery_measurement(void); + +// Menu functions +extern void display_battery_V(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// Battery high voltage threshold +#define BATTERY_HIGH_THRESHOLD (360u) + +// Battery end of life voltage threshold -> disable radio, show "lobatt" message +#define BATTERY_LOW_THRESHOLD (240u) + +// Show "lobatt" message every n seconds +#define BATTERY_LOW_MESSAGE_CYCLE (15u) + +// ************************************************************************************************* +// Global Variable section +struct batt +{ + menu_t state; // MENU_ITEM_NOT_VISIBLE, MENU_ITEM_VISIBLE + u8 lobatt_display; // Counter for alternating "lobatt" display + u16 voltage; // Battery voltage + s16 offset; // Battery voltage offset +}; +extern struct batt sBatt; + +// ************************************************************************************************* +// Extern section + +#endif /*BATTERY_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/bluerobin.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/bluerobin.c new file mode 100755 index 0000000..38273f2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/bluerobin.c @@ -0,0 +1,705 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// BlueRobin functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "radio.h" +#include "ports.h" +#include "timer.h" +#include "rf1a.h" + +// logic +#include "BlueRobin_RX_API.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section +void display_calories(u8 line, u8 update); +void display_distance(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// Set to TRUE if transmitter ID should be remembered when reconnecting +// Transmitter ID can be cleared by pressing button STAR for more than 3 seconds +#define REMEMBER_TX_ID (FALSE) + +// ************************************************************************************************* +// Global Variable section +struct bluerobin sBlueRobin; + +// Display values for user gender selection +const u8 selection_User_Gender[][4] = { "MALE", "FEMA" }; + +// ************************************************************************************************* +// Extern section + +// Stop BlueRobin timer +extern void BRRX__StopTimer_v(void); + +// Calibration value for FSCTRL0 register (corrects deviation of 26MHz crystal) +extern u8 rf_frequoffset; + +// ************************************************************************************************* +// @fn reset_bluerobin +// @brief Reset BlueRobin data. +// @param none +// @return none +// ************************************************************************************************* +void reset_bluerobin(void) +{ + // Reset state is no connection + sBlueRobin.state = BLUEROBIN_OFF; + + // Reset value of chest strap ID is 0 --> connect to next best chest strap + sBlueRobin.cs_id = 0; + + // No new data available + sBlueRobin.update = BLUEROBIN_NO_UPDATE; + sBlueRobin.heartrate = 0; + sBlueRobin.speed = 0; + sBlueRobin.distance = 0; + sBlueRobin.calories = 0; + + // Set user data to default + sBlueRobin.user_sex = USER_SEX_MALE; + sBlueRobin.user_weight = 75; + + // Display calories as default + sBlueRobin.caldist_view = 0; +} + +// ************************************************************************************************* +// @fn mx_rfblue +// @brief BlueRobin sub menu. +// Button STAR resets chest strap ID to 0 and searches for next chest +// strap in range. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void mx_bluerobin(u8 line) +{ +#if REMEMBER_TX_ID == TRUE + u8 i; + + // Reset chest strap ID + sBlueRobin.cs_id = 0; + + display_chars(LCD_SEG_L1_2_0, (u8 *) "CLR", SEG_ON); + for (i = 0; i < 4; i++) + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); +#endif + + // Clear simulated button event + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn sx_bluerobin +// @brief BlueRobin direct function. Button UP connects/disconnects with sender unit. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void sx_bluerobin(u8 line) +{ + u8 stop = 0; + + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if SimpliciTI stack is active + if (is_rf()) + return; + + // UP: connect / disconnect transmitter + if (button.flag.up) + { + if (sBlueRobin.state == BLUEROBIN_OFF) + { + // Init BlueRobin timer and radio + open_radio(); + + // Initialize BR library + BRRX_Init_v(); + + // Set BR data transmission properties + BRRX_SetPowerdownDelay_v(10); // Power down channel after 10 consecutive lost data + // packets (~9 seconds) + BRRX_SetSearchTimeout_v(8); // Stop searching after 8 seconds + + // Sensitivity in learn mode reduced --> connect only to close transmitters + // Skip this part if chest strap id was set in a previous learn mode run +#if REMEMBER_TX_ID == TRUE + if (sBlueRobin.cs_id == 0) + BRRX_SetSignalLevelReduction_v(5); + +#else + // Forget previously learned transmitter ID and connect to next close transmitter + sBlueRobin.cs_id = 0; + BRRX_SetSignalLevelReduction_v(5); +#endif + + // Apply frequency offset compensation to radio register FSCTRL0 + // If calibration memory was erased, rf_frequoffset defaults to 0x00 and has no effect + WriteSingleReg(FSCTRL0, rf_frequoffset); + + // New state is SEARCH + sBlueRobin.state = BLUEROBIN_SEARCHING; + + // Blink RF icon to show searching + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + + // Turn on radio and establish connection if channel not already started + if (BRRX_GetState_t(HR_CHANNEL) == TX_OFF) + { + // Start in learn mode (connect to closest heart rate transmitter) + BRRX_SetID_v(HR_CHANNEL, sBlueRobin.cs_id); + BRRX_Start_v(HR_CHANNEL); + + // Wait until learning phase is over + while (BRRX_GetState_t(HR_CHANNEL) == TX_SEARCH) + { + Timer0_A4_Delay(CONV_MS_TO_TICKS(200)); + } + } + + // Check if connection attempt was successful + if (BRRX_GetState_t(HR_CHANNEL) == TX_ACTIVE) + { + // Successfully connected to transmitter + sBlueRobin.state = BLUEROBIN_CONNECTED; + + // When in learn mode, copy chest strap ID + if (sBlueRobin.cs_id == 0) + { + sBlueRobin.cs_id = BRRX_GetID_u32(HR_CHANNEL); + } + + // Show steady RF icon to indicate established connection + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF); + + // Show blinking icon + display_symbol(LCD_ICON_HEART, SEG_ON_BLINK_ON); + } + else // Error -> Shutdown connection + { + stop = 1; + } + } + else if (sBlueRobin.state == BLUEROBIN_CONNECTED) + { + // Shutdown connection + stop = 1; + } + } + + // Shutdown connection + if (stop) + { + stop_bluerobin(); + } +} + +// ************************************************************************************************* +// @fn display_selection_User_Gender +// @brief Display the configuration for gender in watch +// @param u8 segments LCD segments where value is displayed +// u32 value Integer value to be displayed +// u8 digits Number of digits to convert +// u8 blanks Number of leadings blanks in +// int_to_array result string +// @return none +// ************************************************************************************************* +void display_selection_User_Gender(u8 segments, u32 index, u8 digits, u8 blanks) +{ + if (index < 2) + display_chars(segments, (u8 *) selection_User_Gender[index], SEG_ON_BLINK_ON); +} + +// ************************************************************************************************* +// @fn mx_caldist +// @brief Calories/Distance sub menu. Mx enables setting of total calories, user sex and +// weight. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void mx_caldist(u8 line) +{ + u8 select; + s32 kcalories; + s32 weight; + s32 sex; + + // Clear display + clear_display_all(); + + // Convert global variables to local variables + sex = sBlueRobin.user_sex; + kcalories = sBlueRobin.calories / 1000; + if (sys.flag.use_metric_units) + weight = sBlueRobin.user_weight; + else + weight = ((s32) sBlueRobin.user_weight * 2205) / 1000; // Convert kg to lb + + // Init value index + select = 0; + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout : exit without saving + if (sys.flag.idle_timeout) + break; + + // Button STAR (short): save, then exit + if (button.flag.star) + { + // Store local variables in global structure + sBlueRobin.calories = kcalories * 1000; + sBlueRobin.user_sex = sex; + if (sys.flag.use_metric_units) + sBlueRobin.user_weight = weight; + else + sBlueRobin.user_weight = (weight * 1000) / 2205; + + // Set display update flag + display.flag.line1_full_update = 1; + + break; + } + + switch (select) + { + case 0: // Set calories + display_symbol(LCD_UNIT_L2_KCAL, SEG_ON); + set_value(&kcalories, 6, 5, 0, 199999, SETVALUE_DISPLAY_VALUE + + SETVALUE_FAST_MODE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_5_0, + display_value); + display_symbol(LCD_UNIT_L2_KCAL, SEG_OFF); + clear_line(LINE2); + select = 1; + break; + case 1: // Set user sex + set_value( + &sex, 1, 0, 0, 1, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_SELECTION + + SETVALUE_NEXT_VALUE, LCD_SEG_L2_3_0, display_selection_User_Gender); + select = 2; + break; + case 2: // Set user weight + if (sys.flag.use_metric_units) + { + display_chars(LCD_SEG_L2_1_0, (u8 *) "KG", SEG_ON); + set_value(&weight, 3, 2, USER_WEIGHT_MIN_KG, USER_WEIGHT_MAX_KG, + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_4_2, + display_value); + } + else + { + display_chars(LCD_SEG_L2_1_0, (u8 *) "LB", SEG_ON); + set_value(&weight, 3, 2, USER_WEIGHT_MIN_LB, USER_WEIGHT_MAX_LB, + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_4_2, + display_value); + } + select = 0; + break; + } + } + + // Clear button flags + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn sx_caldist +// @brief Button DOWN toggles between calories and distance display. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_caldist(u8 line) +{ + // Clean up line + display_caldist(line, DISPLAY_LINE_CLEAR); + + // Toggle display + if (sBlueRobin.caldist_view == 0) + sBlueRobin.caldist_view = 1; + else + sBlueRobin.caldist_view = 0; + + // Draw line + display_caldist(line, DISPLAY_LINE_UPDATE_FULL); +} + +// ************************************************************************************************* +// @fn display_heartrate +// @brief Heart rate display routine. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_heartrate(u8 line, u8 update) +{ + u8 *str; + + if (update != DISPLAY_LINE_CLEAR) + { + if (is_bluerobin()) + { + str = int_to_array(sBlueRobin.heartrate, 3, 2); + display_chars(LCD_SEG_L1_2_0, str, SEG_ON); + } + else + { + display_chars(LCD_SEG_L1_2_0, (u8 *) "---", SEG_ON); + } + } + + // Redraw whole screen + if (!is_bluerobin()) + { + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_symbol(LCD_ICON_HEART, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Clear heart when not connected + display_symbol(LCD_ICON_HEART, SEG_OFF); + } + } +} + +// ************************************************************************************************* +// @fn display_speed_kmh +// @brief Speed display routine. Supports kmh and mph. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_PARTIAL, +// DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_speed(u8 line, u8 update) +{ + u8 milesPerHour; + u8 *str; + + // Speed resolution is 0.1 km/h + // Valid range is 0.0 .. 25.0 km/h + + // Display resolution is 0.1km/h + // For speed less than 1 km/h, force "0.x" display + if (update != DISPLAY_LINE_CLEAR) + { + if (sys.flag.use_metric_units) + { + str = int_to_array(sBlueRobin.speed, 3, 1); + } + else + { + milesPerHour = (u16) (sBlueRobin.speed * 0.6214); + str = int_to_array(milesPerHour, 3, 1); + } + display_chars(LCD_SEG_L1_2_0, str, SEG_ON); + } + + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_symbol(LCD_SEG_L1_DP0, SEG_ON); + if (sys.flag.use_metric_units) + { + display_symbol(LCD_UNIT_L1_K, SEG_ON); + display_symbol(LCD_UNIT_L1_M, SEG_ON); + } + else + { + display_symbol(LCD_UNIT_L1_M, SEG_ON); + display_symbol(LCD_UNIT_L1_I, SEG_ON); + } + display_symbol(LCD_UNIT_L1_PER_H, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + display_symbol(LCD_SEG_L1_DP0, SEG_OFF); + display_symbol(LCD_UNIT_L1_K, SEG_OFF); + display_symbol(LCD_UNIT_L1_M, SEG_OFF); + display_symbol(LCD_UNIT_L1_M, SEG_OFF); + display_symbol(LCD_UNIT_L1_I, SEG_OFF); + display_symbol(LCD_UNIT_L1_PER_H, SEG_OFF); + } +} + +// ************************************************************************************************* +// @fn display_distance +// @brief Distance display routine. Supports km and mi. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_PARTIAL, +// DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_distance(u8 line, u8 update) +{ + u8 *str; + u32 miles; + + if (update != DISPLAY_LINE_CLEAR) + { + if (sys.flag.use_metric_units) + { + // Display distance in x.xx km format (resolution is 10m) up to 2000.00 km + if (sBlueRobin.distance < 2000000) + { + // Convert decimal distance in meters to format "xxxx.xx" km + // If distance is less than 1000m, force display to " 0.xx" + // If distance is less than 100m, force display to " 0.0x" + str = int_to_array(sBlueRobin.distance / 10, 6, 3); + } + else + { + str = int_to_array(199999, 6, 3); + } + } + else + { + // Convert km to miles, take care for "0.xx mi" display + miles = (u32) (sBlueRobin.distance * 0.06214); + + // Display distance in x.xx mi format (resolution is 1/100mi) up to 2000.00 mi + if (miles < 2000000) + { + // If distance is less than 1 mile, force display to " 0.xx" + // If distance is less than 1/10 mile, force display to " 0.0x" + str = int_to_array(miles, 6, 3); + } + else + { + // Display maximum value (1999.99 mi) + str = int_to_array(199999, 6, 3); + } + } + display_chars(LCD_SEG_L2_5_0, str, SEG_ON); + } + + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sys.flag.use_metric_units) + { + display_symbol(LCD_UNIT_L2_KM, SEG_ON); + } + else + { + display_symbol(LCD_UNIT_L2_MI, SEG_ON); + } + display_symbol(LCD_SEG_L2_DP, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + display_symbol(LCD_UNIT_L2_KM, SEG_OFF); + display_symbol(LCD_UNIT_L2_MI, SEG_OFF); + display_symbol(LCD_SEG_L2_DP, SEG_OFF); + } +} + +// ************************************************************************************************* +// @fn display_caldist +// @brief Shared calories/distance display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_PARTIAL, +// DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_caldist(u8 line, u8 update) +{ + if (sBlueRobin.caldist_view == 0) + display_calories(line, update); + else + display_distance(line, update); +} + +// ************************************************************************************************* +// @fn display_calories +// @brief Calories display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_PARTIAL, +// DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_calories(u8 line, u8 update) +{ + u8 *str; + + if (update != DISPLAY_LINE_CLEAR) + { + // Convert decimal calories to string + str = int_to_array(sBlueRobin.calories / 1000, 6, 5); + display_chars(LCD_SEG_L2_5_0, str, SEG_ON); + } + + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_symbol(LCD_UNIT_L2_KCAL, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Clean up symbols when leaving function + display_symbol(LCD_UNIT_L2_KCAL, SEG_OFF); + } +} + +// ************************************************************************************************* +// @fn is_bluerobin +// @brief Returns TRUE if BlueRobin transmitter is connected. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_bluerobin(void) +{ + return (sBlueRobin.state == BLUEROBIN_CONNECTED); +} + +// ************************************************************************************************* +// @fn is_bluerobin_searching +// @brief Returns TRUE if BlueRobin is searching for a transmitter. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_bluerobin_searching(void) +{ + return (sBlueRobin.state == BLUEROBIN_SEARCHING); +} + +// ************************************************************************************************* +// @fn get_bluerobin_data +// @brief Read BlueRobin packet data from API. +// @param none +// @return none +// ************************************************************************************************* +void get_bluerobin_data(void) +{ + u16 calories; + brtx_state_t bChannelState; + + // Check connection status + bChannelState = BRRX_GetState_t(HR_CHANNEL); + + switch (bChannelState) + { + case TX_ACTIVE: // Read heart rate data from BlueRobin API + sBlueRobin.heartrate = BRRX_GetHeartRate_u8(); + + // Read speed from BlueRobin API (only valid if sender is USB dongle) + sBlueRobin.speed = BRRX_GetSpeed_u8(); + + // Read distance from BlueRobin API (only valid if sender is USB dongle) + sBlueRobin.distance = BRRX_GetDistance_u16(); + if (sBlueRobin.distance > 2000000) + sBlueRobin.distance = 0; + + // Heart rate high enough for calorie measurement? + if (sBlueRobin.heartrate >= 65 && sBlueRobin.user_weight != 0) + { + calories = ((sBlueRobin.heartrate - 60) * sBlueRobin.user_weight) / 32; + + // Calorie reduction for female user required? + if (sBlueRobin.user_sex == USER_SEX_FEMALE) + { + calories -= calories / 4; + } + + // Restart from 0 when reaching 199999 kcal + sBlueRobin.calories += calories; + if (sBlueRobin.calories > 200000000) + sBlueRobin.calories = 0; + } + sBlueRobin.update = BLUEROBIN_NEW_DATA; + break; + + case TX_OFF: // Shutdown connection + stop_bluerobin(); + break; + + // BR_SEARCH, BR_LEARN, BR_PAUSE: Keep old values until we receive new data + default: + break; + } +} + +// ************************************************************************************************* +// @fn stop_bluerobin +// @brief Stop communication and put peripherals in power-down mode. +// @param none +// @return none +// ************************************************************************************************* +void stop_bluerobin(void) +{ + // Reset connection status byte + sBlueRobin.state = BLUEROBIN_OFF; + + // Stop channel + BRRX_Stop_v(HR_CHANNEL); + + // Powerdown radio + close_radio(); + + // Force full display update to clear heart rate and speed data + sBlueRobin.heartrate = 0; + sBlueRobin.speed = 0; + sBlueRobin.distance = 0; + display.flag.full_update = 1; + + // Clear heart and RF symbol + display_symbol(LCD_ICON_HEART, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/bluerobin.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/bluerobin.h new file mode 100755 index 0000000..b545d11 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/bluerobin.h @@ -0,0 +1,107 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef BLUEROBIN_H_ +#define BLUEROBIN_H_ + +// ************************************************************************************************* +// Include section +#include + +// ************************************************************************************************* +// Prototypes section +extern void reset_bluerobin(void); +extern void mx_bluerobin(u8 line); +extern void sx_bluerobin(u8 line); +extern void mx_caldist(u8 line); +extern void display_heartrate(u8 line, u8 update); +extern void display_speed(u8 line, u8 update); +extern void sx_caldist(u8 line); +extern void mx_caldist(u8 line); +extern void display_caldist(u8 line, u8 update); +extern u8 is_bluerobin(void); +extern u8 is_bluerobin_searching(void); +extern void get_bluerobin_data(void); +extern void stop_bluerobin(void); + +// ************************************************************************************************* +// Defines section + +// BlueRobin connection states +typedef enum +{ + BLUEROBIN_OFF = 0, // Not connected + BLUEROBIN_SEARCHING, // Searching for transmitter + BLUEROBIN_CONNECTED, // Connected + BLUEROBIN_ERROR // Error occurred while trying to connect or while connected +} BlueRobin_state_t; + +// BlueRobin data update states +typedef enum +{ + BLUEROBIN_NO_UPDATE = 0, // No new data available + BLUEROBIN_NEW_DATA // New data arrived +} BlueRobin_update_t; + +#define USER_SEX_MALE 0 +#define USER_SEX_FEMALE 1 +#define USER_WEIGHT_MIN_KG 30 +#define USER_WEIGHT_MAX_KG 150 +#define USER_WEIGHT_MIN_LB 70 +#define USER_WEIGHT_MAX_LB 400 + +// ************************************************************************************************* +// Global Variable section +struct bluerobin +{ + BlueRobin_state_t state; // BLUEROBIN_OFF, BLUEROBIN_SEARCHING, BLUEROBIN_CONNECTED, + // BLUEROBIN_ERROR + BlueRobin_update_t update; // BLUEROBIN_NO_UPDATE, BLUEROBIN_NEW_DATA + u32 cs_id; // Chest strap ID + u8 user_sex; // User settings + u16 user_weight; + u8 heartrate; // Heart rate (1 bpm) + u32 calories; // Calories (1 kCal) - calculated from heart rate, user weight and + // user sex + u8 speed; // Speed (0.1 km/h) - demo version range is 0.0 to 25.5km/h + u32 distance; // Distance (1 m) + u8 caldist_view; // 0=display calories, 1=display distance +}; +extern struct bluerobin sBlueRobin; + +// ************************************************************************************************* +// Extern section + +#endif /*BLUEROBIN_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/clock.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/clock.c new file mode 100755 index 0000000..2eef524 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/clock.c @@ -0,0 +1,444 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Time functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "ports.h" +#include "display.h" +#include "timer.h" + +// logic +#include "menu.h" +#include "clock.h" +#include "user.h" +#include "bluerobin.h" +#include "date.h" + +// ************************************************************************************************* +// Prototypes section +void reset_clock(void); +void clock_tick(void); +void mx_time(u8 line); +void sx_time(u8 line); + +void calc_24H_to_12H(u8 * hours, u8 * timeAM); +void conv_24H_to_12H(u8 * hours24, u8 * hours12, u8 * timeAMorPM); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct time sTime; + +// Display values for time format selection +const u8 selection_Timeformat[][4] = { + "24H", "12H" +}; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); +extern void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn reset_clock +// @brief Resets clock time to 00:00:00, 24H time format. +// @param none +// @return none +// ************************************************************************************************* +void reset_clock(void) +{ + // Set global system time to 0 + sTime.system_time = 0; + + // Set main 24H time to start value + sTime.hour = 4; + sTime.minute = 30; + sTime.second = 0; + + // Display style of both lines is default (HH:MM) + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; + + // Reset timeout detection + sTime.last_activity = 0; +} + +// ************************************************************************************************* +// @fn clock_tick +// @brief Add 1 second to system time and to display time +// @param none +// @return none +// ************************************************************************************************* +void clock_tick(void) +{ + // Use sTime.drawFlag to minimize display updates + // sTime.drawFlag = 1: second + // sTime.drawFlag = 2: minute, second + // sTime.drawFlag = 3: hour, minute + sTime.drawFlag = 1; + + // Increase global system time + sTime.system_time++; + + // Add 1 second + sTime.second++; + + // Add 1 minute + if (sTime.second == 60) + { + sTime.second = 0; + sTime.minute++; + sTime.drawFlag++; + + // Add 1 hour + if (sTime.minute == 60) + { + sTime.minute = 0; + sTime.hour++; + sTime.drawFlag++; + + // Add 1 day + if (sTime.hour == 24) + { + sTime.hour = 0; + add_day(); + } + } + } +} + +// ************************************************************************************************* +// @fn convert_hour_to_12H_format +// @brief Convert internal 24H time to 12H time. +// @param u8 hour Hour in 24H format +// @return u8 Hour in 12H format +// ************************************************************************************************* +u8 convert_hour_to_12H_format(u8 hour) +{ + // 00:00 .. 11:59 --> AM 12:00 .. 11:59 + if (hour == 0) + return (hour + 12); + else if (hour <= 12) + return (hour); + // 13:00 .. 23:59 --> PM 01:00 .. 11:59 + else + return (hour - 12); +} + +// ************************************************************************************************* +// @fn is_hour_am +// @brief Checks if internal 24H time is AM or PM +// @param u8 hour Hour in 24H format +// @return u8 1 = AM, 0 = PM +// ************************************************************************************************* +u8 is_hour_am(u8 hour) +{ + // 00:00 .. 11:59 --> AM 12:00 .. 11:59 + if (hour < 12) + return (1); + // 12:00 .. 23:59 --> PM 12:00 .. 11:59 + else + return (0); +} + +// ************************************************************************************************* +// @fn display_selection_Timeformat +// @brief Display time format 12H / 24H. +// @param u8 segments Target segments where to display information +// u32 index 0 or 1, index for value string +// u8 digits Not used +// u8 blanks Not used +// @return none +// ************************************************************************************************* +void display_selection_Timeformat1(u8 segments, u32 index, u8 digits, u8 blanks) +{ + if (index < 2) + display_chars(segments, (u8 *) selection_Timeformat[index], SEG_ON_BLINK_ON); +} + +// ************************************************************************************************* +// @fn mx_time +// @brief Clock set routine. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void mx_time(u8 line) +{ + u8 select; + s32 timeformat; + s16 timeformat1; + s32 hours; + s32 minutes; + s32 seconds; + u8 *str; + + // Clear display + clear_display_all(); + + // Convert global time to local variables + // Global time keeps on ticking in background until it is overwritten + if (sys.flag.use_metric_units) + { + timeformat = TIMEFORMAT_24H; + } + else + { + timeformat = TIMEFORMAT_12H; + } + timeformat1 = timeformat; + hours = sTime.hour; + minutes = sTime.minute; + seconds = sTime.second; + + // Init value index + select = 0; + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout: exit without saving + if (sys.flag.idle_timeout) + { + // Roll back time format + if (timeformat1 == TIMEFORMAT_24H) + sys.flag.use_metric_units = 1; + else + sys.flag.use_metric_units = 0; + display_symbol(LCD_SYMB_AM, SEG_OFF); + break; + } + + // Button STAR (short): save, then exit + if (button.flag.star) + { + // Stop clock timer + Timer0_Stop(); + + // Store local variables in global clock time + sTime.hour = hours; + sTime.minute = minutes; + sTime.second = seconds; + + // Start clock timer + Timer0_Start(); + + // Full display update is done when returning from function + display_symbol(LCD_SYMB_AM, SEG_OFF); + break; + } + + switch (select) + { + case 0: // Clear LINE1 and LINE2 and AM icon - required when coming back from + // set_value(seconds) + clear_display(); + display_symbol(LCD_SYMB_AM, SEG_OFF); + + // Set 24H / 12H time format + set_value( + &timeformat, 1, 0, 0, 1, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_SELECTION + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_1, display_selection_Timeformat1); + + // Modify global time format variable immediately to update AM/PM icon correctly + if (timeformat == TIMEFORMAT_24H) + sys.flag.use_metric_units = 1; + else + sys.flag.use_metric_units = 0; + select = 1; + break; + + case 1: // Display HH:MM (LINE1) and .SS (LINE2) + str = int_to_array(hours, 2, 0); + display_chars(LCD_SEG_L1_3_2, str, SEG_ON); + display_symbol(LCD_SEG_L1_COL, SEG_ON); + + str = int_to_array(minutes, 2, 0); + display_chars(LCD_SEG_L1_1_0, str, SEG_ON); + + str = int_to_array(seconds, 2, 0); + display_chars(LCD_SEG_L2_1_0, str, SEG_ON); + display_symbol(LCD_SEG_L2_DP, SEG_ON); + + // Set hours + set_value(&hours, 2, 0, 0, 23, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, + display_hours); + select = 2; + break; + + case 2: // Set minutes + set_value(&minutes, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, + display_value); + select = 3; + break; + + case 3: // Set seconds + set_value(&seconds, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L2_1_0, + display_value); + select = 0; + break; + } + } + + // Clear button flags + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn sx_time +// @brief Time user routine. Toggles view style between HH:MM and SS. +// @param line LINE1 +// @return none +// ************************************************************************************************* +void sx_time(u8 line) +{ + // Toggle display view style + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + sTime.line1ViewStyle = DISPLAY_ALTERNATIVE_VIEW; + else + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn display_time +// @brief Clock display routine. Supports 24H and 12H time format. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL +// @return none +// ************************************************************************************************* +void display_time(u8 line, u8 update) +{ + u8 hour12; + + // Partial update + if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + if (sTime.drawFlag != 0) + { + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + { + switch (sTime.drawFlag) + { + case 3: + if (sys.flag.use_metric_units) + { + // Display 24H time "HH" + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(sTime.hour, 2, + 0), SEG_ON); + } + else + { + // Display 12H time "HH" + AM/PM + hour12 = convert_hour_to_12H_format(sTime.hour); + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(hour12, 2, + 0), SEG_ON); + display_am_pm_symbol(sTime.hour); + } + + case 2: + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.minute, 2, + 0), SEG_ON); + } + } + else + { + // Seconds are always updated + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.second, 2, 0), SEG_ON); + } + } + } + else if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Full update + if (sTime.line1ViewStyle == DISPLAY_DEFAULT_VIEW) + { + // Display 24H/12H time + if (sys.flag.use_metric_units) + { + // Display 24H time "HH" + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(sTime.hour, 2, 0), SEG_ON); + } + else + { + // Display 12H time "HH" + AM/PM information + hour12 = convert_hour_to_12H_format(sTime.hour); + display_chars(switch_seg(line, LCD_SEG_L1_3_2, + LCD_SEG_L2_3_2), int_to_array(hour12, 2, 0), SEG_ON); + // Display AM/PM information + if (line == LINE1) + { + display_am_pm_symbol(sTime.hour); + } + } + + // Display minute + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.minute, 2, 0), SEG_ON); + display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_ON_BLINK_ON); + } + else + { + // Display seconds + display_chars(switch_seg(line, LCD_SEG_L1_1_0, + LCD_SEG_L2_1_0), int_to_array(sTime.second, 2, 0), SEG_ON); + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + display_symbol(switch_seg(line, LCD_SEG_L1_COL, LCD_SEG_L2_COL0), SEG_OFF_BLINK_OFF); + // Change display style to default (HH:MM) + sTime.line1ViewStyle = DISPLAY_DEFAULT_VIEW; + // Clean up AM/PM icon + display_symbol(LCD_SYMB_AM, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/clock.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/clock.h new file mode 100755 index 0000000..9084b1b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/clock.h @@ -0,0 +1,74 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef CLOCK_H_ +#define CLOCK_H_ + +// ************************************************************************************************* +// Defines section + +// Definitions for time format +#define TIMEFORMAT_24H (0u) +#define TIMEFORMAT_12H (1u) + +// ************************************************************************************************* +// Prototypes section +extern void reset_clock(void); +extern void sx_time(u8 line); +extern void mx_time(u8 line); +extern void clock_tick(void); +extern void display_selection_Timeformat1(u8 segments, u32 index, u8 digits, u8 blanks); +extern void display_time(u8 line, u8 update); + +// English units support +extern void calc_24H_to_12H(u8 * hours, u8 * timeAM); +extern u8 convert_hour_to_12H_format(u8 hour); +extern u8 is_hour_am(u8 hour); + +// ************************************************************************************************* +// Global Variable section +struct time +{ + u32 system_time; // Global system time. Used to calculate last activity + u32 last_activity; // Inactivity detection (exits set_value() function) + u8 drawFlag; // Flag to minimize display updates + u8 line1ViewStyle; // Viewing style + u8 hour; // Time data + u8 minute; // Time data + u8 second; // Time data +}; +extern struct time sTime; + +#endif /*CLOCK_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/date.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/date.c new file mode 100755 index 0000000..e72ef3d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/date.c @@ -0,0 +1,354 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Date functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" + +// logic +#include "date.h" +#include "user.h" + +// ************************************************************************************************* +// Prototypes section +void reset_date(void); +u8 get_numberOfDays(u8 month, u16 year); +void add_day(void); +void mx_date(u8 line); +void sx_date(u8 line); +void display_date(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct date sDate; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); +extern void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn reset_date +// @brief Reset date to start value. +// @param none +// @return none +// ************************************************************************************************* +void reset_date(void) +{ + // Set date + sDate.year = 2009; + sDate.month = 8; + sDate.day = 1; + + // Show day and month on display + sDate.display = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn get_NumberOfDays +// @brief Return number of days for a given month +// @param month month as char +// year year as int +// @return day count for given month +// ************************************************************************************************* +u8 get_numberOfDays(u8 month, u16 year) +{ + switch (month) + { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + return (31); + + case 4: + case 6: + case 9: + case 11: + return (30); + + // 1. A year that is divisible by 4 is a leap year. (Y % 4) == 0 + // 2. Exception to rule 1: a year that is divisible by 100 is not a leap year. (Y % 100) != + // 0 + // 3. Exception to rule 2: a year that is divisible by 400 is a leap year. (Y % 400) == 0 + + case 2: + if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))) + return (29); + else + return (28); + + default: + return (0); + } +} + +// ************************************************************************************************* +// @fn add_day +// @brief Add one day to current date. Called when clock changes from 23:59 to 00:00 +// @param none +// @return none +// ************************************************************************************************* +void add_day(void) +{ + // Add 1 day + sDate.day++; + + // Check if day overflows into next month + if (sDate.day > get_numberOfDays(sDate.month, sDate.year)) + { + // Add 1 month and reset to day to 1 + sDate.day = 1; + sDate.month++; + + // Check if month overflows into next year + if (sDate.month > 12) + { + // Add 1 year and reset month and day to 1 + sDate.day = 1; + sDate.month = 1; + sDate.year++; + } + } + + // Indicate to display function that new value is available + display.flag.full_update = 1; +} + +// ************************************************************************************************* +// @fn mx_date +// @brief Date set routine. +// @param line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void mx_date(u8 line) +{ + u8 select; + s32 day; + s32 month; + s32 year; + s16 max_days; + u8 *str; + u8 *str1; + + // Clear display + clear_display_all(); + + // Convert global to local variables + day = sDate.day; + month = sDate.month; + year = sDate.year; + + // Init value index + select = 0; + + // Init display + // LINE1: DD.MM (metric units) or MM.DD (English units) + // LINE2: YYYY (will be drawn by set_value) + + if (sys.flag.use_metric_units) + { + str = int_to_array(day, 2, 0); + display_chars(LCD_SEG_L1_3_2, str, SEG_ON); + + str1 = int_to_array(month, 2, 0); + display_chars(LCD_SEG_L1_1_0, str1, SEG_ON); + } + else // English units + { + str = int_to_array(day, 2, 0); + display_chars(LCD_SEG_L1_1_0, str, SEG_ON); + + str1 = int_to_array(month, 2, 0); + display_chars(LCD_SEG_L1_3_2, str1, SEG_ON); + } + display_symbol(LCD_SEG_L1_DP1, SEG_ON); + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout: exit without saving + if (sys.flag.idle_timeout) + break; + + // Button STAR (short): save, then exit + if (button.flag.star) + { + // Copy local variables to global variables + sDate.day = day; + sDate.month = month; + sDate.year = year; + + // Full display update is done when returning from function + break; + } + + switch (select) + { + case 0: // Set year + set_value(&year, 4, 0, 2008, 2100, SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, + LCD_SEG_L2_3_0, + display_value); + select = 1; + break; + case 1: // Set month + if (sys.flag.use_metric_units) + { + set_value( + &month, 2, 0, 1, 12, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value); + } + else // English units + { + set_value( + &month, 2, 0, 1, 12, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_value); + } + select = 2; + break; + case 2: // Set day + if (sys.flag.use_metric_units) + { + set_value( + &day, 2, 0, 1, max_days, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_value); + } + else // English units + { + set_value( + &day, 2, 0, 1, max_days, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value); + } + select = 0; + break; + } + + // Check if day is still valid, if not clamp to last day of current month + max_days = get_numberOfDays(month, year); + if (day > max_days) + day = max_days; + } + + // Clear button flag + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn sx_date +// @brief Date user routine. Toggles view between DD.MM and YYYY. +// @param line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void sx_date(u8 line) +{ + // Toggle display items + if (sDate.display == DISPLAY_DEFAULT_VIEW) + sDate.display = DISPLAY_ALTERNATIVE_VIEW; + else + sDate.display = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn display_date +// @brief Display date in DD.MM format (metric units) or MM.DD (English units). +// @param u8 line LINE1, LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL, +// DISPLAY_LINE_UPDATE_PARTIAL +// @return none +// ************************************************************************************************* +void display_date(u8 line, u8 update) +{ + u8 *str; + + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sDate.display == DISPLAY_DEFAULT_VIEW) + { + // Convert day to string + str = int_to_array(sDate.day, 2, 0); + if (sys.flag.use_metric_units) + { + display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); + } + else + { + display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); + } + + // Convert month to string + str = int_to_array(sDate.month, 2, 0); + if (sys.flag.use_metric_units) + { + display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON); + } + else + { + display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON); + } + + // Display "." to separate day and month + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON); + } + else + { + // Convert year to string + str = int_to_array(sDate.year, 4, 0); + display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_3_0), str, SEG_ON); + + // Clear "." + display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_OFF); + } + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Show day and month on display when coming around next time + sDate.display = DISPLAY_DEFAULT_VIEW; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/date.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/date.h new file mode 100755 index 0000000..f3a65b8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/date.h @@ -0,0 +1,68 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef DATE_H_ +#define DATE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_date(void); +extern void add_day(void); +extern void mx_date(u8 line); +extern void sx_date(u8 line); +extern void display_date(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct date +{ + u8 display; // Toggles view between DISPLAY_DEFAULT_VIEW = DD.MM and + // DISPLAY_ALTERNATIVE_VIEW = YYYY + u8 day; + u8 month; + u16 year; +}; +extern struct date sDate; + +// ************************************************************************************************* +// Extern section + +#endif /*DATE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/menu.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/menu.c new file mode 100755 index 0000000..05a826a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/menu.c @@ -0,0 +1,254 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Menu management functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" + +// logic +#include "menu.h" +#include "user.h" +#include "clock.h" +#include "date.h" +#include "alarm.h" +#include "stopwatch.h" +#include "temperature.h" +#include "altitude.h" +#include "battery.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "acceleration.h" +#include "rfbsl.h" + +// ************************************************************************************************* +// Defines section +#define FUNCTION(function) function + +// ************************************************************************************************* +// Global Variable section +const struct menu *ptrMenu_L1 = NULL; +const struct menu *ptrMenu_L2 = NULL; + +// ************************************************************************************************* +// Global Variable section + +void display_nothing(u8 line, u8 update) +{ +} + +u8 update_time(void) +{ + return (display.flag.update_time); +} + +u8 update_stopwatch(void) +{ + return (display.flag.update_stopwatch); +} + +u8 update_date(void) +{ + return (display.flag.update_date); +} + +u8 update_alarm(void) +{ + return (display.flag.update_alarm); +} + +u8 update_temperature(void) +{ + return (display.flag.update_temperature); +} + +u8 update_battery_voltage(void) +{ + return (display.flag.update_battery_voltage); +} + +u8 update_acceleration(void) +{ + return (display.flag.update_acceleration); +} + +// ************************************************************************************************* +// User navigation ( [____] = default menu item after reset ) +// +// LINE1: [Time] -> Alarm -> Temperature -> Altitude -> Heart rate -> Speed -> Acceleration +// +// LINE2: [Date] -> Stopwatch -> Battery -> ACC -> PPT -> SYNC -> Calories/Distance --> RFBSL +// ************************************************************************************************* + +// Line1 - Time +const struct menu menu_L1_Time = { + FUNCTION(sx_time), // direct function + FUNCTION(mx_time), // sub menu function + FUNCTION(display_time), // display function + FUNCTION(update_time), // new display data + &menu_L1_Alarm, +}; + +// Line1 - Alarm +const struct menu menu_L1_Alarm = { + FUNCTION(sx_alarm), // direct function + FUNCTION(mx_alarm), // sub menu function + FUNCTION(display_alarm), // display function + FUNCTION(update_alarm), // new display data + &menu_L1_Temperature, +}; + +// Line1 - Temperature +const struct menu menu_L1_Temperature = { + FUNCTION(dummy), // direct function + FUNCTION(mx_temperature), // sub menu function + FUNCTION(display_temperature), // display function + FUNCTION(update_temperature), // new display data + &menu_L1_Altitude, +}; + +// Line1 - Altitude +const struct menu menu_L1_Altitude = { + FUNCTION(sx_altitude), // direct function + FUNCTION(mx_altitude), // sub menu function + FUNCTION(display_altitude), // display function + FUNCTION(update_time), // new display data + &menu_L1_Heartrate, +}; + +// Line1 - Heart Rate +const struct menu menu_L1_Heartrate = { + FUNCTION(sx_bluerobin), // direct function + FUNCTION(mx_bluerobin), // sub menu function + FUNCTION(display_heartrate), // display function + FUNCTION(update_time), // new display data + &menu_L1_Speed, +}; + +// Line1 - Speed +const struct menu menu_L1_Speed = { + FUNCTION(dummy), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_speed), // display function + FUNCTION(update_time), // new display data + &menu_L1_Acceleration, +}; + +// Line1 - Acceleration +const struct menu menu_L1_Acceleration = { + FUNCTION(sx_acceleration), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_acceleration), // display function + FUNCTION(update_acceleration), // new display data + &menu_L1_Time, +}; + +// Line2 - Date +const struct menu menu_L2_Date = { + FUNCTION(sx_date), // direct function + FUNCTION(mx_date), // sub menu function + FUNCTION(display_date), // display function + FUNCTION(update_date), // new display data + &menu_L2_Stopwatch, +}; + +// Line2 - Stopwatch +const struct menu menu_L2_Stopwatch = { + FUNCTION(sx_stopwatch), // direct function + FUNCTION(mx_stopwatch), // sub menu function + FUNCTION(display_stopwatch), // display function + FUNCTION(update_stopwatch), // new display data + &menu_L2_Battery, +}; + +// Line2 - Battery +const struct menu menu_L2_Battery = { + FUNCTION(dummy), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_battery_V), // display function + FUNCTION(update_battery_voltage), // new display data + &menu_L2_Rf, +}; + +// Line2 - ACC (acceleration data + button events via SimpliciTI) +const struct menu menu_L2_Rf = { + FUNCTION(sx_rf), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_rf), // display function + FUNCTION(update_time), // new display data + &menu_L2_Ppt, +}; + +// Line2 - PPT (button events via SimpliciTI) +const struct menu menu_L2_Ppt = { + FUNCTION(sx_ppt), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_ppt), // display function + FUNCTION(update_time), // new display data + &menu_L2_Sync, +}; + +// Line2 - SXNC (synchronization/data download via SimpliciTI) +const struct menu menu_L2_Sync = { + FUNCTION(sx_sync), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_sync), // display function + FUNCTION(update_time), // new display data + &menu_L2_CalDist, +}; + +// Line2 - Calories/Distance +const struct menu menu_L2_CalDist = { + FUNCTION(sx_caldist), // direct function + FUNCTION(mx_caldist), // sub menu function + FUNCTION(display_caldist), // display function + FUNCTION(update_time), // new display data + &menu_L2_RFBSL, +}; + +// Line2 - RFBSL +const struct menu menu_L2_RFBSL = { + FUNCTION(sx_rfbsl), // direct function + FUNCTION(dummy), // sub menu function + FUNCTION(display_rfbsl), // display function + FUNCTION(update_time), // new display data + &menu_L2_Date, +}; diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/menu.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/menu.h new file mode 100755 index 0000000..befb3f6 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/menu.h @@ -0,0 +1,92 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef MENU_H_ +#define MENU_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +struct menu +{ + // Pointer to direct function (start, stop etc) + void (*sx_function)(u8 line); + // Pointer to sub menu function (change settings, reset counter etc) + void (*mx_function)(u8 line); + // Pointer to display function + void (*display_function)(u8 line, u8 mode); + // Display update trigger + u8 (*display_update)(void); + // Pointer to next menu item + const struct menu *next; +}; + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section + +// Line1 navigation +extern const struct menu menu_L1_Time; +extern const struct menu menu_L1_Alarm; +extern const struct menu menu_L1_Altitude; +extern const struct menu menu_L1_Temperature; +extern const struct menu menu_L1_Altitude; +extern const struct menu menu_L1_Heartrate; +extern const struct menu menu_L1_Speed; +extern const struct menu menu_L1_Acceleration; + +// Line2 navigation +extern const struct menu menu_L2_Date; +extern const struct menu menu_L2_Stopwatch; +extern const struct menu menu_L2_Battery; +extern const struct menu menu_L2_Rf; +extern const struct menu menu_L2_Ppt; +extern const struct menu menu_L2_Sync; +extern const struct menu menu_L2_CalDist; +extern const struct menu menu_L2_RFBSL; + +// Pointers to current menu item +extern const struct menu *ptrMenu_L1; +extern const struct menu *ptrMenu_L2; + +#endif /*MENU_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfbsl.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfbsl.c new file mode 100755 index 0000000..c32c980 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfbsl.c @@ -0,0 +1,118 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Wireless Update functions. +// ************************************************************************************************* + + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "ports.h" + +// logic +#include "rfbsl.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" + +// ************************************************************************************************* +// Global Variable section +u8 rfBSL_button_confirmation; + +// ************************************************************************************************* +// @fn sx_rfbsl +// @brief This functions starts the RFBSL +// @param line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void sx_rfbsl(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Exit if SimpliciTI stack is active + if (is_rf()) + return; + + rfBSL_button_confirmation++; + + if (rfBSL_button_confirmation == 2) + { + // Before entering RFBSL clear the LINE1 Symbols + display_symbol(LCD_SYMB_AM, SEG_OFF); + + clear_line(LINE1); + + // Write RAM to indicate we will be downloading the RAM Updater first + display_chars(LCD_SEG_L2_5_0, (u8 *) " RFBSL", SEG_ON); + display_chars(LCD_SEG_L1_3_0, (u8 *) " RAM", SEG_ON); + + // Call RFBSL + CALL_RFSBL(); + } +} + +// ************************************************************************************************* +// @fn display_rfbsl +// @brief RFBSL display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_rfbsl(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (rfBSL_button_confirmation == 0) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " RFBSL", SEG_ON); + } + else if (rfBSL_button_confirmation < 2) + { + // Request one more button press to confirm rfBSL call + display_chars(LCD_SEG_L2_5_0, (u8 *) " CONF", SEG_ON); + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfbsl.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfbsl.h new file mode 100755 index 0000000..364749f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfbsl.h @@ -0,0 +1,55 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RFBSL_H_ +#define RFBSL_H_ + +// ************************************************************************************************* +// Prototypes section +extern void sx_rfbsl(u8 line); +extern void display_rfbsl(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// Entry point of of the Flash Updater in BSL memory +#define CALL_RFSBL() ((void (*)()) 0x1000)() + + +// ************************************************************************************************* +// Global Variable section +extern u8 rfBSL_button_confirmation; + +#endif /*RFBSL_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfsimpliciti.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfsimpliciti.c new file mode 100755 index 0000000..d6ba6a3 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfsimpliciti.c @@ -0,0 +1,642 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// SimpliciTI functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "vti_as.h" +#include "ports.h" +#include "timer.h" +#include "radio.h" + +// logic +#include "acceleration.h" +#include "rfsimpliciti.h" +#include "bluerobin.h" +#include "simpliciti.h" +#include "clock.h" +#include "date.h" +#include "alarm.h" +#include "temperature.h" +#include "vti_ps.h" +#include "altitude.h" + +// ************************************************************************************************* +// Prototypes section +void simpliciti_get_data_callback(void); +void start_simpliciti_tx_only(simpliciti_mode_t mode); +void start_simpliciti_sync(void); + +// ************************************************************************************************* +// Defines section + +// Each packet index requires 2 bytes, so we can have 9 packet indizes in 18 bytes usable payload +#define BM_SYNC_BURST_PACKETS_IN_DATA (9u) + +// ************************************************************************************************* +// Global Variable section +struct RFsmpl sRFsmpl; + +// flag contains status information, trigger to send data and trigger to exit SimpliciTI +unsigned char simpliciti_flag; + +// 4 data bytes to send +unsigned char simpliciti_data[SIMPLICITI_MAX_PAYLOAD_LENGTH]; + +// 4 byte device address overrides SimpliciTI end device address set in "smpl_config.dat" +unsigned char simpliciti_ed_address[4]; + +// Length of data +unsigned char simpliciti_payload_length; + +// 1 = send one or more reply packets, 0 = no need to reply +//unsigned char simpliciti_reply; +unsigned char simpliciti_reply_count; + +// 1 = send packets sequentially from burst_start to burst_end, 2 = send packets addressed by their +// index +u8 burst_mode; + +// Start and end index of packets to send out +u16 burst_start, burst_end; + +// Array containing requested packets +u16 burst_packet[BM_SYNC_BURST_PACKETS_IN_DATA]; + +// Current packet index +u8 burst_packet_index; + +// ************************************************************************************************* +// Extern section +extern void (*fptr_lcd_function_line1)(u8 line, u8 update); + +// ************************************************************************************************* +// @fn reset_rf +// @brief Reset SimpliciTI data. +// @param none +// @return none +// ************************************************************************************************* +void reset_rf(void) +{ + // No connection + sRFsmpl.mode = SIMPLICITI_OFF; + + // Standard packets are 4 bytes long + simpliciti_payload_length = 4; +} + +// ************************************************************************************************* +// @fn sx_rf +// @brief Start SimpliciTI. Button DOWN connects/disconnects to access point. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_rf(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Turn off the backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + + BUTTONS_IE &= ~BUTTON_BACKLIGHT_PIN; + + // Start SimpliciTI in tx only mode + start_simpliciti_tx_only(SIMPLICITI_ACCELERATION); + + BUTTONS_IE |= BUTTON_BACKLIGHT_PIN; + +} + +// ************************************************************************************************* +// @fn sx_ppt +// @brief Start SimpliciTI. Button DOWN connects/disconnects to access point. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_ppt(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Turn off the backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + + BUTTONS_IE &= ~BUTTON_BACKLIGHT_PIN; + + // Start SimpliciTI in tx only mode + start_simpliciti_tx_only(SIMPLICITI_BUTTONS); + + BUTTONS_IE |= BUTTON_BACKLIGHT_PIN; +} + +// ************************************************************************************************* +// @fn sx_sync +// @brief Start SimpliciTI. Button DOWN connects/disconnects to access point. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_sync(u8 line) +{ + // Exit if battery voltage is too low for radio operation + if (sys.flag.low_battery) + return; + + // Exit if BlueRobin stack is active + if (is_bluerobin()) + return; + + // Turn off the backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + + BUTTONS_IE &= ~BUTTON_BACKLIGHT_PIN; + + // Start SimpliciTI in sync mode + start_simpliciti_sync(); + + BUTTONS_IE |= BUTTON_BACKLIGHT_PIN; +} + +// ************************************************************************************************* +// @fn start_simpliciti_tx_only +// @brief Start SimpliciTI (tx only). +// @param simpliciti_state_t SIMPLICITI_ACCELERATION, SIMPLICITI_BUTTONS +// @return none +// ************************************************************************************************* +void start_simpliciti_tx_only(simpliciti_mode_t mode) +{ + // Display time in line 1 + clear_line(LINE1); + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + display_time(LINE1, DISPLAY_LINE_UPDATE_FULL); + + // Preset simpliciti_data with mode (key or mouse click) and clear other data bytes + if (mode == SIMPLICITI_ACCELERATION) + { + simpliciti_data[0] = SIMPLICITI_MOUSE_EVENTS; + } + else + { + simpliciti_data[0] = SIMPLICITI_KEY_EVENTS; + } + simpliciti_data[1] = 0; + simpliciti_data[2] = 0; + simpliciti_data[3] = 0; + + // Turn on beeper icon to show activity + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + + // Debounce button event + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + + // Prepare radio for RF communication + open_radio(); + + // Set SimpliciTI mode + sRFsmpl.mode = mode; + + // Set SimpliciTI timeout to save battery power + sRFsmpl.timeout = SIMPLICITI_TIMEOUT; + + // Start SimpliciTI stack. Try to link to access point. + // Exit with timeout or by a button DOWN press. + if (simpliciti_link()) + { + if (mode == SIMPLICITI_ACCELERATION) + { + // Start acceleration sensor + as_start(); + } + + // Enter TX only routine. This will transfer button events and/or acceleration data to + // access point. + simpliciti_main_tx_only(); + } + + // Set SimpliciTI state to OFF + sRFsmpl.mode = SIMPLICITI_OFF; + + // Stop acceleration sensor + as_stop(); + + // Powerdown radio + close_radio(); + + // Clear last button events + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + BUTTONS_IFG = 0x00; + button.all_flags = 0; + + // Clear icons + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); + + // Clean up line 1 + clear_line(LINE1); + display_time(LINE1, DISPLAY_LINE_CLEAR); + + // Force full display update + display.flag.full_update = 1; +} + +// ************************************************************************************************* +// @fn display_rf +// @brief SimpliciTI display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_rf(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " ACC", SEG_ON); + } +} + +// ************************************************************************************************* +// @fn display_ppt +// @brief SimpliciTI display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_ppt(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " PPT", SEG_ON); + } +} + +// ************************************************************************************************* +// @fn display_sync +// @brief SimpliciTI display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_sync(u8 line, u8 update) +{ + if (update == DISPLAY_LINE_UPDATE_FULL) + { + display_chars(LCD_SEG_L2_5_0, (u8 *) " SYNC", SEG_ON); + } +} + +// ************************************************************************************************* +// @fn is_rf +// @brief Returns TRUE if SimpliciTI receiver is connected. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_rf(void) +{ + return (sRFsmpl.mode != SIMPLICITI_OFF); +} + +// ************************************************************************************************* +// @fn simpliciti_get_ed_data_callback +// @brief Callback function to read end device data from acceleration sensor (if available) +// and trigger sending. Can be also be used to transmit other data at +// different packet rates. +// Please observe the applicable duty limit in the chosen ISM band. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_get_ed_data_callback(void) +{ + static u8 packet_counter = 0; + + if (sRFsmpl.mode == SIMPLICITI_ACCELERATION) + { + // Wait for next sample + Timer0_A4_Delay(CONV_MS_TO_TICKS(5)); + + // Read from sensor if DRDY pin indicates new data (set in PORT2 ISR) + if (request.flag.acceleration_measurement && ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN)) + { + // Clear flag + request.flag.acceleration_measurement = 0; + + // Get data from sensor + as_get_data(sAccel.xyz); + + // Transmit only every 3rd data set (= 33 packets / second) + if (packet_counter++ > 1) + { + // Reset counter + packet_counter = 0; + + // Store XYZ data in SimpliciTI variable + simpliciti_data[1] = sAccel.xyz[0]; + simpliciti_data[2] = sAccel.xyz[1]; + simpliciti_data[3] = sAccel.xyz[2]; + + // Trigger packet sending + simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; + } + } + } + else // transmit only button events + { + // New button event is stored in data + if ((packet_counter == 0) && (simpliciti_data[0] & 0xF0) != 0) + { + packet_counter = 5; + } + + // Send packet several times + if (packet_counter > 0) + { + // Clear button event when sending last packet + if (--packet_counter == 0) + { + simpliciti_data[0] &= ~0xF0; + } + else + { + // Trigger packet sending in regular intervals + Timer0_A4_Delay(CONV_MS_TO_TICKS(30)); + simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; + } + } + else + { + // Wait in LPM3 for next button press + _BIS_SR(LPM3_bits + GIE); + __no_operation(); + } + } + + // Update clock every 1/1 second + if (display.flag.update_time) + { + display_time(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + display.flag.update_time = 0; + + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; + } +} + +// ************************************************************************************************* +// @fn start_simpliciti_sync +// @brief Start SimpliciTI (sync mode). +// @param none +// @return none +// ************************************************************************************************* +void start_simpliciti_sync(void) +{ + // Clear LINE1 + clear_line(LINE1); + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + + // Stop acceleration sensor + as_stop(); + + // Get updated altitude + start_altitude_measurement(); + stop_altitude_measurement(); + + // Get updated temperature + temperature_measurement(FILTER_OFF); + + // Turn on beeper icon to show activity + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + + // Debounce button event + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + + // Prepare radio for RF communication + open_radio(); + + // Set SimpliciTI mode + sRFsmpl.mode = SIMPLICITI_SYNC; + + // Set SimpliciTI timeout to save battery power + sRFsmpl.timeout = SIMPLICITI_TIMEOUT; + + // Start SimpliciTI stack. Try to link to access point. + // Exit with timeout or by a button DOWN press. + if (simpliciti_link()) + { + // Enter sync routine. This will send ready-to-receive packets at regular intervals to the + // access point. + // The access point replies with a command (NOP if no other command is set) + simpliciti_main_sync(); + } + + // Set SimpliciTI state to OFF + sRFsmpl.mode = SIMPLICITI_OFF; + + // Powerdown radio + close_radio(); + + // Clear last button events + Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); + BUTTONS_IFG = 0x00; + button.all_flags = 0; + + // Clear icons + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); + + // Force full display update + display.flag.full_update = 1; +} + +// ************************************************************************************************* +// @fn simpliciti_sync_decode_ap_cmd_callback +// @brief For SYNC mode only: Decode command from access point and trigger actions. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_sync_decode_ap_cmd_callback(void) +{ + u8 i; + s16 t1, offset; + + // Default behaviour is to send no reply packets + simpliciti_reply_count = 0; + + switch (simpliciti_data[0]) + { + case SYNC_AP_CMD_NOP: + break; + + case SYNC_AP_CMD_GET_STATUS: // Send watch parameters + simpliciti_data[0] = SYNC_ED_TYPE_STATUS; + // Send single reply packet + simpliciti_reply_count = 1; + break; + + case SYNC_AP_CMD_SET_WATCH: // Set watch parameters + sys.flag.use_metric_units = (simpliciti_data[1] >> 7) & 0x01; + sTime.hour = simpliciti_data[1] & 0x7F; + sTime.minute = simpliciti_data[2]; + sTime.second = simpliciti_data[3]; + sDate.year = (simpliciti_data[4] << 8) + simpliciti_data[5]; + sDate.month = simpliciti_data[6]; + sDate.day = simpliciti_data[7]; + sAlarm.hour = simpliciti_data[8]; + sAlarm.minute = simpliciti_data[9]; + // Set temperature and temperature offset + t1 = (s16) ((simpliciti_data[10] << 8) + simpliciti_data[11]); + offset = t1 - (sTemp.degrees - sTemp.offset); + sTemp.offset = offset; + sTemp.degrees = t1; + // Set altitude + sAlt.altitude = (s16) ((simpliciti_data[12] << 8) + simpliciti_data[13]); + update_pressure_table(sAlt.altitude, sAlt.pressure, sAlt.temperature); + + display_chars(LCD_SEG_L2_5_0, (u8 *) " DONE", SEG_ON); + sRFsmpl.display_sync_done = 1; + break; + + case SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_1: + // Send sequential packets out in a burst + simpliciti_data[0] = SYNC_ED_TYPE_MEMORY; + // Get burst start and end packet + burst_start = (simpliciti_data[1] << 8) + simpliciti_data[2]; + burst_end = (simpliciti_data[3] << 8) + simpliciti_data[4]; + // Set burst mode + burst_mode = 1; + // Number of packets to send + simpliciti_reply_count = burst_end - burst_start; + break; + + case SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_2: + // Send specified packets out in a burst + simpliciti_data[0] = SYNC_ED_TYPE_MEMORY; + // Store the requested packets + for (i = 0; i < BM_SYNC_BURST_PACKETS_IN_DATA; i++) + { + burst_packet[i] = (simpliciti_data[i * 2 + 1] << 8) + simpliciti_data[i * 2 + 2]; + } + // Set burst mode + burst_mode = 2; + // Number of packets to send + simpliciti_reply_count = BM_SYNC_BURST_PACKETS_IN_DATA; + break; + + case SYNC_AP_CMD_ERASE_MEMORY: // Erase data logger memory + break; + + case SYNC_AP_CMD_EXIT: // Exit sync mode + simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; + break; + } +} + +// ************************************************************************************************* +// @fn simpliciti_sync_get_data_callback +// @brief For SYNC mode only: Access point has requested data. Copy this data into the TX +// buffer now. +// @param u16 index Index used for memory requests +// @return none +// ************************************************************************************************* +void simpliciti_sync_get_data_callback(unsigned int index) +{ + u8 i; + + // simpliciti_data[0] contains data type and needs to be returned to AP + switch (simpliciti_data[0]) + { + case SYNC_ED_TYPE_STATUS: // Assemble status packet + simpliciti_data[1] = (sys.flag.use_metric_units << 7) | (sTime.hour & 0x7F); + simpliciti_data[2] = sTime.minute; + simpliciti_data[3] = sTime.second; + simpliciti_data[4] = sDate.year >> 8; + simpliciti_data[5] = sDate.year & 0xFF; + simpliciti_data[6] = sDate.month; + simpliciti_data[7] = sDate.day; + simpliciti_data[8] = sAlarm.hour; + simpliciti_data[9] = sAlarm.minute; + simpliciti_data[10] = sTemp.degrees >> 8; + simpliciti_data[11] = sTemp.degrees & 0xFF; + simpliciti_data[12] = sAlt.altitude >> 8; + simpliciti_data[13] = sAlt.altitude & 0xFF; + break; + + case SYNC_ED_TYPE_MEMORY: + if (burst_mode == 1) + { + // Set burst packet address + simpliciti_data[1] = ((burst_start + index) >> 8) & 0xFF; + simpliciti_data[2] = (burst_start + index) & 0xFF; + // Assemble payload + for (i = 3; i < BM_SYNC_DATA_LENGTH; i++) + simpliciti_data[i] = index; + } + else if (burst_mode == 2) + { + // Set burst packet address + simpliciti_data[1] = (burst_packet[index] >> 8) & 0xFF; + simpliciti_data[2] = burst_packet[index] & 0xFF; + // Assemble payload + for (i = 3; i < BM_SYNC_DATA_LENGTH; i++) + simpliciti_data[i] = index; + } + break; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfsimpliciti.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfsimpliciti.h new file mode 100755 index 0000000..cd02f41 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/rfsimpliciti.h @@ -0,0 +1,98 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RFSIMPLICITI_H_ +#define RFSIMPLICITI_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section +extern void reset_rf(void); +extern void sx_rf(u8 line); +extern void sx_ppt(u8 line); +extern void sx_sync(u8 line); +extern void display_rf(u8 line, u8 update); +extern void display_ppt(u8 line, u8 update); +extern void display_sync(u8 line, u8 update); +extern void send_smpl_data(u16 data); +extern u8 is_rf(void); + +// ************************************************************************************************* +// Defines section + +// SimpliciTI connection states +typedef enum +{ + SIMPLICITI_OFF = 0, // Not connected + SIMPLICITI_ACCELERATION, // Transmitting acceleration data and button events + SIMPLICITI_BUTTONS, // Transmitting button events + SIMPLICITI_SYNC // Syncing +} simpliciti_mode_t; + +// Stop SimpliciTI transmission after 60 minutes to save power +#define SIMPLICITI_TIMEOUT (60 * 60u) + +// Button flags for SimpliciTI data +#define SIMPLICITI_BUTTON_STAR (0x10) +#define SIMPLICITI_BUTTON_NUM (0x20) +#define SIMPLICITI_BUTTON_UP (0x30) + +// SimpliciTI mode flag +#define SIMPLICITI_MOUSE_EVENTS (0x01) +#define SIMPLICITI_KEY_EVENTS (0x02) + +// ************************************************************************************************* +// Global Variable section +struct RFsmpl +{ + // SIMPLICITI_OFF, SIMPLICITI_ACCELERATION, SIMPLICITI_BUTTONS + simpliciti_mode_t mode; + + // Timeout until SimpliciTI transmission is automatically stopped + u16 timeout; + + // Variable to display + u8 display_sync_done; +}; +extern struct RFsmpl sRFsmpl; + +extern unsigned char simpliciti_flag; + +// ************************************************************************************************* +// Extern section + +#endif /*RFSIMPLICITI_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/stopwatch.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/stopwatch.c new file mode 100755 index 0000000..18d112b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/stopwatch.c @@ -0,0 +1,444 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Stopwatch functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" +#include + +// driver +#include "stopwatch.h" +#include "ports.h" +#include "display.h" +#include "timer.h" + +// logic +#include "menu.h" + +// ************************************************************************************************* +// Prototypes section +void start_stopwatch(void); +void stop_stopwatch(void); +void reset_stopwatch(void); +void stopwatch_tick(void); +void update_stopwatch_timer(void); +void mx_stopwatch(u8 line); +void sx_stopwatch(u8 line); +void display_stopwatch(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct stopwatch sStopwatch; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn update_stopwatch_timer +// @brief Set new compare time for next 1/1Hz or 1/100Hz interrupt. Takes care for exact 1 +// second timing. +// @param ticks (1 tick = 1/32768 sec) +// @return none +// ************************************************************************************************* +void update_stopwatch_timer(void) +{ + u16 value; + + // Load CCR register with next capture time + if (sStopwatch.viewStyle == DISPLAY_DEFAULT_VIEW) + { + // Timer interrupts occur every 32768/100 = 328 ACLK + // --> stopwatch runs too slow (1 sec nominal != 100 interupts * 328 ACLK = 32800 ACLK = + // 1.00098 sec) + // --> ideally correct timer value every 10 ticks by (32768 - 32800)/10 = 3.2 + // --> correct timer value every 10Hz by 3, + // --> correct timer value every 1Hz correct by 5 + value = TA0CCR2 + STOPWATCH_100HZ_TICK; + + if (sStopwatch.swtIs1Hz) + { + value -= 5; + sStopwatch.swtIs1Hz = 0; + sStopwatch.swtIs10Hz = 0; + } + else if (sStopwatch.swtIs10Hz) + { + value -= 3; + sStopwatch.swtIs10Hz = 0; + } + } + else // Alternative view + { + // Timer interrupts occur every 32768/1 = 32768 ACLK + value = TA0CCR2; + value += STOPWATCH_1HZ_TICK; + } + + // Update CCR + TA0CCR2 = value; +} + +// ************************************************************************************************* +// @fn stopwatch_tick +// @brief Called by 1/100Hz interrupt handler. +// Increases stopwatch counter and triggers display update. +// @param none +// @return none +// ************************************************************************************************* +void stopwatch_tick(void) +{ + static u8 delay = 0; + + // Default view (< 20 minutes): display and count MM:SS:hh + if (sStopwatch.viewStyle == DISPLAY_DEFAULT_VIEW) + { + // Add 1/100 sec + sStopwatch.time[7]++; + + // Draw flag minimizes display update activity + // + // swt.drawFlag = 1: second L + // swt.drawFlag = 2: second H/L + // swt.drawFlag = 3: minutes L, second H/L + // swt.drawFlag = 4: minutes H/L, second H/L + // swt.drawFlag = 5: hours L, minutes H/L, second H/L + // swt.drawFlag = 6: hours H/L, minutes H/L, second H/L + // swt.drawFlag = 7: 1/10 sec, 1/100 sec + // swt.drawFlag = 8: 1/100 sec (every 17/100 sec to reduce display draw activity) + if (delay++ > 17) + { + sStopwatch.drawFlag = 8; + delay = 0; + } + + // Add 1/10 sec + if (sStopwatch.time[7] == 0x3A) + { + sStopwatch.time[7] = '0'; + sStopwatch.time[6]++; + + // 1/10Hz trigger + sStopwatch.swtIs10Hz = 1; + + // Update draw flag + sStopwatch.drawFlag = 7; + } + } + else // Alternative view (20 minutes .. 20 hours): display and count + // HH:MM:SS + { + // Just add 1 second + sStopwatch.time[6] = 0x3A; + } + + // Second overflow? + if (sStopwatch.time[6] == 0x3A) + { + // Reset draw flag + sStopwatch.drawFlag = 1; + + // 1Hz trigger + sStopwatch.swtIs1Hz = 1; + + // Add data + sStopwatch.time[6] = '0'; + sStopwatch.time[5]++; // second L (0 - 9) + if (sStopwatch.time[5] == 0x3A) + { + sStopwatch.drawFlag++; // 2 + sStopwatch.time[5] = '0'; + sStopwatch.time[4]++; // second H (0 - 5) + if (sStopwatch.time[4] == '6') + { + sStopwatch.drawFlag++; // 3 + sStopwatch.time[4] = '0'; + sStopwatch.time[3]++; // minutes L (0 - 9) + if (sStopwatch.time[3] == 0x3A) + { + sStopwatch.drawFlag++; // 4 + sStopwatch.time[3] = '0'; + sStopwatch.time[2]++; // minutes H (0 - 5) + if (sStopwatch.time[2] == '2') + { + // SWT display changes from MM:SS:hh to HH:MM:SS when reaching 20 minutes + sStopwatch.viewStyle = DISPLAY_ALTERNATIVE_VIEW; + display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_FULL); + + } + else if (sStopwatch.time[2] == '6') + { + sStopwatch.drawFlag++; // 5 + sStopwatch.time[2] = '0'; + sStopwatch.time[1]++; // hours L (0-9) + + if (sStopwatch.time[1] == 0x3A) + { + sStopwatch.drawFlag++; // 6 + sStopwatch.time[1] = '0'; + sStopwatch.time[0]++; // hours H (0-1) + + if (sStopwatch.time[0] == '2') + { + // When reaching 20 hours, start over + reset_stopwatch(); + sStopwatch.state = STOPWATCH_RUN; + display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_FULL); + } + } + } + } + } + } + } + + // Always set display update flag + display.flag.update_stopwatch = 1; +} + +// ************************************************************************************************* +// @fn reset_stopwatch +// @brief Clears stopwatch counter and sets stopwatch state to off. +// @param none +// @return none +// ************************************************************************************************* +void reset_stopwatch(void) +{ + // Clear counter + memcpy(sStopwatch.time, "00000000", sizeof(sStopwatch.time)); + + // Clear trigger + sStopwatch.swtIs10Hz = 0; // 1/10Hz trigger + sStopwatch.swtIs1Hz = 0; // 1Hz trigger + + // Init stopwatch state 'Off' + sStopwatch.state = STOPWATCH_STOP; + + // Default display style is MM:SS:HH + sStopwatch.viewStyle = DISPLAY_DEFAULT_VIEW; +} + +// ************************************************************************************************* +// @fn is_stopwatch +// @brief Is stopwatch operating and visible? +// @param none +// @return 1=STOPWATCH_RUN, 0=other states +// ************************************************************************************************* +u8 is_stopwatch(void) +{ + return ((sStopwatch.state == STOPWATCH_RUN) && (ptrMenu_L2 == &menu_L2_Stopwatch)); +} + +// ************************************************************************************************* +// @fn start_stopwatch +// @brief Starts stopwatch timer interrupt and sets stopwatch state to on. +// @param none +// @return none +// ************************************************************************************************* +void start_stopwatch(void) +{ + // Set stopwatch run flag + sStopwatch.state = STOPWATCH_RUN; + + // Init CCR register with current time + TA0CCR2 = TA0R; + + // Load CCR register with next capture time + update_stopwatch_timer(); + + // Reset IRQ flag + TA0CCTL2 &= ~CCIFG; + + // Enable timer interrupt + TA0CCTL2 |= CCIE; + + // Set stopwatch icon + display_symbol(LCD_ICON_STOPWATCH, SEG_ON); +} + +// ************************************************************************************************* +// @fn stop_stopwatch +// @brief Stops stopwatch timer interrupt and sets stopwatch state to off. +// Does not reset stopwatch count. +// @param none +// @return none +// ************************************************************************************************* +void stop_stopwatch(void) +{ + // Clear timer interrupt enable + TA0CCTL2 &= ~CCIE; + + // Clear stopwatch run flag + sStopwatch.state = STOPWATCH_STOP; + + // Clear stopwatch icon + display_symbol(LCD_ICON_STOPWATCH, SEG_OFF); + + // Call draw routine immediately + display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_FULL); +} + +// ************************************************************************************************* +// @fn mx_stopwatch +// @brief Stopwatch set routine. Mx stops stopwatch and resets count. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void mx_stopwatch(u8 line) +{ + // Stop stopwatch + stop_stopwatch(); + + // Reset stopwatch count + reset_stopwatch(); + + // Display "00:00:00" + display_stopwatch(line, DISPLAY_LINE_UPDATE_FULL); +} + +// ************************************************************************************************* +// @fn sx_stopwatch +// @brief Stopwatch direct function. Button DOWN starts/stops stopwatch, but does not reset +// count. +// @param u8 line LINE2 +// @return none +// ************************************************************************************************* +void sx_stopwatch(u8 line) +{ + // DOWN: RUN, STOP + if (button.flag.down) + { + if (sStopwatch.state == STOPWATCH_STOP) + { + // (Re)start stopwatch + start_stopwatch(); + } + else + { + // Stop stopwatch + stop_stopwatch(); + } + + } +} + +// ************************************************************************************************* +// @fn display_stopwatch +// @brief Stopwatch user routine. Sx starts/stops stopwatch, but does not reset count. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_PARTIAL, +// DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +void display_stopwatch(u8 line, u8 update) +{ + // Partial line update only + if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + if (display.flag.update_stopwatch) + { + if (sStopwatch.viewStyle == DISPLAY_DEFAULT_VIEW) + { + // Display MM:SS:hh + + // Check draw flag to minimize workload + if (sStopwatch.drawFlag != 0) + { + switch (sStopwatch.drawFlag) + { + case 4: + display_char(LCD_SEG_L2_5, sStopwatch.time[2], SEG_ON); + case 3: + display_char(LCD_SEG_L2_4, sStopwatch.time[3], SEG_ON); + case 2: + display_char(LCD_SEG_L2_3, sStopwatch.time[4], SEG_ON); + case 1: + display_char(LCD_SEG_L2_2, sStopwatch.time[5], SEG_ON); + case 7: + display_char(LCD_SEG_L2_1, sStopwatch.time[6], SEG_ON); + case 8: + display_char(LCD_SEG_L2_0, sStopwatch.time[7], SEG_ON); + } + } + } + else // DISPLAY_ALTERNATIVE_VIEW + { + // Display HH:MM:SS + switch (sStopwatch.drawFlag) + { + case 6: + display_char(LCD_SEG_L2_5, sStopwatch.time[0], SEG_ON); + case 5: + display_char(LCD_SEG_L2_4, sStopwatch.time[1], SEG_ON); + case 4: + display_char(LCD_SEG_L2_3, sStopwatch.time[2], SEG_ON); + case 3: + display_char(LCD_SEG_L2_2, sStopwatch.time[3], SEG_ON); + case 2: + display_char(LCD_SEG_L2_1, sStopwatch.time[4], SEG_ON); + case 1: + display_char(LCD_SEG_L2_0, sStopwatch.time[5], SEG_ON); + } + } + } + } + // Redraw whole line + else if (update == DISPLAY_LINE_UPDATE_FULL) + { + if (sStopwatch.viewStyle == DISPLAY_DEFAULT_VIEW) + { + // Display MM:SS:hh + display_chars(LCD_SEG_L2_5_0, sStopwatch.time + 2, SEG_ON); + } + else // DISPLAY_ALTERNATIVE_VIEW + { + // Display HH:MM:SS + display_chars(LCD_SEG_L2_5_0, sStopwatch.time, SEG_ON); + } + display_symbol(LCD_SEG_L2_COL1, SEG_ON); + display_symbol(LCD_SEG_L2_COL0, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Clean up symbols when leaving function + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/stopwatch.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/stopwatch.h new file mode 100755 index 0000000..3676491 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/stopwatch.h @@ -0,0 +1,89 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef STOPWATCH_H_ +#define STOPWATCH_H_ + +// ************************************************************************************************* +// Include section +#include + +// ************************************************************************************************* +// Prototypes section +extern void start_stopwatch(void); +extern void stop_stopwatch(void); +extern void reset_stopwatch(void); +extern u8 is_stopwatch(void); +extern void stopwatch_tick(void); +extern void update_stopwatch_timer(void); +extern void mx_stopwatch(u8 line); +extern void sx_stopwatch(u8 line); +extern void display_stopwatch(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section +#define STOPWATCH_1HZ_TICK (32768 / 1) +#define STOPWATCH_100HZ_TICK (32768 / 100) +#define STOPWATCH_STOP (0u) +#define STOPWATCH_RUN (1u) +#define STOPWATCH_HIDE (2u) + +// ************************************************************************************************* +// Global Variable section +struct stopwatch +{ + u8 state; + u8 drawFlag; + u8 swtIs1Hz; + u8 swtIs10Hz; + + u8 time[8]; // time[0] hour H + // time[1] hour L + // time[2] minute H + // time[3] minute L + // time[4] second H + // time[5] second L + // time[6] 1/10 sec + // time[7] 1/100 sec + + // Display style + u8 viewStyle; +}; +extern struct stopwatch sStopwatch; + +// ************************************************************************************************* +// Extern section + +#endif /*STOPWATCH_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/temperature.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/temperature.c new file mode 100755 index 0000000..8da9472 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/temperature.c @@ -0,0 +1,332 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Temperature measurement functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "temperature.h" +#include "ports.h" +#include "display.h" +#include "adc12.h" +#include "timer.h" + +// logic +#include "user.h" + +// ************************************************************************************************* +// Prototypes section +u8 is_temp_measurement(void); +s16 convert_C_to_F(s16 value); +s16 convert_F_to_C(s16 value); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct temp sTemp; + +// ************************************************************************************************* +// Extern section + +// ************************************************************************************************* +// @fn reset_temp_measurement +// @brief Reset temperature measurement module. +// @param none +// @return none +// ************************************************************************************************* +void reset_temp_measurement(void) +{ + // Set flag to off + sTemp.state = MENU_ITEM_NOT_VISIBLE; + + // Perform one temperature measurements with disabled filter + temperature_measurement(FILTER_OFF); +} + +// ************************************************************************************************* +// @fn temperature_measurement +// @brief Init ADC12. Do single conversion of temperature sensor voltage. Turn off ADC12. +// @param none +// @return none +// ************************************************************************************************* +void temperature_measurement(u8 filter) +{ + u16 adc_result; + volatile s32 temperature; + + // Convert internal temperature diode voltage + adc_result = adc12_single_conversion(REFVSEL_0, ADC12SHT0_8, ADC12INCH_10); + + // Convert ADC value to "xx.x °C" + // Temperature in Celsius + // ((A10/4096*1500mV) - 680mV)*(1/2.25mV) = (A10/4096*667) - 302 + // = (A10 - 1855) * (667 / 4096) + temperature = (((s32) ((s32) adc_result - 1855)) * 667 * 10) / 4096; + + // Add temperature offset + temperature += sTemp.offset; + + // Store measured temperature + if (filter == FILTER_ON) + { + // Change temperature in 0.1° steps towards measured value + if (temperature > sTemp.degrees) + sTemp.degrees += 1; + else if (temperature < sTemp.degrees) + sTemp.degrees -= 1; + } + else + { + // Override filter + sTemp.degrees = (s16) temperature; + } + + // New data is available --> do display update + display.flag.update_temperature = 1; +} + +// ************************************************************************************************* +// @fn convert_C_to_F +// @brief Convert °C to °F +// @param s16 value Temperature in °C +// @return s16 Temperature in °F +// ************************************************************************************************* +s16 convert_C_to_F(s16 value) +{ + s16 DegF; + + // Celsius in Fahrenheit = (( TCelsius × 9 ) / 5 ) + 32 + DegF = ((value * 9 * 10) / 5 / 10) + 32 * 10; + + return (DegF); +} + +// ************************************************************************************************* +// @fn convert_F_to_C +// @brief Convert °F to °C +// @param s16 value Temperature in 2.1 °F +// @return s16 Temperature in 2.1 °C +// ************************************************************************************************* +s16 convert_F_to_C(s16 value) +{ + s16 DegC; + + // TCelsius =( TFahrenheit - 32 ) × 5 / 9 + DegC = (((value - 320) * 5)) / 9; + + return (DegC); +} + +// ************************************************************************************************* +// @fn is_temp_measurement +// @brief Returns TRUE if temperature measurement is enabled. +// @param none +// @return u8 +// ************************************************************************************************* +u8 is_temp_measurement(void) +{ + return (sTemp.state == MENU_ITEM_VISIBLE); +} + +// ************************************************************************************************* +// @fn mx_temperature +// @brief Mx button handler to set the temperature offset. +// @param u8 line LINE1 +// @return none +// ************************************************************************************************* +void mx_temperature(u8 line) +{ + s32 temperature; + s16 temperature0; + volatile s16 temperature1; + volatile s16 offset; + + // Clear display + clear_display_all(); + + // When using English units, convert internal °C to °F before handing over value to set_value + // function + if (!sys.flag.use_metric_units) + { + // Convert global variable to local variable + temperature = convert_C_to_F(sTemp.degrees); + temperature0 = sTemp.degrees; + } + else + { + // Convert global variable to local variable + temperature = sTemp.degrees; + temperature0 = temperature; + } + + // Loop values until all are set or user breaks set + while (1) + { + // Idle timeout: exit without saving + if (sys.flag.idle_timeout) + break; + + // Button STAR (short): save, then exit + if (button.flag.star) + { + // For English units, convert set °F to °C + if (!sys.flag.use_metric_units) + { + temperature1 = convert_F_to_C(temperature); + } + else + { + temperature1 = temperature; + } + + // New offset is difference between old and new value + offset = temperature1 - temperature0; + sTemp.offset += offset; + + // Force filter to new value + sTemp.degrees = temperature1; + + // Set display update flag + display.flag.line1_full_update = 1; + + break; + } + + // Display °C or °F depending on unit system + if (sys.flag.use_metric_units) + display_char(LCD_SEG_L1_0, 'C', SEG_ON); + else + display_char(LCD_SEG_L1_0, 'F', SEG_ON); + display_symbol(LCD_SEG_L1_DP1, SEG_ON); + display_symbol(LCD_UNIT_L1_DEGREE, SEG_ON); + + // Set current temperature - offset is set when leaving function + set_value(&temperature, 3, 1, -999, 999, SETVALUE_DISPLAY_VALUE + SETVALUE_DISPLAY_ARROWS, + LCD_SEG_L1_3_1, + display_value); + } + + // Clear button flags + button.all_flags = 0; +} + +// ************************************************************************************************* +// @fn display_temperature +// @brief Common display routine for metric and English units. +// @param u8 line LINE1 +// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR +// @return none +// ************************************************************************************************* +void display_temperature(u8 line, u8 update) +{ + u8 *str; + s16 temperature; + + // Redraw whole screen + if (update == DISPLAY_LINE_UPDATE_FULL) + { + // Menu item is visible + sTemp.state = MENU_ITEM_VISIBLE; + + // Display °C / °F + display_symbol(LCD_SEG_L1_DP1, SEG_ON); + display_symbol(LCD_UNIT_L1_DEGREE, SEG_ON); + if (sys.flag.use_metric_units) + display_char(LCD_SEG_L1_0, 'C', SEG_ON); + else + display_char(LCD_SEG_L1_0, 'F', SEG_ON); + + // Perform one temperature measurement with disabled filter + temperature_measurement(FILTER_OFF); + + // Display temperature + display_temperature(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + else if (update == DISPLAY_LINE_UPDATE_PARTIAL) + { + // When using English units, convert °C to °F (temp*1.8+32) + if (!sys.flag.use_metric_units) + { + temperature = convert_C_to_F(sTemp.degrees); + } + else + { + temperature = sTemp.degrees; + } + + // Indicate temperature sign through arrow up/down icon + if (temperature < 0) + { + // Convert negative to positive number + temperature = ~temperature; + temperature += 1; + + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + } + else // Temperature is >= 0 + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + } + + // Limit min/max temperature to +/- 99.9 °C / °F + if (temperature > 999) + temperature = 999; + + // Display result in xx.x format + str = int_to_array(temperature, 3, 1); + display_chars(LCD_SEG_L1_3_1, str, SEG_ON); + } + else if (update == DISPLAY_LINE_CLEAR) + { + // Menu item is not visible + sTemp.state = MENU_ITEM_NOT_VISIBLE; + + // Clean up function-specific segments before leaving function + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + display_symbol(LCD_UNIT_L1_DEGREE, SEG_OFF); + display_symbol(LCD_SEG_L1_DP1, SEG_OFF); + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/temperature.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/temperature.h new file mode 100755 index 0000000..68a2138 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/temperature.h @@ -0,0 +1,70 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef TEMPERATURE_H_ +#define TEMPERATURE_H_ + +// ************************************************************************************************* +// Include section + +// ************************************************************************************************* +// Prototypes section + +// internal functions +extern void reset_temp_measurement(void); +extern u8 is_temp_measurement(void); +extern void temperature_measurement(u8 filter); + +// menu functions +extern void mx_temperature(u8 line); +extern void display_temperature(u8 line, u8 update); + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section +struct temp +{ + menu_t state; // MENU_ITEM_NOT_VISIBLE, MENU_ITEM_VISIBLE + s16 degrees; // Temperature (°C) in 2.1 format + s16 offset; // User set calibration value (°C) in 2.1 format +}; +extern struct temp sTemp; + +// ************************************************************************************************* +// Extern section + +#endif /*TEMPERATURE_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/test.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/test.c new file mode 100755 index 0000000..3ef6dcd --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/test.c @@ -0,0 +1,296 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Test functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "vti_as.h" +#include "vti_ps.h" +#include "ports.h" +#include "timer.h" + +// logic +#include "acceleration.h" +#include "altitude.h" +#include "temperature.h" +#include "bluerobin.h" +#include "test.h" + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Prototype section + +// ************************************************************************************************* +// @fn test_mode +// @brief Manual test mode. Activated by holding buttons STAR and UP simultaneously. +// Cancelled by any other button press. +// @param none +// @return none +// ************************************************************************************************* +void test_mode(void) +{ + u8 test_step, start_next_test; + u8 *str; + u8 i; + + // Disable timer - no need for a clock tick + Timer0_Stop(); + + // Disable LCD charge pump while in standby mode + // This reduces current consumption by ca. 5µA to ca. 10µA + LCDBVCTL = 0; + + // Show welcome screen + display_chars(LCD_SEG_L1_3_0, (u8 *) "0430", SEG_ON); + display_chars(LCD_SEG_L2_4_0, (u8 *) "CC430", SEG_ON); + display_symbol(LCD_SEG_L1_COL, SEG_ON); + display_symbol(LCD_ICON_HEART, SEG_ON); + display_symbol(LCD_ICON_STOPWATCH, SEG_ON); + display_symbol(LCD_ICON_RECORD, SEG_ON); + display_symbol(LCD_ICON_ALARM, SEG_ON); + display_symbol(LCD_ICON_BEEPER1, SEG_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON); + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + display_symbol(LCD_SYMB_AM, SEG_ON); + + // Hold watchdog + WDTCTL = WDTPW + WDTHOLD; + + // Wait for button press + _BIS_SR(LPM3_bits + GIE); + __no_operation(); + + // Clear display + display_all_off(); + +#ifdef USE_LCD_CHARGE_PUMP + // Charge pump voltage generated internally, internal bias (V2-V4) generation + // This ensures that the contrast and LCD control is constant for the whole battery lifetime + LCDBVCTL = LCDCPEN | VLCD_2_72; +#endif + + // Renenable timer + Timer0_Start(); + + // Debounce button press + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + + while (1) + { + // Check button event + if (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED) + { + // Start with test #0 + test_step = 0; + start_next_test = 1; + while (1) + { + if (start_next_test) + { + // Clean up previous test display + display_all_off(); + + start_next_test = 0; + + switch (test_step) + { + case 0: // All LCD segments on + display_all_on(); + // Wait until buttons are off + while (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED) ; + break; + case 1: // Altitude measurement + display_altitude(LINE1, DISPLAY_LINE_UPDATE_FULL); + for (i = 0; i < 2; i++) + { + while ((PS_INT_IN & PS_INT_PIN) == 0) ; + do_altitude_measurement(FILTER_OFF); + display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + stop_altitude_measurement(); + break; + case 2: // Temperature measurement + display_temperature(LINE1, DISPLAY_LINE_UPDATE_FULL); + for (i = 0; i < 4; i++) + { + Timer0_A4_Delay(CONV_MS_TO_TICKS(250)); + temperature_measurement(FILTER_OFF); + display_temperature(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + break; + case 3: // Acceleration measurement + as_start(); + for (i = 0; i < 4; i++) + { + Timer0_A4_Delay(CONV_MS_TO_TICKS(250)); + as_get_data(sAccel.xyz); + str = int_to_array(sAccel.xyz[0], 3, 0); + display_chars(LCD_SEG_L1_2_0, str, SEG_ON); + str = int_to_array(sAccel.xyz[2], 3, 0); + display_chars(LCD_SEG_L2_2_0, str, SEG_ON); + } + as_stop(); + break; + case 4: // BlueRobin test + button.flag.up = 1; + sx_bluerobin(LINE1); + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + get_bluerobin_data(); + display_heartrate(LINE1, DISPLAY_LINE_UPDATE_FULL); + stop_bluerobin(); + break; + } + + // Debounce button + Timer0_A4_Delay(CONV_MS_TO_TICKS(200)); + } + + // Check button event + if (BUTTON_STAR_IS_PRESSED) + { + test_step = 1; + start_next_test = 1; + } + else if (BUTTON_NUM_IS_PRESSED) + { + test_step = 2; + start_next_test = 1; + } + else if (BUTTON_UP_IS_PRESSED) + { + test_step = 3; + start_next_test = 1; + } + else if (BUTTON_DOWN_IS_PRESSED) + { + test_step = 4; + start_next_test = 1; + } + else if (BUTTON_BACKLIGHT_IS_PRESSED) + { + // Wait until button has been released (avoid restart) + while (BUTTON_BACKLIGHT_IS_PRESSED) ; + + // Disable LCD and LCD charge pump + LCDBCTL0 &= ~BIT0; + LCDBVCTL = 0; + + // Debounce button press + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); + + // Disable timer - no need for a clock tick + Timer0_Stop(); + + // Hold watchdog + WDTCTL = WDTPW + WDTHOLD; + + // Sleep until button is pressed (ca. 4µA current consumption) + _BIS_SR(LPM4_bits + GIE); + __no_operation(); + + // Force watchdog reset for a clean restart + WDTCTL = 1; + } + +#ifdef USE_WATCHDOG + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; +#endif + // To LPM3 + _BIS_SR(LPM3_bits + GIE); + __no_operation(); + } + } + else + { + // Debounce button + Timer0_A4_Delay(CONV_MS_TO_TICKS(100)); + button.all_flags = 0; + + // Turn off backlight + P2OUT &= ~BUTTON_BACKLIGHT_PIN; + P2DIR &= ~BUTTON_BACKLIGHT_PIN; + break; + } + } +} + +// ************************************************************************************************* +// @fn display_all_on +// @brief Turns on all LCD segments +// @param none +// @return none +// ************************************************************************************************* +void display_all_on(void) +{ + u8 *lcdptr = (u8 *) 0x0A20; + u8 i; + + for (i = 1; i <= 12; i++) + { + *lcdptr = 0xFF; + lcdptr++; + } +} + +// ************************************************************************************************* +// @fn display_all_off +// @brief Turns off all LCD segments +// @param none +// @return none +// ************************************************************************************************* +void display_all_off(void) +{ + u8 *lcdptr = (u8 *) 0x0A20; + u8 i; + + for (i = 1; i <= 12; i++) + { + *lcdptr = 0x00; + lcdptr++; + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/test.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/test.h new file mode 100755 index 0000000..469426e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/test.h @@ -0,0 +1,47 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Test functions. +// ************************************************************************************************* + +#ifndef TEST_H_ +#define TEST_H_ + +// ************************************************************************************************* +// Extern section +extern void test_mode(void); +extern void display_all_on(void); +extern void display_all_off(void); + +#endif /*TEST_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/user.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/user.c new file mode 100755 index 0000000..3207cbf --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/user.c @@ -0,0 +1,291 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Several user functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" + +// driver +#include "display.h" +#include "buzzer.h" +#include "ports.h" + +// logic +#include "menu.h" +#include "date.h" +#include "clock.h" +#include "user.h" +#include "stopwatch.h" + +// ************************************************************************************************* +// Prototypes section + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// ************************************************************************************************* +// Extern section +extern void idle_loop(void); + +// ************************************************************************************************* +// @fn dummy +// @brief Dummy direct function. +// @param u8 line LINE1, LINE2 +// @return none +// ************************************************************************************************* +void dummy(u8 line) +{ +} + +// ************************************************************************************************* +// @fn set_value +// @brief Generic value setting routine +// @param s32 * value Pointer to value to +// set +// u8digits +// Number of digits +// u8 blanks +// Number of whitespaces before first valid +// digit +// s32 limitLow Lower limit +// of value +// s32 limitHigh Upper limit +// of value +// u16 mode +// u8 segments +// Segments where value should be drawn +// fptr_setValue_display_function1 Value-specific display +// routine +// @return none +// ************************************************************************************************* +void set_value(s32 * value, u8 digits, u8 blanks, s32 limitLow, s32 limitHigh, u16 mode, + u8 segments, + void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, + u8 blanks)) +{ + u8 update; + s16 stepValue = 1; + u8 doRound = 0; + u8 stopwatch_state; + u32 val; + + // Clear button flags + button.all_flags = 0; + + // Clear blink memory + clear_blink_mem(); + + // For safety only - buzzer on/off and button_repeat share same IRQ + stop_buzzer(); + + // Disable stopwatch display update while function is active + stopwatch_state = sStopwatch.state; + sStopwatch.state = STOPWATCH_HIDE; + + // Init step size and repeat counter + sButton.repeats = 0; + + // Initial display update + update = 1; + + // Turn on 200ms button repeat function + button_repeat_on(200); + + // Start blinking with with 2Hz + set_blink_rate(BIT6 + BIT5); + + // Value set loop + while (1) + { + // Idle timeout: exit function + if (sys.flag.idle_timeout) + break; + + // Button STAR (short) button: exit function + if (button.flag.star) + break; + + // NUM button: exit function and goto to next value (if available) + if (button.flag.num) + { + if ((mode & SETVALUE_NEXT_VALUE) == SETVALUE_NEXT_VALUE) + break; + } + + // UP button: increase value + if (button.flag.up) + { + // Increase value + *value = *value + stepValue; + + // Check value limits + if (*value > limitHigh) + { + // Check if value can roll over, else stick to limit + if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) + *value = limitLow; + else + *value = limitHigh; + + // Reset step size to default + stepValue = 1; + } + + // Trigger display update + update = 1; + + // Clear button flag + button.flag.up = 0; + } + + // DOWN button: decrease value + if (button.flag.down) + { + // Decrease value + *value = *value - stepValue; + + // Check value limits + if (*value < limitLow) + { + // Check if value can roll over, else stick to limit + if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) + *value = limitHigh; + else + *value = limitLow; + + // Reset step size to default + stepValue = 1; + } + + // Trigger display update + update = 1; + + // Clear button flag + button.flag.down = 0; + } + + // When fast mode is enabled, increase step size if Sx button is continuously + if ((mode & SETVALUE_FAST_MODE) == SETVALUE_FAST_MODE) + { + switch (sButton.repeats) + { + case 0: + stepValue = 1; + doRound = 0; + break; + case 10: + case -10: + stepValue = 10; + doRound = 1; + break; + case 20: + case -20: + stepValue = 100; + doRound = 1; + break; + case 30: + case -30: + stepValue = 1000; + doRound = 1; + break; + } + + // Round value to avoid odd numbers on display + if (stepValue != 1 && doRound == 1) + { + *value -= *value % stepValue; + doRound = 0; + } + } + + // Update display when there is new data + if (update) + { + // Display up or down arrow according to sign of value + if ((mode & SETVALUE_DISPLAY_ARROWS) == SETVALUE_DISPLAY_ARROWS) + { + if (*value >= 0) + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + val = *value; + } + else + { + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); + val = *value * (-1); + } + } + else + { + val = *value; + } + + // Display function can either display value directly, modify value before displaying + // or display a string referenced by the value + fptr_setValue_display_function1(segments, val, digits, blanks); + + // Clear update flag + update = 0; + } + + // Call idle loop to serve background tasks + idle_loop(); + + } + + // Clear up and down arrows + display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); + display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); + + // Set blinking rate to 1Hz and stop + set_blink_rate(BIT7 + BIT6 + BIT5); + clear_blink_mem(); + + // Turn off button repeat function + button_repeat_off(); + + // Enable stopwatch display updates again + sStopwatch.state = stopwatch_state; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/user.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/user.h new file mode 100755 index 0000000..f48cea4 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/logic/user.h @@ -0,0 +1,59 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef USER_H_ +#define USER_H_ + +// ************************************************************************************************* +// Defines section +#define SETVALUE_ROLLOVER_VALUE BIT0 +#define SETVALUE_DISPLAY_VALUE BIT1 +#define SETVALUE_DISPLAY_ARROWS BIT2 +#define SETVALUE_DISPLAY_SELECTION BIT3 +#define SETVALUE_FAST_MODE BIT4 +#define SETVALUE_NEXT_VALUE BIT5 + +// ************************************************************************************************* +// Prototypes section +extern u8 *select_view_style(u8 line, u8 * view1, u8 * view2); + +extern void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, u8 blanks); +extern void set_value(s32 * value, u8 digits, u8 blanks, s32 limitLow, s32 limitHigh, u16 mode, + u8 segments, + void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, + u8 blanks)); +extern void dummy(u8 line); + +#endif /*USER_H_ */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/main.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/main.c new file mode 100755 index 0000000..cc1d207 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/main.c @@ -0,0 +1,743 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//****************************************************************************** +// eZ430-Chronos +// +// Description: This is the standard software for the eZ430-Chronos +// +// P.Francisco +// Version 1.6 +// Texas Instruments, Inc +// January 2011 +// Known working builds: +// IAR Embedded Workbench (Version: 5.20.2) +// Code Composer Studio (Version 4.2.0.10012) +//****************************************************************************** +//Change Log (More detailed information can be found in change_record.txt): +//****************************************************************************** +//Version: 1.6 +//Comments: Several bugs were fixed. +// LCD shows "done" after successfully received data +// rfBSL requires two button presses in order to update watch +// New method detects a long button press +// Removed file display1.c. The content is now in display.c +// Backlight of Chronos stays on for 3 sec after backlight button was pushed. +// After timeout the accelerometer menu shows "----" +// +//Version: 1.5 +//Comments: Changed XT1 drive level to highest +// Modified key lock procedure. +// Negative °C are now converted correctly to Kelvin +// Enabled fast mode when changing altitude offset +// Disabled stopwatch stop when watch buttons are locked +// Added SimpliciTI sources to project. Upgraded to Version 1.1.1. +// Changed button names from M1/M2/S1/S2/BL to STAR/NUM/UP/DOWN/BACKLIGHT +// +//Version: 1.4 +//Comments: Initial Release Version +//********************************************************************************** + +// ************************************************************************************************* +// Initialization and control of application. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project.h" +#include + +// driver +#include "clock.h" +#include "display.h" +#include "vti_as.h" +#include "vti_ps.h" +#include "radio.h" +#include "buzzer.h" +#include "ports.h" +#include "timer.h" +#include "pmm.h" +#include "rf1a.h" + +// logic +#include "menu.h" +#include "date.h" +#include "alarm.h" +#include "stopwatch.h" +#include "battery.h" +#include "temperature.h" +#include "altitude.h" +#include "battery.h" +#include "acceleration.h" +#include "bluerobin.h" +#include "rfsimpliciti.h" +#include "simpliciti.h" +#include "rfbsl.h" +#include "test.h" + +// ************************************************************************************************* +// Prototypes section +void init_application(void); +void init_global_variables(void); +void wakeup_event(void); +void process_requests(void); +void display_update(void); +void idle_loop(void); +void configure_ports(void); +void read_calibration_values(void); + +// ************************************************************************************************* +// Defines section + +// Number of calibration data bytes in INFOA memory +#define CALIBRATION_DATA_LENGTH (13u) + +// ************************************************************************************************* +// Global Variable section + +// Variable holding system internal flags +volatile s_system_flags sys; + +// Variable holding flags set by logic modules +volatile s_request_flags request; + +// Variable holding message flags +volatile s_message_flags message; + +// Global radio frequency offset taken from calibration memory +// Compensates crystal deviation from 26MHz nominal value +u8 rf_frequoffset; + +// Function pointers for LINE1 and LINE2 display function +void (*fptr_lcd_function_line1)(u8 line, u8 update); +void (*fptr_lcd_function_line2)(u8 line, u8 update); + +// ************************************************************************************************* +// Extern section + +extern void start_simpliciti_sync(void); + +extern u16 ps_read_register(u8 address, u8 mode); +extern u8 ps_write_register(u8 address, u8 data); + +// ************************************************************************************************* +// @fn main +// @brief Main routine +// @param none +// @return none +// ************************************************************************************************* +int main(void) +{ + // Init MCU + init_application(); + + // Assign initial value to global variables + init_global_variables(); + + // Branch to welcome screen + test_mode(); + + // Main control loop: wait in low power mode until some event needs to be processed + while (1) + { + // When idle go to LPM3 + idle_loop(); + + // Process wake-up events + if (button.all_flags || sys.all_flags) + wakeup_event(); + + // Process actions requested by logic modules + if (request.all_flags) + process_requests(); + + // Before going to LPM3, update display + if (display.all_flags) + display_update(); + } +} + +// ************************************************************************************************* +// @fn init_application +// @brief Initialize the microcontroller. +// @param none +// @return none +// ************************************************************************************************* +void init_application(void) +{ + volatile unsigned char *ptr; + + // --------------------------------------------------------------------- + // Enable watchdog + + // Watchdog triggers after 16 seconds when not cleared +#ifdef USE_WATCHDOG + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK; +#else + WDTCTL = WDTPW + WDTHOLD; +#endif + + // --------------------------------------------------------------------- + // Configure PMM + SetVCore(3); + + // Set global high power request enable + PMMCTL0_H = 0xA5; + PMMCTL0_L |= PMMHPMRE; + PMMCTL0_H = 0x00; + + // --------------------------------------------------------------------- + // Enable 32kHz ACLK + P5SEL |= 0x03; // Select XIN, XOUT on P5.0 and P5.1 + UCSCTL6 &= ~XT1OFF; // XT1 On, Highest drive strength + UCSCTL6 |= XCAP_3; // Internal load cap + + UCSCTL3 = SELA__XT1CLK; // Select XT1 as FLL reference + UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; + + // --------------------------------------------------------------------- + // Configure CPU clock for 12MHz + _BIS_SR(SCG0); // Disable the FLL control loop + UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx + UCSCTL1 = DCORSEL_5; // Select suitable range + UCSCTL2 = FLLD_1 + 0x16E; // Set DCO Multiplier + _BIC_SR(SCG0); // Enable the FLL control loop + + // Worst-case settling time for the DCO when the DCO range bits have been + // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx + // UG for optimization. + // 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle + __delay_cycles(375000); + + // Loop until XT1 & DCO stabilizes, use do-while to insure that + // body is executed at least once + do + { + UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); + SFRIFG1 &= ~OFIFG; // Clear fault flags + } + while ((SFRIFG1 & OFIFG)); + + // --------------------------------------------------------------------- + // Configure port mapping + + // Disable all interrupts + __disable_interrupt(); + // Get write-access to port mapping registers: + PMAPPWD = 0x02D52; + // Allow reconfiguration during runtime: + PMAPCTL = PMAPRECFG; + + // P2.7 = TA0CCR1A or TA1CCR0A output (buzzer output) + ptr = &P2MAP0; + *(ptr + 7) = PM_TA1CCR0A; + P2OUT &= ~BIT7; + P2DIR |= BIT7; + + // P1.5 = SPI MISO input + ptr = &P1MAP0; + *(ptr + 5) = PM_UCA0SOMI; + // P1.6 = SPI MOSI output + *(ptr + 6) = PM_UCA0SIMO; + // P1.7 = SPI CLK output + *(ptr + 7) = PM_UCA0CLK; + + // Disable write-access to port mapping registers: + PMAPPWD = 0; + // Re-enable all interrupts + __enable_interrupt(); + + // --------------------------------------------------------------------- + // Configure ports + + // --------------------------------------------------------------------- + // Reset radio core + radio_reset(); + radio_powerdown(); + + // --------------------------------------------------------------------- + // Init acceleration sensor + as_init(); + + // --------------------------------------------------------------------- + // Init LCD + lcd_init(); + + // --------------------------------------------------------------------- + // Init buttons + init_buttons(); + + // --------------------------------------------------------------------- + // Configure Timer0 for use by the clock and delay functions + Timer0_Init(); + + // --------------------------------------------------------------------- + // Init pressure sensor + ps_init(); +} + +// ************************************************************************************************* +// @fn init_global_variables +// @brief Initialize global variables. +// @param none +// @return none +// ************************************************************************************************* +void init_global_variables(void) +{ + // -------------------------------------------- + // Apply default settings + + // set menu pointers to default menu items + ptrMenu_L1 = &menu_L1_Time; + // ptrMenu_L1 = &menu_L1_Alarm; + // ptrMenu_L1 = &menu_L1_Heartrate; + // ptrMenu_L1 = &menu_L1_Speed; + // ptrMenu_L1 = &menu_L1_Temperature; + // ptrMenu_L1 = &menu_L1_Altitude; + // ptrMenu_L1 = &menu_L1_Acceleration; + ptrMenu_L2 = &menu_L2_Date; + // ptrMenu_L2 = &menu_L2_Stopwatch; + // ptrMenu_L2 = &menu_L2_Rf; + // ptrMenu_L2 = &menu_L2_Ppt; + // ptrMenu_L2 = &menu_L2_Sync; + // ptrMenu_L2 = &menu_L2_Distance; + // ptrMenu_L2 = &menu_L2_Calories; + // ptrMenu_L2 = &menu_L2_Battery; + // ptrMenu_L2 = &menu_L2_RFBSL; + + // Assign LINE1 and LINE2 display functions + fptr_lcd_function_line1 = ptrMenu_L1->display_function; + fptr_lcd_function_line2 = ptrMenu_L2->display_function; + + // Init system flags + button.all_flags = 0; + sys.all_flags = 0; + request.all_flags = 0; + display.all_flags = 0; + message.all_flags = 0; + + // Force full display update when starting up + display.flag.full_update = 1; + +#ifndef ISM_US + // Use metric units when displaying values + sys.flag.use_metric_units = 1; +#endif + + // Read calibration values from info memory + read_calibration_values(); + + // Set system time to default value + reset_clock(); + + // Set date to default value + reset_date(); + + // Set alarm time to default value + reset_alarm(); + + // Set buzzer to default value + reset_buzzer(); + + // Reset stopwatch + reset_stopwatch(); + + // Reset altitude measurement + reset_altitude_measurement(); + + // Reset acceleration measurement + reset_acceleration(); + + // Reset BlueRobin stack + reset_bluerobin(); + + // Reset SimpliciTI stack + reset_rf(); + + // Reset temperature measurement + reset_temp_measurement(); + + // Reset battery measurement + reset_batt_measurement(); + battery_measurement(); +} + +// ************************************************************************************************* +// @fn wakeup_event +// @brief Process external / internal wakeup events. +// @param none +// @return none +// ************************************************************************************************* +void wakeup_event(void) +{ + // Enable idle timeout + sys.flag.idle_timeout_enabled = 1; + + // If buttons are locked, only display "buttons are locked" message + if (button.all_flags && sys.flag.lock_buttons) + { + // Show "buttons are locked" message synchronously with next second tick + if (!(BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED)) + { + message.flag.prepare = 1; + message.flag.type_locked = 1; + } + // Clear buttons + button.all_flags = 0; + } + // Process long button press event (while button is held) + else if (button.flag.star_long) + { + // Clear button event + button.flag.star_long = 0; + + // Call sub menu function + ptrMenu_L1->mx_function(LINE1); + + // Set display update flag + display.flag.full_update = 1; + } + else if (button.flag.num_long) + { + // Clear button event + button.flag.num_long = 0; + + // Call sub menu function + ptrMenu_L2->mx_function(LINE2); + + // Set display update flag + display.flag.full_update = 1; + } + // Process single button press event (after button was released) + else if (button.all_flags) + { + // M1 button event --------------------------------------------------------------------- + // (Short) Advance to next menu item + if (button.flag.star) + { + // Clean up display before activating next menu item + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR); + + // Go to next menu entry + ptrMenu_L1 = ptrMenu_L1->next; + + // Assign new display function + fptr_lcd_function_line1 = ptrMenu_L1->display_function; + + // Set Line1 display update flag + display.flag.line1_full_update = 1; + + // Clear button flag + button.flag.star = 0; + } + // NUM button event --------------------------------------------------------------------- + // (Short) Advance to next menu item + else if (button.flag.num) + { + // Clear rfBSL confirmation flag + rfBSL_button_confirmation = 0; + + // Clean up display before activating next menu item + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_CLEAR); + + // Go to next menu entry + ptrMenu_L2 = ptrMenu_L2->next; + + // Assign new display function + fptr_lcd_function_line2 = ptrMenu_L2->display_function; + + // Set Line2 display update flag + display.flag.line2_full_update = 1; + + // Clear button flag + button.flag.num = 0; + } + // UP button event --------------------------------------------------------------------- + // Activate user function for Line1 menu item + else if (button.flag.up) + { + // Call direct function + ptrMenu_L1->sx_function(LINE1); + + // Set Line1 display update flag + display.flag.line1_full_update = 1; + + // Clear button flag + button.flag.up = 0; + } + // DOWN button event --------------------------------------------------------------------- + // Activate user function for Line2 menu item + else if (button.flag.down) + { + if (ptrMenu_L2 == &menu_L2_RFBSL) + { + + } + + // Call direct function + ptrMenu_L2->sx_function(LINE2); + + // Set Line1 display update flag + display.flag.line2_full_update = 1; + + // Clear button flag + button.flag.down = 0; + } + } + // Process internal events + if (sys.all_flags) + { + // Idle timeout --------------------------------------------------------------------- + if (sys.flag.idle_timeout) + { + // Clear timeout flag + sys.flag.idle_timeout = 0; + + // Clear display + clear_display(); + + // Set display update flags + display.flag.full_update = 1; + } + } + // Disable idle timeout + sys.flag.idle_timeout_enabled = 0; +} + +// ************************************************************************************************* +// @fn process_requests +// @brief Process requested actions outside ISR context. +// @param none +// @return none +// ************************************************************************************************* +void process_requests(void) +{ + // Do temperature measurement + if (request.flag.temperature_measurement) + temperature_measurement(FILTER_ON); + + // Do pressure measurement + if (request.flag.altitude_measurement) + do_altitude_measurement(FILTER_ON); + + // Do acceleration measurement + if (request.flag.acceleration_measurement) + do_acceleration_measurement(); + + // Do voltage measurement + if (request.flag.voltage_measurement) + battery_measurement(); + + // Generate alarm (two signals every second) + if (request.flag.buzzer) + start_buzzer(2, BUZZER_ON_TICKS, BUZZER_OFF_TICKS); + + // Reset request flag + request.all_flags = 0; +} + +// ************************************************************************************************* +// @fn display_update +// @brief Process display flags and call LCD update routines. +// @param none +// @return none +// ************************************************************************************************* +void display_update(void) +{ + u8 line; + u8 string[8]; + + // --------------------------------------------------------------------- + // Call Line1 display function + if (display.flag.full_update || display.flag.line1_full_update) + { + clear_line(LINE1); + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_UPDATE_FULL); + } else if (ptrMenu_L1->display_update()) + { + // Update line1 only when new data is available + fptr_lcd_function_line1(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); + } + + // --------------------------------------------------------------------- + // If message text should be displayed on Line2, skip normal update + if (message.flag.show) + { + line = LINE2; + + // Select message to display + if (message.flag.type_locked) + memcpy(string, " LO?T", 6); + else if (message.flag.type_unlocked) + memcpy(string, " OPEN", 6); + else if (message.flag.type_lobatt) + memcpy(string, "LOBATT", 6); + else if (message.flag.type_alarm_on) + { + memcpy(string, " ON", 4); + line = LINE1; + } else if (message.flag.type_alarm_off) + { + memcpy(string, " OFF", 4); + line = LINE1; + } + // Clear previous content + clear_line(line); + fptr_lcd_function_line2(line, DISPLAY_LINE_CLEAR); + + if (line == LINE2) + display_chars(LCD_SEG_L2_5_0, string, SEG_ON); + else + display_chars(LCD_SEG_L1_3_0, string, SEG_ON); + + // Next second tick erases message and repaints original screen content + message.all_flags = 0; + message.flag.erase = 1; + } + // --------------------------------------------------------------------- + // Call Line2 display function + else if (display.flag.full_update || display.flag.line2_full_update) + { + clear_line(LINE2); + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_UPDATE_FULL); + } else if (ptrMenu_L2->display_update() && !message.all_flags) + { + // Update line2 only when new data is available + fptr_lcd_function_line2(LINE2, DISPLAY_LINE_UPDATE_PARTIAL); + } + // --------------------------------------------------------------------- + // Restore blinking icons (blinking memory is cleared when calling set_value) + if (display.flag.full_update) + { + if (is_bluerobin() == BLUEROBIN_CONNECTED) + { + // Turn on beeper icon to show activity + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF); + } + } + // Clear display flag + display.all_flags = 0; +} + +// ************************************************************************************************* +// @fn to_lpm +// @brief Go to LPM0/3. +// @param none +// @return none +// ************************************************************************************************* +void to_lpm(void) +{ + // Go to LPM3 + _BIS_SR(LPM3_bits + GIE); + __no_operation(); +} + +// ************************************************************************************************* +// @fn idle_loop +// @brief Go to LPM. Service watchdog timer when waking up. +// @param none +// @return none +// ************************************************************************************************* +void idle_loop(void) +{ + // To low power mode + to_lpm(); + +#ifdef USE_WATCHDOG + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; +#endif +} + +// ************************************************************************************************* +// @fn read_calibration_values +// @brief Read calibration values for temperature measurement, voltage measurement +// and radio from INFO memory. +// @param none +// @return none +// ************************************************************************************************* +void read_calibration_values(void) +{ + u8 cal_data[CALIBRATION_DATA_LENGTH]; // Temporary storage for constants + u8 i; + u8 *flash_mem; // Memory pointer + + // Read calibration data from Info D memory + flash_mem = (u8 *) 0x1800; + for (i = 0; i < CALIBRATION_DATA_LENGTH; i++) + { + cal_data[i] = *flash_mem++; + } + + if (cal_data[0] == 0xFF) + { + // If no values are available (i.e. INFO D memory has been erased by user), assign + // experimentally derived values + rf_frequoffset = 4; + sTemp.offset = -250; + sBatt.offset = -10; + simpliciti_ed_address[0] = 0x79; + simpliciti_ed_address[1] = 0x56; + simpliciti_ed_address[2] = 0x34; + simpliciti_ed_address[3] = 0x12; + sAlt.altitude_offset = 0; + } else + { + // Assign calibration data to global variables + rf_frequoffset = cal_data[1]; + // Range check for calibrated FREQEST value (-20 .. + 20 is ok, else use default value) + if ((rf_frequoffset > 20) && (rf_frequoffset < (256 - 20))) + { + rf_frequoffset = 0; + } + sTemp.offset = (s16) ((cal_data[2] << 8) + cal_data[3]); + sBatt.offset = (s16) ((cal_data[4] << 8) + cal_data[5]); + simpliciti_ed_address[0] = cal_data[6]; + simpliciti_ed_address[1] = cal_data[7]; + simpliciti_ed_address[2] = cal_data[8]; + simpliciti_ed_address[3] = cal_data[9]; + // S/W version byte set during calibration? + if (cal_data[12] != 0xFF) + { + sAlt.altitude_offset = (s16) ((cal_data[10] << 8) + cal_data[11]); + } else + { + sAlt.altitude_offset = 0; + } + } +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.cspy.bat b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.cspy.bat new file mode 100755 index 0000000..668d3c5 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.cspy.bat @@ -0,0 +1,15 @@ +@REM This batch file has been generated by the IAR Embedded Workbench +@REM C-SPY Debugger, as an aid to preparing a command line for running +@REM the cspybat command line utility using the appropriate settings. +@REM +@REM You can launch cspybat by typing the name of this batch file followed +@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). +@REM Note that this file is generated every time a new debug session +@REM is initialized, so you may want to move or rename the file before +@REM making changes. +@REM + + +"C:\Program Files\IAR Systems\Embedded Workbench 6.0\common\bin\cspybat" "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\bin\430proc.dll" "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\bin\430fet.dll" %1 --plugin "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\bin\430bat.dll" --backend -B "-p" "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\config\CC430F6137.ddf" "--core=430Xv2" "--data_model=small" "--iv_base" "0xFF80" "--no_wrap_around" "-d" "fet" "--erase_main_and_info" "--derivative" "CC430F6137" "--protocol" "automatic" "--eem" "EMEX_SMALL_5XX" "--port" "Automatic" "--connection" "ti_usb" "--settlingtime=0" "--msp430_dll" "msp430.dll" "--vccDefault" "3.3" + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.dbgdt b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.dbgdt new file mode 100755 index 0000000..796ccb4 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.dbgdt @@ -0,0 +1,89 @@ + + + + + + + + + 20894 + + + + + + 2067017844 + + + + + + + 177272727 + + + + + + 111 + + + + + + + + + TabID-6682-31467 + Debug Log + Debug-Log + + + + TabID-16908-31480 + Build + Build + + + + + 0 + + + TabID-17431-31470 + Workspace + Workspace + + + ez430_chronosez430_chronos/driver + + + + 0 + + + TabID-28179-31473 + Disassembly + Disassembly + + + + + 0 + + + + + + TextEditor$WS_DIR$\main.c01476219621900100000010000001 + + + + + + + iaridepm.enu1debuggergui.enu1430fet1-2-2585267-2-2269283210156295407210156612735-2-2585267-2-2269283210156295407210156612735-2-22811282-2-212842831003125295407210156295407 + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.dni b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.dni new file mode 100755 index 0000000..c72a32b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.dni @@ -0,0 +1,89 @@ +[State Storage] +Control Register=0 +[Sequencer] +Control Register=0 +NextState0=0 +NextState1=0 +[Action Register] +Break=1 +State Storage=0 +[DebugChecksum] +Checksum=562905950 +[DisAssemblyWindow] +NumStates=_ 1 +State 1=_ 1 +[InstructionProfiling] +Enabled=_ 0 +[CodeCoverage] +Enabled=_ 0 +[StackPlugin] +Enabled=1 +OverflowWarningsEnabled=1 +WarningThreshold=90 +SpWarningsEnabled=1 +WarnHow=0 +UseTrigger=1 +TriggerName=main +LimitSize=0 +ByteLimit=50 +[InterruptLog] +LogEnabled=0 +SumEnabled=0 +GraphEnabled=0 +ShowTimeLog=1 +ShowTimeSum=1 +SumSortOrder=0 +[Interrupts] +Enabled=1 +[MemoryMap] +Enabled=0 +Base=0 +UseAuto=0 +TypeViolation=1 +UnspecRange=1 +ActionState=1 +[TraceHelper] +Enabled=0 +ShowSource=1 +[Log file] +LoggingEnabled=_ 0 +LogFile=_ "" +Category=_ 0 +[TermIOLog] +LoggingEnabled=_ 0 +LogFile=_ "" +[CallStackLog] +Enabled=0 +[DriverProfiling] +Enabled=0 +Mode=1075610178 +Graph=0 +Symbiont=0 +[Breakpoints] +Bp0=_ "STD_CODE" "{$PROJ_DIR$\driver\timer.c}.412.5@1" 0 0 0 0 "" 0 "" +Count=1 +[FET] +Clock mode=14 +Extended Clock mode=-1 +Secure Password= +Extended Clock Control Enable=1 +Advanced Extended Clock Control=0 +Emulation mode=0 +Free running=0 +Shutting Down=3 +[Memory Dump] +Start address= +Lenghth= +Address info=0 +Format=0 +Dump registers=0 +PC=0 +SP=0 +SR=0 +all registers=0 +File name= +[Aliases] +A0=_ "C:\Documents and Settings\x0144126.ENT\My Documents\Tasks\New Release\new chronos release 23-11\windows\Software Projects\Chronos Watch\IAR\Sports Watch\driver\adc12.c" "" +A1=_ "C:\Documents and Settings\x0144126.ENT\My Documents\Tasks\New Release\new chronos release 23-11\windows\Software Projects\Chronos Watch\IAR\Sports Watch\driver\ports.c" "" +Count=2 +SuppressDialog=0 diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.wsdt b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.wsdt new file mode 100755 index 0000000..4868da4 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/settings/ez430_chronos.wsdt @@ -0,0 +1,66 @@ + + + + + + ez430_chronos/433MHz - Unrestricted IAR Workbench (Other regions) + + + + + + + + + 2871270 + + + + + + + 2091624461 + 46601303201222 + + + + + + + TabID-31076-2853 + Workspace + Workspace + + + ez430_chronos + + + + 0 + + + TabID-19282-2870 + Build + Build + + + TabID-12108-28463Find in FilesFind-in-Files + + 0 + + + + + + TextEditor$WS_DIR$\main.c0018818800100000010000001 + + + + + + + iaridepm.enu1-2-2716335-2-2200200156250208768263281749478-2-21981282-2-212842001003125208768156250208768 + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Applications/application/End Device/main_ED_BM.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Applications/application/End Device/main_ED_BM.c new file mode 100755 index 0000000..af83d41 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Applications/application/End Device/main_ED_BM.c @@ -0,0 +1,264 @@ +/********************************************************************************************** + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +// ************************************************************************************************* +// Include section +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "bsp_leds.h" +#include "bsp_buttons.h" +#include "simpliciti.h" + + +// ************************************************************************************************* +// Defines section +#define TIMEOUT (10u) + +// Conversion from msec to ACLK timer ticks +#define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000) + +// U16 +typedef unsigned short u16; + +// ************************************************************************************************* +// Prototypes section + + +// ************************************************************************************************* +// Extern section +extern uint8_t sInit_done; + +// SimpliciTI has no low power delay function, so we have to use ours +extern void Timer0_A4_Delay(u16 ticks); + + +// ************************************************************************************************* +// Global Variable section +static linkID_t sLinkID1; + + + +// ************************************************************************************************* +// @fn simpliciti_link +// @brief Init hardware and try to link to access point. +// @param none +// @return unsigned char 0 = Could not link, timeout or external cancel. +// 1 = Linked successful. +// ************************************************************************************************* +unsigned char simpliciti_link(void) +{ + uint8_t timeout; + addr_t lAddr; + uint8_t i; + uint8_t pwr; + + // Configure timer + BSP_InitBoard(); + + // Change network address to value set in calling function + for (i=0; i TIMEOUT) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + simpliciti_flag = SIMPLICITI_STATUS_ERROR; + return (0); + } + + // Break when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + return (0); + } + } + + // Set output power to +3.3dmB + pwr = IOCTL_LEVEL_2; + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &pwr); + + /* Unconditional link to AP which is listening due to successful join. */ + timeout = 0; + while (SMPL_SUCCESS != SMPL_Link(&sLinkID1)) + { + NWK_DELAY(1000); + + // Service watchdog + WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; + + // Stop linking after timeout + if (timeout++ > TIMEOUT) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + simpliciti_flag = SIMPLICITI_STATUS_ERROR; + return (0); + } + + // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + return (0); + } + } + simpliciti_flag = SIMPLICITI_STATUS_LINKED; + + return (1); +} + + + +// ************************************************************************************************* +// @fn simpliciti_main_tx_only +// @brief Get data through callback. Transfer data when external trigger is set. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_main_tx_only(void) +{ + while(1) + { + // Get end device data from callback function + simpliciti_get_ed_data_callback(); + + // Send data when flag bit SIMPLICITI_TRIGGER_SEND_DATA is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA)) + { + // Get radio ready. Wakes up in IDLE state. + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); + + // Acceleration / button events packets are 4 bytes long + SMPL_SendOpt(sLinkID1, simpliciti_data, 4, SMPL_TXOPTION_NONE); + + // Put radio back to SLEEP state + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); + + clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA); + } + + // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) + { + // Clean up SimpliciTI stack to enable restarting + sInit_done = 0; + break; + } + } +} + + + +// ************************************************************************************************* +// @fn simpliciti_main_sync +// @brief Send ready-to-receive packets in regular intervals. Listen shortly for host reply. +// Decode received host command and trigger action. +// @param none +// @return none +// ************************************************************************************************* +void simpliciti_main_sync(void) +{ + uint8_t len, i; + uint8_t ed_data[2]; + + while(1) + { + // Sleep 0.5sec between ready-to-receive packets + // SimpliciTI has no low power delay function, so we have to use ours + Timer0_A4_Delay(CONV_MS_TO_TICKS(500)); + + // Get radio ready. Radio wakes up in IDLE state. + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); + + // Send 2 byte long ready-to-receive packet to stimulate host reply + ed_data[0] = SYNC_ED_TYPE_R2R; + ed_data[1] = 0xCB; + SMPL_SendOpt(sLinkID1, ed_data, 2, SMPL_TXOPTION_NONE); + + // Wait shortly for host reply + SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); + NWK_DELAY(10); + + // Check if a command packet was received + while (SMPL_Receive(sLinkID1, simpliciti_data, &len) == SMPL_SUCCESS) + { + // Decode received data + if (len > 0) + { + // Use callback function in application to decode data and react + simpliciti_sync_decode_ap_cmd_callback(); + + // Get reply data and send out reply packet burst (19 bytes each) + for (i=0; i level) + SetVCoreDown(--actLevel); /* Set VCore (step by step) */ + }while (actLevel != level); +} + +/************************************************************************************************** + * @fn SetVCoreUp + * + * @brief Set VCore up. Change level by one step only. + * + * @param level - VcCore level + * + * @return none + ************************************************************************************************* + */ +static void SetVCoreUp (uint8_t level) +{ + PMMCTL0_H = 0xA5; /* Open PMM module registers for write access */ + + SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; /* Set SVS/M high side to new level */ + + SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; /* Set SVM new Level */ + while ((PMMIFG & SVSMLDLYIFG) == 0); /* Wait till SVM is settled (Delay) */ + PMMCTL0_L = PMMCOREV0 * level; /* Set VCore to x */ + PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); /* Clear already set flags */ + if ((PMMIFG & SVMLIFG)) + while ((PMMIFG & SVMLVLRIFG) == 0); /* Wait till level is reached */ + + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; /* Set SVS/M Low side to new level */ + PMMCTL0_H = 0x00; /* Lock PMM module registers for write access */ +} + +/************************************************************************************************** + * @fn SetVCoreDown + * + * @brief Set VCore down + * + * @param level - VcCore level + * + * @return none + ************************************************************************************************** + */ +static void SetVCoreDown (uint8_t level) +{ + PMMCTL0_H = 0xA5; /* Open PMM module registers for write access */ + SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; /* Set SVS/M Low side to new level */ + while ((PMMIFG & SVSMLDLYIFG) == 0); /* Wait till SVM is settled (Delay) */ + PMMCTL0_L = (level * PMMCOREV0); /* Set VCore to 1.85 V for Max Speed. */ + PMMCTL0_H = 0x00; /* Lock PMM module registers for write access */ +} + +/************************************************************************************************** + * @fn Bsp_SetVCore + * + * @brief Setup the core voltage. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Bsp_SetVCore(void) +{ + SetVCore(3); +} + +/************************************************************************************************** + * @fn Bsp_SetClocks + * + * @brief Set up system clocks. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Bsp_SetClocks(void) +{ + /* Configure CPU clock for 12MHz */ + + /* If clock settings are changed, remember to update BSP_TIMER_CLK_MHZ. + * Otherwise, all timer settings would be incorrect. + */ + UCSCTL3 |= SELREF_2; /* Set DCO FLL reference = REFO */ + UCSCTL4 |= SELA_2; /* Set ACLK = REFO */ + + __bis_SR_register(SCG0); /* Disable the FLL control loop */ + UCSCTL0 = 0x0000; /* Set lowest possible DCOx, MODx */ + UCSCTL1 = DCORSEL_5; /* Select DCO range 24MHz operation */ + UCSCTL2 = FLLD_1 + 374; /* Set DCO Multiplier for 12MHz */ + /* (N + 1) * FLLRef = Fdco */ + /* (374 + 1) * 32768 = 12MHz */ + /* Set FLL Div = fDCOCLK/2 */ + __bic_SR_register(SCG0); /* Enable the FLL control loop */ + + /* Worst-case settling time for the DCO when the DCO range bits have been + * changed is n x 32 x 32 x f_MCLK / f_FLL_reference. + * 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle + */ + __delay_cycles(375000); + + /* Loop until XT1,XT2 & DCO fault flag is cleared */ + do + { + UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); + /* Clear XT2,XT1,DCO fault flags */ + SFRIFG1 &= ~OFIFG; /* Clear fault flags */ + }while (SFRIFG1&OFIFG); /* Test oscillator fault flag */ + + /* Select REFO as ACLK source and DCOCLK as MCLK and SMCLK source */ + UCSCTL4 = SELA__REFOCLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; +} + +/************************************************************************************************** + * @fn BSP_EARLY_INIT + * + * @brief This function is called by start-up code before doing the normal initialization + * of data segments. If the return value is zero, initialization is not performed. + * The global macro label "BSP_EARLY_INIT" gets #defined in the bsp_msp430_defs.h + * file, according to the specific compiler environment (CCE or IAR). In the CCE + * environment this macro invokes "_system_pre_init()" and in the IAR environment + * this macro invokes "__low_level_init()". + * + * @param None + * + * @return 0 - don't intialize data segments / 1 - do initialization + ************************************************************************************************* + */ +BSP_EARLY_INIT(void) +{ + /* Disable watchdog timer */ + WDTCTL = WDTPW | WDTHOLD; + + /* Setup Vcore */ + Bsp_SetVCore(); + + /* Configure System clocks */ + Bsp_SetClocks(); + + /* Return 1 - run seg_init */ + return (1); +} + +/************************************************************************************************** + * @fn BSP_InitBoard + * + * @brief Initialize the board. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitBoard(void) +{ + /* Configure TimerA for use by the delay function */ + + /* Reset the timer */ + //TA0CTL |= TACLR; /* Set the TACLR */ + + /* Clear all settings */ + //TA0CTL = 0x0; + + /* Select the clk source to be - SMCLK (Sub-Main CLK)*/ + //TA0CTL |= TASSEL_2; + + // [BM] We need to use TA1 for delay function, because TA0 is already occupied + TA1CTL |= TACLR; /* Set the TACLR */ + TA1CTL = 0x0; + TA1CTL |= TASSEL_2; +} + +/************************************************************************************************** + * @fn BSP_Delay + * + * @brief Delay for the requested amount of time. + * + * @param # of microseconds to delay. + * + * @return none + ************************************************************************************************** + */ +void BSP_Delay(uint16_t usec) +{ + BSP_ASSERT(usec < BSP_DELAY_MAX_USEC); + + //TA0R = 0; /* initial count */ + //TA0CCR0 = BSP_TIMER_CLK_MHZ*usec; /* compare count. (delay in ticks) */ + + /* Start the timer in UP mode */ + //TA0CTL |= MC_1; + + /* Loop till compare interrupt flag is set */ + //while(!(TA0CCTL0 & CCIFG)); + + /* Stop the timer */ + //TA0CTL &= ~(MC_1); + + /* Clear the interrupt flag */ + //TA0CCTL0 &= ~CCIFG; + + // [BM] We need to use TA1 for delay function, because TA0 is already occupied + TA1R = 0; + TA1CCR0 = BSP_TIMER_CLK_MHZ*usec; + TA1CTL |= MC_1; + while(!(TA1CCTL0 & CCIFG)); + TA1CTL &= ~(MC_1); + TA1CCTL0 &= ~CCIFG; +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h new file mode 100755 index 0000000..f3e01ad --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_board_defs.h @@ -0,0 +1,83 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Board definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BOARD_DEFS_H +#define BSP_BOARD_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Board Unique Define + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BOARD_CC430EM + + +/* ------------------------------------------------------------------------------------------------ + * Mcu + * ------------------------------------------------------------------------------------------------ + */ +#include "mcus/bsp_msp430_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Clock + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_config.h" +#define __bsp_CLOCK_MHZ__ BSP_CONFIG_CLOCK_MHZ + + +/* ------------------------------------------------------------------------------------------------ + * Board Initialization + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BOARD_C "bsp_board.c" +#define BSP_INIT_BOARD() BSP_InitBoard() +#define BSP_DELAY_USECS(x) BSP_Delay(x) + +void BSP_InitBoard(void); +void BSP_Delay(uint16_t usec); + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h new file mode 100755 index 0000000..453863c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_button_defs.h @@ -0,0 +1,91 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Button definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BUTTON_DEFS_H +#define BSP_BUTTON_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Button Configuration + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_NUM_BUTTONS__ 1 +#define __bsp_BUTTON_DEBOUNCE_WAIT__(expr) st( int i; for(i=0; i<500; i++) { if (!(expr)) i = 0; } ) + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * BUTTON #1 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : S2 + * Description : Push Button + * Polarity : Active Low + * GPIO : P1.7 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_BUTTON1_BIT__ 7 +#define __bsp_BUTTON1_PORT__ P1IN +#define __bsp_BUTTON1_IS_ACTIVE_LOW__ 1 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Extended Configuration + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +/* Enable the internal PullUp for button #1. */ +#define __bsp_BUTTON_EXTENDED_CONFIG__() st( P1OUT |= BV(__bsp_BUTTON1_BIT__); /* PullUp */ \ + P1REN |= BV(__bsp_BUTTON1_BIT__);)/* Enable PullUp */ + + +/* ------------------------------------------------------------------------------------------------ + * Include Generic Button Macros + * ------------------------------------------------------------------------------------------------ + */ +#include "code/bsp_generic_buttons.h" + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h new file mode 100755 index 0000000..a4550e2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_config.h @@ -0,0 +1,47 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Board configuration file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_CONFIG_H +#define BSP_CONFIG_H + + +/* Nothing needed for this platform. */ + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h new file mode 100755 index 0000000..b3f7066 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_driver_defs.h @@ -0,0 +1,54 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Driver definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_DRIVER_DEFS_H +#define BSP_DRIVER_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Driver Initialization + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_DRIVERS_C "bsp_drivers.c" +#define BSP_INIT_DRIVERS() BSP_InitDrivers() +void BSP_InitDrivers(void); + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c new file mode 100755 index 0000000..563f59c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_drivers.c @@ -0,0 +1,88 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * Top-level driver file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_driver_defs.h" +#include "bsp_leds.h" +#include "bsp_buttons.h" +#include "bsp_config.h" + + +/************************************************************************************************** + * @fn BSP_InitDrivers + * + * @brief Initialize all enabled BSP drivers. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitDrivers(void) +{ +#if (!defined BSP_NO_LEDS) + BSP_InitLeds(); +#endif + +#if (!defined BSP_NO_BUTTONS) + BSP_InitButtons(); +#endif +} + + +/* ================================================================================================ + * C Code Includes + * ================================================================================================ + */ +#ifndef BSP_NO_LEDS +#include "drivers/code/bsp_leds.c" +#endif + +#ifndef BSP_NO_BUTTONS +#include "drivers/code/bsp_buttons.c" +#endif + + +/************************************************************************************************** +*/ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h new file mode 100755 index 0000000..38840c0 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_external/mrfi_board_defs.h @@ -0,0 +1,81 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Board definition file. + * Target : Texas Instruments CC430EM + * Radios : CC430 + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_BOARD_DEFS_H +#define MRFI_BOARD_DEFS_H + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + + +/* ------------------------------------------------------------------------------------------------ + * Radio Selection + * ------------------------------------------------------------------------------------------------ + */ +#if (!defined MRFI_CC430) + #error "ERROR: A compatible radio must be specified for the CC430EM board." +#endif + + +/* Radio Interface critical section macros */ +typedef bspIState_t mrfiRIFIState_t; +#define MRFI_RIF_ENTER_CRITICAL_SECTION(x) BSP_ENTER_CRITICAL_SECTION(x) +#define MRFI_RIF_EXIT_CRITICAL_SECTION(x) BSP_EXIT_CRITICAL_SECTION(x) + + +/************************************************************************************************** + * Compile Time Integrity Checks + ************************************************************************************************** + */ +#ifndef BSP_BOARD_CC430EM +#error "ERROR: Mismatch between specified board and MRFI configuration." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h new file mode 100755 index 0000000..5cd33b6 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/boards/CC430EM/bsp_led_defs.h @@ -0,0 +1,97 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC430EM + * LED definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_LED_DEFS_H +#define BSP_LED_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Configuration + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_NUM_LEDS__ 2 +#define __bsp_LED_BLINK_LOOP_COUNT__ 0x34000 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * LED #1 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : LED1 + * Color : Green + * Polarity : Active High + * GPIO : P1.0 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_LED1_BIT__ 0 +#define __bsp_LED1_PORT__ P1OUT +#define __bsp_LED1_DDR__ P1DIR +#define __bsp_LED1_IS_ACTIVE_LOW__ 0 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * LED #2 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : LED2 + * Color : Green + * Polarity : Active High + * GPIO : P3.6 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_LED2_BIT__ 6 +#define __bsp_LED2_PORT__ P3OUT +#define __bsp_LED2_DDR__ P3DIR +#define __bsp_LED2_IS_ACTIVE_LOW__ 0 + + +/* ------------------------------------------------------------------------------------------------ + * Include Generic LED Macros + * ------------------------------------------------------------------------------------------------ + */ +#include "code/bsp_generic_leds.h" + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/bsp.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/bsp.c new file mode 100755 index 0000000..cee0b33 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/bsp.c @@ -0,0 +1,101 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Top-level BSP code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "bsp_driver_defs.h" + + +/************************************************************************************************** + * @fn BSP_Init + * + * @brief Initialize the board and drivers. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_Init(void) +{ + BSP_INIT_BOARD(); + BSP_INIT_DRIVERS(); + + /*------------------------------------------------------------- + * Run time integrity checks. Perform only if asserts + * are enabled. + */ +#ifdef BSP_ASSERTS_ARE_ON + /* verify endianess is correctly specified */ + { + uint16_t test = 0x00AA; /* first storage byte of 'test' is non-zero for little endian */ + BSP_ASSERT(!(*((uint8_t *)&test)) == !BSP_LITTLE_ENDIAN); /* endianess mismatch */ + } +#endif +} + + +/* ================================================================================================ + * C Code Includes + * ================================================================================================ + */ +#ifdef BSP_BOARD_C +#include BSP_BOARD_C +#endif + +#ifdef BSP_DRIVERS_C +#include BSP_DRIVERS_C +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +BSP_STATIC_ASSERT( sizeof( uint8_t ) == 1 ); +BSP_STATIC_ASSERT( sizeof( int8_t ) == 1 ); +BSP_STATIC_ASSERT( sizeof( uint16_t ) == 2 ); +BSP_STATIC_ASSERT( sizeof( int16_t ) == 2 ); +BSP_STATIC_ASSERT( sizeof( uint32_t ) == 4 ); +BSP_STATIC_ASSERT( sizeof( int32_t ) == 4 ); + + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/bsp.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/bsp.h new file mode 100755 index 0000000..8cff5a0 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/bsp.h @@ -0,0 +1,183 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Include file for core BSP services. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_H +#define BSP_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + +/* ------------------------------------------------------------------------------------------------ + * BSP Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP +#define BSP_VER 100 /* BSP version 1.00a */ +#define BSP_SUBVER a + + +/* ------------------------------------------------------------------------------------------------ + * Clock + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CLOCK_MHZ __bsp_CLOCK_MHZ__ + + +/* ------------------------------------------------------------------------------------------------ + * Memory + * ------------------------------------------------------------------------------------------------ + */ +#ifndef __bsp_LITTLE_ENDIAN__ +#error ERROR: Endianess not defined +#endif + +#define BSP_LITTLE_ENDIAN __bsp_LITTLE_ENDIAN__ + +#define CODE __bsp_CODE_MEMSPACE__ +#define XDATA __bsp_XDATA_MEMSPACE__ + +/* ------------------------------------------------------------------------------------------------ + * Interrupts + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_ISR_FUNCTION(func,vect) __bsp_ISR_FUNCTION__(func,vect) + +#define BSP_ENABLE_INTERRUPTS() __bsp_ENABLE_INTERRUPTS__() +#define BSP_DISABLE_INTERRUPTS() __bsp_DISABLE_INTERRUPTS__() +#define BSP_INTERRUPTS_ARE_ENABLED() __bsp_INTERRUPTS_ARE_ENABLED__() + + +/* ------------------------------------------------------------------------------------------------ + * Critical Sections + * ------------------------------------------------------------------------------------------------ + */ +typedef __bsp_ISTATE_T__ bspIState_t; + +#define BSP_ENTER_CRITICAL_SECTION(x) st( x = __bsp_GET_ISTATE__(); __bsp_DISABLE_INTERRUPTS__(); ) +#define BSP_EXIT_CRITICAL_SECTION(x) __bsp_RESTORE_ISTATE__(x) +#define BSP_CRITICAL_STATEMENT(x) st( bspIState_t s; \ + BSP_ENTER_CRITICAL_SECTION(s); \ + x; \ + BSP_EXIT_CRITICAL_SECTION(s); ) + + +/* ------------------------------------------------------------------------------------------------ + * Asserts + * ------------------------------------------------------------------------------------------------ + */ + +/* + * BSP_ASSERT( expression ) - The given expression must evaluate as "true" or else the assert + * handler is called. From here, the call stack feature of the debugger can pinpoint where + * the problem occurred. + * + * BSP_FORCE_ASSERT() - If asserts are in use, immediately calls the assert handler. + * + * BSP_ASSERTS_ARE_ON - can use #ifdef to see if asserts are enabled + * + * Asserts can be disabled for optimum performance and minimum code size (ideal for + * finalized, debugged production code). + */ + +#if (!defined BSP_NO_DEBUG) +#ifndef BSP_ASSERT_HANDLER +#define BSP_ASSERT_HANDLER() st( __bsp_DISABLE_INTERRUPTS__(); while(1); ) +#endif +#define BSP_ASSERT(expr) st( if (!(expr)) BSP_ASSERT_HANDLER(); ) +#define BSP_FORCE_ASSERT() BSP_ASSERT_HANDLER() +#define BSP_ASSERTS_ARE_ON +#else +#define BSP_ASSERT(expr) /* empty */ +#define BSP_FORCE_ASSERT() /* empty */ +#endif + +/* static assert */ +#define BSP_STATIC_ASSERT(expr) void bspDummyPrototype( char dummy[1/((expr)!=0)] ) + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_Init(void); +/************************************************************************************************** + */ + +/**************************************************************************************** + * BEGIN ENDIAN SUPPORT + * + * Security encrypt/decrypt operates on unsigned long quantities. These must match on + * source and destination platforms. These macros enforce the standard conversions. + * Currently all platforms (CC2520/CC2x30 and MSP430) are little endian. + * + ******************* Network order for encryption is LITTLE ENDIAN ****************** + * + ****************************************************************************************/ + +#if (BSP_LITTLE_ENDIAN != 0) +#define ntohs(x) (x) +#define htons(x) (x) + +#define ntohl(x) (x) +#define htonl(x) (x) + +#else + +#define ntohs(x) (((x>>8) & 0xFF) | ((x & 0xFF)<<8)) +#define htons(x) (((x>>8) & 0xFF) | ((x & 0xFF)<<8)) + +#define ntohl(x) ( ((x>>24) & 0xFF) | ((x>>8) & 0xFF00) | \ + ((x & 0xFF00)<<8) | ((x & 0xFF)<<24) \ + ) +#define htonl(x) ( ((x>>24) & 0xFF) | ((x>>8) & 0xFF00) | \ + ((x & 0xFF00)<<8) | ((x & 0xFF)<<24) \ + ) + +#endif /* (BSP_LITTLE_ENDIAN != 0) */ + +/*************************************************************************************** + * END ENDIAN SUPPORT + ***************************************************************************************/ + + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/bsp_macros.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/bsp_macros.h new file mode 100755 index 0000000..ee99a19 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/bsp_macros.h @@ -0,0 +1,79 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Include file for BSP utility macros. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_MACROS_H +#define BSP_MACROS_H + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +/* bit value */ +#ifndef BV +#define BV(n) (1 << (n)) +#endif + +/* + * This macro is for use by other macros to form a fully valid C statement. + * Without this, the if/else conditionals could show unexpected behavior. + * + * For example, use... + * #define SET_REGS() st( ioreg1 = 0; ioreg2 = 0; ) + * instead of ... + * #define SET_REGS() { ioreg1 = 0; ioreg2 = 0; } + * or + * #define SET_REGS() ioreg1 = 0; ioreg2 = 0; + * The last macro would not behave as expected in the if/else construct. + * The second to last macro will cause a compiler error in certain uses + * of if/else construct + * + * It is not necessary, or recommended, to use this macro where there is + * already a valid C statement. For example, the following is redundant... + * #define CALL_FUNC() st( func(); ) + * This should simply be... + * #define CALL_FUNC() func() + * + * (The while condition below evaluates false without generating a + * constant-controlling-loop type of warning on most compilers.) + */ +#define st(x) do { x } while (__LINE__ == -1) + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/bsp_buttons.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/bsp_buttons.h new file mode 100755 index 0000000..b73d615 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/bsp_buttons.h @@ -0,0 +1,90 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Button driver include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BUTTONS_H +#define BSP_BUTTONS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_button_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_NUM_BUTTONS __bsp_NUM_BUTTONS__ + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BUTTON_DEBOUNCE_WAIT(expr) __bsp_BUTTON_DEBOUNCE_WAIT__(expr) + +#define BSP_BUTTON1() __bsp_BUTTON1__() +#define BSP_BUTTON2() __bsp_BUTTON2__() +#define BSP_BUTTON3() __bsp_BUTTON3__() +#define BSP_BUTTON4() __bsp_BUTTON4__() +#define BSP_BUTTON5() __bsp_BUTTON5__() +#define BSP_BUTTON6() __bsp_BUTTON6__() +#define BSP_BUTTON7() __bsp_BUTTON7__() +#define BSP_BUTTON8() __bsp_BUTTON8__() + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_InitButtons(void); + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +#ifdef BSP_NO_BUTTONS +#error "ERROR: The button driver is disabled. This file should not be included." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/bsp_leds.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/bsp_leds.h new file mode 100755 index 0000000..b01338b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/bsp_leds.h @@ -0,0 +1,133 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * LED driver include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_LEDS_H +#define BSP_LEDS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_led_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_NUM_LEDS __bsp_NUM_LEDS__ + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ + +/* blink delay loop */ +#define BSP_LED_BLINK_DELAY() st( { volatile uint32_t i; \ + for (i=0; i<__bsp_LED_BLINK_LOOP_COUNT__; i++) { }; } ) + +/* LED1 */ +#define BSP_TURN_ON_LED1() __bsp_LED1_TURN_ON__() +#define BSP_TURN_OFF_LED1() __bsp_LED1_TURN_OFF__() +#define BSP_TOGGLE_LED1() __bsp_LED1_TOGGLE__() +#define BSP_LED1_IS_ON() __bsp_LED1_IS_ON__() + +/* LED2 */ +#define BSP_TURN_ON_LED2() __bsp_LED2_TURN_ON__() +#define BSP_TURN_OFF_LED2() __bsp_LED2_TURN_OFF__() +#define BSP_TOGGLE_LED2() __bsp_LED2_TOGGLE__() +#define BSP_LED2_IS_ON() __bsp_LED2_IS_ON__() + +/* LED3 */ +#define BSP_TURN_ON_LED3() __bsp_LED3_TURN_ON__() +#define BSP_TURN_OFF_LED3() __bsp_LED3_TURN_OFF__() +#define BSP_TOGGLE_LED3() __bsp_LED3_TOGGLE__() +#define BSP_LED3_IS_ON() __bsp_LED3_IS_ON__() + +/* LED4 */ +#define BSP_TURN_ON_LED4() __bsp_LED4_TURN_ON__() +#define BSP_TURN_OFF_LED4() __bsp_LED4_TURN_OFF__() +#define BSP_TOGGLE_LED4() __bsp_LED4_TOGGLE__() +#define BSP_LED4_IS_ON() __bsp_LED4_IS_ON__() + +/* LED5 */ +#define BSP_TURN_ON_LED5() __bsp_LED5_TURN_ON__() +#define BSP_TURN_OFF_LED5() __bsp_LED5_TURN_OFF__() +#define BSP_TOGGLE_LED5() __bsp_LED5_TOGGLE__() +#define BSP_LED5_IS_ON() __bsp_LED5_IS_ON__() + +/* LED6 */ +#define BSP_TURN_ON_LED6() __bsp_LED6_TURN_ON__() +#define BSP_TURN_OFF_LED6() __bsp_LED6_TURN_OFF__() +#define BSP_TOGGLE_LED6() __bsp_LED6_TOGGLE__() +#define BSP_LED6_IS_ON() __bsp_LED6_IS_ON__() + +/* LED7 */ +#define BSP_TURN_ON_LED7() __bsp_LED7_TURN_ON__() +#define BSP_TURN_OFF_LED7() __bsp_LED7_TURN_OFF__() +#define BSP_TOGGLE_LED7() __bsp_LED7_TOGGLE__() +#define BSP_LED7_IS_ON() __bsp_LED7_IS_ON__() + +/* LED8 */ +#define BSP_TURN_ON_LED8() __bsp_LED8_TURN_ON__() +#define BSP_TURN_OFF_LED8() __bsp_LED8_TURN_OFF__() +#define BSP_TOGGLE_LED8() __bsp_LED8_TOGGLE__() +#define BSP_LED8_IS_ON() __bsp_LED8_IS_ON__() + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_InitLeds(void); + + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +#ifdef BSP_NO_LEDS +#error "ERROR: The LED driver is disabled. This file should not be included." +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_buttons.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_buttons.c new file mode 100755 index 0000000..b8f2018 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_buttons.c @@ -0,0 +1,97 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic button driver code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_buttons.h" +#include "bsp_button_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CONFIG_BUTTON1() __bsp_BUTTON1_CONFIG__() +#define BSP_CONFIG_BUTTON2() __bsp_BUTTON2_CONFIG__() +#define BSP_CONFIG_BUTTON3() __bsp_BUTTON3_CONFIG__() +#define BSP_CONFIG_BUTTON4() __bsp_BUTTON4_CONFIG__() +#define BSP_CONFIG_BUTTON5() __bsp_BUTTON5_CONFIG__() +#define BSP_CONFIG_BUTTON6() __bsp_BUTTON6_CONFIG__() +#define BSP_CONFIG_BUTTON7() __bsp_BUTTON7_CONFIG__() +#define BSP_CONFIG_BUTTON8() __bsp_BUTTON8_CONFIG__() + +#ifdef __bsp_BUTTON_EXTENDED_CONFIG__ +#define BSP_BUTTON_EXTENDED_CONFIG() __bsp_BUTTON_EXTENDED_CONFIG__() +#else +#define BSP_BUTTON_EXTENDED_CONFIG() +#endif + + +/************************************************************************************************** + * @fn BSP_InitButtons + * + * @brief Initialize button hardware and driver code. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitButtons(void) +{ + /* configure LEDs */ + BSP_CONFIG_BUTTON1(); + BSP_CONFIG_BUTTON2(); + BSP_CONFIG_BUTTON3(); + BSP_CONFIG_BUTTON4(); + BSP_CONFIG_BUTTON5(); + BSP_CONFIG_BUTTON6(); + BSP_CONFIG_BUTTON7(); + BSP_CONFIG_BUTTON8(); + + /* peform extended configuration if needed */ + BSP_BUTTON_EXTENDED_CONFIG(); +} + + +/************************************************************************************************** +*/ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h new file mode 100755 index 0000000..e9ae165 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h @@ -0,0 +1,203 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic button macro include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_GENERIC_BUTTONS_H +#define BSP_GENERIC_BUTTONS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_BUTTON__(port,bit,low) ((low) ? (!((port) & BV(bit))) : ((port) & BV(bit)) ) + + +/* ------------------------- populate BUTTON #1 macros ------------------------- */ +#define __bsp_NUM_BUTTON1_DEFINES__ ((defined __bsp_BUTTON1_PORT__) + \ + (defined __bsp_BUTTON1_BIT__) + \ + (defined __bsp_BUTTON1_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON1_DEFINES__ == 3) +#define __bsp_BUTTON1__() __bsp_BUTTON__( __bsp_BUTTON1_PORT__, __bsp_BUTTON1_BIT__, __bsp_BUTTON1_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON1_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON1_DEFINES__ == 0) +#define __bsp_BUTTON1__() /* no button */ 0 +#define __bsp_BUTTON1_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON1." +#endif + +/* ------------------------- populate BUTTON #2 macros ------------------------- */ +#define __bsp_NUM_BUTTON2_DEFINES__ ((defined __bsp_BUTTON2_PORT__) + \ + (defined __bsp_BUTTON2_BIT__) + \ + (defined __bsp_BUTTON2_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON2_DEFINES__ == 3) +#define __bsp_BUTTON2__() __bsp_BUTTON__( __bsp_BUTTON2_PORT__, __bsp_BUTTON2_BIT__, __bsp_BUTTON2_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON2_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON2_DEFINES__ == 0) +#define __bsp_BUTTON2__() /* no button */ 0 +#define __bsp_BUTTON2_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON2." +#endif + +/* ------------------------- populate BUTTON #3 macros ------------------------- */ +#define __bsp_NUM_BUTTON3_DEFINES__ ((defined __bsp_BUTTON3_PORT__) + \ + (defined __bsp_BUTTON3_BIT__) + \ + (defined __bsp_BUTTON3_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON3_DEFINES__ == 3) +#define __bsp_BUTTON3__() __bsp_BUTTON__( __bsp_BUTTON3_PORT__, __bsp_BUTTON3_BIT__, __bsp_BUTTON3_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON3_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON3_DEFINES__ == 0) +#define __bsp_BUTTON3__() /* no button */ 0 +#define __bsp_BUTTON3_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON3." +#endif + +/* ------------------------- populate BUTTON #4 macros ------------------------- */ +#define __bsp_NUM_BUTTON4_DEFINES__ ((defined __bsp_BUTTON4_PORT__) + \ + (defined __bsp_BUTTON4_BIT__) + \ + (defined __bsp_BUTTON4_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON4_DEFINES__ == 3) +#define __bsp_BUTTON4__() __bsp_BUTTON__( __bsp_BUTTON4_PORT__, __bsp_BUTTON4_BIT__, __bsp_BUTTON4_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON4_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON4_DEFINES__ == 0) +#define __bsp_BUTTON4__() /* no button */ 0 +#define __bsp_BUTTON4_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON4." +#endif + +/* ------------------------- populate BUTTON #5 macros ------------------------- */ +#define __bsp_NUM_BUTTON5_DEFINES__ ((defined __bsp_BUTTON5_PORT__) + \ + (defined __bsp_BUTTON5_BIT__) + \ + (defined __bsp_BUTTON5_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON5_DEFINES__ == 3) +#define __bsp_BUTTON5__() __bsp_BUTTON__( __bsp_BUTTON5_PORT__, __bsp_BUTTON5_BIT__, __bsp_BUTTON5_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON5_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON5_DEFINES__ == 0) +#define __bsp_BUTTON5__() /* no button */ 0 +#define __bsp_BUTTON5_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON5." +#endif + +/* ------------------------- populate BUTTON #6 macros ------------------------- */ +#define __bsp_NUM_BUTTON6_DEFINES__ ((defined __bsp_BUTTON6_PORT__) + \ + (defined __bsp_BUTTON6_BIT__) + \ + (defined __bsp_BUTTON6_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON6_DEFINES__ == 3) +#define __bsp_BUTTON6__() __bsp_BUTTON__( __bsp_BUTTON6_PORT__, __bsp_BUTTON6_BIT__, __bsp_BUTTON6_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON6_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON6_DEFINES__ == 0) +#define __bsp_BUTTON6__() /* no button */ 0 +#define __bsp_BUTTON6_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON6." +#endif + +/* ------------------------- populate BUTTON #7 macros ------------------------- */ +#define __bsp_NUM_BUTTON7_DEFINES__ ((defined __bsp_BUTTON7_PORT__) + \ + (defined __bsp_BUTTON7_BIT__) + \ + (defined __bsp_BUTTON7_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON7_DEFINES__ == 3) +#define __bsp_BUTTON7__() __bsp_BUTTON__( __bsp_BUTTON7_PORT__, __bsp_BUTTON7_BIT__, __bsp_BUTTON7_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON7_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON7_DEFINES__ == 0) +#define __bsp_BUTTON7__() /* no button */ 0 +#define __bsp_BUTTON7_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON7." +#endif + +/* ------------------------- populate BUTTON #8 macros ------------------------- */ +#define __bsp_NUM_BUTTON8_DEFINES__ ((defined __bsp_BUTTON8_PORT__) + \ + (defined __bsp_BUTTON8_BIT__) + \ + (defined __bsp_BUTTON8_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON8_DEFINES__ == 3) +#define __bsp_BUTTON8__() __bsp_BUTTON__( __bsp_BUTTON8_PORT__, __bsp_BUTTON8_BIT__, __bsp_BUTTON8_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON8_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON8_DEFINES__ == 0) +#define __bsp_BUTTON8__() /* no button */ 0 +#define __bsp_BUTTON8_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON8." +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* -------------------- number of buttons defined -------------------- */ +#ifndef __bsp_NUM_BUTTONS__ +#error "ERROR: Number of buttons is not specified." +#else +#if ((__bsp_NUM_BUTTONS__ > 8) || (__bsp_NUM_BUTTONS__ < 0)) +#error "ERROR: Unsupported number of buttons specified. Maximum is eight." +#endif +#endif + +#if (((__bsp_NUM_BUTTON1_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON2_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON3_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON4_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON5_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON6_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON7_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON8_DEFINES__ != 0)) != __bsp_NUM_BUTTONS__) +#error "ERROR: Inconsistency between defined macros and specified number of buttons." +#endif + +/* -------------------- debounce macro -------------------- */ +#ifndef __bsp_BUTTON_DEBOUNCE_WAIT__ +#error "ERROR: Debounce delay macro is missing." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h new file mode 100755 index 0000000..6e1e42b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h @@ -0,0 +1,278 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic LED macro include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_GENERIC_LEDS_H +#define BSP_GENERIC_LEDS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ + +/* + * Note : The conditionals in the following macros evaulate compile time constants. + * Any compiler worth its salt will optimize these conditionals out for the + * smallest possible code. + */ + +#define __bsp_LED_TURN_ON__(bit,port,ddr,low) \ + st( if (low) { port &= ~BV(bit); } else { port |= BV(bit); } ) + +#define __bsp_LED_TURN_OFF__(bit,port,ddr,low) \ + st( if (low) { port |= BV(bit); } else { port &= ~BV(bit); } ) + +#define __bsp_LED_IS_ON__(bit,port,ddr,low) \ + ( (low) ? (!((port) & BV(bit))) : ((port) & BV(bit)) ) + +#define __bsp_LED_TOGGLE__(bit,port,ddr,low) st( port ^= BV(bit); ) +#define __bsp_LED_CONFIG__(bit,port,ddr,low) st( ddr |= BV(bit); ) + + + +/* ------------------------- populate LED1 macros ------------------------- */ +#define __bsp_NUM_LED1_DEFINES__ ((defined __bsp_LED1_BIT__) + \ + (defined __bsp_LED1_PORT__) + \ + (defined __bsp_LED1_DDR__) + \ + (defined __bsp_LED1_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED1_DEFINES__ == 4) +#define __bsp_LED1_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED1_DEFINES__ == 0) +#define __bsp_LED1_TURN_ON__() /* no LED */ +#define __bsp_LED1_TURN_OFF__() /* no LED */ +#define __bsp_LED1_TOGGLE__() /* no LED */ +#define __bsp_LED1_IS_ON__() /* no LED */ 0 +#define __bsp_LED1_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED1." +#endif + + +/* ------------------------- populate LED2 macros ------------------------- */ +#define __bsp_NUM_LED2_DEFINES__ ((defined __bsp_LED2_BIT__) + \ + (defined __bsp_LED2_PORT__) + \ + (defined __bsp_LED2_DDR__) + \ + (defined __bsp_LED2_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED2_DEFINES__ == 4) +#define __bsp_LED2_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED2_DEFINES__ == 0) +#define __bsp_LED2_TURN_ON__() /* no LED */ +#define __bsp_LED2_TURN_OFF__() /* no LED */ +#define __bsp_LED2_TOGGLE__() /* no LED */ +#define __bsp_LED2_IS_ON__() /* no LED */ 0 +#define __bsp_LED2_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED2." +#endif + + +/* ------------------------- populate LED3 macros ------------------------- */ +#define __bsp_NUM_LED3_DEFINES__ ((defined __bsp_LED3_BIT__) + \ + (defined __bsp_LED3_PORT__) + \ + (defined __bsp_LED3_DDR__) + \ + (defined __bsp_LED3_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED3_DEFINES__ == 4) +#define __bsp_LED3_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED3_DEFINES__ == 0) +#define __bsp_LED3_TURN_ON__() /* no LED */ +#define __bsp_LED3_TURN_OFF__() /* no LED */ +#define __bsp_LED3_TOGGLE__() /* no LED */ +#define __bsp_LED3_IS_ON__() /* no LED */ 0 +#define __bsp_LED3_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED3." +#endif + + +/* ------------------------- populate LED4 macros ------------------------- */ +#define __bsp_NUM_LED4_DEFINES__ ((defined __bsp_LED4_BIT__) + \ + (defined __bsp_LED4_PORT__) + \ + (defined __bsp_LED4_DDR__) + \ + (defined __bsp_LED4_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED4_DEFINES__ == 4) +#define __bsp_LED4_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED4_DEFINES__ == 0) +#define __bsp_LED4_TURN_ON__() /* no LED */ +#define __bsp_LED4_TURN_OFF__() /* no LED */ +#define __bsp_LED4_TOGGLE__() /* no LED */ +#define __bsp_LED4_IS_ON__() /* no LED */ 0 +#define __bsp_LED4_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED4." +#endif + +/* ------------------------- populate LED5 macros ------------------------- */ +#define __bsp_NUM_LED5_DEFINES__ ((defined __bsp_LED5_BIT__) + \ + (defined __bsp_LED5_PORT__) + \ + (defined __bsp_LED5_DDR__) + \ + (defined __bsp_LED5_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED5_DEFINES__ == 4) +#define __bsp_LED5_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED5_DEFINES__ == 0) +#define __bsp_LED5_TURN_ON__() /* no LED */ +#define __bsp_LED5_TURN_OFF__() /* no LED */ +#define __bsp_LED5_TOGGLE__() /* no LED */ +#define __bsp_LED5_IS_ON__() /* no LED */ 0 +#define __bsp_LED5_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED5." +#endif + +/* ------------------------- populate LED6 macros ------------------------- */ +#define __bsp_NUM_LED6_DEFINES__ ((defined __bsp_LED6_BIT__) + \ + (defined __bsp_LED6_PORT__) + \ + (defined __bsp_LED6_DDR__) + \ + (defined __bsp_LED6_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED6_DEFINES__ == 4) +#define __bsp_LED6_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED6_DEFINES__ == 0) +#define __bsp_LED6_TURN_ON__() /* no LED */ +#define __bsp_LED6_TURN_OFF__() /* no LED */ +#define __bsp_LED6_TOGGLE__() /* no LED */ +#define __bsp_LED6_IS_ON__() /* no LED */ 0 +#define __bsp_LED6_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED6." +#endif + +/* ------------------------- populate LED7 macros ------------------------- */ +#define __bsp_NUM_LED7_DEFINES__ ((defined __bsp_LED7_BIT__) + \ + (defined __bsp_LED7_PORT__) + \ + (defined __bsp_LED7_DDR__) + \ + (defined __bsp_LED7_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED7_DEFINES__ == 4) +#define __bsp_LED7_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED7_DEFINES__ == 0) +#define __bsp_LED7_TURN_ON__() /* no LED */ +#define __bsp_LED7_TURN_OFF__() /* no LED */ +#define __bsp_LED7_TOGGLE__() /* no LED */ +#define __bsp_LED7_IS_ON__() /* no LED */ 0 +#define __bsp_LED7_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED7." +#endif + +/* ------------------------- populate LED8 macros ------------------------- */ +#define __bsp_NUM_LED8_DEFINES__ ((defined __bsp_LED8_BIT__) + \ + (defined __bsp_LED8_PORT__) + \ + (defined __bsp_LED8_DDR__) + \ + (defined __bsp_LED8_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED8_DEFINES__ == 4) +#define __bsp_LED8_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED8_DEFINES__ == 0) +#define __bsp_LED8_TURN_ON__() /* no LED */ +#define __bsp_LED8_TURN_OFF__() /* no LED */ +#define __bsp_LED8_TOGGLE__() /* no LED */ +#define __bsp_LED8_IS_ON__() /* no LED */ 0 +#define __bsp_LED8_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED8." +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* -------------------- number of LEDs defined -------------------- */ +#ifndef __bsp_NUM_LEDS__ +#error "ERROR: Number of LEDs is not specified." +#else +#if ((__bsp_NUM_LEDS__ > 8) || (__bsp_NUM_LEDS__ < 0)) +#error "ERROR: Unsupported number of LEDs specified. Maximum is eight." +#endif +#endif + +#if (((__bsp_NUM_LED1_DEFINES__ != 0) + \ + (__bsp_NUM_LED2_DEFINES__ != 0) + \ + (__bsp_NUM_LED3_DEFINES__ != 0) + \ + (__bsp_NUM_LED4_DEFINES__ != 0) + \ + (__bsp_NUM_LED5_DEFINES__ != 0) + \ + (__bsp_NUM_LED6_DEFINES__ != 0) + \ + (__bsp_NUM_LED7_DEFINES__ != 0) + \ + (__bsp_NUM_LED8_DEFINES__ != 0)) != __bsp_NUM_LEDS__) +#error "ERROR: Inconsistency between defined macros and specified number of LEDs." +#endif + +/* -------------------- blink delay loop count -------------------- */ +#ifndef __bsp_LED_BLINK_LOOP_COUNT__ +#error "ERROR: Blink delay count is missing." +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_leds.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_leds.c new file mode 100755 index 0000000..4bc83e0 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/drivers/code/bsp_leds.c @@ -0,0 +1,107 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic LED driver code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_leds.h" +#include "bsp_led_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CONFIG_LED1() __bsp_LED1_CONFIG__() +#define BSP_CONFIG_LED2() __bsp_LED2_CONFIG__() +#define BSP_CONFIG_LED3() __bsp_LED3_CONFIG__() +#define BSP_CONFIG_LED4() __bsp_LED4_CONFIG__() +#define BSP_CONFIG_LED5() __bsp_LED5_CONFIG__() +#define BSP_CONFIG_LED6() __bsp_LED6_CONFIG__() +#define BSP_CONFIG_LED7() __bsp_LED7_CONFIG__() +#define BSP_CONFIG_LED8() __bsp_LED8_CONFIG__() + +#ifdef __bsp_LED_EXTENDED_CONFIG__ +#define BSP_LED_EXTENDED_CONFIG() __bsp_LED_EXTENDED_CONFIG__() +#else +#define BSP_LED_EXTENDED_CONFIG() +#endif + + +/************************************************************************************************** + * @fn BSP_InitLeds + * + * @brief Initialize LED hardware and driver. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitLeds(void) +{ + /* configure LEDs */ + BSP_CONFIG_LED1(); + BSP_CONFIG_LED2(); + BSP_CONFIG_LED3(); + BSP_CONFIG_LED4(); + BSP_CONFIG_LED5(); + BSP_CONFIG_LED6(); + BSP_CONFIG_LED7(); + BSP_CONFIG_LED8(); + + /* peform extended configuration if needed */ + BSP_LED_EXTENDED_CONFIG(); + + /* turn all LEDs off as power-up default */ + BSP_TURN_OFF_LED1(); + BSP_TURN_OFF_LED2(); + BSP_TURN_OFF_LED3(); + BSP_TURN_OFF_LED4(); + BSP_TURN_OFF_LED5(); + BSP_TURN_OFF_LED6(); + BSP_TURN_OFF_LED7(); + BSP_TURN_OFF_LED8(); +} + + +/************************************************************************************************** +*/ + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h new file mode 100755 index 0000000..af9357f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h @@ -0,0 +1,141 @@ +/************************************************************************************************** + Filename: bsp_msp430_defs.h + Revised: $Date: 2009-10-11 18:52:46 -0700 (Sun, 11 Oct 2009) $ + Revision: $Revision: 20897 $ + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * MCU : Texas Instruments MSP430 family + * Microcontroller definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_MSP430_DEFS_H +#define BSP_MSP430_DEFS_H + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_MCU_MSP430 + +/* ------------------------------------------------------------------------------------------------ + * Compiler Abstraction + * ------------------------------------------------------------------------------------------------ + */ + +/* ---------------------- IAR Compiler ---------------------- */ +#ifdef __IAR_SYSTEMS_ICC__ +#define BSP_COMPILER_IAR + +#if (__VER__ < 342) + #error "ERROR: This IAR compiler port requires at least revision v3.42A." +/* + * Compiler versions previous to v3.42A do not have the universal msp430.h include file. + * To use an earlier version of the compiler, replace the above #error statement with + * the appropriate, device specific #include statement. + */ +#endif + +/* Workaround for release v3.42A - the msp430.h file did not include support for some devices */ +#if ((__VER__ == 342) && (__SUBVERSION__ == 'A')) && \ + (defined (__MSP430F1610__) || defined (__MSP430F1611__) || defined (__MSP430F1612__)) +#include +#else +#include +#endif + +#define __bsp_ISTATE_T__ istate_t +#define __bsp_ISR_FUNCTION__(f,v) __bsp_QUOTED_PRAGMA__(vector=v) __interrupt void f(void); \ + __bsp_QUOTED_PRAGMA__(vector=v) __interrupt void f(void) + +/* Initialization call provided in IAR environment before standard C-startup */ +#include +#define BSP_EARLY_INIT(void) __intrinsic int __low_level_init(void) + +/* ---------------------- Code Composer ---------------------- */ +#elif (defined __TI_COMPILER_VERSION__) && (defined __MSP430__) +#define BSP_COMPILER_CODE_COMPOSER + +/* At time of 1.1.0 release, CC430 support not in msp430.h */ +#if (__CC430F6137__) +#include +#else +#include +#endif + +#define __bsp_ISTATE_T__ unsigned short +#define __bsp_ISR_FUNCTION__(f,v) __bsp_QUOTED_PRAGMA__(vector=v) __interrupt void f(void) + +/* Initialization call provided in CCE environment before standard C-startup */ +// [BM] Cannot have a second low level init! Already done by application! +//#define BSP_EARLY_INIT(void) int _system_pre_init(void) + +/* ------------------ Unrecognized Compiler ------------------ */ +#else +#error "ERROR: Unknown compiler." +#endif + +#if (defined BSP_COMPILER_IAR) || (defined BSP_COMPILER_CODE_COMPOSER) +#include +#define __bsp_ENABLE_INTERRUPTS__() __enable_interrupt() +#define __bsp_DISABLE_INTERRUPTS__() __disable_interrupt() +#define __bsp_INTERRUPTS_ARE_ENABLED__() (__get_SR_register() & GIE) + +#define __bsp_GET_ISTATE__() __get_interrupt_state() +#define __bsp_RESTORE_ISTATE__(x) __set_interrupt_state(x) + +#define __bsp_QUOTED_PRAGMA__(x) _Pragma(#x) + +#endif + +/* ------------------------------------------------------------------------------------------------ + * Common + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_LITTLE_ENDIAN__ 1 +#define __bsp_CODE_MEMSPACE__ /* blank */ +#define __bsp_XDATA_MEMSPACE__ /* blank */ + +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed long int32_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; + +#ifndef NULL +#define NULL 0 +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/mrfi.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/mrfi.c new file mode 100755 index 0000000..5b7337b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/mrfi.c @@ -0,0 +1,87 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Top-level code file. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "mrfi_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * C Code Includes + * ------------------------------------------------------------------------------------------------ + */ + +/* ----- Radio Family 1 ----- */ +#if (defined MRFI_RADIO_FAMILY1) +#include "radios/family1/mrfi_radio.c" +#include "radios/family1/mrfi_spi.c" +#include "radios/common/mrfi_f1f2.c" +#include "bsp_external/mrfi_board.c" + +/* ----- Radio Family 2 ----- */ +#elif (defined MRFI_RADIO_FAMILY2) +#include "radios/family2/mrfi_radio.c" +#include "radios/common/mrfi_f1f2.c" + +/* ----- Radio Family 3 ----- */ +#elif (defined MRFI_RADIO_FAMILY3) +#include "bsp_external/mrfi_board.c" +#include "radios/family3/mrfi_spi.c" +#include "radios/family3/mrfi_radio.c" + +/* ----- Radio Family 4 ----- */ +#elif (defined MRFI_RADIO_FAMILY4) +#include "radios/family4/mrfi_radio.c" + +/* ----- Radio Family 5 ----- */ +#elif (defined MRFI_RADIO_FAMILY5) +#include "radios/family5/mrfi_radio.c" +#include "radios/family5/mrfi_radio_interface.c" + +/* ----- Radio Family 6 ----- */ +#elif (defined MRFI_RADIO_FAMILY6) +#include "radios/family6/mrfi_radio.c" + +#else +#error "ERROR: Radio family is not defined." +#endif + + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/mrfi.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/mrfi.h new file mode 100755 index 0000000..ca49e02 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/mrfi.h @@ -0,0 +1,182 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Include file for all MRFI services. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_H +#define MRFI_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "mrfi_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_NUM_LOGICAL_CHANS __mrfi_NUM_LOGICAL_CHANS__ + +#define MRFI_NUM_POWER_SETTINGS __mrfi_NUM_POWER_SETTINGS__ + +/* return values for MRFI_Transmit */ +#define MRFI_TX_RESULT_SUCCESS 0 +#define MRFI_TX_RESULT_FAILED 1 + +/* transmit type parameter for MRFI_Transmit */ +#define MRFI_TX_TYPE_FORCED 0 +#define MRFI_TX_TYPE_CCA 1 + +/* Network header size definition */ +/* ********************************* NOTE **************************************** + * There is a dependency here that really shouldn't exist. A reimplementation + * is necessary to avoid it. + * + * MRFI allocates the frame buffer which means it needs to know at compile time + * how big the buffer is. This means in must know the NWK header size, the + * maximum NWK and User application payload sizes and whether Security is enabled. + * ******************************************************************************** + */ +#ifndef SMPL_SECURE +#define NWK_HDR_SIZE 3 +#define NWK_PAYLOAD MAX_NWK_PAYLOAD +#else +#define NWK_HDR_SIZE 6 +#define NWK_PAYLOAD (MAX_NWK_PAYLOAD+4) +#endif + +/* if external code has defined a maximum payload, use that instead of default */ +#ifdef MAX_APP_PAYLOAD +#ifndef MAX_NWK_PAYLOAD +#error ERROR: MAX_NWK_PAYLOAD not defined +#endif +#if MAX_APP_PAYLOAD < NWK_PAYLOAD +#define MAX_PAYLOAD NWK_PAYLOAD +#else +#define MAX_PAYLOAD MAX_APP_PAYLOAD +#endif +#define MRFI_MAX_PAYLOAD_SIZE (MAX_PAYLOAD+NWK_HDR_SIZE) /* SimpliciTI payload size plus six byte overhead */ +#endif + + +/* frame definitions */ +#define MRFI_ADDR_SIZE __mrfi_ADDR_SIZE__ +#ifndef MRFI_MAX_PAYLOAD_SIZE +#define MRFI_MAX_PAYLOAD_SIZE __mrfi_MAX_PAYLOAD_SIZE__ +#endif +#define MRFI_MAX_FRAME_SIZE (MRFI_MAX_PAYLOAD_SIZE + __mrfi_FRAME_OVERHEAD_SIZE__) +#define MRFI_RX_METRICS_SIZE __mrfi_RX_METRICS_SIZE__ +#define MRFI_RX_METRICS_RSSI_OFS __mrfi_RX_METRICS_RSSI_OFS__ +#define MRFI_RX_METRICS_CRC_LQI_OFS __mrfi_RX_METRICS_CRC_LQI_OFS__ + +/* Radio States */ +#define MRFI_RADIO_STATE_UNKNOWN 0 +#define MRFI_RADIO_STATE_OFF 1 +#define MRFI_RADIO_STATE_IDLE 2 +#define MRFI_RADIO_STATE_RX 3 + +/* Platform constant used to calculate worst-case for an application + * acknowledgment delay. Used in the NWK_REPLY_DELAY() macro. + * + + processing time on peer + | round trip + | | max number of replays + | | | number of backoff opportunities + | | | | average number of backoffs + | | | | | */ +#define PLATFORM_FACTOR_CONSTANT (2 + 2*(MAX_HOPS*(MRFI_CCA_RETRIES*(8*MRFI_BACKOFF_PERIOD_USECS)/1000))) + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_GET_PAYLOAD_LEN(p) __mrfi_GET_PAYLOAD_LEN__(p) +#define MRFI_SET_PAYLOAD_LEN(p,x) __mrfi_SET_PAYLOAD_LEN__(p,x) + +#define MRFI_P_DST_ADDR(p) __mrfi_P_DST_ADDR__(p) +#define MRFI_P_SRC_ADDR(p) __mrfi_P_SRC_ADDR__(p) +#define MRFI_P_PAYLOAD(p) __mrfi_P_PAYLOAD__(p) + +/* ------------------------------------------------------------------------------------------------ + * Typdefs + * ------------------------------------------------------------------------------------------------ + */ +typedef struct +{ + uint8_t frame[MRFI_MAX_FRAME_SIZE]; + uint8_t rxMetrics[MRFI_RX_METRICS_SIZE]; +} mrfiPacket_t; + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void MRFI_Init(void); +uint8_t MRFI_Transmit(mrfiPacket_t *, uint8_t); +void MRFI_Receive(mrfiPacket_t *); +void MRFI_RxCompleteISR(void); /* populated by code using MRFI */ +uint8_t MRFI_GetRadioState(void); +void MRFI_RxOn(void); +void MRFI_RxIdle(void); +int8_t MRFI_Rssi(void); +void MRFI_SetLogicalChannel(uint8_t); +uint8_t MRFI_SetRxAddrFilter(uint8_t *); +void MRFI_EnableRxAddrFilter(void); +void MRFI_DisableRxAddrFilter(void); +void MRFI_Sleep(void); +void MRFI_WakeUp(void); +uint8_t MRFI_RandomByte(void); +void MRFI_DelayMs(uint16_t); +void MRFI_ReplyDelay(void); +void MRFI_PostKillSem(void); +void MRFI_SetRFPwr(uint8_t); + +/* ------------------------------------------------------------------------------------------------ + * Global Constants + * ------------------------------------------------------------------------------------------------ + */ +extern const uint8_t mrfiBroadcastAddr[]; + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/mrfi_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/mrfi_defs.h new file mode 100755 index 0000000..2e1c546 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/mrfi_defs.h @@ -0,0 +1,226 @@ +/************************************************************************************************** + Revised: $Date: 2009-01-13 16:32:00 -0700 (Wed, 13 Jan 2009) $ + Revision: $Revision: 18768 $ + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Definition and abstraction for radio targets. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ +#ifndef MRFI_DEFS_H +#define MRFI_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + + +/* ------------------------------------------------------------------------------------------------ + * Common Defines + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_CCA_RETRIES 4 + +#define MRFI_ASSERT(x) BSP_ASSERT(x) +#define MRFI_FORCE_ASSERT() BSP_FORCE_ASSERT() +#define MRFI_ASSERTS_ARE_ON BSP_ASSERTS_ARE_ON + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family Assigment + * ------------------------------------------------------------------------------------------------ + */ + +/* ------ Radio Family 1 ------ */ +#if (defined MRFI_CC1100) /* Sub 1 GHz RF Transceiver */ || \ + (defined MRFI_CC1101) /* Sub 1 GHz RF Transceiver */ || \ + (defined MRFI_CC1100E_470) /* Sub 1 GHz RF Transceiver (CC1100E Asia) */ || \ + (defined MRFI_CC1100E_950) /* Sub 1 GHz RF Transceiver (CC1100E Asia) */ || \ + (defined MRFI_CC2500) /* 2.4 GHz RF Transceiver */ +#define MRFI_RADIO_FAMILY1 + +/* ------ Radio Family 2 ------ */ +#elif (defined MRFI_CC1110) /* Sub 1 GHz SoC */ || \ + (defined MRFI_CC1111) /* Sub 1 GHz SoC with USB controller */ || \ + (defined MRFI_CC2510) /* 2.4 GHz SoC */ || \ + (defined MRFI_CC2511) /* 2.4 GHz SoC with USB controller */ +#define MRFI_RADIO_FAMILY2 + +/* ------ Radio Family 3 ------ */ +#elif (defined MRFI_CC2420) /* 2.4 GHz IEEE 802.15.4 RF Transceiver */ || \ + (defined MRFI_CC2520) /* 2.4 GHz IEEE 802.15.4 RF Transceiver */ + +#define MRFI_RADIO_FAMILY3 + +/* ------ Radio Family 4 ------ */ +#elif (defined MRFI_CC2430) /* 2.4 GHz IEEE 802.15.4 SoC */ || \ + (defined MRFI_CC2431) /* 2.4 GHz IEEE 802.15.4 SoC */ +#define MRFI_RADIO_FAMILY4 + +/* ------ Radio Family 5 ------ */ +#elif (defined MRFI_CC430) /* Sub 1 GHz MSP SoC */ +#define MRFI_RADIO_FAMILY5 + +/* ------ Radio Family 6 ------ */ +#elif (defined MRFI_CC2530) /* 2.4 GHz IEEE 802.15.4 SoC */ + +#define MRFI_RADIO_FAMILY6 + +#else +#error "ERROR: Unknown or missing radio selection." +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family 1 / Radio Family 2 / Radio Family 5 + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_RADIO_FAMILY1) || (defined MRFI_RADIO_FAMILY2) || (defined MRFI_RADIO_FAMILY5) + +#define __mrfi_LENGTH_FIELD_SIZE__ 1 +#define __mrfi_ADDR_SIZE__ 4 +#define __mrfi_MAX_PAYLOAD_SIZE__ 20 + +#define __mrfi_RX_METRICS_SIZE__ 2 +#define __mrfi_RX_METRICS_RSSI_OFS__ 0 +#define __mrfi_RX_METRICS_CRC_LQI_OFS__ 1 +#define __mrfi_RX_METRICS_CRC_OK_MASK__ 0x80 +#define __mrfi_RX_METRICS_LQI_MASK__ 0x7F + +#define __mrfi_NUM_LOGICAL_CHANS__ 4 +#define __mrfi_NUM_POWER_SETTINGS__ 3 + +#define __mrfi_BACKOFF_PERIOD_USECS__ 250 + +#define __mrfi_LENGTH_FIELD_OFS__ 0 +#define __mrfi_DST_ADDR_OFS__ (__mrfi_LENGTH_FIELD_OFS__ + __mrfi_LENGTH_FIELD_SIZE__) +#define __mrfi_SRC_ADDR_OFS__ (__mrfi_DST_ADDR_OFS__ + __mrfi_ADDR_SIZE__) +#define __mrfi_PAYLOAD_OFS__ (__mrfi_SRC_ADDR_OFS__ + __mrfi_ADDR_SIZE__) + +#define __mrfi_HEADER_SIZE__ (2 * __mrfi_ADDR_SIZE__) +#define __mrfi_FRAME_OVERHEAD_SIZE__ (__mrfi_LENGTH_FIELD_SIZE__ + __mrfi_HEADER_SIZE__) + +#define __mrfi_GET_PAYLOAD_LEN__(p) ((p)->frame[__mrfi_LENGTH_FIELD_OFS__] - __mrfi_HEADER_SIZE__) +#define __mrfi_SET_PAYLOAD_LEN__(p,x) st( (p)->frame[__mrfi_LENGTH_FIELD_OFS__] = x + __mrfi_HEADER_SIZE__; ) + +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family 3 / Radio Family 4 / Radio Family 6 + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_RADIO_FAMILY3) || (defined MRFI_RADIO_FAMILY4) || (defined MRFI_RADIO_FAMILY6) + +#define __mrfi_LENGTH_FIELD_SIZE__ 1 +#define __mrfi_FCF_SIZE__ 2 +#define __mrfi_DSN_SIZE__ 1 +#define __mrfi_ADDR_SIZE__ 4 +#define __mrfi_MAX_PAYLOAD_SIZE__ 20 + +#define __mrfi_RX_METRICS_SIZE__ 2 +#define __mrfi_RX_METRICS_RSSI_OFS__ 0 +#define __mrfi_RX_METRICS_CRC_LQI_OFS__ 1 +#define __mrfi_RX_METRICS_CRC_OK_MASK__ 0x80 +#define __mrfi_RX_METRICS_LQI_MASK__ 0x7F + +#define __mrfi_NUM_LOGICAL_CHANS__ 4 +#define __mrfi_NUM_POWER_SETTINGS__ 3 + +#define __mrfi_BACKOFF_PERIOD_USECS__ 250 + +#define __mrfi_LENGTH_FIELD_OFS__ 0 +#define __mrfi_FCF_OFS__ (__mrfi_LENGTH_FIELD_OFS__ + __mrfi_LENGTH_FIELD_SIZE__) +#define __mrfi_DSN_OFS__ (__mrfi_FCF_OFS__ + __mrfi_FCF_SIZE__) +#define __mrfi_DST_ADDR_OFS__ (__mrfi_DSN_OFS__ + __mrfi_DSN_SIZE__) +#define __mrfi_SRC_ADDR_OFS__ (__mrfi_DST_ADDR_OFS__ + __mrfi_ADDR_SIZE__) +#define __mrfi_PAYLOAD_OFS__ (__mrfi_SRC_ADDR_OFS__ + __mrfi_ADDR_SIZE__) + +#define __mrfi_HEADER_SIZE__ ((2 * __mrfi_ADDR_SIZE__) + __mrfi_FCF_SIZE__ + __mrfi_DSN_SIZE__) +#define __mrfi_FRAME_OVERHEAD_SIZE__ (__mrfi_LENGTH_FIELD_SIZE__ + __mrfi_HEADER_SIZE__) + +#define __mrfi_GET_PAYLOAD_LEN__(p) ((p)->frame[__mrfi_LENGTH_FIELD_OFS__] - __mrfi_HEADER_SIZE__) +#define __mrfi_SET_PAYLOAD_LEN__(p,x) st( (p)->frame[__mrfi_LENGTH_FIELD_OFS__] = x + __mrfi_HEADER_SIZE__; ) + +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family Commonality + * ------------------------------------------------------------------------------------------------ + */ +#define __mrfi_P_DST_ADDR__(p) (&((p)->frame[__mrfi_DST_ADDR_OFS__])) +#define __mrfi_P_SRC_ADDR__(p) (&((p)->frame[__mrfi_SRC_ADDR_OFS__])) +#define __mrfi_P_PAYLOAD__(p) (&((p)->frame[__mrfi_PAYLOAD_OFS__])) + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* verify that only one supported radio is selected */ +#define MRFI_NUM_SUPPORTED_RADIOS_SELECTED ((defined MRFI_CC1100) + \ + (defined MRFI_CC1101) + \ + (defined MRFI_CC1110) + \ + (defined MRFI_CC1111) + \ + (defined MRFI_CC1100E_470) + \ + (defined MRFI_CC1100E_950) + \ + (defined MRFI_CC2500) + \ + (defined MRFI_CC2510) + \ + (defined MRFI_CC2511) + \ + (defined MRFI_CC2430) + \ + (defined MRFI_CC2431) + \ + (defined MRFI_CC2520) + \ + (defined MRFI_CC430) + \ + (defined MRFI_CC2530)) +#if (MRFI_NUM_SUPPORTED_RADIOS_SELECTED == 0) +#error "ERROR: A valid radio is not selected." +#elif (MRFI_NUM_SUPPORTED_RADIOS_SELECTED > 1) +#error "ERROR: More than one radio is selected." +#endif + +/* verify that a radio family is selected */ +#if (!defined MRFI_RADIO_FAMILY1) && \ + (!defined MRFI_RADIO_FAMILY2) && \ + (!defined MRFI_RADIO_FAMILY3) && \ + (!defined MRFI_RADIO_FAMILY4) && \ + (!defined MRFI_RADIO_FAMILY5) && \ + (!defined MRFI_RADIO_FAMILY6) +#error "ERROR: A radio family has not been assigned." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c new file mode 100755 index 0000000..9de4b6a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio.c @@ -0,0 +1,1778 @@ +/************************************************************************************************** + Revised: $Date: 2009-11-23 07:50:43 -0800 (Mon, 23 Nov 2009) $ + Revision: $Revision: 21225 $ + + Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS? + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radios: CC430 + * Primary code file for supported radios. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include +#include "mrfi.h" +#include "bsp.h" +#include "bsp_macros.h" +#include "bsp_external/mrfi_board_defs.h" +#include "mrfi_defs.h" +#include "mrfi_radio_interface.h" +#include "smartrf/CC430/smartrf_CC430.h" + +/* ------------------------------------------------------------------------------------------------ + * Global Constants + * ------------------------------------------------------------------------------------------------ + */ +const uint8_t mrfiBroadcastAddr[] = { 0xFF, 0xFF, 0xFF, 0xFF }; + +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(MRFI_ADDR_SIZE == ((sizeof(mrfiBroadcastAddr)/sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0]))); + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_CC430) + #define MRFI_RSSI_OFFSET 74 /* no units */ +#else + #error "ERROR: RSSI offset value not defined for this radio" +#endif + +#define MRFI_LENGTH_FIELD_OFS __mrfi_LENGTH_FIELD_OFS__ +#define MRFI_LENGTH_FIELD_SIZE __mrfi_LENGTH_FIELD_SIZE__ +#define MRFI_HEADER_SIZE __mrfi_HEADER_SIZE__ +#define MRFI_FRAME_BODY_OFS __mrfi_DST_ADDR_OFS__ +#define MRFI_BACKOFF_PERIOD_USECS __mrfi_BACKOFF_PERIOD_USECS__ + +#define MRFI_RANDOM_OFFSET 67 +#define MRFI_RANDOM_MULTIPLIER 109 +#define MRFI_MIN_SMPL_FRAME_SIZE (MRFI_HEADER_SIZE + NWK_HDR_SIZE) + +/* rx metrics definitions, known as appended "packet status bytes" in datasheet parlance */ +#define MRFI_RX_METRICS_CRC_OK_MASK __mrfi_RX_METRICS_CRC_OK_MASK__ +#define MRFI_RX_METRICS_LQI_MASK __mrfi_RX_METRICS_LQI_MASK__ + + +/* ---------- Radio Abstraction ---------- */ + +#define MRFI_RADIO_PARTNUM 0x00 +#define MRFI_RADIO_VERSION 0x06 + +/* GDO0 == PA_PD signal */ +#define MRFI_SETTING_IOCFG0 27 + +/* GDO1 == RSSI_VALID signal */ +#define MRFI_SETTING_IOCFG1 30 + +/* Main Radio Control State Machine control configuration: + * Auto Calibrate - when going from IDLE to RX/TX + * XOSC is OFF in Sleep state. + */ +#define MRFI_SETTING_MCSM0 (0x10) + +/* Main Radio Control State Machine control configuration: + * - Remain RX state after RX + * - Go to IDLE after TX + * - RSSI below threshold and NOT receiving. + */ +#define MRFI_SETTING_MCSM1 0x3C + +/* + * Packet Length - Setting for maximum allowed packet length. + * The PKTLEN setting does not include the length field but maximum frame size does. + * Subtract length field size from maximum frame size to get value for PKTLEN. + */ +#define MRFI_SETTING_PKTLEN (MRFI_MAX_FRAME_SIZE - MRFI_LENGTH_FIELD_SIZE) + +/* Packet automation control - Original value except WHITE_DATA is extracted from SmartRF setting. */ +#define MRFI_SETTING_PKTCTRL0 (0x05 | (SMARTRF_SETTING_PKTCTRL0 & BV(6))) + +/* FIFO threshold - this register has fields that need to be configured for the CC1101 */ +#define MRFI_SETTING_FIFOTHR (0x07 | (SMARTRF_SETTING_FIFOTHR & (BV(4)|BV(5)|BV(6)|BV(7)))) + +/* Max time we can be in a critical section within the delay function. + * This could be fine-tuned by observing the overhead is calling the bsp delay + * function. The overhead should be very small compared to this value. + */ +#define MRFI_MAX_DELAY_US 16 /* usec */ + +/* Packet automation control - base value is power up value whick has APPEND_STATUS enabled; no CRC autoflush */ +#define PKTCTRL1_BASE_VALUE BV(2) +#define PKTCTRL1_ADDR_FILTER_OFF PKTCTRL1_BASE_VALUE +#define PKTCTRL1_ADDR_FILTER_ON (PKTCTRL1_BASE_VALUE | (BV(0)|BV(1))) + +#ifdef MRFI_ASSERTS_ARE_ON +#define RX_FILTER_ADDR_INITIAL_VALUE 0xFF +#endif + + /* The SW timer is calibrated by adjusting the call to the microsecond delay + * routine. This allows maximum calibration control with repects to the longer + * times requested by applicationsd and decouples internal from external calls + * to the microsecond routine which can be calibrated independently. + */ +#if defined(SW_TIMER) +#define APP_USEC_VALUE 1000 +#else +#define APP_USEC_VALUE 1000 +#endif + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_ENABLE_SYNC_PIN_INT() (RF1AIE |= BV(9)) +#define MRFI_DISABLE_SYNC_PIN_INT() (RF1AIE &= ~BV(9)) +#define MRFI_CLEAR_SYNC_PIN_INT_FLAG() (RF1AIFG &= ~BV(9)) +#define MRFI_SYNC_PIN_INT_IS_ENABLED() (RF1AIE & BV(9)) +#define MRFI_SYNC_PIN_IS_HIGH() (RF1AIN & BV(9)) +#define MRFI_SYNC_PIN_INT_FLAG_IS_SET() (RF1AIFG & BV(9)) + + +#define MRFI_CLEAR_PAPD_PIN_INT_FLAG() (RF1AIFG &= ~BV(0)) +#define MRFI_PAPD_PIN_IS_HIGH() (RF1AIN & BV(0)) +#define MRFI_PAPD_INT_FLAG_IS_SET() (RF1AIFG & BV(0)) + + +/* RSSI valid signal is available on the GDO_1 */ +#define MRFI_RSSI_VALID_WAIT() while(!(RF1AIN & BV(1))); + + +/* Abstract radio interface calls. Could use these later to + * merge code from similar radio but different interface. + */ +#define MRFI_STROBE(cmd) mrfiRadioInterfaceCmdStrobe(cmd) +#define MRFI_RADIO_REG_READ(reg) mrfiRadioInterfaceReadReg(reg) +#define MRFI_RADIO_REG_WRITE(reg, value) mrfiRadioInterfaceWriteReg(reg, value) +#define MRFI_RADIO_WRITE_TX_FIFO(pData, len) mrfiRadioInterfaceWriteTxFifo(pData, len) +#define MRFI_RADIO_READ_RX_FIFO(pData, len) mrfiRadioInterfaceReadRxFifo(pData, len) + + +#define MRFI_STROBE_IDLE_AND_WAIT() \ +{ \ + MRFI_STROBE( SIDLE ); \ + /* Wait for XOSC to be stable and radio in IDLE state */ \ + while (MRFI_STROBE( SNOP ) & 0xF0) ; \ +} + + +/* ------------------------------------------------------------------------------------------------ + * Local Constants + * ------------------------------------------------------------------------------------------------ + */ +const uint8_t mrfiRadioCfg[][2] = +{ + /* internal radio configuration */ + { IOCFG0, MRFI_SETTING_IOCFG0 }, /* Configure GDO_0 to output PA_PD signal (low during TX, high otherwise). */ + { IOCFG1, MRFI_SETTING_IOCFG1 }, /* Configure GDO_1 to output RSSI_VALID signal (high when RSSI is valid, low otherwise). */ + { MCSM1, MRFI_SETTING_MCSM1 }, /* CCA mode, RX_OFF_MODE and TX_OFF_MODE */ + { MCSM0, MRFI_SETTING_MCSM0 }, /* AUTO_CAL and XOSC state in sleep */ + { PKTLEN, MRFI_SETTING_PKTLEN }, + { PKTCTRL0, MRFI_SETTING_PKTCTRL0 }, + { FIFOTHR, MRFI_SETTING_FIFOTHR }, + +/* imported SmartRF radio configuration */ + + { FSCTRL1, SMARTRF_SETTING_FSCTRL1 }, + { FSCTRL0, SMARTRF_SETTING_FSCTRL0 }, + { FREQ2, SMARTRF_SETTING_FREQ2 }, + { FREQ1, SMARTRF_SETTING_FREQ1 }, + { FREQ0, SMARTRF_SETTING_FREQ0 }, + { MDMCFG4, SMARTRF_SETTING_MDMCFG4 }, + { MDMCFG3, SMARTRF_SETTING_MDMCFG3 }, + { MDMCFG2, SMARTRF_SETTING_MDMCFG2 }, + { MDMCFG1, SMARTRF_SETTING_MDMCFG1 }, + { MDMCFG0, SMARTRF_SETTING_MDMCFG0 }, + { DEVIATN, SMARTRF_SETTING_DEVIATN }, + { FOCCFG, SMARTRF_SETTING_FOCCFG }, + { BSCFG, SMARTRF_SETTING_BSCFG }, + { AGCCTRL2, SMARTRF_SETTING_AGCCTRL2 }, + { AGCCTRL1, SMARTRF_SETTING_AGCCTRL1 }, + { AGCCTRL0, SMARTRF_SETTING_AGCCTRL0 }, + { FREND1, SMARTRF_SETTING_FREND1 }, + { FREND0, SMARTRF_SETTING_FREND0 }, + { FSCAL3, SMARTRF_SETTING_FSCAL3 }, + { FSCAL2, SMARTRF_SETTING_FSCAL2 }, + { FSCAL1, SMARTRF_SETTING_FSCAL1 }, + { FSCAL0, SMARTRF_SETTING_FSCAL0 }, + { TEST2, SMARTRF_SETTING_TEST2 }, + { TEST1, SMARTRF_SETTING_TEST1 }, + { TEST0, SMARTRF_SETTING_TEST0 }, +}; + + +/* + * Logical channel table - this table translates logical channel into + * actual radio channel number. Channel 0, the default channel, is + * determined by the channel exported from SmartRF Studio. The other + * table entries are derived from that default. Each derived channel is + * masked with 0xFF to prevent generation of an illegal channel number. + * + * This table is easily customized. Just replace or add entries as needed. + * If the number of entries changes, the corresponding #define must also + * be adjusted. It is located in mrfi_defs.h and is called __mrfi_NUM_LOGICAL_CHANS__. + * The static assert below ensures that there is no mismatch. + */ +// [BM] Changed channel assignment to comply with local regulations +#ifdef ISM_EU +static const uint8_t mrfiLogicalChanTable[] = +{ + 0, + 50, + 80, + 110 +}; +#else + #ifdef ISM_US + static const uint8_t mrfiLogicalChanTable[] = + { + 20, + 50, + 80, + 110 + }; + #else + #ifdef ISM_LF + static const uint8_t mrfiLogicalChanTable[] = + { + 0, + 50, + 80, + 110 + }; + #else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" + #endif + #endif +#endif +//static const uint8_t mrfiLogicalChanTable[] = +//{ +// SMARTRF_SETTING_CHANNR, +// 50, +// 80, +// 110 +//}; +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(__mrfi_NUM_LOGICAL_CHANS__ == ((sizeof(mrfiLogicalChanTable)/sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0]))); + +/* + * RF Power setting table - this table translates logical power value + * to radio register setting. The logical power value is used directly + * as an index into the power setting table. The values in the table are + * from low to high. The default settings set 3 values: -20 dBm, -10 dBm, + * and 0 dBm. The default at startup is the highest value. Note that these + * are approximate depending on the radio. Information is taken from the + * data sheet. + * + * This table is easily customized. Just replace or add entries as needed. + * If the number of entries changes, the corresponding #define must also + * be adjusted. It is located in mrfi_defs.h and is called __mrfi_NUM_POWER_SETTINGS__. + * The static assert below ensures that there is no mismatch. + * + * For the CC430 use the CC1100 values. + */ +static const uint8_t mrfiRFPowerTable[] = +{ +// [BM] Changed default output power to comply with dongle settings + 0x0F, + 0x27, +// [BM] Increase output power from -0.3dBm to +1.4dBm (433MHz) / +1.1dBm (868MHz) / +1.3dBm (915MHz) to compensate antenna loss +#ifdef ISM_EU + 0x8C +#else + #ifdef ISM_US + 0x8B + #else + #ifdef ISM_LF + 0x8D + #else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" + #endif + #endif +#endif +}; +//static const uint8_t mrfiRFPowerTable[] = +//{ +// 0x0D, +// 0x34, +// 0x8E +//}; + +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(__mrfi_NUM_POWER_SETTINGS__ == ((sizeof(mrfiRFPowerTable)/sizeof(mrfiRFPowerTable[0])) * sizeof(mrfiRFPowerTable[0]))); + +/* ------------------------------------------------------------------------------------------------ + * Local Prototypes + * ------------------------------------------------------------------------------------------------ + */ +static void Mrfi_SyncPinRxIsr(void); +static void Mrfi_RxModeOn(void); +static void Mrfi_RandomBackoffDelay(void); +static void Mrfi_RxModeOff(void); +static void Mrfi_DelayUsec(uint16_t howLong); +static void Mrfi_DelayUsecSem(uint16_t howLong); +static int8_t Mrfi_CalculateRssi(uint8_t rawValue); +static uint8_t Mrfi_RxAddrIsFiltered(uint8_t * pAddr); + + +/* ------------------------------------------------------------------------------------------------ + * Local Variables + * ------------------------------------------------------------------------------------------------ + */ +static uint8_t mrfiRadioState = MRFI_RADIO_STATE_UNKNOWN; +static mrfiPacket_t mrfiIncomingPacket; +static uint8_t mrfiRndSeed = 0; + +/* reply delay support */ +static volatile uint8_t sKillSem = 0; +static volatile uint8_t sReplyDelayContext = 0; +static uint16_t sReplyDelayScalar = 0; +static uint16_t sBackoffHelper = 0; + +static uint8_t mrfiRxFilterEnabled = 0; +static uint8_t mrfiRxFilterAddr[MRFI_ADDR_SIZE] = { RX_FILTER_ADDR_INITIAL_VALUE }; + +/* These counters are only for diagnostic purpose */ +static uint32_t crcFail = 0; +static uint32_t crcPass = 0; +static uint32_t noFrame = 0; + +// [BM] Radio frequency offset read from calibration memory +// Compensates crystal deviation from 26MHz nominal value +extern unsigned char rf_frequoffset; + +/************************************************************************************************** + * @fn MRFI_Init + * + * @brief Initialize MRFI. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_Init(void) +{ + /* ------------------------------------------------------------------ + * Radio power-up reset + * ---------------------- + */ + memset(&mrfiIncomingPacket, 0x0, sizeof(mrfiIncomingPacket)); + + /* Initialize the radio interface */ + mrfiRadioInterfaceInit(); + + /* Strobe Reset: Resets the radio and puts it in SLEEP state. */ + MRFI_STROBE( SRES ); + + /* verify the correct radio is installed */ + MRFI_ASSERT( MRFI_RADIO_REG_READ( PARTNUM ) == MRFI_RADIO_PARTNUM ); /* incorrect radio specified */ + MRFI_ASSERT( MRFI_RADIO_REG_READ( VERSION ) == MRFI_RADIO_VERSION ); /* incorrect radio specified */ + + /* Put radio in Idle state */ + MRFI_STROBE_IDLE_AND_WAIT(); + + + /* ------------------------------------------------------------------ + * Configure radio + * ----------------- + */ + + /* Configure Radio interrupts: + * + * RF1AIN_0 => Programmed to PA_PD signal. + * Configure it to interrupt on falling edge. + * + * RF1AIN_1 => Programmed to RSSI Valid signal. + * No need to configure for interrupt. This value will be read + * through polling. + * + * RF1AIN_9 => Rising edge indicates SYNC sent/received and + * Falling edge indicates end of packet. + * Configure it to interrupt on falling edge. + */ + + /* Select Interrupt edge for PA_PD and SYNC signal: + * Interrupt Edge select register: 1 == Interrupt on High to Low transition. + */ + RF1AIES = BV(0) | BV(9); + + /* Write the power output to the PA_TABLE and verify the write operation. */ + { + uint8_t readbackPATableValue = 0; + bspIState_t s; + + BSP_ENTER_CRITICAL_SECTION(s); + + while( !(RF1AIFCTL1 & RFINSTRIFG)); + RF1AINSTRW = 0x7E51; /* PA Table write (burst) */ + + while( !(RF1AIFCTL1 & RFINSTRIFG)); + RF1AINSTRB = RF_SNOP; /* reset pointer */ + + while( !(RF1AIFCTL1 & RFINSTRIFG)); + RF1AINSTRB = 0xFE; /* PA Table read (burst) */ + + while( !(RF1AIFCTL1 & RFDINIFG)); + RF1ADINB = 0x00; /* dummy write */ + + while( !(RF1AIFCTL1 & RFDOUTIFG)); + readbackPATableValue = RF1ADOUT0B; + + MRFI_ASSERT(readbackPATableValue == 0x51); + + while( !(RF1AIFCTL1 & RFINSTRIFG)); + RF1AINSTRB = RF_SNOP; + + BSP_EXIT_CRITICAL_SECTION(s); + } + + /* initialize radio registers */ + { + uint8_t i; + + for (i=0; i<(sizeof(mrfiRadioCfg)/sizeof(mrfiRadioCfg[0])); i++) + { + MRFI_RADIO_REG_WRITE(mrfiRadioCfg[i][0], mrfiRadioCfg[i][1]); + } + } + + /* Confirm that the values were written correctly. + */ + { + uint8_t i; + + for (i=0; i<(sizeof(mrfiRadioCfg)/sizeof(mrfiRadioCfg[0])); i++) + { + MRFI_ASSERT( mrfiRadioCfg[i][1] == MRFI_RADIO_REG_READ(mrfiRadioCfg[i][0]) ); + } + } + + // [BM] Apply global frequency offset to FSCTRL0 + MRFI_STROBE_IDLE_AND_WAIT(); + MRFI_RADIO_REG_WRITE(FSCTRL0, rf_frequoffset); + + /* set default channel */ + MRFI_SetLogicalChannel( 0 ); + + /* Set default power level */ + MRFI_SetRFPwr(MRFI_NUM_POWER_SETTINGS- 1); + + /* Generate Random seed: + * We will use the RSSI value to generate our random seed. + */ + + /* Put the radio in RX state */ + MRFI_STROBE( SRX ); + + /* delay for the rssi to be valid */ + MRFI_RSSI_VALID_WAIT(); + + { + uint8_t i; + for(i=0; i<16; i++) + { + /* use most random bit of rssi to populate the random seed */ + mrfiRndSeed = (mrfiRndSeed << 1) | (MRFI_RADIO_REG_READ(RSSI) & 0x01); + } + } + + /* Force the seed to be non-zero by setting one bit, just in case... */ + mrfiRndSeed |= 0x0080; + + /* Turn off RF. */ + Mrfi_RxModeOff(); + + /* Strobe Power Down (SPWD): puts the radio in SLEEP state. */ + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + MRFI_STROBE( SXOFF ); + + /* Initial radio state is IDLE state */ + mrfiRadioState = MRFI_RADIO_STATE_OFF; + + /***************************************************************************************** + * Compute reply delay scalar + * + * Formula from data sheet for all the narrow band radios is: + * + * (256 + DATAR_Mantissa) * 2^(DATAR_Exponent) + * DATA_RATE = ------------------------------------------ * f(xosc) + * 2^28 + * + * To try and keep some accuracy we change the exponent of the denominator + * to (28 - (exponent from the configuration register)) so we do a division + * by a smaller number. We find the power of 2 by shifting. + * + * The maximum delay needed depends on the MAX_APP_PAYLOAD parameter. Figure + * out how many bits that will be when overhead is included. Bits/bits-per-second + * is seconds to transmit (or receive) the maximum frame. We multiply this number + * by 1000 to find the time in milliseconds. We then additionally multiply by + * 10 so we can add 5 and divide by 10 later, thus rounding up to the number of + * milliseconds. This last won't matter for slow transmissions but for faster ones + * we want to err on the side of being conservative and making sure the radio is on + * to receive the reply. The semaphore monitor will shut it down. The delay adds in + * a fudge factor that includes processing time on peer plus lags in Rx and processing + * time on receiver's side. + * + * Note that we assume a 26 MHz clock for the radio... + * *************************************************************************************** + */ +#define MRFI_RADIO_OSC_FREQ 26000000 +#define PHY_PREAMBLE_SYNC_BYTES 8 + + { + uint32_t dataRate, bits; + uint16_t exponent, mantissa; + + /* mantissa is in MDMCFG3 */ + mantissa = 256 + SMARTRF_SETTING_MDMCFG3; + + /* exponent is lower nibble of MDMCFG4. */ + exponent = 28 - (SMARTRF_SETTING_MDMCFG4 & 0x0F); + + /* we can now get data rate */ + dataRate = mantissa * (MRFI_RADIO_OSC_FREQ>>exponent); + + bits = ((uint32_t)((PHY_PREAMBLE_SYNC_BYTES + MRFI_MAX_FRAME_SIZE)*8))*10000; + + /* processing on the peer + the Tx/Rx time plus more */ + sReplyDelayScalar = PLATFORM_FACTOR_CONSTANT + (((bits/dataRate)+5)/10); + + /* This helper value is used to scale the backoffs during CCA. At very + * low data rates we need to backoff longer to prevent continual sampling + * of valid frames which take longer to send at lower rates. Use the scalar + * we just calculated divided by 32. With the backoff algorithm backing + * off up to 16 periods this will result in waiting up to about 1/2 the total + * scalar value. For high data rates this does not contribute at all. Value + * is in microseconds. + */ + sBackoffHelper = MRFI_BACKOFF_PERIOD_USECS + (sReplyDelayScalar>>5)*1000; + } + + /* Clean out buffer to protect against spurious frames */ + memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame)); + memset(mrfiIncomingPacket.rxMetrics, 0x00, sizeof(mrfiIncomingPacket.rxMetrics)); + + /* enable global interrupts */ + BSP_ENABLE_INTERRUPTS(); +} + + +/************************************************************************************************** + * @fn MRFI_Transmit + * + * @brief Transmit a packet using CCA algorithm. + * + * @param pPacket - pointer to packet to transmit + * + * @return Return code indicates success or failure of transmit: + * MRFI_TX_RESULT_SUCCESS - transmit succeeded + * MRFI_TX_RESULT_FAILED - transmit failed because CCA failed + ************************************************************************************************** + */ +uint8_t MRFI_Transmit(mrfiPacket_t * pPacket, uint8_t txType) +{ + uint8_t ccaRetries; + uint8_t txBufLen; + uint8_t returnValue = MRFI_TX_RESULT_SUCCESS; + + /* radio must be awake to transmit */ + MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF ); + + /* Turn off reciever. We can ignore/drop incoming packets during transmit. */ + Mrfi_RxModeOff(); + + /* compute number of bytes to write to transmit FIFO */ + txBufLen = pPacket->frame[MRFI_LENGTH_FIELD_OFS] + MRFI_LENGTH_FIELD_SIZE; + + /* ------------------------------------------------------------------ + * Write packet to transmit FIFO + * -------------------------------- + */ + MRFI_RADIO_WRITE_TX_FIFO(&(pPacket->frame[0]), txBufLen); + + + /* ------------------------------------------------------------------ + * Immediate transmit + * --------------------- + */ + if (txType == MRFI_TX_TYPE_FORCED) + { + /* Issue the TX strobe. */ + MRFI_STROBE( STX ); + + /* Wait for transmit to complete */ + while(!MRFI_SYNC_PIN_INT_FLAG_IS_SET()); + + /* Clear the interrupt flag */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + } + else + { + /* ------------------------------------------------------------------ + * CCA transmit + * --------------- + */ + + MRFI_ASSERT( txType == MRFI_TX_TYPE_CCA ); + + /* set number of CCA retries */ + ccaRetries = MRFI_CCA_RETRIES; + + + /* =============================================================================== + * Main Loop + * ============= + */ + for (;;) + { + /* Radio must be in RX mode for CCA to happen. + * Otherwise it will transmit without CCA happening. + */ + + /* Can not use the Mrfi_RxModeOn() function here since it turns on the + * Rx interrupt, which we don't want in this case. + */ + MRFI_STROBE( SRX ); + + /* wait for the rssi to be valid. */ + MRFI_RSSI_VALID_WAIT(); + + /* + * Clear the PA_PD pin interrupt flag. This flag, not the interrupt itself, + * is used to capture the transition that indicates a transmit was started. + * The pin level cannot be used to indicate transmit success as timing may + * prevent the transition from being detected. The interrupt latch captures + * the event regardless of timing. + */ + MRFI_CLEAR_PAPD_PIN_INT_FLAG(); + + /* send strobe to initiate transmit */ + MRFI_STROBE( STX ); + + /* Delay long enough for the PA_PD signal to indicate a + * successful transmit. This is the 250 XOSC periods + * (9.6 us for a 26 MHz crystal). + * Found out that we need a delay of atleast 25 us on CC1100 to see + * the PA_PD signal change. Hence keeping the same for CC430 + */ + Mrfi_DelayUsec(25); + + + /* PA_PD signal goes from HIGH to LOW when going from RX to TX state. + * This transition is trapped as a falling edge interrupt flag + * to indicate that CCA passed and the transmit has started. + */ + if (MRFI_PAPD_INT_FLAG_IS_SET()) + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment passed. + * ---------------------------------- + */ + + /* Clear the PA_PD int flag */ + MRFI_CLEAR_PAPD_PIN_INT_FLAG(); + + /* PA_PD signal stays LOW while in TX state and goes back to HIGH when + * the radio transitions to RX state. + */ + /* wait for transmit to complete */ + while (!MRFI_PAPD_PIN_IS_HIGH()); + + /* transmit done, break */ + break; + } + else + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment failed. + * ---------------------------------- + */ + + /* Turn off radio and save some power during backoff */ + + /* NOTE: Can't use Mrfi_RxModeOff() - since it tries to update the + * sync signal status which we are not using during the TX operation. + */ + MRFI_STROBE_IDLE_AND_WAIT(); + + /* flush the receive FIFO of any residual data */ + MRFI_STROBE( SFRX ); + + /* Retry ? */ + if (ccaRetries != 0) + { + /* delay for a random number of backoffs */ + Mrfi_RandomBackoffDelay(); + + /* decrement CCA retries before loop continues */ + ccaRetries--; + } + else /* No CCA retries are left, abort */ + { + /* set return value for failed transmit and break */ + returnValue = MRFI_TX_RESULT_FAILED; + break; + } + } /* CCA Failed */ + } /* CCA loop */ + }/* txType is CCA */ + + + /* Done with TX. Clean up time... */ + + /* Radio is already in IDLE state */ + + /* + * Flush the transmit FIFO. It must be flushed so that + * the next transmit can start with a clean slate. + */ + MRFI_STROBE( SFTX ); + + /* If the radio was in RX state when transmit was attempted, + * put it back to Rx On state. + */ + if(mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOn(); + } + + return( returnValue ); +} + +/************************************************************************************************** + * @fn MRFI_Receive + * + * @brief Copies last packet received to the location specified. + * This function is meant to be called after the ISR informs + * higher level code that there is a newly received packet. + * + * @param pPacket - pointer to location of where to copy received packet + * + * @return none + ************************************************************************************************** + */ +void MRFI_Receive(mrfiPacket_t * pPacket) +{ + *pPacket = mrfiIncomingPacket; +} + +/************************************************************************************************** + * @fn Mrfi_SyncPinRxIsr + * + * @brief This interrupt is called when the SYNC signal transition from high to low. + * The sync signal is routed to the sync pin which is a GPIO pin. This high-to-low + * transition signifies a receive has completed. The SYNC signal also goes from + * high to low when a transmit completes. This is protected against within the + * transmit function by disabling sync pin interrupts until transmit completes. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Mrfi_SyncPinRxIsr(void) +{ + uint8_t frameLen = 0x00; + uint8_t rxBytes; + + /* We should receive this interrupt only in RX state + * Should never receive it if RX was turned On only for + * some internal mrfi processing like - during CCA. + * Otherwise something is terribly wrong. + */ + MRFI_ASSERT( mrfiRadioState == MRFI_RADIO_STATE_RX ); + + /* ------------------------------------------------------------------ + * Get RXBYTES + * ------------- + */ + + /* + * Read the RXBYTES register from the radio. + * Bit description of RXBYTES register: + * bit 7 - RXFIFO_OVERFLOW, set if receive overflow occurred + * bits 6:0 - NUM_BYTES, number of bytes in receive FIFO + * + * Due a chip bug, the RXBYTES register must read the same value twice + * in a row to guarantee an accurate value. + */ + { + uint8_t rxBytesVerify; + + rxBytesVerify = MRFI_RADIO_REG_READ( RXBYTES ); + + do + { + rxBytes = rxBytesVerify; + rxBytesVerify = MRFI_RADIO_REG_READ( RXBYTES ); + } + while (rxBytes != rxBytesVerify); + } + + + /* ------------------------------------------------------------------ + * FIFO empty? + * ------------- + */ + + /* + * See if the receive FIFIO is empty before attempting to read from it. + * It is possible nothing the FIFO is empty even though the interrupt fired. + * This can happen if address check is enabled and a non-matching packet is + * received. In that case, the radio automatically removes the packet from + * the FIFO. + */ + if (rxBytes == 0) + { + /* receive FIFO is empty - do nothing, skip to end */ + } + else + { + /* receive FIFO is not empty, continue processing */ + + /* ------------------------------------------------------------------ + * Process frame length + * ---------------------- + */ + + /* read the first byte from FIFO - the packet length */ + MRFI_RADIO_READ_RX_FIFO(&frameLen, MRFI_LENGTH_FIELD_SIZE); + + + /* + * Make sure that the frame length just read corresponds to number of bytes in the buffer. + * If these do not match up something is wrong. + * + * This can happen for several reasons: + * 1) Incoming packet has an incorrect format or is corrupted. + * 2) The receive FIFO overflowed. Overflow is indicated by the high + * bit of rxBytes. This guarantees the value of rxBytes value will not + * match the number of bytes in the FIFO for overflow condition. + * 3) Interrupts were blocked for an abnormally long time which + * allowed a following packet to at least start filling the + * receive FIFO. In this case, all received and partially received + * packets will be lost - the packet in the FIFO and the packet coming in. + * This is the price the user pays if they implement a giant + * critical section. + * 4) A failed transmit forced radio to IDLE state to flush the transmit FIFO. + * This could cause an active receive to be cut short. + * + * Also check the sanity of the length to guard against rogue frames. + */ + if ((rxBytes != (frameLen + MRFI_LENGTH_FIELD_SIZE + MRFI_RX_METRICS_SIZE)) || + ((frameLen + MRFI_LENGTH_FIELD_SIZE) > MRFI_MAX_FRAME_SIZE) || + (frameLen < MRFI_MIN_SMPL_FRAME_SIZE) + ) + { + bspIState_t s; + noFrame++; + + /* mismatch between bytes-in-FIFO and frame length */ + + /* + * Flush receive FIFO to reset receive. Must go to IDLE state to do this. + * The critical section guarantees a transmit does not occur while cleaning up. + */ + BSP_ENTER_CRITICAL_SECTION(s); + MRFI_STROBE_IDLE_AND_WAIT(); + MRFI_STROBE( SFRX ); + MRFI_STROBE( SRX ); + BSP_EXIT_CRITICAL_SECTION(s); + + /* flush complete, skip to end */ + } + else + { + /* bytes-in-FIFO and frame length match up - continue processing */ + + /* ------------------------------------------------------------------ + * Get packet + * ------------ + */ + + /* clean out buffer to help protect against spurious frames */ + memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame)); + + /* set length field */ + mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFS] = frameLen; + + /* get packet from FIFO */ + MRFI_RADIO_READ_RX_FIFO(&(mrfiIncomingPacket.frame[MRFI_FRAME_BODY_OFS]), frameLen); + + /* get receive metrics from FIFO */ + MRFI_RADIO_READ_RX_FIFO(&(mrfiIncomingPacket.rxMetrics[0]), MRFI_RX_METRICS_SIZE); + + + /* ------------------------------------------------------------------ + * CRC check + * ------------ + */ + + /* + * Note! Automatic CRC check is not, and must not, be enabled. This feature + * flushes the *entire* receive FIFO when CRC fails. If this feature is + * enabled it is possible to be reading from the FIFO and have a second + * receive occur that fails CRC and automatically flushes the receive FIFO. + * This could cause reads from an empty receive FIFO which puts the radio + * into an undefined state. + */ + + /* determine if CRC failed */ + if (!(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & MRFI_RX_METRICS_CRC_OK_MASK)) + { + /* CRC failed - do nothing, skip to end */ + crcFail++; + } + else + { + /* CRC passed - continue processing */ + crcPass++; + + /* ------------------------------------------------------------------ + * Filtering + * ----------- + */ + + /* if address is not filtered, receive is successful */ + if (!Mrfi_RxAddrIsFiltered(MRFI_P_DST_ADDR(&mrfiIncomingPacket))) + { + { + /* ------------------------------------------------------------------ + * Receive successful + * -------------------- + */ + + /* Convert the raw RSSI value and do offset compensation for this radio */ + mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS] = + Mrfi_CalculateRssi(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS]); + + /* Remove the CRC valid bit from the LQI byte */ + mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] = + (mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & MRFI_RX_METRICS_LQI_MASK); + + + /* call external, higher level "receive complete" processing routine */ + MRFI_RxCompleteISR(); + } + } + } + } + } + + /* ------------------------------------------------------------------ + * End of function + * ------------------- + */ +} + +/************************************************************************************************** + * @fn Mrfi_RxModeOn + * + * @brief Put radio into receive mode. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Mrfi_RxModeOn(void) +{ + /* clear any residual receive interrupt */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + + /* send strobe to enter receive mode */ + MRFI_STROBE( SRX ); + + /* enable receive interrupts */ + MRFI_ENABLE_SYNC_PIN_INT(); +} + +/************************************************************************************************** + * @fn MRFI_RxOn + * + * @brief Turn on the receiver. No harm is done if this function is called when + * receiver is already on. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_RxOn(void) +{ + /* radio must be awake before we can move it to RX state */ + MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF ); + + /* if radio is off, turn it on */ + if(mrfiRadioState != MRFI_RADIO_STATE_RX) + { + mrfiRadioState = MRFI_RADIO_STATE_RX; + Mrfi_RxModeOn(); + } +} + +/************************************************************************************************** + * @fn Mrfi_RxModeOff + * + * @brief - + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Mrfi_RxModeOff(void) +{ + /* disable receive interrupts */ + MRFI_DISABLE_SYNC_PIN_INT(); + + /* turn off radio */ + MRFI_STROBE_IDLE_AND_WAIT(); + + /* flush the receive FIFO of any residual data */ + MRFI_STROBE( SFRX ); + + /* clear receive interrupt */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); +} + + +/************************************************************************************************** + * @fn MRFI_RxIdle + * + * @brief Put radio in idle mode (receiver if off). No harm is done this function is + * called when radio is already idle. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_RxIdle(void) +{ + /* radio must be awake to move it to idle mode */ + MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF ); + + /* if radio is on, turn it off */ + if(mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOff(); + mrfiRadioState = MRFI_RADIO_STATE_IDLE; + } +} + + +/************************************************************************************************** + * @fn MRFI_Sleep + * + * @brief Request radio go to sleep. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_Sleep(void) +{ + bspIState_t s; + + /* Critical section necessary for watertight testing and + * setting of state variables. + */ + BSP_ENTER_CRITICAL_SECTION(s); + + /* If radio is not asleep, put it to sleep */ + if(mrfiRadioState != MRFI_RADIO_STATE_OFF) + { + /* go to idle so radio is in a known state before sleeping */ + MRFI_RxIdle(); + + /* Strobe Power Down (SPWD): puts the radio in SLEEP state. */ + /* Chip bug: Radio does not come out of this SLEEP when put to sleep + * using the SPWD cmd. However, it does wakes up if SXOFF was used to + * put it to sleep. + */ + MRFI_STROBE( SXOFF ); + + /* Our new state is OFF */ + mrfiRadioState = MRFI_RADIO_STATE_OFF; + } + + BSP_EXIT_CRITICAL_SECTION(s); +} + + +/************************************************************************************************** + * @fn MRFI_WakeUp + * + * @brief Wake up radio from sleep state. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_WakeUp(void) +{ + /* if radio is already awake, just ignore wakeup request */ + if(mrfiRadioState != MRFI_RADIO_STATE_OFF) + { + return; + } + + MRFI_STROBE_IDLE_AND_WAIT(); + + /* enter idle mode */ + mrfiRadioState = MRFI_RADIO_STATE_IDLE; +} + + +/************************************************************************************************** + * @fn MRFI_RadioIsr + * + * @brief Radio Interface interrupts as well as Radio interrupts are + * mapped to this interrupt vector. + * + * @param - + * + * @return - + ************************************************************************************************** + */ +// [BM] Changed because CC1101_VECTOR ISR is declared of source code and this handler is called indirect +//BSP_ISR_FUNCTION( MRFI_RadioIsr, CC1101_VECTOR ) +void MRFI_RadioIsr(void) +{ + uint16_t coreIntSource = RF1AIV; /* Radio Core interrupt register */ + uint16_t interfaceIntSource = RF1AIFIV; /* Radio Interface interrupt register */ + + /* Interface interrupt */ + if(interfaceIntSource) + { + if(interfaceIntSource == RF1AIFIV_RFERRIFG) + { + uint16_t interfaceError = RF1AIFERRV; + + if(interfaceError == RF1AIFERRV_LVERR) + { + /* Low core voltage error */ + } + else if(interfaceError == RF1AIFERRV_OPERR) + { + /* Operand error */ + } + else if(interfaceError == RF1AIFERRV_OUTERR) + { + /* output data not available error */ + } + else if(interfaceError == RF1AIFERRV_OPOVERR) + { + /* Operand overwrite error */ + } + else + { + /* Can't possibly happen. If interface error flag was set, + * then one of the interface errors must be set. + */ + MRFI_FORCE_ASSERT(); + } + + /* Assert anyways. No error handling implemented. */ + MRFI_FORCE_ASSERT(); + } + else + { + /* Not expecting any other interface interrupts (data in/out, status/instr in, fifo rx/tx) */ + MRFI_FORCE_ASSERT(); + } + } + + /* Radio Core interrupt */ + if(coreIntSource) + { + /* Check for SYNC interrupt */ + if(coreIntSource == RF1AIV_RFIFG9) + { + if(MRFI_SYNC_PIN_INT_IS_ENABLED()) + { + /* clear the sync pin interrupt, run sync pin ISR */ + /* + * NOTE! The following macro clears the interrupt flag but it also *must* + * reset the interrupt capture. In other words, if a second interrupt + * occurs after the flag is cleared it must be processed, i.e. this interrupt + * exits then immediately starts again. Most microcontrollers handle this + * naturally but it must be verified for every target. + */ + MRFI_CLEAR_SYNC_PIN_INT_FLAG(); + + Mrfi_SyncPinRxIsr(); + } + else + { + /* Fatal error. SYNC interrupt is not supposed to happen at this time. */ + MRFI_FORCE_ASSERT(); + } + } + else + { + /* Fatal error. No other Radio interurpt is enabled. */ + MRFI_FORCE_ASSERT(); + } + } +} + + +/************************************************************************************************** + * @fn MRFI_Rssi + * + * @brief Returns "live" RSSI value + * + * @param none + * + * @return RSSI value in units of dBm. + ************************************************************************************************** + */ +int8_t MRFI_Rssi(void) +{ + uint8_t regValue; + + /* Radio must be in RX state to measure rssi. */ + MRFI_ASSERT( mrfiRadioState == MRFI_RADIO_STATE_RX ); + + /* Wait for the RSSI to be valid: + * Just having the Radio ON is not enough to read + * the correct RSSI value. The Radio must in RX mode for + * a certain duration. This duration depends on + * the baud rate and the received signal strength itself. + */ + MRFI_RSSI_VALID_WAIT(); + + /* Read the RSSI value */ + regValue = MRFI_RADIO_REG_READ( RSSI ); + + /* convert and do offset compensation */ + return( Mrfi_CalculateRssi(regValue) ); +} + + +/************************************************************************************************** + * @fn Mrfi_CalculateRssi + * + * @brief Does binary to decimal conversion and offset compensation. + * + * @param none + * + * @return RSSI value in units of dBm. + ************************************************************************************************** + */ +int8_t Mrfi_CalculateRssi(uint8_t rawValue) +{ + int16_t rssi; + + /* The raw value is in 2's complement and in half db steps. Convert it to + * decimal taking into account the offset value. + */ + if(rawValue >= 128) + { + rssi = (int16_t)(rawValue - 256)/2 - MRFI_RSSI_OFFSET; + } + else + { + rssi = (rawValue/2) - MRFI_RSSI_OFFSET; + } + + /* Restrict this value to least value can be held in an 8 bit signed int */ + if(rssi < -128) + { + rssi = -128; + } + + return rssi; +} + +/************************************************************************************************** + * @fn MRFI_RandomByte + * + * @brief Returns a random byte. This is a pseudo-random number generator. + * The generated sequence will repeat every 256 values. + * The sequence itself depends on the initial seed value. + * + * @param none + * + * @return a random byte + ************************************************************************************************** + */ +uint8_t MRFI_RandomByte(void) +{ + mrfiRndSeed = (mrfiRndSeed*MRFI_RANDOM_MULTIPLIER) + MRFI_RANDOM_OFFSET; + + return mrfiRndSeed; +} + +/************************************************************************************************** + * @fn Mrfi_RandomBackoffDelay + * + * @brief - + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Mrfi_RandomBackoffDelay(void) +{ + uint8_t backoffs; + uint8_t i; + + /* calculate random value for backoffs - 1 to 16 */ + backoffs = (MRFI_RandomByte() & 0x0F) + 1; + + /* delay for randomly computed number of backoff periods */ + for (i=0; i MRFI_RADIO_MAX_PKTLEN) +#error "ERROR: Maximum possible value for PKTLEN exceeded. Decrease value of maximum payload." +#endif + +/* verify largest possible packet fits within FIFO buffer */ +#if ((MRFI_MAX_FRAME_SIZE + MRFI_RX_METRICS_SIZE) > MRFI_RADIO_TX_FIFO_SIZE) +#error "ERROR: Maximum possible packet length exceeds FIFO buffer. Decrease value of maximum payload." +#endif + +/* verify that the SmartRF file supplied is compatible */ +#if ((!defined SMARTRF_RADIO_CC430)) + #error "ERROR: The SmartRF export file is not compatible." +#endif + +/* + * These asserts happen if there is extraneous compiler padding of arrays. + * Modify compiler settings for no padding, or, if that is not possible, + * comment out the offending asserts. + */ +BSP_STATIC_ASSERT(sizeof(mrfiRadioCfg) == ((sizeof(mrfiRadioCfg)/sizeof(mrfiRadioCfg[0])) * sizeof(mrfiRadioCfg[0]))); + + +/* + * These asserts happen if there is extraneous compiler padding of arrays. + * Modify compiler settings for no padding, or, if that is not possible, + * comment out the offending asserts. + */ +BSP_STATIC_ASSERT(sizeof(mrfiLogicalChanTable) == ((sizeof(mrfiLogicalChanTable)/sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0]))); +BSP_STATIC_ASSERT(sizeof(mrfiBroadcastAddr) == ((sizeof(mrfiBroadcastAddr)/sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0]))); + +/************************************************************************************************** +*/ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c new file mode 100755 index 0000000..99c5bd9 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.c @@ -0,0 +1,374 @@ +/************************************************************************************************** + Revised: $Date: 2009-11-23 07:50:43 -0800 (Mon, 23 Nov 2009) $ + Revision: $Revision: 21225 $ + + Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS? + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radios: CC430 + * Radio Interface (RIF) code. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "mrfi_radio_interface.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_RADIO_STATUS_READ_CLEAR() RF1AIFCTL1 &= ~(RFSTATIFG); + +#define MRFI_RADIO_STATUS_READ_WAIT() while( !(RF1AIFCTL1 & RFSTATIFG) ); +#define MRFI_RADIO_INST_WRITE_WAIT() while( !(RF1AIFCTL1 & RFINSTRIFG)); +#define MRFI_RADIO_DATA_WRITE_WAIT() while( !(RF1AIFCTL1 & RFDINIFG) ); +#define MRFI_RADIO_DATA_READ_WAIT() while( !(RF1AIFCTL1 & RFDOUTIFG) ); + +#define MRFI_RIF_DEBUG +#ifdef MRFI_RIF_DEBUG +#define MRFI_RIF_ASSERT(x) BSP_ASSERT(x) +#else +#define MRFI_RIF_ASSERT(x) +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Local Prototypes + * ------------------------------------------------------------------------------------------------ + */ + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceInit + * + * @brief Initialize the Radio Interface + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void mrfiRadioInterfaceInit(void) +{ + /* Enable interrupt on interface error. + * The code behaves differently between different runs on the debugger, and seemingly fails + * due to error flags on the bench. The code does not fail, however, on functional tests. + * This points to problems with the debugger that need to be sorted through carefully. + * For the time being, remove the following line, since it will likely cause operational + * failures. + */ + // RF1AIFCTL1 |= RFERRIE; +} + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceCmdStrobe + * + * @brief Send command strobe to the radio. Returns status byte read during transfer + * of strobe command. + * + * @param addr - address of register to strobe + * + * @return status byte of radio + ************************************************************************************************** + */ +uint8_t mrfiRadioInterfaceCmdStrobe(uint8_t addr) +{ + uint8_t statusByte, gdoState; + mrfiRIFIState_t s; + + /* Check for invalid address. + * 0xBD is for SNOP with MSP set to read the bytes available in RX FIFO. + */ + MRFI_RIF_ASSERT( (addr == 0xBD) || (addr >= RF_SRES) && (addr <= RF_SNOP)); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Clear the Status read flag */ + MRFI_RADIO_STATUS_READ_CLEAR(); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + if ((addr > RF_SRES) && (addr < RF_SNOP)) + { + /* buffer IOCFG2 state */ + gdoState = MRFI_RADIO_REG_READ(IOCFG2); + + /* c-ready to GDO2 */ + MRFI_RADIO_REG_WRITE(IOCFG2, 0x29); + + RF1AINSTRB = addr; + + /* chip at sleep mode */ + if ((RF1AIN & 0x04) == 0x04) + { + if ( (addr == RF_SXOFF) || (addr == RF_SPWD) || (addr == RF_SWOR) ) + { + /* Do nothing */ + } + else + { + /* c-ready */ + while ((RF1AIN & 0x04) == 0x04); + + /* Delay should be 760us */ + Mrfi_DelayUsec(760); + } + } + + /* restore IOCFG2 setting */ + MRFI_RADIO_REG_WRITE(IOCFG2, gdoState); + } + else + { + /* chip active mode */ + RF1AINSTRB = addr; + } + + /* Read status byte */ + statusByte = RF1ASTAT0B; + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); + + /* return the status byte */ + return statusByte; +} + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceReadReg + * + * @brief Read value from radio register. + * + * @param addr - address of register + * + * @return register value + ************************************************************************************************** + */ +uint8_t mrfiRadioInterfaceReadReg(uint8_t addr) +{ + mrfiRIFIState_t s; + uint8_t regValue; + + /* Check for valid range. 0x3E is for PATABLE access */ + MRFI_RIF_ASSERT( (addr <= 0x3B) || (addr == 0x3E) ); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + if( (addr <= 0x2E) || (addr == 0x3E)) + { + /* Write cmd: read the Configuration register */ + RF1AINSTR1B = (0x80 | addr); + } + else + { + /* Write cmd: read the Status register */ + RF1AINSTR1B = (0xC0 | addr); + } + + /* Read out the register value */ + regValue = RF1ADOUT1B; //auto read + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); + + return( regValue); +} + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceWriteReg + * + * @brief Write value to radio register. + * + * @param addr - address of register + * @param value - register value to write + * + * @return none + ************************************************************************************************** + */ +void mrfiRadioInterfaceWriteReg(uint8_t addr, uint8_t value) +{ + mrfiRIFIState_t s; + + /* Check for valid range. 0x3E is for PATABLE access */ + MRFI_RIF_ASSERT((addr <= 0x2E) || (addr == 0x3E)); + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: 'write to register' */ + RF1AINSTRB = (0x00 | addr); + + /* Wait for radio to be ready to accept the data */ + MRFI_RADIO_DATA_WRITE_WAIT(); + + /* Write the register value */ + RF1ADINB = value; /* value to be written to the radio register */ + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceWriteTxFifo + * + * @brief Write data to radio transmit FIFO. + * + * @param pData - pointer for storing write data + * @param len - length of data in bytes + * + * @return none + ************************************************************************************************** + */ +void mrfiRadioInterfaceWriteTxFifo(uint8_t * pData, uint8_t len) +{ + mrfiRIFIState_t s; + + MRFI_RIF_ASSERT(len != 0); /* zero length is not allowed */ + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: TXFIFOWR */ + RF1AINSTRB = 0x7F; + + do + { + /* Wait for radio to be ready to accept the data */ + MRFI_RADIO_DATA_WRITE_WAIT(); + + /* Write one byte to FIFO */ + RF1ADINB = *pData; + + pData++; + len--; + + }while(len); + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + + +/************************************************************************************************** + * @fn mrfiRadioInterfaceReadRxFifo + * + * @brief Read data from radio receive FIFO. + * + * @param pData - pointer for storing read data + * @param len - length of data in bytes + * + * @return none + ************************************************************************************************** + */ +uint8_t method = 2; +void mrfiRadioInterfaceReadRxFifo(uint8_t * pData, uint8_t len) +{ + mrfiRIFIState_t s; + + MRFI_RIF_ASSERT(len != 0); /* zero length is not allowed */ + + /* Lock out access to Radio IF */ + MRFI_RIF_ENTER_CRITICAL_SECTION(s); + + if(method == 1) + { + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: RXFIFORD */ + RF1AINSTRB = 0xFF; + + do + { + /* dummy write */ + RF1ADINB = 0; + + /* Wait for data to be available for reading */ + MRFI_RADIO_DATA_READ_WAIT(); + + /* Read one byte from FIFO */ + *pData = RF1ADOUT0B; + + pData++; + len--; + + }while(len); + } + + if(method == 2) + { + do + { + /* Wait for radio to be ready for next instruction */ + MRFI_RADIO_INST_WRITE_WAIT(); + + /* Write cmd: SNGLRXRD */ + RF1AINSTR1B = 0xBF; + + /* Read byte from FIFO */ + *pData = RF1ADOUT1B; //auto read register + + pData++; + len--; + + }while(len); + } + + /* Allow access to Radio IF */ + MRFI_RIF_EXIT_CRITICAL_SECTION(s); +} + + +/************************************************************************************************** +*/ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h new file mode 100755 index 0000000..ebdacfc --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/radios/family5/mrfi_radio_interface.h @@ -0,0 +1,150 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Radio interface code for CC430 + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_RADIO_INTERFACE_H +#define MRFI_RADIO_INTERFACE_H + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + +/* configuration registers */ +#define IOCFG2 0x00 /* IOCFG2 - GDO2 output pin configuration */ +#define IOCFG1 0x01 /* IOCFG1 - GDO1 output pin configuration */ +#define IOCFG0 0x02 /* IOCFG1 - GDO0 output pin configuration */ +#define FIFOTHR 0x03 /* FIFOTHR - RX FIFO and TX FIFO thresholds */ +#define SYNC1 0x04 /* SYNC1 - Sync word, high byte */ +#define SYNC0 0x05 /* SYNC0 - Sync word, low byte */ +#define PKTLEN 0x06 /* PKTLEN - Packet length */ +#define PKTCTRL1 0x07 /* PKTCTRL1 - Packet automation control */ +#define PKTCTRL0 0x08 /* PKTCTRL0 - Packet automation control */ +#define ADDR 0x09 /* ADDR - Device address */ +#define CHANNR 0x0A /* CHANNR - Channel number */ +#define FSCTRL1 0x0B /* FSCTRL1 - Frequency synthesizer control */ +#define FSCTRL0 0x0C /* FSCTRL0 - Frequency synthesizer control */ +#define FREQ2 0x0D /* FREQ2 - Frequency control word, high byte */ +#define FREQ1 0x0E /* FREQ1 - Frequency control word, middle byte */ +#define FREQ0 0x0F /* FREQ0 - Frequency control word, low byte */ +#define MDMCFG4 0x10 /* MDMCFG4 - Modem configuration */ +#define MDMCFG3 0x11 /* MDMCFG3 - Modem configuration */ +#define MDMCFG2 0x12 /* MDMCFG2 - Modem configuration */ +#define MDMCFG1 0x13 /* MDMCFG1 - Modem configuration */ +#define MDMCFG0 0x14 /* MDMCFG0 - Modem configuration */ +#define DEVIATN 0x15 /* DEVIATN - Modem deviation setting */ +#define MCSM2 0x16 /* MCSM2 - Main Radio Control State Machine configuration */ +#define MCSM1 0x17 /* MCSM1 - Main Radio Control State Machine configuration */ +#define MCSM0 0x18 /* MCSM0 - Main Radio Control State Machine configuration */ +#define FOCCFG 0x19 /* FOCCFG - Frequency Offset Compensation configuration */ +#define BSCFG 0x1A /* BSCFG - Bit Synchronization configuration */ +#define AGCCTRL2 0x1B /* AGCCTRL2 - AGC control */ +#define AGCCTRL1 0x1C /* AGCCTRL1 - AGC control */ +#define AGCCTRL0 0x1D /* AGCCTRL0 - AGC control */ +#define WOREVT1 0x1E /* WOREVT1 - High byte Event0 timeout */ +#define WOREVT0 0x1F /* WOREVT0 - Low byte Event0 timeout */ +#define WORCTRL 0x20 /* WORCTRL - Wake On Radio control */ +#define FREND1 0x21 /* FREND1 - Front end RX configuration */ +#define FREND0 0x22 /* FREDN0 - Front end TX configuration */ +#define FSCAL3 0x23 /* FSCAL3 - Frequency synthesizer calibration */ +#define FSCAL2 0x24 /* FSCAL2 - Frequency synthesizer calibration */ +#define FSCAL1 0x25 /* FSCAL1 - Frequency synthesizer calibration */ +#define FSCAL0 0x26 /* FSCAL0 - Frequency synthesizer calibration */ +#define RCCTRL1 0x27 /* RCCTRL1 - RC oscillator configuration */ +#define RCCTRL0 0x28 /* RCCTRL0 - RC oscillator configuration */ +#define FSTEST 0x29 /* FSTEST - Frequency synthesizer calibration control */ +#define PTEST 0x2A /* PTEST - Production test */ +#define AGCTEST 0x2B /* AGCTEST - AGC test */ +#define TEST2 0x2C /* TEST2 - Various test settings */ +#define TEST1 0x2D /* TEST1 - Various test settings */ +#define TEST0 0x2E /* TEST0 - Various test settings */ + +/* status registers */ +#define PARTNUM 0x30 /* PARTNUM - Chip ID */ +#define VERSION 0x31 /* VERSION - Chip ID */ +#define FREQEST 0x32 /* FREQEST – Frequency Offset Estimate from demodulator */ +#define LQI 0x33 /* LQI – Demodulator estimate for Link Quality */ +#define RSSI 0x34 /* RSSI – Received signal strength indication */ +#define MARCSTATE 0x35 /* MARCSTATE – Main Radio Control State Machine state */ +#define WORTIME1 0x36 /* WORTIME1 – High byte of WOR time */ +#define WORTIME0 0x37 /* WORTIME0 – Low byte of WOR time */ +#define PKTSTATUS 0x38 /* PKTSTATUS – Current GDOx status and packet status */ +#define VCO_VC_DAC 0x39 /* VCO_VC_DAC – Current setting from PLL calibration module */ +#define TXBYTES 0x3A /* TXBYTES – Underflow and number of bytes */ +#define RXBYTES 0x3B /* RXBYTES – Overflow and number of bytes */ + +/* burst write registers */ +#define PATABLE 0x3E /* PATABLE - PA control settings table */ + +/* command strobe registers */ +#define SRES 0x30 /* SRES - Reset chip. */ +#define SFSTXON 0x31 /* SFSTXON - Enable and calibrate frequency synthesizer. */ +#define SXOFF 0x32 /* SXOFF - Turn off crystal oscillator. */ +#define SCAL 0x33 /* SCAL - Calibrate frequency synthesizer and turn it off. */ +#define SRX 0x34 /* SRX - Enable RX. Perform calibration if enabled. */ +#define STX 0x35 /* STX - Enable TX. If in RX state, only enable TX if CCA passes. */ +#define SIDLE 0x36 /* SIDLE - Exit RX / TX, turn off frequency synthesizer. */ +#define SRSVD 0x37 /* SRVSD - Reserved. Do not use. */ +#define SWOR 0x38 /* SWOR - Start automatic RX polling sequence (Wake-on-Radio) */ +#define SPWD 0x39 /* SPWD - Enter power down mode when CSn goes high. */ +#define SFRX 0x3A /* SFRX - Flush the RX FIFO buffer. */ +#define SFTX 0x3B /* SFTX - Flush the TX FIFO buffer. */ +#define SWORRST 0x3C /* SWORRST - Reset real time clock. */ +#define SNOP 0x3D /* SNOP - No operation. Returns status byte. */ + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void mrfiRadioInterfaceInit(void); +void mrfiRadioInterfaceWriteReg(uint8_t addr, uint8_t value); +void mrfiRadioInterfaceWriteTxFifo(uint8_t * pWriteData, uint8_t len); +void mrfiRadioInterfaceReadRxFifo(uint8_t * pReadData, uint8_t len); + +uint8_t mrfiRadioInterfaceCmdStrobe(uint8_t addr); +uint8_t mrfiRadioInterfaceReadReg(uint8_t addr); + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/smartrf/CC1101/smartrf_CC1101.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/smartrf/CC1101/smartrf_CC1101.h new file mode 100755 index 0000000..f014b1a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/smartrf/CC1101/smartrf_CC1101.h @@ -0,0 +1,130 @@ +/*************************************************************** + * SmartRF Studio(tm) Export + * + * Radio register settings specifed with C-code + * compatible #define statements. + * + ***************************************************************/ + +#ifndef SMARTRF_CC1101_H +#define SMARTRF_CC1101_H + +// ISM_EU configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 869.524963 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_US configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 905.998993 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +#define SMARTRF_RADIO_CC1101 + +#define SMARTRF_SETTING_FSCTRL1 0x08 +#define SMARTRF_SETTING_FSCTRL0 0x00 +#ifdef ISM_EU + #define SMARTRF_SETTING_FREQ2 0x21 + #define SMARTRF_SETTING_FREQ1 0x71 + #define SMARTRF_SETTING_FREQ0 0x7A +#else + #ifdef ISM_US + // 902MHz (CHANNR=20->906MHz) + #define SMARTRF_SETTING_FREQ2 0x22 + #define SMARTRF_SETTING_FREQ1 0xB1 + #define SMARTRF_SETTING_FREQ0 0x3B + #else + #ifdef ISM_LF + // 433.92MHz + #define SMARTRF_SETTING_FREQ2 0x10 + #define SMARTRF_SETTING_FREQ1 0xB0 + #define SMARTRF_SETTING_FREQ0 0x71 + #else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" + #endif // ISM_LF + #endif // ISM_US +#endif // ISM_EU +#define SMARTRF_SETTING_MDMCFG4 0x7B +#define SMARTRF_SETTING_MDMCFG3 0x83 +#define SMARTRF_SETTING_MDMCFG2 0x13 +#define SMARTRF_SETTING_MDMCFG1 0x22 +#define SMARTRF_SETTING_MDMCFG0 0xF8 +#define SMARTRF_SETTING_CHANNR 0x00 +#define SMARTRF_SETTING_DEVIATN 0x42 +#define SMARTRF_SETTING_FREND1 0xB6 +#define SMARTRF_SETTING_FREND0 0x10 +#define SMARTRF_SETTING_MCSM0 0x18 +#define SMARTRF_SETTING_FOCCFG 0x1D +#define SMARTRF_SETTING_BSCFG 0x1C +#define SMARTRF_SETTING_AGCCTRL2 0xC7 +#define SMARTRF_SETTING_AGCCTRL1 0x00 +#define SMARTRF_SETTING_AGCCTRL0 0xB2 +#define SMARTRF_SETTING_FSCAL3 0xEA +#define SMARTRF_SETTING_FSCAL2 0x2A +#define SMARTRF_SETTING_FSCAL1 0x00 +#define SMARTRF_SETTING_FSCAL0 0x1F +#define SMARTRF_SETTING_FSTEST 0x59 +#define SMARTRF_SETTING_TEST2 0x81 +#define SMARTRF_SETTING_TEST1 0x35 +#define SMARTRF_SETTING_TEST0 0x09 +#define SMARTRF_SETTING_FIFOTHR 0x47 +#define SMARTRF_SETTING_IOCFG2 0x29 +#define SMARTRF_SETTING_IOCFG0D 0x06 +#define SMARTRF_SETTING_PKTCTRL1 0x04 +#define SMARTRF_SETTING_PKTCTRL0 0x05 +#define SMARTRF_SETTING_ADDR 0x00 +#define SMARTRF_SETTING_PKTLEN 0xFF + +#endif // SMARTRF_CC1101_H diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h new file mode 100755 index 0000000..fc6b49e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/mrfi/smartrf/CC430/smartrf_CC430.h @@ -0,0 +1,164 @@ +/*************************************************************** + * SmartRF Studio(tm) Export + * + * Radio register settings specifed with C-code + * compatible #define statements. + * + ***************************************************************/ + +#ifndef SMARTRF_CC430_H +#define SMARTRF_CC430_H + +// [BM] Modified radio settings for 433MHz, 868MHz, 915MHz + +// ISM_LF configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 433.92 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_EU configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 869.524963 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +// ISM_US configuration +// +// Chipcon +// Product = CC1101 +// Chip version = A (VERSION = 0x04) +// Crystal accuracy = 10 ppm +// X-tal frequency = 26 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 232.142857 kHz +// Deviation = 32 kHz +// Datarate = 76.766968 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 905.998993 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// FIFO autoflush = 0 +// Device address = 0 +// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet +// GDO2 signal selection = (41) CHIP_RDY + +#define SMARTRF_RADIO_CC430 + +#define SMARTRF_SETTING_FSCTRL1 0x08 +#define SMARTRF_SETTING_FSCTRL0 0x00 +#ifdef ISM_EU + // 869.50MHz + #define SMARTRF_SETTING_FREQ2 0x21 + #define SMARTRF_SETTING_FREQ1 0x71 + #define SMARTRF_SETTING_FREQ0 0x7A +#else + #ifdef ISM_US + // 902MHz (CHANNR=20->906MHz) + #define SMARTRF_SETTING_FREQ2 0x22 + #define SMARTRF_SETTING_FREQ1 0xB1 + #define SMARTRF_SETTING_FREQ0 0x3B + #else + #ifdef ISM_LF + // 433.92MHz + #define SMARTRF_SETTING_FREQ2 0x10 + #define SMARTRF_SETTING_FREQ1 0xB0 + #define SMARTRF_SETTING_FREQ0 0x71 + #else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" + #endif // ISM_LF + #endif // ISM_US +#endif // ISM_EU +#define SMARTRF_SETTING_MDMCFG4 0x7B +#define SMARTRF_SETTING_MDMCFG3 0x83 +#define SMARTRF_SETTING_MDMCFG2 0x13 +#define SMARTRF_SETTING_MDMCFG1 0x22 +#define SMARTRF_SETTING_MDMCFG0 0xF8 +#define SMARTRF_SETTING_CHANNR 0x00 +#define SMARTRF_SETTING_DEVIATN 0x42 +#define SMARTRF_SETTING_FREND1 0xB6 +#define SMARTRF_SETTING_FREND0 0x10 +#define SMARTRF_SETTING_MCSM0 0x18 +#define SMARTRF_SETTING_FOCCFG 0x1D +#define SMARTRF_SETTING_BSCFG 0x1C +#define SMARTRF_SETTING_AGCCTRL2 0xC7 +#define SMARTRF_SETTING_AGCCTRL1 0x00 +#define SMARTRF_SETTING_AGCCTRL0 0xB2 +#define SMARTRF_SETTING_FSCAL3 0xEA +#define SMARTRF_SETTING_FSCAL2 0x2A +#define SMARTRF_SETTING_FSCAL1 0x00 +#define SMARTRF_SETTING_FSCAL0 0x1F +#define SMARTRF_SETTING_FSTEST 0x59 +#define SMARTRF_SETTING_TEST2 0x81 +#define SMARTRF_SETTING_TEST1 0x35 +#define SMARTRF_SETTING_TEST0 0x09 +#define SMARTRF_SETTING_FIFOTHR 0x47 +#define SMARTRF_SETTING_IOCFG2 0x29 +#define SMARTRF_SETTING_IOCFG0D 0x06 +#define SMARTRF_SETTING_PKTCTRL1 0x04 +#define SMARTRF_SETTING_PKTCTRL0 0x05 +#define SMARTRF_SETTING_ADDR 0x00 +#define SMARTRF_SETTING_PKTLEN 0xFF + +#endif // SMARTRF_CC430_H diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk.c new file mode 100755 index 0000000..e02c77c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk.c @@ -0,0 +1,1078 @@ +/************************************************************************************************** + Filename: nwk.c + Revised: $Date: 2009-03-11 15:29:07 -0700 (Wed, 11 Mar 2009) $ + Revision: $Revision: 19382 $ + Author $Author: lfriedman $ + + Description: This file supports the SimpliciTI network layer. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "nwk_globals.h" +#include "nwk_QMgmt.h" + +/****************************************************************************** + * MACROS + */ +/************************* NETWORK MANIFEST CONSTANT SANITY CHECKS ****************************/ +#if !defined(ACCESS_POINT) && !defined(RANGE_EXTENDER) && !defined(END_DEVICE) +#error ERROR: No SimpliciTI device type defined +#endif + +#if defined(END_DEVICE) && !defined(RX_POLLS) +#define RX_USER +#endif + +#ifndef MAX_HOPS +#define MAX_HOPS 3 +#elif MAX_HOPS > 4 +#error ERROR: MAX_HOPS must be 4 or fewer +#endif + +#ifndef MAX_APP_PAYLOAD +#error ERROR: MAX_APP_PAYLOAD must be defined +#endif + +#if ( MAX_PAYLOAD < MAX_FREQ_APP_FRAME ) +#error ERROR: Application payload size too small for Frequency frame +#endif + +#if ( MAX_PAYLOAD < MAX_JOIN_APP_FRAME ) +#error ERROR: Application payload size too small for Join frame +#endif + +#if ( MAX_PAYLOAD < MAX_LINK_APP_FRAME ) +#error ERROR: Application payload size too small for Link frame +#endif + +#if ( MAX_PAYLOAD < MAX_MGMT_APP_FRAME ) +#error ERROR: Application payload size too small for Management frame +#endif + +#if ( MAX_PAYLOAD < MAX_SEC_APP_FRAME ) +#error ERROR: Application payload size too small for Security frame +#endif + +#if ( MAX_PAYLOAD < MAX_PING_APP_FRAME ) +#error ERROR: Application payload size too small for Ping frame +#endif + +#if NWK_FREQ_TBL_SIZE < 1 +#error ERROR: NWK_FREQ_TBL_SIZE must be > 0 +#endif + +/************************* END NETWORK MANIFEST CONSTANT SANITY CHECKS ************************/ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ +#define SYS_NUM_CONNECTIONS (NUM_CONNECTIONS+1) + +/* Increment this if the persistentContext_t structure is changed. It will help + * detect the upgrade context: any saved values will have a version with a + * lower number. + */ +#define CONNTABLEINFO_STRUCTURE_VERSION 1 + +#define SIZEOF_NV_OBJ sizeof(sPersistInfo) + +/****************************************************************************** + * TYPEDEFS + */ +/* This structure aggregates eveything necessary to save if we want to restore + * the connection information later. + */ +typedef struct +{ + const uint8_t structureVersion; /* to dectect upgrades... */ + uint8_t numConnections; /* count includes the UUD port/link ID */ +/* The next two are used to detect overlapping port assignments. When _sending_ a + * link frame the local port is assigned from the top down. When sending a _reply_ + * the assignment is bottom up. Overlapping assignments are rejected. That said it + * is extremely unlikely that this will ever happen. If it does the test implemented + * here is overly cautious (it will reject assignments when it needn't). But we leave + * it that way on the assumption that it will never happen anyway. + */ + uint8_t curNextLinkPort; + uint8_t curMaxReplyPort; + linkID_t nextLinkID; +#ifdef ACCESS_POINT + sfInfo_t sSandFContext; +#endif +/* Connection table entries last... */ + connInfo_t connStruct[SYS_NUM_CONNECTIONS]; +} persistentContext_t; + +/****************************************************************************** + * LOCAL VARIABLES + */ + +/* This will be overwritten if we restore the structure from NV for example. + * Note that restoring will not permit overwriting the version element as it + * is declared 'const'. + */ +static persistentContext_t sPersistInfo = {CONNTABLEINFO_STRUCTURE_VERSION}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static uint8_t map_lid2idx(linkID_t, uint8_t *); +static void initializeConnection(connInfo_t *); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_nwkInit + * + * @brief Initialize NWK conext. + * + * input parameters + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_nwkInit(uint8_t (*f)(linkID_t)) +{ + // [BM] Added variable + uint8_t i; + + /* Truly ugly initialization because CCE won't initialize properly. Must + * skip first const element. Yuk. + */ + memset((((uint8_t *)&sPersistInfo)+1), 0x0, (sizeof(sPersistInfo)-1)); + /* OK. The zeroed elements are set. Now go back and do fixups... */ + + sPersistInfo.numConnections = SYS_NUM_CONNECTIONS; + sPersistInfo.curNextLinkPort = SMPL_PORT_USER_MAX; + sPersistInfo.curMaxReplyPort = PORT_BASE_NUMBER; + sPersistInfo.nextLinkID = 1; + + /* initialize globals */ + nwk_globalsInit(); + + /* initialize frame processing */ + nwk_frameInit(f); + + /* initialize queue manager */ + nwk_QInit(); + + /* initialize each network application. */ + nwk_freqInit(); + nwk_pingInit(); + nwk_joinInit(f); + nwk_mgmtInit(); + nwk_linkInit(); + nwk_securityInit(); + + // [BM] Workaround to enable stack restarting + for (i=0; iportTx = 0; + + pCInfo->connState = CONNSTATE_CONNECTED; + pCInfo->thisLinkID = *locLID; + + /* Generate the next Link ID. This isn't foolproof. If the count wraps + * we can end up with confusing duplicates. We can protect aginst using + * one that is already in use but we can't protect against a stale Link ID + * remembered by an application that doesn't know its connection has been + * torn down. The test for 0 will hopefully never be true (indicating a wrap). + */ + (*locLID)++; + + while (!*locLID || (*locLID == SMPL_LINKID_USER_UUD) || map_lid2idx(*locLID, &tmp)) + { + (*locLID)++; + } + + return; +} + + +/****************************************************************************** + * @fn nwk_freeConnection + * + * @brief Return the connection structure to the free pool. Currently + * this routine is only called when a link freame is sent and + * no reply is received so the freeing steps are pretty simple. + * But eventually this will be more complex so this place-holder + * is introduced. + * + * input parameters + * @param pCInfo - pointer to entry to be freed + * + * output parameters + * + * @return None. + */ +void nwk_freeConnection(connInfo_t *pCInfo) +{ +#if NUM_CONNECTIONS > 0 + pCInfo->connState = CONNSTATE_FREE; +#endif +} + +/****************************************************************************** + * @fn nwk_getConnInfo + * + * @brief Return the connection info structure to which the input Link ID maps. + * + * input parameters + * @param port - port for which mapping desired + * + * output parameters + * + * @return pointer to connInfo_t structure found. NULL if no mapping + * found or entry not valid. + */ +connInfo_t *nwk_getConnInfo(linkID_t linkID) +{ + uint8_t idx, rc; + + rc = map_lid2idx(linkID, &idx); + + return (rc && (CONNSTATE_CONNECTED == sPersistInfo.connStruct[idx].connState)) ? &sPersistInfo.connStruct[idx] : (connInfo_t *)0; +} + +/****************************************************************************** + * @fn nwk_isLinkDuplicate + * + * @brief Help determine if the link has already been established.. Defense + * against duplicate link frames. This file owns the data structure + * so the comparison is done here. + * + * input parameters + * @param addr - pointer to address of linker in question + * @param remotePort - remote port number provided by linker + * + * output parameters + * + * @return Returns pointer to connection entry if the address and remote Port + * match an existing entry, otherwise 0. + */ +connInfo_t *nwk_isLinkDuplicate(uint8_t *addr, uint8_t remotePort) +{ +#if NUM_CONNECTIONS > 0 + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + if (!(memcmp(ptr->peerAddr, addr, NET_ADDR_SIZE)) && + (ptr->portTx == remotePort)) + { + return ptr; + } + } + } +#endif + + return (connInfo_t *)NULL; +} + +/****************************************************************************** + * @fn nwk_findAddressMatch + * + * @brief Used to look for an address match in the Connection table. + * Match is based on source address in frame. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns non-zero if a match is found, otherwise 0. + */ +uint8_t nwk_findAddressMatch(mrfiPacket_t *frame) +{ +#if NUM_CONNECTIONS > 0 + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + if (!(memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + return 1; + } + } + } +#endif + + return 0; +} + +#ifdef ACCESS_POINT +/****************************************************************************** + * @fn nwk_getSFInfoPtr + * + * @brief Get pointer to store-and-forward information object kept in the + * NV object aggregate. + * + * input parameters + * + * output parameters + * + * @return Returns pointer to the store-nad-forward object. + */ +sfInfo_t *nwk_getSFInfoPtr(void) +{ + return &sPersistInfo.sSandFContext; +} + +#if defined(AP_IS_DATA_HUB) +/*************************************************************************************** + * @fn nwk_saveJoinedDevice + * + * @brief Save the address of a joining device on the Connection Table expecting + * a Link frame to follow. Only for when AP is a data hub. We want to + * use the space already allocated for a connection able entry instead + * of having redundant arrays for alread-joined devices in the data hub + * case. + * + * input parameters + * @param frame - pointer to frame containing address or joining device. + * + * output parameters + * + * @return Returns non-zero if this is a new device and it is saved. Returns + * 0 if device already there or there is no room in the Connection + * Table. + */ +uint8_t nwk_saveJoinedDevice(mrfiPacket_t *frame) +{ + uint8_t i; + connInfo_t *avail = 0; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState == CONNSTATE_CONNECTED) || (ptr->connState == CONNSTATE_JOINED)) + { + if (!memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + return 0; + } + } + else + { + avail = ptr; + } + } + + if (!avail) + { + return 0; + } + + avail->connState = CONNSTATE_JOINED; + memcpy(avail->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + return 1; +} + +/*********************************************************************************** + * @fn nwk_findAlreadyJoined + * + * @brief Used when AP is a data hub to look for an address match in the + * Connection table for a device that is already enterd in the joined + * state. This means that the Connection Table resource is already + * allocated so the link-listen doesn't have to do it again. Match is + * based on source address in frame. Thsi shoudl only be called from + * the Link-listen context during the link frame reply. + * + * If found the Connection Table entry is initialized as if it were + * found using the nwk_getNextConnection() method. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns pointer to Connection Table entry if match is found, otherwise + * 0. This call will only fail if the Connection Table was full when the + * device tried to join initially. + */ +connInfo_t *nwk_findAlreadyJoined(mrfiPacket_t *frame) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + /* Is this it? */ + if (!(memcmp(&ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + /* Yes. Initilize tabel entry and return the pointer. */ + initializeConnection(ptr); + return ptr; + } + } + } + + /* Nothing found... */ + return (connInfo_t *)NULL; +} +#endif /* AP_IS_DATA_HUB */ +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_checkConnInfo + * + * @brief Do a sanity/validity check on the connection info + * + * input parameters + * @param ptr - pointer to a valid connection info structure to validate + * @param which - Tx or Rx port checked + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_checkConnInfo(connInfo_t *ptr, uint8_t which) +{ + uint8_t port; + + /* make sure port isn't null and that the entry is active */ + port = (CHK_RX == which) ? ptr->portRx : ptr->portTx; + if (!port || (CONNSTATE_FREE == ptr->connState)) + { + return SMPL_BAD_PARAM; + } + + /* validate port number */ + if (port < PORT_BASE_NUMBER) + { + return SMPL_BAD_PARAM; + } + + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_isConnectionValid + * + * @brief Do a sanity/validity check on the frame target address by + * validating frame against connection info + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * @param lid - link ID of found connection + * + * @return 0 if connection specified in frame is not valid, otherwise non-zero. + */ +uint8_t nwk_isConnectionValid(mrfiPacket_t *frame, linkID_t *lid) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + uint8_t port = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_PORT_OS); + + for (i=0; iconnState) + { + /* check port first since we're done if the port is the user bcast port. */ + if (port == ptr->portRx) + { + /* yep...ports match. */ + if ((SMPL_PORT_USER_BCAST == port) || !(memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + uint8_t rc = 1; + + /* we're done. */ + *lid = ptr->thisLinkID; +#ifdef APP_AUTO_ACK + /* can't ack the broadcast port... */ + if (!(SMPL_PORT_USER_BCAST == port)) + { + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_ACK_REQ)) + { + /* Ack requested. Send ack now */ + nwk_sendAckReply(frame, ptr->portTx); + } + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_ACK_RPLY)) + { + /* This is a reply. Signal that it was received by resetting the + * saved transaction ID in the connection object if they match. The + * main thread is polling this value. The setting here is in the + * Rx ISR thread. + */ + if (ptr->ackTID == GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS)) + { + ptr->ackTID = 0; + } + /* This causes the frame to be dropped. All ack frames are + * dropped. + */ + rc = 0; + } + } +#endif /* APP_AUTO_ACK */ + /* Unconditionally kill the reply delay semaphore. This used to be done + * unconditionally in the calling routine. + */ + MRFI_PostKillSem(); + return rc; + } + } + } + } + + /* no matches */ + return 0; +} + +/****************************************************************************** + * @fn nwk_allocateLocalRxPort + * + * @brief Allocate a local port on which to receive frames from a peer. + * + * Allocation differs depending on whether the allocation is for + * a link reply frame or a link frame. In the former case we + * know the address of the peer so we can ensure allocating a + * unique port number for that address. The same port number can be + * used mulitple times for distinct peers. Allocations are done from + * the bottom of the namespace upward. + * + * If allocation is for a link frame we do not yet know the peer + * address so we must ensure the port number is unique now. + * Allocations are done from the top of the namespace downward. + * + * The two allocation methods track the extreme values used in each + * case to detect overlap, i.e., exhausted namespace. This can only + * happen if the number of connections supported is greater than the + * total namespace available. + * + * input parameters + * @param which - Sending a link frame or a link reply frame + * @param newPtr - pointer to connection info structure to be populated + * + * output parameters + * @param newPtr->portRx - element is populated with port number. + * + * @return Non-zero if port number assigned. 0 if no port available. + */ +uint8_t nwk_allocateLocalRxPort(uint8_t which, connInfo_t *newPtr) +{ +#if NUM_CONNECTIONS > 0 + uint8_t num, i; + uint8_t marker[NUM_CONNECTIONS]; + connInfo_t *ptr = sPersistInfo.connStruct; + + memset(&marker, 0x0, sizeof(marker)); + + for (i=0; iconnState) && (ptr->portRx <= SMPL_PORT_USER_MAX)) + { + if (LINK_SEND == which) + { + if (ptr->portRx > sPersistInfo.curNextLinkPort) + { + marker[SMPL_PORT_USER_MAX - ptr->portRx] = 1; + } + } + else if (!memcmp(ptr->peerAddr, newPtr->peerAddr, NET_ADDR_SIZE)) + { + marker[ptr->portRx - PORT_BASE_NUMBER] = 1; + } + } + } + + num = 0; + for (i=0; i sPersistInfo.curMaxReplyPort) + { + /* remember maximum port number used */ + sPersistInfo.curMaxReplyPort = num; + } + } + else + { + /* the port number we need has already been used in the other context. It may or + * may not have been used for the same address but we don't bother to check...we + * just reject the asignment. This is the overly cautious part but is extermely + * unlikely to ever occur. + */ + num = 0; + } + } + else + { + /* if the number we have doesn't overlap the assignment of ports used + * for sending link frame replies, use it. + */ + if (num >= sPersistInfo.curMaxReplyPort) + { + if (num == sPersistInfo.curNextLinkPort) + { + sPersistInfo.curNextLinkPort--; + } + } + else + { + /* the port number we need has already been used in the other context. It may or + * may not have been used for the same address but we don't bother to check...we + * just reject the asignment. This is the overly cautious part but is extermely + * unlikely to ever occur. + */ + num = 0; + } + } + + newPtr->portRx = num; + + return num; +#else + return 0; +#endif /* NUM_CONNECTIONS > 0 */ + +} + +/******************************************************************************* + * @fn nwk_isValidReply + * + * @brief Examine a frame to see if it is a valid reply when compared with + * expected parameters. + * + * input parameters + * @param frame - pointer to frmae being examined + * @param tid - expected transaction ID in application payload + * @param infoOffset - offset to payload information containing reply hint + * @param tidOffset - offset to transaction ID in payload + * + * output parameters + * + * @return reply category: + * SMPL_NOT_REPLY: not a reply + * SMPL_MY_REPLY : a reply that matches input parameters + * SMPL_A_REPLY : a reply but does not match input parameters + */ +uint8_t nwk_isValidReply(mrfiPacket_t *frame, uint8_t tid, uint8_t infoOffset, uint8_t tidOffset) +{ + uint8_t rc = SMPL_NOT_REPLY; + + if ((*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+infoOffset) & NWK_APP_REPLY_BIT)) + { + if ((*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+tidOffset) == tid) && + !memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + rc = SMPL_MY_REPLY; + } + else + { + rc = SMPL_A_REPLY; + } + } + + return rc; +} + +/****************************************************************************** + * @fn map_lid2idx + * + * @brief Map link ID to index into connection table. + * + * input parameters + * @param lid - Link ID to be matched + * + * output parameters + * @param idx - populated with index into connection table + * + * @return Non-zero if Link ID found and output is valid else 0. + */ +static uint8_t map_lid2idx(linkID_t lid, uint8_t *idx) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) && (ptr->thisLinkID == lid)) + { + *idx = i; + return 1; + } + } + + return 0; +} + +/****************************************************************************** + * @fn nwk_findPeer + * + * @brief Find connection entry for a peer + * + * input parameters + * @param peerAddr - address of peer + * @param peerPort - port on which this device was sending to peer. + * + * output parameters + * + * @return Pointer to matching connection table entry else 0. + */ +connInfo_t *nwk_findPeer(addr_t *peerAddr, uint8_t peerPort) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + if (!memcmp(peerAddr, ptr->peerAddr, NET_ADDR_SIZE)) + { + if (peerPort == ptr->portTx) + { + return ptr; + } + } + } + } + + return (connInfo_t *)NULL; +} + +/****************************************************************************** + * @fn nwk_checkAppMsgTID + * + * @brief Compare received TID to last-seen TID to decide whether the + * received message is a duplicate or we missed some. + * + * input parameters + * @param lastTID - last-seen TID + * @param appMsgTID - TID from current application payload. + * + * output parameters + * + * @return Returns zero if message with supplied TID should be discarded. + * Otherwise returns non-zero. In this case the message should be + * processed. The last-seen TID should be updated with the current + * application payload TID. + * + */ +uint8_t nwk_checkAppMsgTID(appPTid_t lastTID, appPTid_t appMsgTID) +{ + uint8_t rc = 0; + + /* If the values are equal this is a duplicate. We're done. */ + if (lastTID != appMsgTID) + { + /* Is the new TID bigger? */ + if (appMsgTID > lastTID) + { + /* In this case the current payload is OK unless we've received a late + * (duplicate) message that occurred just before the TID wrapped. This is + * considered a duplicate and we should discard it. + */ + if (!(DUP_TID_AFTER_WRAP(lastTID, appMsgTID))) + { + rc = 1; + } + } + else + { + /* New TID is smaller. Accept the payload if this is the wrap case or we missed + * the specific wrap frame but are still within the range in which we assume + * we missed it. Otherwise is a genuine late frame so we should ignore it. + */ + if (CHECK_TID_WRAP(lastTID, appMsgTID)) + { + rc = 1; + } + } + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_getNumObjectFromMsg + * + * @brief Get a numeric object from a message buffer. Take care of + * alignment and endianess issues. + * + * input parameters + * @param src - pointer to object location in message buffer + * @param objSize - size of numeric object + * + * output parameters + * @param dest - pointer to numeric type variable receiving the object + * contains aligned number in correct endian order on return. + * + * @return void. There is no warning if there is no case for the supplied + * object size. A simple copy is then done. Alignment is + * guaranteed only for object size cases defined (and + * vacuously size 1). + * + */ +void nwk_getNumObjectFromMsg(void *src, void *dest, uint8_t objSize) +{ + /* Take care of alignment */ + memmove(dest, src, objSize); + + /* Take care of endianess */ + switch(objSize) + { + case 2: + *((uint16_t *)dest) = ntohs(*((uint16_t *)dest)); + break; + + case 4: + *((uint32_t *)dest) = ntohl(*((uint32_t *)dest)); + break; + } + + return; +} + +/****************************************************************************** + * @fn nwk_putNumObjectIntoMsg + * + * @brief Put a numeric object into a message buffer. Take care of + * alignment and endianess issues. + * + * input parameters + * @param src - pointer to numeric type variable providing the object + * @param objSize - size of numeric object. Fuction works for object size 1. + * + * output parameters + * @param dest - pointer to object location in message buffer where the + * correct endian order representation will be placed. + * + * @return void. There is no warning if there is no case for the supplied + * object size. A simple copy is then done. + * + */ +void nwk_putNumObjectIntoMsg(void *src, void *dest, uint8_t objSize) +{ + + uint8_t *ptr; + uint16_t u16; + uint32_t u32; + + /* Take care of endianess */ + switch(objSize) + { + case 1: + ptr = (uint8_t *)src; + break; + + case 2: + u16 = htons(*((uint16_t *)src)); + ptr = (uint8_t *)&u16; + break; + + case 4: + u32 = htonl(*((uint32_t *)src)); + ptr = (uint8_t *)&u32; + break; + + default: + ptr = (uint8_t *)src; + break; + } + + /* Take care of alignment */ + memmove(dest, ptr, objSize); + + return; +} +/****************************************************************************** + * @fn nwk_NVObj + * + * @brief GET and SET support for NV object (connection context). + * + * input parameters + * @param action - GET or SET + * @param val - (GET/SET) pointer to NV IOCTL object. + * (SET) NV length and version values to be used for sanity + * checks. + * + * output parameters + * @param val - (GET) Version number of NV object, size of NV object and + * pointer to the connection context memory. + * - (SET) Pointer to the connection context memory. + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Object version or size do not conform on a SET call + * or illegal action specified. + */ +smplStatus_t nwk_NVObj(ioctlAction_t action, ioctlNVObj_t *val) +{ +#ifdef NVOBJECT_SUPPORT + smplStatus_t rc = SMPL_SUCCESS; + + if (IOCTL_ACT_GET == action) + { + /* Populate helper objects */ + val->objLen = SIZEOF_NV_OBJ; + val->objVersion = sPersistInfo.structureVersion; + /* Set pointer to connection context if address of pointer is not null */ + if (val->objPtr) + { + *(val->objPtr) = (uint8_t *)&sPersistInfo; + } + } + else + { + rc = SMPL_BAD_PARAM; + } + + return rc; +#else /* NVOBJECT_SUPPORT */ + return SMPL_BAD_PARAM; +#endif +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk.h new file mode 100755 index 0000000..6009f38 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk.h @@ -0,0 +1,159 @@ +/************************************************************************************************** + Filename: nwk.h + Revised: $Date: 2008-12-01 11:58:33 -0800 (Mon, 01 Dec 2008) $ + Revision: $Revision: 18551 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI network layer. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_H +#define NWK_H + + +/* well known ports*/ +#define SMPL_PORT_PING 0x01 +#define SMPL_PORT_LINK 0x02 +#define SMPL_PORT_JOIN 0x03 +#define SMPL_PORT_SECURITY 0x04 +#define SMPL_PORT_FREQ 0x05 +#define SMPL_PORT_MGMT 0x06 + +#define SMPL_PORT_NWK_BCAST 0x1F +#define SMPL_PORT_USER_BCAST 0x3F + +/* Unconnected User Datagram Link ID */ +#define SMPL_LINKID_USER_UUD ((linkID_t) ~0) + +#define PORT_BASE_NUMBER 0x20 + +/* Reserve the top of the User port namespace below the broadcast + * address for static allocation. + */ +#define PORT_USER_STATIC_NUM 1 +#define SMPL_PORT_STATIC_MAX 0x3E +#define SMPL_PORT_USER_MAX (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM) + + +/* to check connection info sanity */ +#define CHK_RX 0 +#define CHK_TX 1 + +/* return types for validating a reply frame */ +#define SMPL_MY_REPLY 0 +#define SMPL_A_REPLY 1 +#define SMPL_NOT_REPLY 2 + +/* when allocating local Rx port it depends on whether the allocation + * is being done as a result of a link or a link reply + */ +#define LINK_SEND 1 +#define LINK_REPLY 2 + +#define CONNSTATE_FREE (0x00) +#define CONNSTATE_JOINED (0x01) +#define CONNSTATE_CONNECTED (0x02) + +typedef struct +{ + volatile uint8_t connState; + uint8_t hops2target; +#ifdef APP_AUTO_ACK + volatile uint8_t ackTID; +#endif + uint8_t peerAddr[NET_ADDR_SIZE]; + rxMetrics_t sigInfo; + uint8_t portRx; + uint8_t portTx; + linkID_t thisLinkID; +#ifdef SMPL_SECURE + uint32_t connTxCTR; + uint32_t connRxCTR; +#endif +} connInfo_t; + +/**************************************************************************************** + * Application Payload TID support + * + * Sometimes the receiving application uses a payload TID to determine if either it + * missed frames (received TID > (last-seen TID+1)) or is seeing a duplicate (received + * TID <= last-seen TID). Typically the TID simply increments for each successive frame. + * But when the count wraps there is a problem. The received TID should always be one + * more than the last TID. If it's equal, it's a duplicate. If it's less it's late. If + * it's one more it's the one we expect. If it's more than 1 more then we missed frames. + * Simple increments work for the wrap arithmetically. If the received TID is 0 and the last + * seen ID is the biggest number in the world -- 0xFF... depending on type we can detect + * the wrap. But if the receiver misses the 0 TID value for any reason or the biggest + * number in the world TID is missed then susbequent testing for missed or duplicate + * frames can get confused. We resolve this by allowing some leeway in the wrap testing. + * this testing is assisted by the following macros. Setting TID_VALID_WINDOW to 0 + * will enforce a no leniency policy. In this case you'd better not miss either the + * biggest number or the 0. The CHECK_TID_WRAP macro is only needed if the received + * TID is less than the last-seen TID. The DUP_TID_AFTER_WRAP macro is only needed if the + * received TID is greater than 1 more than the last-seen TID. + ***************************************************************************************/ +#define MAX_APT ((appPTid_t)~0) /* max value of application payload TID type */ +#define TID_VALID_WINDOW 2 /* window around max and 0 */ + +#define CHECK_TID_WRAP(lastTID, newTID) ((lastTID >= (MAX_APT - TID_VALID_WINDOW)) && \ + (newTID <= TID_VALID_WINDOW) \ + ) +#define DUP_TID_AFTER_WRAP(lastTID, newTID) ((newTID >= (MAX_APT - TID_VALID_WINDOW)) && \ + (lastTID <= TID_VALID_WINDOW) \ + ) + +/* prototypes */ +smplStatus_t nwk_nwkInit(uint8_t (*)(linkID_t)); +connInfo_t *nwk_getNextConnection(void); +void nwk_freeConnection(connInfo_t *); +uint8_t nwk_getNextClientPort(void); +connInfo_t *nwk_getConnInfo(linkID_t port); +connInfo_t *nwk_isLinkDuplicate(uint8_t *, uint8_t); +uint8_t nwk_findAddressMatch(mrfiPacket_t *); +smplStatus_t nwk_checkConnInfo(connInfo_t *, uint8_t); +uint8_t nwk_isConnectionValid(mrfiPacket_t *, linkID_t *); +uint8_t nwk_allocateLocalRxPort(uint8_t, connInfo_t *); +uint8_t nwk_isValidReply(mrfiPacket_t *, uint8_t, uint8_t, uint8_t); +connInfo_t *nwk_findPeer(addr_t *, uint8_t); +smplStatus_t nwk_NVObj(ioctlAction_t, ioctlNVObj_t *); + + +uint8_t nwk_checkAppMsgTID(appPTid_t, appPTid_t); +void nwk_getNumObjectFromMsg(void *, void *, uint8_t); +void nwk_putNumObjectIntoMsg(void *, void *, uint8_t); +#ifdef ACCESS_POINT +sfInfo_t *nwk_getSFInfoPtr(void); +#ifdef AP_IS_DATA_HUB +uint8_t nwk_saveJoinedDevice(mrfiPacket_t *); +connInfo_t *nwk_findAlreadyJoined(mrfiPacket_t *); +#endif +#endif + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.c new file mode 100755 index 0000000..4cb34ea --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.c @@ -0,0 +1,417 @@ +/************************************************************************************************** + Filename: nwk_QMgmt.c + Revised: $Date: 2009-03-10 17:01:56 -0700 (Tue, 10 Mar 2009) $ + Revision: $Revision: 19372 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI input and output frame queues + + Copyright 2007-2008 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk.h" +#include "nwk_frame.h" +#include "nwk_QMgmt.h" +#include "nwk_mgmt.h" /* need offsets for poll frames */ + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +#if SIZE_INFRAME_Q > 0 +static frameInfo_t sInFrameQ[SIZE_INFRAME_Q]; +#else +static frameInfo_t *sInFrameQ = NULL; +#endif /* SIZE_INFRAME_Q > 0 */ + +static frameInfo_t sOutFrameQ[SIZE_OUTFRAME_Q]; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** +* @fn nwk_QInit +* +* @brief Initialize the input and output frame queues to hold no packets. +* +* input parameters +* +* output parameters +* +* @return void +*/ +void nwk_QInit(void) +{ +#if SIZE_INFRAME_Q > 0 + memset(sInFrameQ, 0, sizeof(sInFrameQ)); +#endif // SIZE_INFRAME_Q > 0 + memset(sOutFrameQ, 0, sizeof(sOutFrameQ)); +} + +/****************************************************************************** + * @fn nwk_QfindSlot + * + * @brief Finds a slot to use to retrieve the frame from the radio. It + * uses a LRU cast-out scheme. It is possible that this routine + * finds no slot. This can happen if the queue is of size 1 or 2 + * and the Rx interrupt occurs during a retrieval call from an + * application. There are meta-states for frames as the application + * looks for the oldest frame on the port being requested. + * + * This routine is running in interrupt context. + * + * input parameters + * @param which - INQ or OUTQ to search + * + * output parameters + * + * @return Pointer to oldest available frame in the queue + */ +frameInfo_t *nwk_QfindSlot(uint8_t which) +{ + frameInfo_t *pFI, *oldest= 0, *newFI = 0; + uint8_t i, num, newOrder = 0, orderTest; + + if (INQ == which) + { + pFI = sInFrameQ; + num = SIZE_INFRAME_Q; + } + else + { + pFI = sOutFrameQ; + num = SIZE_OUTFRAME_Q; + } + + orderTest = num + 1; + + for (i=0; ifi_usage != FI_AVAILABLE) + { + if (INQ == which) /* TODO: do cast-out for Tx as well */ + { + + /* need to know the number of occupied slots so we know the age value + * for the unoccupied slot (if there is one). + */ + newOrder++; + + /* make sure nwk_retrieveFrame() is not processing this frame */ + if (FI_INUSE_TRANSITION == pFI->fi_usage) + { + continue; + } + /* is this frame older than any we've seen? */ + if (orderTest > pFI->orderStamp) + { + /* yes. */ + oldest = pFI; + orderTest = pFI->orderStamp; + } + } + } + else + { + if (OUTQ == which) /* TODO: do cast-out for Tx as well */ + { + return pFI; + } + newFI = pFI; + } + } + + /* did we find anything? */ + if (!newFI) + { + /* queue was full. cast-out happens here...unless... */ + if (!oldest) + { + /* This can happen if the queue is only of size 1 or 2 and all + * the frames are in transition when the Rx interrupt occurs. + */ + return (frameInfo_t *)0; + } + newFI = oldest; + nwk_QadjustOrder(which, newFI->orderStamp); + newFI->orderStamp = i; + } + else + { + /* mark the available slot. */ + newFI->orderStamp = ++newOrder; + } + + return newFI; +} + +/****************************************************************************** + * @fn nwk_QadjustOrder + * + * @brief Adjusts the age of everyone in the queue newer than the frame + * being removed. + * + * input parameters + * @param which - INQ or OUTQ to adjust + * @param stamp - value of frame being removed + * + * output parameters + * + * @return void + */ +void nwk_QadjustOrder(uint8_t which, uint8_t stamp) +{ + frameInfo_t *pFI; + uint8_t i, num; + bspIState_t intState; + + if (INQ == which) + { + pFI = sInFrameQ; + num = SIZE_INFRAME_Q; + } + else + { +/* pFI = sOutFrameQ; */ +/* num = SIZE_OUTFRAME_Q; */ + return; + } + + BSP_ENTER_CRITICAL_SECTION(intState); + + for (i=0; ifi_usage != FI_AVAILABLE) && (pFI->orderStamp > stamp)) + { + pFI->orderStamp--; + } + } + + BSP_EXIT_CRITICAL_SECTION(intState); + + return; +} + +/****************************************************************************** + * @fn nwk_QfindOldest + * + * @brief Look through frame queue and find the oldest available frame + * in the context in question. Supports connection-based (user), + * non-connection based (NWK applications), and the special case + * of store-and-forward. + * + * input parameters + * @param which - INQ or OUTQ to adjust + * @param rcvContext - context information for finding the oldest + * @param usage - normal usage or store-and-forward usage + * + * output parameters + * + * @return Pointer to frame that is the oldsest on the requested port, or + * 0 if there are none. + */ +frameInfo_t *nwk_QfindOldest(uint8_t which, rcvContext_t *rcv, uint8_t fi_usage) +{ + uint8_t i, oldest, num, port; + uint8_t uType, addr12Compare; + bspIState_t intState; + frameInfo_t *fPtr = 0, *wPtr; + connInfo_t *pCInfo = 0; + uint8_t *pAddr1, *pAddr2, *pAddr3 = 0; + + if (INQ == which) + { + wPtr = sInFrameQ; + num = SIZE_INFRAME_Q; + oldest = SIZE_INFRAME_Q+1; + } + else + { +/* pFI = sOutFrameQ; */ +/* num = SIZE_OUTFRAME_Q; */ + return 0; + } + + if (RCV_APP_LID == rcv->type) + { + pCInfo = nwk_getConnInfo(rcv->t.lid); + if (!pCInfo) + { + return (frameInfo_t *)0; + } + port = pCInfo->portRx; + pAddr2 = pCInfo->peerAddr; + } + else if (RCV_NWK_PORT == rcv->type) + { + port = rcv->t.port; + } +#ifdef ACCESS_POINT + else if (RCV_RAW_POLL_FRAME == rcv->type) + { + port = *(MRFI_P_PAYLOAD(rcv->t.pkt)+F_APP_PAYLOAD_OS+M_POLL_PORT_OS); + pAddr2 = MRFI_P_SRC_ADDR(rcv->t.pkt); + pAddr3 = MRFI_P_PAYLOAD(rcv->t.pkt)+F_APP_PAYLOAD_OS+M_POLL_ADDR_OS; + } +#endif + else + { + return (frameInfo_t *)0; + } + + uType = (USAGE_NORMAL == fi_usage) ? FI_INUSE_UNTIL_DEL : FI_INUSE_UNTIL_FWD; + + for (i=0; ifi_usage) + { + wPtr->fi_usage = FI_INUSE_TRANSITION; + + BSP_EXIT_CRITICAL_SECTION(intState); /* release hold */ + /* message sent to this device? */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&wPtr->mrfiPkt), F_PORT_OS) == port) + { + /* Port matches. If the port of interest is a NWK applicaiton we're a + * match...the NWK applications are not connection-based. If it is a + * NWK application we need to check the source address for disambiguation. + * Also need to check source address if it's a raw frame lookup (S&F frame) + */ + if (RCV_APP_LID == rcv->type) + { + if (SMPL_PORT_USER_BCAST == port) + { + /* guarantee a match... */ + pAddr1 = pCInfo->peerAddr; + } + else + { + pAddr1 = MRFI_P_SRC_ADDR(&wPtr->mrfiPkt); + } + } +#ifdef ACCESS_POINT + else if (RCV_RAW_POLL_FRAME == rcv->type) + { + pAddr1 = MRFI_P_DST_ADDR(&wPtr->mrfiPkt); + } +#endif + + addr12Compare = memcmp(pAddr1, pAddr2, NET_ADDR_SIZE); + if ( (RCV_NWK_PORT == rcv->type) || + (!pAddr3 && !addr12Compare) || + (pAddr3 && !memcmp(pAddr3, MRFI_P_SRC_ADDR(&wPtr->mrfiPkt), NET_ADDR_SIZE)) + ) + { + if (wPtr->orderStamp < oldest) + { + if (fPtr) + { + /* restore previous oldest one */ + fPtr->fi_usage = uType; + } + oldest = wPtr->orderStamp; + fPtr = wPtr; + continue; + } + else + { + /* not oldest. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + /* not a match. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + /* wrong port. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + BSP_EXIT_CRITICAL_SECTION(intState); + } + } + + return fPtr; +} + +/****************************************************************************** + * @fn nwk_getQ + * + * @brief Get location of teh specified frame queue. + * + * input parameters + * @param which - INQ or OUTQ to get + * + * output parameters + * + * @return Pointer to frame queue + */ +frameInfo_t *nwk_getQ(uint8_t which) +{ + return (INQ == which) ? sInFrameQ : sOutFrameQ; +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.h new file mode 100755 index 0000000..aa5535b --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_QMgmt.h @@ -0,0 +1,53 @@ +/************************************************************************************************** + Filename: nwk_QMgmt.h + Revised: $Date: 2009-01-17 15:14:16 -0800 (Sat, 17 Jan 2009) $ + Revision: $Revision: 18788 $ + Author: $Author: rlord $ + + Description: This header file supports the SimpliciTI input and output frame queues. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_QMGMT_H +#define NWK_QMGMT_H + + +#define INQ 1 +#define OUTQ 2 + +#define USAGE_NORMAL 1 +#define USAGE_FWD 2 + +/* prototypes */ +void nwk_QInit(void); +frameInfo_t *nwk_QfindSlot(uint8_t); +void nwk_QadjustOrder(uint8_t, uint8_t); +frameInfo_t *nwk_QfindOldest(uint8_t, rcvContext_t *, uint8_t); +frameInfo_t *nwk_getQ(uint8_t); + +#endif /* NWK_QMGMT_H */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_api.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_api.c new file mode 100755 index 0000000..da5c0b7 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_api.c @@ -0,0 +1,858 @@ +/************************************************************************************************** + Filename: nwk_api.c + Revised: $Date: 2009-01-28 18:27:38 -0800 (Wed, 28 Jan 2009) $ + Revision: $Revision: 18875 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI appliction layer API. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "mrfi.h" +#include "nwk_globals.h" +#include "nwk_freq.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/* These defines are in support an application listening for a link frame to + * terminate after some amount of time. The intention is that this guard be + * the exception. The intention of the SimpliciTI design is that the + * temporal contiguity between the listen and the reception of the link frame + * from the peer be very tight. The SMPL_LinkListen() should be termninated + * by the reception of the link frame. But in case it does not receive the frame + * the support below allows intervention by the application. + */ + +/* The intention is for user to modify just the following single value */ +#define LINKLISTEN_MILLISECONDS_2_WAIT (5000) + +#define LINKLISTEN_POLL_PERIOD_MS (10) +#define LINKLISTEN_POLL_COUNT ( (LINKLISTEN_MILLISECONDS_2_WAIT) / (LINKLISTEN_POLL_PERIOD_MS) ) + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +// [BM] Workaround to enable multiple stack restarts +// static uint8_t sInit_done = 0; +uint8_t sInit_done = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static uint8_t ioctlPreInitAccessIsOK(ioctlObject_t); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/*********************************************************************************** + * @fn SMPL_Init + * + * @brief Initialize the SimpliciTI stack. + * + * input parameters + * @param f - Pointer to call back function. Function called by NWK when + * user application frame received. The callback is done in the + * ISR thread. Argument is Link ID associated with frame. Function + * returns 0 if frame is to be kept by NWK, otherwise 1. Frame + * should be kept if application will do a SMPL_Receive() in the + * user thread (recommended). Pointer may be NULL. + * + * output parameters + * + * @return Status of operation: + * SMPL_SUCCESS + * SMPL_NO_JOIN No Join reply. AP possibly not yet up. + * SMPL_NO_CHANNEL Only if Frequency Agility enabled. Channel scan + * failed. AP possibly not yet up. + */ +smplStatus_t SMPL_Init(uint8_t (*f)(linkID_t)) +{ + smplStatus_t rc; + + if (!sInit_done) + { + /* set up radio. */ + MRFI_Init(); + + /* initialize network */ + if ((rc=nwk_nwkInit(f)) != SMPL_SUCCESS) + { + return rc; + } + + MRFI_WakeUp(); +#if defined( FREQUENCY_AGILITY ) + { + freqEntry_t chan; + + chan.logicalChan = 0; + /* ok to set default channel explicitly now that MRFI initialized. */ + nwk_setChannel(&chan); + } +#endif + /* don't turn Rx on if we're an end device that isn't always on. */ +#if !defined( END_DEVICE ) + MRFI_RxOn(); +#endif + +#if defined( END_DEVICE ) + /* All except End Devices are in promiscuous mode */ + MRFI_SetRxAddrFilter((uint8_t *)nwk_getMyAddress()); + MRFI_EnableRxAddrFilter(); +#endif + } + sInit_done = 1; + + /* Join. if no AP or Join fails that status is returned. */ + rc = nwk_join(); + + return rc; +} + +/****************************************************************************** + * @fn SMPL_LinkListen + * + * @brief Listen for a link frame from a 'client' device. + * + * input parameters + * + * output parameters + * @param linkID - pointer to Link ID to be used by application to + * read and write to the linked peer. + * + * @return status of operation. + * SMPL_SUCCESS + * SMPL_TIMEOUT No link frame received during listen interval. +* Interval set in #defines above. linkID not valid. + * + */ + +smplStatus_t SMPL_LinkListen(linkID_t *linkID) +{ + uint8_t radioState = MRFI_GetRadioState(); + uint16_t i; + linkID_t locLinkID; + + /* Set the context. We want to reject any link frames received if + * we're not listening. For example if we're an AP we are in + * promiscuous mode and we'll see any broadcast link frames. + */ + nwk_setListenContext(LINK_LISTEN_ON); + + NWK_CHECK_FOR_SETRX(radioState); + + for (i=0; i MAX_APP_PAYLOAD)) + { + return rc; + } + + /* Build an outgoing message frame destined for the port from the + * connection info using the destination address also from the + * connection info. + */ + if (SMPL_TXOPTION_NONE == options) + { + pFrameInfo = nwk_buildFrame(pCInfo->portTx, msg, len, pCInfo->hops2target); + } +#if defined(APP_AUTO_ACK) + else if (options & SMPL_TXOPTION_ACKREQ) + { + if (SMPL_LINKID_USER_UUD != lid) + { + pFrameInfo = nwk_buildAckReqFrame(pCInfo->portTx, msg, len, pCInfo->hops2target, &pCInfo->ackTID); + ackreq = 1; + } + else + { + /* can't request an ack on the UUD link ID */ + return SMPL_BAD_PARAM; + } + } +#endif /* APP_AUTO_ACK */ + else + { + return SMPL_BAD_PARAM; + } + + if (!pFrameInfo) + { + return SMPL_NOMEM; + } + memcpy(MRFI_P_DST_ADDR(&pFrameInfo->mrfiPkt), pCInfo->peerAddr, NET_ADDR_SIZE); + +#if defined(SMPL_SECURE) + { + uint32_t *pUL = 0; + + if (pCInfo->thisLinkID != SMPL_LINKID_USER_UUD) + { + pUL = &pCInfo->connTxCTR; + } + nwk_setSecureFrame(&pFrameInfo->mrfiPkt, len, pUL); + } +#endif /* SMPL_SECURE */ + +#if defined(ACCESS_POINT) + /* If we are an AP trying to send to a polling device, don't do it. + * See if the target is a store-and-forward client. + */ + if (nwk_isSandFClient(MRFI_P_DST_ADDR(&pFrameInfo->mrfiPkt), &loc)) + { + pFrameInfo->fi_usage = FI_INUSE_UNTIL_FWD; + return SMPL_SUCCESS; + } + else +#endif /* ACCESS_POINT */ + { + rc = nwk_sendFrame(pFrameInfo, MRFI_TX_TYPE_CCA); + } + +#if !defined(APP_AUTO_ACK) + /* save a little code space with this #if */ + (void) ackreq; /* keep compiler happy */ + return rc; +#else + /* we're done if the send failed or no ack requested. */ + if (SMPL_SUCCESS != rc || !ackreq) + { + return rc; + } + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + { + bspIState_t intState; + + /* If the saved TID hasn't been reset then we never got the ack. */ + BSP_ENTER_CRITICAL_SECTION(intState); + if (pCInfo->ackTID) + { + pCInfo->ackTID = 0; + rc = SMPL_NO_ACK; + } + BSP_EXIT_CRITICAL_SECTION(intState); + } + + return rc; +#endif /* APP_AUTO_ACK */ +} + +/************************************************************************************** + * @fn SMPL_Receive + * + * @brief Receive a message from a peer application. + * + * input parameters + * @param lid - Link ID (port) from application + * + * + * output parameters + * @param msg - pointer to where received message should be copied. + * buffer should be of size == MAX_APP_PAYLOAD + * @param len - pointer to receive length of received message + * + * @return Status of operation. + * Caller should not use the value returned in 'len' to decide + * whether there is a frame or not. It could be useful to the + * Caller to distinguish between no frame and a frame with no data. + * For example, in the polling case a frame with no application payload + * is the way the AP conveys that there are no frames waiting. + * + * SMPL_SUCCESS + * + * SMPL_BAD_PARAM No valid Connection Table entry for Link ID + * Data in Connection Table entry bad + * SMPL_NO_FRAME No frame received. + * SMPL_NO_PAYLOAD Frame received with no payload (not necessarily + * an error and could be deduced by application + * because the returned length will be 0) + * + * Polling device only: + * + * SMPL_TIMEOUT No response from Access Point + * SMPL_NO_AP_ADDRESS Access Point address unknown + * SMPL_TX_CCA_FAIL Could not send poll frame + * SMPL_NOMEM No memory in output frame queue + * SMPL_NO_CHANNEL Frequency Agility enabled and could not find channel + */ +smplStatus_t SMPL_Receive(linkID_t lid, uint8_t *msg, uint8_t *len) +{ + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + rcvContext_t rcv; + + if (!pCInfo || ((rc=nwk_checkConnInfo(pCInfo, CHK_RX)) != SMPL_SUCCESS)) + { + return rc; + } + + rcv.type = RCV_APP_LID; + rcv.t.lid = lid; + +#if defined(RX_POLLS) + { + uint8_t numChans = 1; +#if defined(FREQUENCY_AGILITY) + freqEntry_t chans[NWK_FREQ_TBL_SIZE]; + uint8_t scannedB4 = 0; +#endif + + do + { + uint8_t radioState = MRFI_GetRadioState(); + + /* I'm polling. Do the poll to stimulate the sending of a frame. If the + * frame has application length of 0 it means there were no frames. If + * no reply is received infer that the channel is changed. We then need + * to scan and then retry the poll on each channel returned. + */ + if (SMPL_SUCCESS != (rc=nwk_poll(pCInfo->portRx, pCInfo->peerAddr))) + { + /* for some reason couldn't send the poll out. */ + return rc; + } + + /* do this before code block below which may reset it. */ + numChans--; + + /* Wait until there's a frame. if the len is 0 then return SMPL_NO_FRAME + * to the caller. In the poll case the AP always sends something. + */ + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + /* TODO: deal with pending */ + rc = nwk_retrieveFrame(&rcv, msg, len, 0, 0); + +#if defined(FREQUENCY_AGILITY) + if (SMPL_SUCCESS == rc) + { + /* we received something... */ + return (*len) ? SMPL_SUCCESS : SMPL_NO_PAYLOAD; + } + + /* No reply. scan for other channel(s) if we haven't already. Then set + * one and try again. + */ + if (!scannedB4) + { + numChans = nwk_scanForChannels(chans); + scannedB4 = 1; + } + if (numChans) + { + nwk_setChannel(&chans[numChans-1]); + } +#else /* FREQUENCY_AGILITY */ + return (*len) ? rc : ((SMPL_SUCCESS == rc) ? SMPL_NO_PAYLOAD : SMPL_TIMEOUT); +#endif + } while (numChans); + } + +#if defined(FREQUENCY_AGILITY) + return SMPL_NO_CHANNEL; +#endif + +#else /* RX_POLLS */ + return nwk_retrieveFrame(&rcv, msg, len, 0, 0); +#endif /* RX_POLLS */ +} + + +/****************************************************************************** + * @fn SMPL_Link + * + * @brief Link to a peer. + * + * input parameters + * + * output parameters + * @param lid - pointer to where we should write the link ID to which the + * application will read and write. + * + * @return Status of operation. + * SMPL_SUCCESS + * SMPL_NOMEM No room to allocate local Rx port, no more + * room in Connection Table, or no room in + * output frame queue. + * SMPL_NO_LINK No reply frame during wait window. + * SMPL_TX_CCA_FAIL Could not send Link frame. + */ +smplStatus_t SMPL_Link(linkID_t *lid) +{ + return nwk_link(lid); +} + +#if defined(EXTENDED_API) +/************************************************************************************** + * @fn SMPL_Unlink + * + * @brief Tear down connection to a peer. + * + * input parameters + * @param lid - Link ID whose connection is to be terminated. + * + * output parameters + * + * @return Status of operation. The Connection Table entry for the Link ID + * is always freed successfuly. The returned status value is the + * status of the _peer's_ connection tear-down as a result of the + * message sent here. + * SMPL_SUCCESS Local and remote connection destroyed. + * SMPL_BAD_PARAM No local connection table entry for this Link ID + * SMPL_TIMEOUT No reply from peer. + * SMPL_NO_PEER_UNLINK Peer did not have a Connection Table entry for me. + */ +smplStatus_t SMPL_Unlink(linkID_t lid) +{ + return nwk_unlink(lid); +} + +/************************************************************************************** + * @fn SMPL_Ping + * + * @brief Ping a peer. Synchronous call. Although a link ID is used it is the + * NWK Ping application that is pinged, not the peer of this Link ID. The + * peer is not expected to be the responder to the frame sent from here. + * This API is a proxy for a real ping since the application doesn't + * have direct access to SimpliciTI device addresses. Kind of hokey but a + * useful keep-alive mechanism without having to support it with + * user application service. + * + * input parameters + * @param lid - The link ID whose peer device address is used to direct the NWK Ping + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t SMPL_Ping(linkID_t lid) +{ + return nwk_ping(lid); +} + +/************************************************************************************** + * @fn SMPL_Commission + * + * @brief Commission a connection. + * + * input parameters + * @param peerAddr - Pointer to address of the peer for this connection + * @param locPort - Port on which to listen for messages from the peer + * @param rmtPort - Port on which to send messages to the peer. + * @param lid - Pointer to Link ID object. If content of location is + * non-zero on input the value is placed in the Connection + * object. + * + * output parameters + * @param lid - Pointer to Link ID object. If content of location is zero + * on input the value in the Connection object is stored there. + * + * @return SMPL_SUCCESS + * SMPL_NOMEM - No room left in Connection table. + * SMPL_BAD_PARAM - A pointer to a Link object was not supplied. + */ +smplStatus_t SMPL_Commission(addr_t *peerAddr, uint8_t locPort, uint8_t rmtPort, linkID_t *lid) +{ + connInfo_t *pCInfo = nwk_getNextConnection(); + smplStatus_t rc = SMPL_BAD_PARAM; + + do { + if (pCInfo) + { + /* sanity checks... */ + + /* Check port info. */ + if ((locPort > SMPL_PORT_STATIC_MAX) || (locPort < (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM + 1))) + { + continue; + } + + if ((rmtPort > SMPL_PORT_STATIC_MAX) || (rmtPort < (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM + 1))) + { + continue; + } + + /* Must supply a pointer to the Link ID object */ + if (!lid) + { + /* No Link ID pointer supplied */ + continue; + } + + /* we're sane */ + + /* Use the value generated at connection object assign time. */ + *lid = pCInfo->thisLinkID; + + /* store peer's address */ + memcpy(pCInfo->peerAddr, peerAddr, NET_ADDR_SIZE); + + /* store port info */ + pCInfo->portRx = locPort; + pCInfo->portTx = rmtPort; + + pCInfo->hops2target = MAX_HOPS; + + rc = SMPL_SUCCESS; + } + else + { + /* No room in Connection table */ + rc = SMPL_NOMEM; + } + } while (0); + + if ((SMPL_SUCCESS != rc) && pCInfo) + { + nwk_freeConnection(pCInfo); + } + + return rc; +} +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn SMPL_Ioctl + * + * @brief This routine supplies the SimpliciTI IOCTL support. + * + * input parameters + * @param object - The IOCTL target object + * @param action - The IOCTL target action on the object + * @param val - pointer to value. exact forn depends on object type. + * + * output parameters + * + * @return Status of action. Value depends on object, action, and result. + * + * SMPL_BAD_PARAM is returned if this API is called before + * initialization and the object is not one of + * the valid exceptions. + */ +smplStatus_t SMPL_Ioctl(ioctlObject_t object, ioctlAction_t action, void *val) +{ + smplStatus_t rc; + + /* if init hasn't occurred see if access is still valid */ + if (!sInit_done && !ioctlPreInitAccessIsOK(object)) + { + return SMPL_BAD_PARAM; + } + + switch (object) + { +#if defined(EXTENDED_API) + case IOCTL_OBJ_TOKEN: + { + ioctlToken_t *t = (ioctlToken_t *)val; + + rc = SMPL_SUCCESS; + if (TT_LINK == t->tokenType) + { + if (IOCTL_ACT_SET == action) + { + nwk_setLinkToken(t->token.linkToken); + } + else if (IOCTL_ACT_GET == action) + { + nwk_getLinkToken(&t->token.linkToken); + } + else + { + rc = SMPL_BAD_PARAM; + } + } + else if (TT_JOIN == t->tokenType) + { + if (IOCTL_ACT_SET == action) + { + nwk_setJoinToken(t->token.joinToken); + } + else if (IOCTL_ACT_GET == action) + { + nwk_getJoinToken(&t->token.joinToken); + } + else + { + rc = SMPL_BAD_PARAM; + } + } + else + { + rc = SMPL_BAD_PARAM; + } + } + break; + + case IOCTL_OBJ_NVOBJ: + rc = nwk_NVObj(action, (ioctlNVObj_t *)val); + break; +#endif /* EXTENDED_API */ + + case IOCTL_OBJ_CONNOBJ: + rc = nwk_connectionControl(action, val); + break; + + case IOCTL_OBJ_ADDR: + if ((IOCTL_ACT_GET == action) || (IOCTL_ACT_SET == action)) + { + rc = nwk_deviceAddress(action, (addr_t *)val); + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_RAW_IO: + if (IOCTL_ACT_WRITE == action) + { + rc = nwk_rawSend((ioctlRawSend_t *)val); + } + else if (IOCTL_ACT_READ == action) + { + rc = nwk_rawReceive((ioctlRawReceive_t *)val); + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_RADIO: + rc = nwk_radioControl(action, val); + break; + +#if defined(ACCESS_POINT) + case IOCTL_OBJ_AP_JOIN: + rc = nwk_joinContext(action); + break; +#endif +#if defined(FREQUENCY_AGILITY) + case IOCTL_OBJ_FREQ: + rc = nwk_freqControl(action, val); + break; +#endif + case IOCTL_OBJ_FWVER: + if (IOCTL_ACT_GET == action) + { + memcpy(val, nwk_getFWVersion(), SMPL_FWVERSION_SIZE); + rc = SMPL_SUCCESS; + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_PROTOVER: + if (IOCTL_ACT_GET == action) + { + *((uint8_t *)val) = nwk_getProtocolVersion(); + rc = SMPL_SUCCESS; + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + default: + rc = SMPL_BAD_PARAM; + break; + } + + return rc; +} + +/****************************************************************************** + * @fn ioctlPreInitAccessIsOK + * + * @brief Is the request legal yet? Most requests are not legal before + * SMPL_Init(). + * + * input parameters + * @param object - The IOCTL target object + * + * output parameters + * + * @return Returns non-zero if request should be honored for further + * processing, otherwise returns 0. This function does not + * determine of the object-action pair are valid. It only knows + * about exceptions, i.e., those that are valid before the + * SMPL_Init() call. + * + */ +static uint8_t ioctlPreInitAccessIsOK(ioctlObject_t object) +{ + uint8_t rc; + + /* Currently the only legal pre-init accesses are the address and + * the token objects. + */ + switch (object) + { + case IOCTL_OBJ_ADDR: + case IOCTL_OBJ_TOKEN: + rc = 1; /* legal */ + break; + + default: + rc = 0; /* not legal when init not done */ + break; + } + + return rc; +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_api.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_api.h new file mode 100755 index 0000000..07ccf85 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_api.h @@ -0,0 +1,56 @@ +/************************************************************************************************** + Filename: nwk_api.h + Revised: $Date: 2008-11-24 12:09:31 -0800 (Mon, 24 Nov 2008) $ + Revision: $Revision: 18508 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI appliction layer API. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_API_H +#define NWK_API_H + +/* Tx options (bit map) */ +#define SMPL_TXOPTION_NONE ((txOpt_t)0x00) +#define SMPL_TXOPTION_ACKREQ ((txOpt_t)0x01) + +smplStatus_t SMPL_Init(uint8_t (*)(linkID_t)); +smplStatus_t SMPL_Link(linkID_t *); +smplStatus_t SMPL_LinkListen(linkID_t *); +smplStatus_t SMPL_Send(linkID_t lid, uint8_t *msg, uint8_t len); +smplStatus_t SMPL_SendOpt(linkID_t lid, uint8_t *msg, uint8_t len, txOpt_t); +smplStatus_t SMPL_Receive(linkID_t lid, uint8_t *msg, uint8_t *len); +smplStatus_t SMPL_Ioctl(ioctlObject_t, ioctlAction_t, void *); +#ifdef EXTENDED_API +smplStatus_t SMPL_Ping(linkID_t); +smplStatus_t SMPL_Unlink(linkID_t); +smplStatus_t SMPL_Commission(addr_t *, uint8_t, uint8_t, linkID_t *); +#endif /* EXTENDED_API */ + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_app.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_app.h new file mode 100755 index 0000000..45883b4 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_app.h @@ -0,0 +1,53 @@ + +/************************************************************************************************** + Filename: nwk_app.h + Revised: $Date: 2007-07-10 11:21:35 -0700 (Tue, 10 Jul 2007) $ + Revision: $Revision: 14865 $ + Author: $Author: lfriedman $ + + Description: This header file is for convenience and includes the headers for all the + network applications. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + + + +#ifndef NWK_APP_H +#define NWK_APP_H + +#include "nwk_freq.h" +#include "nwk_ping.h" +#include "nwk_link.h" +#include "nwk_mgmt.h" +#include "nwk_join.h" +#include "nwk_security.h" +#include "nwk_ioctl.h" + +#endif + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_frame.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_frame.c new file mode 100755 index 0000000..4279b25 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_frame.c @@ -0,0 +1,948 @@ +/************************************************************************************************** + Filename: nwk_frame.c + Revised: $Date: 2009-03-10 16:21:40 -0700 (Tue, 10 Mar 2009) $ + Revision: $Revision: 19368 $ + Author $Author: lfriedman $ + + Description: This file supports the SimpliciTI frame handling functions. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "nwk_QMgmt.h" +#include "nwk_globals.h" +#include "nwk_mgmt.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +#if SIZE_INFRAME_Q > 0 +/* array of function pointers to handle NWK application frames */ +static fhStatus_t (* const func[])(mrfiPacket_t *) = { nwk_processPing, + nwk_processLink, + nwk_processJoin, + nwk_processSecurity, + nwk_processFreq, + nwk_processMgmt + }; +#endif /* SIZE_INFRAME_Q > 0 */ + +static uint8_t sTRACTID = 0; + +static addr_t const *sMyAddr = NULL; + +static uint8_t sMyRxType = 0, sMyTxType = 0; + +#if !defined(RX_POLLS) +static uint8_t (*spCallback)(linkID_t) = NULL; +#endif + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +#if SIZE_INFRAME_Q > 0 +/* local helper functions for Rx devices */ +static void dispatchFrame(frameInfo_t *); +#if !defined(END_DEVICE) +#if defined(ACCESS_POINT) +/* only Access Points need to worry about duplicate S&F frames */ +uint8_t isDupSandFFrame(mrfiPacket_t *); +#endif /* ACCESS_POINT */ +#endif /* !END_DEVICE */ +#endif /* SIZE_INFRAME_Q > 0 */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_frameInit + * + * @brief Initialize network context. + * + * input parameters + * pF - Pointer to callback function. If none intended should be NULL. + * + * output parameters + * + * @return void + */ + +void nwk_frameInit(uint8_t (*pF)(linkID_t)) +{ + +/****** Fill static values for the DEVICEINFO byte that will go in each frame ******/ + /* Rx type when frame originates from this device. Set in nwk_buildFrame() */ + /* Tx type when frame sent from this device. Set in nwk_sendframe() */ +#if !defined(END_DEVICE) + sMyRxType = F_RX_TYPE_USER_CTL; + #if defined(ACCESS_POINT) + sMyTxType = F_TX_DEVICE_AP; + #else + sMyTxType = F_TX_DEVICE_RE; + #endif +#else + sMyTxType = F_TX_DEVICE_ED; + #if defined(RX_POLLS) + sMyRxType = F_RX_TYPE_POLLS; + #endif + #if defined(RX_USER) + sMyRxType = F_RX_TYPE_USER_CTL; + #endif +#endif +/****** DONE fill static values for the DEVICEINFO byte that will go in each frame ******/ + +#if !defined(RX_POLLS) + spCallback = pF; +#else + (void) pF; +#endif + + sMyAddr = nwk_getMyAddress(); + + while (!(sTRACTID=MRFI_RandomByte())) ; + + return; +} + +/****************************************************************************** + * @fn nwk_buildFrame + * + * @brief Builds an output frame for the port and message enclosed. + * This routine prepends the frame header and populates the + * frame in the output queue. + * + * input parameters + * @param port - port from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param hops - number of hops allowed. this is less than MAX_HOPS + * whenever the frame is being sent to the AP. this is to + * help mitigate the (short) broadcast storms + * + * output parameters + * + * @return pointer to frameInfo_t structure created. NULL if there is + * no room in output queue. + */ +frameInfo_t *nwk_buildFrame(uint8_t port, uint8_t *msg, uint8_t len, uint8_t hops) +{ + frameInfo_t *fInfoPtr; + + if (!(fInfoPtr=nwk_QfindSlot(OUTQ))) + { + return (frameInfo_t *)NULL; + } + + MRFI_SET_PAYLOAD_LEN(&fInfoPtr->mrfiPkt, len+F_APP_PAYLOAD_OS); + + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ENCRYPT_OS, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_PORT_OS, port); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_TRACTID_OS, sTRACTID); + while (!(++sTRACTID)) ; /* transaction ID can't be 0 */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_RX_TYPE, sMyRxType); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_HOP_COUNT, hops); + + /* reset ack-relevant bits */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_REQ, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_RPLY, 0); + + /* reset forwarding bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_FWD_FRAME, 0); + + memcpy(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt)+F_APP_PAYLOAD_OS, msg, len); + memcpy(MRFI_P_SRC_ADDR(&fInfoPtr->mrfiPkt), sMyAddr, NET_ADDR_SIZE); + + return fInfoPtr; +} + +#if defined(APP_AUTO_ACK) +/****************************************************************************** + * @fn nwk_buildAckReqFrame + * + * @brief Builds an output frame for the port and message enclosed. + * This routine prepends the frame header and populates the + * frame in the output queue. The frame is set to request that + * an ack frame be sent by the peer. + * + * input parameters + * @param port - port from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param hops - number of hops allowed. this is less than MAX_HOPS + * whenever the frame is being sent to the AP. this is to + * help mitigate the (short) broadcast storms + * @param tid - Transaction ID to insert in NWK header used to match + * the ack reply. + * + * output parameters + * + * @return pointer to frameInfo_t structure created. NULL if there is + * no room in output queue. + */ +frameInfo_t *nwk_buildAckReqFrame(uint8_t port, uint8_t *msg, uint8_t len, uint8_t hops, volatile uint8_t *tid) +{ + frameInfo_t *fInfoPtr; + + /* Build a normal frame first. */ + if (!(fInfoPtr=nwk_buildFrame(port, msg, len, hops))) + { + return (frameInfo_t *)NULL; + } + + /* save TID */ + *tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_TRACTID_OS); + /* Set REQ_ACK bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_REQ, F_ACK_REQ_TYPE); + + return fInfoPtr; +} +#endif /* APP_AUTO_ACK */ + +#if SIZE_INFRAME_Q > 0 +/****************************************************************************** + * @fn MRFI_RxCompleteISR + * + * @brief Here on Rx interrupt from radio. Process received frame from the + * radio Rx FIFO. + * + * input parameters + * + * output parameters + * + * @return void + */ +void MRFI_RxCompleteISR() +{ + frameInfo_t *fInfoPtr; + + /* room for more? */ + if (fInfoPtr=nwk_QfindSlot(INQ)) + { + MRFI_Receive(&fInfoPtr->mrfiPkt); + + dispatchFrame(fInfoPtr); + } + + return; +} + +/****************************************************************************** + * @fn nwk_retrieveFrame + * + * @brief Retrieve frame from Rx frame queue. Invoked by application-level + * code either app through SMPL_Receive() or IOCTL through raw Rx. This + * should run in a user thread, not an ISR thread. + * + * input parameters + * @param port - port on which to get a frame + * + * output parameters + * @param msg - pointer to where app payload should be copied. Buffer + * allocated should be == MAX_APP_PAYLOAD. + * + * @param len - pointer to where payload length should be stored. Caller + * can check for non-zero when polling the port. initialized + * to 0 even if no frame is retrieved. + * @param srcAddr - if non-NULL, a pointer to where to copy the source address + * of the retrieved message. + * @param hopCount - if non-NULL, a pointer to where to copy the hop count + of the retrieved message. + * + * @return SMPL_SUCCESS + * SMPL_NO_FRAME - no frame found for specified destination + * SMPL_BAD_PARAM - no valid connection info for the Link ID + * + */ +smplStatus_t nwk_retrieveFrame(rcvContext_t *rcv, uint8_t *msg, uint8_t *len, addr_t *srcAddr, uint8_t *hopCount) +{ + frameInfo_t *fPtr; + uint8_t done; + + do { + /* look for a frame on requested port. */ + *len = 0; + done = 1; + + fPtr = nwk_QfindOldest(INQ, rcv, USAGE_NORMAL); + if (fPtr) + { + connInfo_t *pCInfo = 0; + + if (RCV_APP_LID == rcv->type) + { + pCInfo = nwk_getConnInfo(rcv->t.lid); + if (!pCInfo) + { + return SMPL_BAD_PARAM; + } +#if defined(SMPL_SECURE) + /* decrypt here...we have all the context we need. */ + { + uint32_t ctr = pCInfo->connRxCTR; + uint32_t *pctr = &ctr; + uint8_t len = MRFI_GET_PAYLOAD_LEN(&fPtr->mrfiPkt) - F_SEC_CTR_OS; + + if (pCInfo->thisLinkID == SMPL_LINKID_USER_UUD) + { + pctr = NULL; + } +#if defined(RX_POLLS) + else if ((F_APP_PAYLOAD_OS - F_SEC_CTR_OS) == len) + { + /* This was an empty poll reply frame generated by the AP. + * It uses the single-byte CTR value like network applications. + * We do not want to use the application layer counter in this case. + */ + pctr = NULL; + } +#endif + if (nwk_getSecureFrame(&fPtr->mrfiPkt, len, pctr)) + { + if (pctr) + { + /* Update connection's counter. */ + pCInfo->connRxCTR = ctr; + } + } + else + { + /* Frame bogus. Check for another frame. */ + done = 0; + continue; + } + } +#endif /* SMPL_SECURE */ + } + + /* it's on the requested port. */ + *len = MRFI_GET_PAYLOAD_LEN(&fPtr->mrfiPkt) - F_APP_PAYLOAD_OS; + memcpy(msg, MRFI_P_PAYLOAD(&fPtr->mrfiPkt)+F_APP_PAYLOAD_OS, *len); + /* save signal info */ + if (pCInfo) + { + /* Save Rx metrics... */ + pCInfo->sigInfo.rssi = fPtr->mrfiPkt.rxMetrics[MRFI_RX_METRICS_RSSI_OFS]; + pCInfo->sigInfo.lqi = fPtr->mrfiPkt.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS]; + } + if (srcAddr) + { + /* copy source address if requested */ + memcpy(srcAddr, MRFI_P_SRC_ADDR(&fPtr->mrfiPkt), NET_ADDR_SIZE); + } + if (hopCount) + { + /* copy hop count if requested */ + *hopCount = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fPtr->mrfiPkt), F_HOP_COUNT); + } + /* input frame no longer needed. free it. */ + nwk_QadjustOrder(INQ, fPtr->orderStamp); + + fPtr->fi_usage = FI_AVAILABLE; + return SMPL_SUCCESS; + } + } while (!done); + + return SMPL_NO_FRAME; +} + +/****************************************************************************** + * @fn dispatchFrame + * + * @brief Received frame looks OK so far. Dispatch to either NWK app by + * invoking the handler or the user's app by simply leaving the + * frame in the queue and letting the app poll the port. + * + * input parameters + * @param fiPtr - frameInfo_t pointer to received frame + * + * output parameters + * + * @return void + */ +static void dispatchFrame(frameInfo_t *fiPtr) +{ + uint8_t port = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_PORT_OS); + uint8_t nwkAppSize = sizeof(func)/sizeof(func[0]); + fhStatus_t rc; + linkID_t lid; +#if defined(ACCESS_POINT) + uint8_t loc; +#endif +#if !defined(END_DEVICE) + uint8_t isForMe; +#endif + + /* be sure it's not an echo... */ + if (!memcmp(MRFI_P_SRC_ADDR(&fiPtr->mrfiPkt), sMyAddr, NET_ADDR_SIZE)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + + /* Make sure encyrption bit conforms to our security support context. */ +#if defined(SMPL_SECURE) + if (!(GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ENCRYPT_OS))) + { + /* Encyrption bit is not on when when it should be */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +#else + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ENCRYPT_OS)) + { + /* Encyrption bit is on when when it should not be */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +#endif /* SMPL_SECURE */ + + /* If it's a network application port dispatch to service routine. Dispose + * of frame depending on return code. + */ + if (port && (port <= nwkAppSize)) + { +#if defined(SMPL_SECURE) + /* Non-connection-based frame. We can decode here if it was encrypted */ + if (!nwk_getSecureFrame(&fiPtr->mrfiPkt, MRFI_GET_PAYLOAD_LEN(&fiPtr->mrfiPkt) - F_SEC_CTR_OS, 0)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +#endif + rc = func[port-1](&fiPtr->mrfiPkt); + if (FHS_KEEP == rc) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + } +#if !defined(END_DEVICE) + else if (FHS_REPLAY == rc) + { + /* an AP or an RE could be relaying a NWK application frame... */ + nwk_replayFrame(fiPtr); + } +#endif + else /* rc == FHS_RELEASE (default...) */ + { + fiPtr->fi_usage = FI_AVAILABLE; + } + return; + } + /* sanity check */ + else if ((port != SMPL_PORT_USER_BCAST) && ((port < PORT_BASE_NUMBER) || (port > SMPL_PORT_STATIC_MAX))) + { + /* bogus port. drop frame */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + + /* At this point we know the target is a user app. If this is an end device + * and we got this far save the frame and we're done. If we're an AP there + * are 3 cases: it's for us, it's for s store-and-forward client, or we need + * to replay the frame. If we're and RE and the frame didn't come from an RE + * and it's not for us, replay the frame. + */ + +#if defined(END_DEVICE) + /* If we're s polling end device we only accept application frames from + * the AP. This prevents duplicate reception if we happen to be on when + * a linked peer sends. + */ +#if defined(RX_POLLS) + if (F_TX_DEVICE_ED != GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE)) + { + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } +#else + /* it's destined for a user app. */ + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + if (spCallback && spCallback(lid)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } +#endif /* RX_POLLS */ + +#else /* END_DEVICE */ + + /* We have an issue if the frame is broadcast to the UUD port. The AP (or RE) must + * handle this frame as if it were the target in case there is an application + * running that is listening on that port. But if it's a broadcast it must also be + * replayed. It isn't enough just to test for the UUD port because it could be a + * directed frame to another device. We must check explicitly for broadcast + * destination address. + */ + isForMe = !memcmp(sMyAddr, MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), NET_ADDR_SIZE); + if (isForMe || ((port == SMPL_PORT_USER_BCAST) && !memcmp(nwk_getBCastAddress(), MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), NET_ADDR_SIZE))) + { + /* The folllowing test will succeed for the UUD port regardless of the + * source address. + */ + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + /* If this is for the UUD port and we are here then the device is either + * an AP or an RE. In either case it must replay the UUD port frame if the + * frame is not "for me". But it also must handle it since it could have a + * UUD-listening application. Do the reply first and let the subsequent code + * correctly set the frame usage state. Note that the routine return can be + * from this code block. If not it will drop through to the bottom without + * doing a replay. + */ + /* Do I need to replay it? */ + if (!isForMe) + { + /* must be a broadcast for the UUD port */ + nwk_replayFrame(fiPtr); + } + /* OK. Now I handle it... */ + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + if (spCallback && spCallback(lid)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } +#if defined( ACCESS_POINT ) + /* Check to see if we need to save this for a S and F client. Otherwise, + * if it's not for us, get rid of it. + */ + else if (nwk_isSandFClient(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), &loc)) + { + /* Don't bother if it is a duplicate frame or if it's a forwarded frame + * echoed back from an RE. + */ + if (!isDupSandFFrame(&fiPtr->mrfiPkt) && + !(GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_FWD_FRAME)) + ) + { +#if defined(APP_AUTO_ACK) + /* Make sure ack request bit is off. Sender will have gone away. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ACK_REQ, 0); +#endif + fiPtr->fi_usage = FI_INUSE_UNTIL_FWD; + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE) == F_TX_DEVICE_AP) + { + /* I'm an AP and this frame came from an AP. Don't replay. */ + fiPtr->fi_usage = FI_AVAILABLE; + } +#elif defined( RANGE_EXTENDER ) + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE) == F_TX_DEVICE_RE) + { + /* I'm an RE and this frame came from an RE. Don't replay. */ + fiPtr->fi_usage = FI_AVAILABLE; + } +#endif + else + { + /* It's not for me and I'm either an AP or I'm an RE and the frame + * didn't come from an RE. Replay the frame. + */ + nwk_replayFrame(fiPtr); + } +#endif /* !END_DEVICE */ + return; +} +#endif /* SIZE_INFRAME_Q > 0 */ + +/****************************************************************************** + * @fn nwk_sendFrame + * + * @brief Send a frame by copying it to the radio Tx FIFO. + * + * input parameters + * @param pFrameInfo - pointer to frame to be sent + * @param txOption - do CCA or force frame out. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_TX_CCA_FAIL Tx failed because of CCA failure. + * Tx FIFO flushed in this case. + */ +smplStatus_t nwk_sendFrame(frameInfo_t *pFrameInfo, uint8_t txOption) +{ + smplStatus_t rc; + + /* set the type of device sending the frame in the header */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_TX_DEVICE, sMyTxType); + + if (MRFI_TX_RESULT_SUCCESS == MRFI_Transmit(&pFrameInfo->mrfiPkt, txOption)) + { + rc = SMPL_SUCCESS; + } + else + { + /* Tx failed -- probably CCA. free up frame buffer. We do not have NWK + * level retries. Let application do it. + */ + rc = SMPL_TX_CCA_FAIL; + } + + /* TX is done. free up the frame buffer */ + pFrameInfo->fi_usage = FI_AVAILABLE; + + return rc; +} + + +/****************************************************************************** + * @fn nwk_getMyRxType + * + * @brief Get my Rx type. Used to help populate the hops count in the + * frame header to try and limit the broadcast storm. Info is + * exchanged when linking. + * + * input parameters + * + * output parameters + * + * @return The address LSB. + */ +uint8_t nwk_getMyRxType(void) +{ + return sMyRxType; +} + +#if defined(APP_AUTO_ACK) +/****************************************************************************** + * @fn nwk_sendAckReply + * + * @brief Send an acknowledgement reply frame. + * + * input parameters + * @param frame - pointer to frame with ack request. + * @param port - port on whcih reply expected. + * + * output parameters + * + * @return void + */ +void nwk_sendAckReply(mrfiPacket_t *frame, uint8_t port) +{ + mrfiPacket_t dFrame; + uint8_t tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS); + + /* set the type of device sending the frame in the header */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, sMyTxType); + + /* set the listen type of device sending the frame in the header. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); + + /* destination address from received frame */ + memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + /* source address */ + memcpy(MRFI_P_SRC_ADDR(&dFrame), sMyAddr, NET_ADDR_SIZE); + + /* port is the source the Tx port from the connection object */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); + + /* frame length... */ + MRFI_SET_PAYLOAD_LEN(&dFrame,F_APP_PAYLOAD_OS); + + /* transaction ID taken from source frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, tid); + + /* hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS); + + /* set ACK field */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, F_ACK_RPLY_TYPE); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); + + /* This is not a forwarded frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, 0); + + /* Encryption state */ +#if !defined(SMPL_SECURE) + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); +#else + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + nwk_setSecureFrame(&dFrame, 0, 0); +#endif + + MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); + + return; +} +#endif /* APP_AUTO_ACK */ + +#if !defined(END_DEVICE) +/****************************************************************************** + * @fn nwk_replayFrame + * + * @brief Deal with hop count on a Range Extender or Access Point replay. + * Queue entry usage always left as available when done. + * + * input parameters + * @param pFrameInfo - pointer to frame information structure + * + * output parameters + * + * @return void + */ +void nwk_replayFrame(frameInfo_t *pFrameInfo) +{ + uint8_t hops = GET_FROM_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_HOP_COUNT); + + /* if hops are zero, drop frame. othewise send it. */ + if (hops--) + { + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt),F_HOP_COUNT,hops); + /* Don't care if the Tx fails because of TO. Either someone else + * will retransmit or the application itself will recover. + */ +#if defined(SMPL_SECURE) + /* If the frame was targeted to a NWK port it was decrypted on spec in + * the 'dispatchFrame()' method. It must be re-encypted in this case. + */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_PORT_OS) <= SMPL_PORT_NWK_BCAST) + { + nwk_setSecureFrame(&pFrameInfo->mrfiPkt, MRFI_GET_PAYLOAD_LEN(&pFrameInfo->mrfiPkt)-F_APP_PAYLOAD_OS, 0); + } +#endif + MRFI_DelayMs(1); + nwk_sendFrame(pFrameInfo, MRFI_TX_TYPE_CCA); + } + else + { + pFrameInfo->fi_usage = FI_AVAILABLE; + } + return; +} + +#if defined(ACCESS_POINT) +/****************************************************************************** + * @fn nwk_getSandFFrame + * + * @brief Get any frame waiting for the client on the port supplied in + * the frame payload. + * TODO: support returning NWK application frames always. the + * port requested in the call should be an user application port. + * NWK app ports will never be in the called frame. + * TODO: deal with broadcast NWK frames from AP. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return pointer to frame if there is one, otherwise 0. + */ +frameInfo_t *nwk_getSandFFrame(mrfiPacket_t *frame, uint8_t osPort) +{ + uint8_t i, port = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+osPort); + frameInfo_t *fiPtr; + rcvContext_t rcv; + + rcv.type = RCV_RAW_POLL_FRAME; + rcv.t.pkt = frame; + /* check the input queue for messages sent by others. */ + if (fiPtr=nwk_QfindOldest(INQ, &rcv, USAGE_FWD)) + { + return fiPtr; + } + + /* Check the output queue to see if we ourselves need to send anything. + * TODO: use the cast-out scheme for output queue so this routine finds + * the oldest in either queue. + */ + fiPtr = nwk_getQ(OUTQ); + for (i=0; ifi_usage) + { + if (!memcmp(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_PORT_OS) == port) + { + return fiPtr; + } + } + } + } + return 0; +} + +/****************************************************************************** + * @fn nwk_SendEmptyPollRspFrame + * + * @brief There are no frames waiting for the requester on the specified + * port. Send a frame back to that port with no payload. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return void + */ +void nwk_SendEmptyPollRspFrame(mrfiPacket_t *frame) +{ + mrfiPacket_t dFrame; + uint8_t port = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+M_POLL_PORT_OS); + + /* set the type of device sending the frame in the header. we know it's an AP */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, F_TX_DEVICE_AP); + /* set the listen type of device sending the frame in the header. we know it's + * an AP is is probably always on...but use the static variable anyway. + */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); + /* destination address from received frame (polling device) */ + memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + /* source address */ + memcpy(MRFI_P_SRC_ADDR(&dFrame), MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+M_POLL_ADDR_OS, NET_ADDR_SIZE); + /* port is the port requested */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); + /* frame length... */ + MRFI_SET_PAYLOAD_LEN(&dFrame,F_APP_PAYLOAD_OS); + /* transaction ID... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, sTRACTID); + sTRACTID++; + /* hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS_FROM_AP); + + /* Ack fields */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); + + /* This is logically a forwarded frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, F_FRAME_FWD_TYPE); + + /* Encryption state */ +#if !defined(SMPL_SECURE) + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); +#else + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + nwk_setSecureFrame(&dFrame, 0, 0); +#endif + + MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +/****************************************************************************** + * @fn isDupSandFFrame + * + * @brief Have we already stored this frame on behalf of a client? + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns 1 if the frame is a duplicate, otherwise 0. + */ +uint8_t isDupSandFFrame(mrfiPacket_t *frame) +{ + uint8_t i, plLen = MRFI_GET_PAYLOAD_LEN(frame); + frameInfo_t *fiPtr; + + /* check the input queue for duplicate S&F frame. */ + fiPtr = nwk_getQ(INQ); + for (i=0; ifi_usage) + { + /* compare everything except the DEVICE INFO byte. */ + if (MRFI_GET_PAYLOAD_LEN(&fiPtr->mrfiPkt) == plLen && + !memcmp(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), MRFI_P_DST_ADDR(frame), NET_ADDR_SIZE) && + !memcmp(MRFI_P_SRC_ADDR(&fiPtr->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE) && + !memcmp(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), MRFI_P_PAYLOAD(frame), 1) && + !memcmp(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt)+F_TRACTID_OS, MRFI_P_PAYLOAD(frame)+F_TRACTID_OS, plLen-F_TRACTID_OS) + ) + { + return 1; + } + } + } + return 0; +} +#endif /* ACCESS_POINT */ + +#endif /* !END_DEVICE */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_frame.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_frame.h new file mode 100755 index 0000000..6c616f8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_frame.h @@ -0,0 +1,151 @@ +/************************************************************************************************** + Filename: nwk_frame.h + Revised: $Date: 2008-12-23 13:49:41 -0800 (Tue, 23 Dec 2008) $ + Revision: $Revision: 18651 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI frame handling functions. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_FRAME_H +#define NWK_FRAME_H + +/* Frame field defines and masks. Mask name must be field name with '_MSK' appended + * so the GET and PUT macros work correctly -- they use token pasting. Offset values + * are with respect to the MRFI payload and not the entire frame. + */ +#define F_PORT_OS 0 +#define F_PORT_OS_MSK (0x3F) +#define F_ENCRYPT_OS 0 +#define F_ENCRYPT_OS_MSK (0x40) +#define F_FWD_FRAME 0 +#define F_FWD_FRAME_MSK (0x80) +#define F_RX_TYPE 1 +#define F_RX_TYPE_MSK (0x40) +#define F_ACK_REQ 1 +#define F_ACK_REQ_MSK (0x80) +#define F_ACK_RPLY 1 +#define F_ACK_RPLY_MSK (0x08) +#define F_TX_DEVICE 1 +#define F_TX_DEVICE_MSK (0x30) +#define F_HOP_COUNT 1 +#define F_HOP_COUNT_MSK (0x07) +#define F_TRACTID_OS 2 +#define F_TRACTID_OS_MSK (0xFF) +#define SMPL_NWK_HDR_SIZE 3 + +#ifdef SMPL_SECURE + +#define F_SECURE_OS 3 + +#define F_SEC_CTR_OS 3 /* counter hint */ +#define F_SEC_CTR_OS_MSK (0xFF) +#define F_SEC_ICHK_OS 4 /* Message integrity check */ +#define F_SEC_ICHK_OS_MSK (0xFF) +#define F_SEC_MAC_OS 5 /* Message authentication code */ +#define F_SEC_MAC_OS_MSK (0xFF) + +#else + +#define F_SECURE_OS 0 + +#endif /* SMPL_SECURE */ + +#define F_APP_PAYLOAD_OS (SMPL_NWK_HDR_SIZE+F_SECURE_OS) + +/* sub field details. they are in the correct bit locations (already shifted) */ +#define F_RX_TYPE_USER_CTL 0x00 /* does not poll... */ +#define F_RX_TYPE_POLLS 0x40 /* polls for held messages */ + +#define F_ACK_REQ_TYPE 0x80 +#define F_ACK_RPLY_TYPE 0x08 +#define F_FRAME_FWD_TYPE 0x80 +#define F_FRAME_ENCRYPT_TYPE 0x40 + +/* device type fields */ +#define F_TX_DEVICE_ED 0x00 /* End Device */ +#define F_TX_DEVICE_RE 0x10 /* Range Extender */ +#define F_TX_DEVICE_AP 0x20 /* Access Point */ + +/* macro to get a field from a frame buffer */ +#define GET_FROM_FRAME(b,f) ((b)[f] & (f##_MSK)) + +/* Macro to put a value 'v' into a frame buffer 'b'. 'v' value must already be shifted + * if necessary. 'b' is a byte array + */ +#define PUT_INTO_FRAME(b,f,v) do {(b)[f] = ((b)[f] & ~(f##_MSK)) | (v); } while(0) + + +/* **** frame information objects + * info kept on each frame object + */ +#define FI_AVAILABLE 0 /* entry available for use */ +#define FI_INUSE_UNTIL_DEL 1 /* in use. will be explicitly reclaimed */ +#define FI_INUSE_UNTIL_TX 2 /* in use. will be reclaimed after Tx */ +#define FI_INUSE_UNTIL_FWD 3 /* in use until forwarded by AP */ +#define FI_INUSE_TRANSITION 4 /* being retrieved. do not delete in Rx ISR thread. */ + +typedef struct +{ + uint8_t rssi; + uint8_t lqi; +} sigInfo_t; + +typedef struct +{ + volatile uint8_t fi_usage; + uint8_t orderStamp; + mrfiPacket_t mrfiPkt; +} frameInfo_t; + + +/* prototypes */ +frameInfo_t *nwk_buildFrame(uint8_t, uint8_t *msg, uint8_t len, uint8_t hops); +#ifdef APP_AUTO_ACK +frameInfo_t *nwk_buildAckReqFrame(uint8_t, uint8_t *, uint8_t, uint8_t, volatile uint8_t *); +#endif +void nwk_receiveFrame(void); +void nwk_frameInit(uint8_t (*)(linkID_t)); +smplStatus_t nwk_retrieveFrame(rcvContext_t *, uint8_t *, uint8_t *, addr_t *, uint8_t *); +smplStatus_t nwk_sendFrame(frameInfo_t *, uint8_t txOption); +frameInfo_t *nwk_getSandFFrame(mrfiPacket_t *, uint8_t); +uint8_t nwk_getMyRxType(void); +void nwk_SendEmptyPollRspFrame(mrfiPacket_t *); +#ifdef APP_AUTO_ACK +void nwk_sendAckReply(mrfiPacket_t *, uint8_t); +#endif + +#ifndef END_DEVICE +/* only APs and REs repeat frames */ +void nwk_replayFrame(frameInfo_t *); +#endif + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_globals.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_globals.c new file mode 100755 index 0000000..121b5e3 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_globals.c @@ -0,0 +1,258 @@ +/************************************************************************************************** + Filename: nwk_globals.c + Revised: $Date: 2009-10-27 20:48:11 -0700 (Tue, 27 Oct 2009) $ + Revision: $Revision: 20995 $ + + Description: This file manages global NWK data. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_globals.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static const addr_t sMyROMAddress = THIS_DEVICE_ADDRESS; +static addr_t sAPAddress; +static addr_t sMyRAMAddress; +static uint8_t sRAMAddressIsSet = 0; + +/* Version number set as a 4 byte quantity. Each byte is a revision number + * in the form w.x.y.z. The subfields are each limited to values 0x0-0xFF. + */ +static const smplVersionInfo_t sVersionInfo = { + 0x02, /* protocol version */ + 0x01, /* major revision number */ + 0x01, /* minor revision number */ + 0x01, /* maintenance release number */ + 0x00 /* special release */ + }; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_globalsInit + * + * @brief Initialization of global symbols + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_globalsInit(void) +{ + + memset(&sAPAddress, 0x00, sizeof(addr_t)); + + /* populate RAM address from ROM default if it hasn't laready been set + * using the IOCTL interface. + */ + if (!sRAMAddressIsSet) + { + memcpy(&sMyRAMAddress, &sMyROMAddress, sizeof(addr_t)); + sRAMAddressIsSet = 1; /* RAM address is now valid */ + } + + return; +} + +/****************************************************************************** + * @fn nwk_getMyAddress + * + * @brief Return a pointer to my address. It comes either from ROM as + * set in the configuration file or it was set using the IOCTL + * interface -- probably from random bytes. + * + * input parameters + * + * output parameters + * + * @return pointer to a constant address type object. + */ +addr_t const *nwk_getMyAddress(void) +{ + /* This call supports returning a valid pointer before either the + * initialization or external setting of the address. But caller needs + * to be careful -- if this routine is called immediately it will return + * the ROM address. If the application then sets the address using the + * IOCTL before doing the SMPL_Init() the original pointer is no longer + * valid as it points to the wrong address. + */ + return sRAMAddressIsSet ? &sMyRAMAddress : &sMyROMAddress; +} + +/****************************************************************************** + * @fn nwk_getFWVersion + * + * @brief Return a pointer to the current firmware version string. + * + * input parameters + * + * output parameters + * + * @return pointer to a constant uint16_t object. + */ +uint8_t const *nwk_getFWVersion() +{ + return sVersionInfo.fwVerString; +} + +/****************************************************************************** + * @fn nwk_getProtocolVersion + * + * @brief Return the current protocol version. + * + * input parameters + * + * output parameters + * + * @return Protocol version. + */ +uint8_t nwk_getProtocolVersion(void) +{ + return sVersionInfo.protocolVersion; +} + +/****************************************************************************** + * @fn nwk_setMyAddress + * + * @brief Set my address object if it hasn't already been set. This call + * is referenced by the IOCTL support used to change the device + * address. It is effective only if the address has not already + * been set. + * + * input parameters + * + * @param addr - pointer to the address object to be used to set my address. + * + * output parameters + * + * @return Returns non-zero if request is respected, otherwise returns 0. + */ +uint8_t nwk_setMyAddress(addr_t *addr) +{ + uint8_t rc = 0; + + if (!sRAMAddressIsSet) + { + memcpy(&sMyRAMAddress, addr, sizeof(addr_t)); + sRAMAddressIsSet = 1; /* RAM address is now valid */ + rc = 1; + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_setAPAddress + * + * @brief Set the AP's address. Called after the AP address is gleaned + * from the Join reply. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_setAPAddress(addr_t *addr) +{ + + memcpy((void *)&sAPAddress, (void *)addr, NET_ADDR_SIZE); + + return; +} + +/****************************************************************************** + * @fn nwk_getAPAddress + * + * @brief Get the AP's address. + * + * input parameters + * + * output parameters + * + * @return Pointer to a constant address object or null if the address has not + * yet been set. + */ +addr_t const *nwk_getAPAddress(void) +{ + addr_t addr; + + memset(&addr, 0x0, sizeof(addr)); + + return !memcmp(&sAPAddress, &addr, NET_ADDR_SIZE) ? 0 : &sAPAddress; +} + +/****************************************************************************** + * @fn nwk_getBCastAddress + * + * @brief Get the network broadcast address. + * + * input parameters + * + * output parameters + * + * @return Pointer to a constant address object. + */ +addr_t const *nwk_getBCastAddress(void) +{ + return (addr_t const *)mrfiBroadcastAddr; +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_globals.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_globals.h new file mode 100755 index 0000000..728c2ab --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_globals.h @@ -0,0 +1,51 @@ +/************************************************************************************************** + Filename: nwk_globals.h + Revised: $Date: 2008-07-30 11:22:21 -0700 (Wed, 30 Jul 2008) $ + Revision: $Revision: 17655 $ + Author: $Author: lfriedman $ + + Description: This header file supports the management of NWK global symbols. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_GLOBALS_H +#define NWK_GLOBALS_H + + +/* Prototypes */ +void nwk_globalsInit(void); +addr_t const *nwk_getMyAddress(void); +uint8_t nwk_setMyAddress(addr_t *addr); +void nwk_setAPAddress(addr_t *addr); +addr_t const *nwk_getAPAddress(void); +addr_t const *nwk_getBCastAddress(void); +uint8_t const *nwk_getFWVersion(void); +uint8_t nwk_getProtocolVersion(void); + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_types.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_types.h new file mode 100755 index 0000000..bb277ba --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk/nwk_types.h @@ -0,0 +1,344 @@ +/************************************************************************************************** + Filename: nwk_types.h + Revised: $Date: 2009-01-13 11:31:14 -0800 (Tue, 13 Jan 2009) $ + Revision: $Revision: 18744 $ + Author: $Author: lfriedman $ + + Description: This header file defines the SimpliciTI typedefs. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_TYPES_H +#define NWK_TYPES_H + +#define NWK_TX_RETRY_COUNT 10 +#define NWK_RX_RETRY_COUNT 10 + +#define NWK_APP_REPLY_BIT (0x80) + +#define NET_ADDR_SIZE MRFI_ADDR_SIZE /* size of address in bytes */ + +#ifdef FREQUENCY_AGILITY +#define NWK_FREQ_TBL_SIZE MRFI_NUM_LOGICAL_CHANS +#else +#define NWK_FREQ_TBL_SIZE 1 +#endif + +typedef struct +{ + uint8_t addr[NET_ADDR_SIZE]; +} addr_t; + +typedef uint8_t linkID_t; +typedef uint8_t ccRadioStatus_t; + + +/* *********************************************** + * Begin IOCTL Support + * *********************************************** + */ +enum ioctlObject { + IOCTL_OBJ_FREQ, + IOCTL_OBJ_CRYPTKEY, + IOCTL_OBJ_RAW_IO, + IOCTL_OBJ_RADIO, + IOCTL_OBJ_AP_JOIN, + IOCTL_OBJ_ADDR, + IOCTL_OBJ_CONNOBJ, + IOCTL_OBJ_FWVER, + IOCTL_OBJ_PROTOVER, + IOCTL_OBJ_NVOBJ, + IOCTL_OBJ_TOKEN +}; + +enum ioctlAction { + IOCTL_ACT_SET, + IOCTL_ACT_GET, + IOCTL_ACT_READ, + IOCTL_ACT_WRITE, + IOCTL_ACT_RADIO_SLEEP, + IOCTL_ACT_RADIO_AWAKE, + IOCTL_ACT_RADIO_SIGINFO, + IOCTL_ACT_RADIO_RSSI, + IOCTL_ACT_RADIO_RXON, + IOCTL_ACT_RADIO_RXIDLE, + IOCTL_ACT_RADIO_SETPWR, + IOCTL_ACT_ON, + IOCTL_ACT_OFF, + IOCTL_ACT_SCAN, + IOCTL_ACT_DELETE +}; + +typedef enum ioctlObject ioctlObject_t; +typedef enum ioctlAction ioctlAction_t; + +enum ioctlLevel +{ + IOCTL_LEVEL_0, + IOCTL_LEVEL_1, + IOCTL_LEVEL_2 +}; + +typedef enum ioctlLevel ioctlLevel_t; + +typedef struct +{ + addr_t *addr; + uint8_t *msg; + uint8_t len; + uint8_t port; +} ioctlRawSend_t; + +typedef struct +{ + addr_t *addr; + uint8_t *msg; + uint8_t len; + uint8_t port; + uint8_t hopCount; +} ioctlRawReceive_t; + +/* + * Signal information support + */ +typedef int8_t rssi_t; + +typedef struct +{ + rssi_t rssi; + uint8_t lqi; +} rxMetrics_t; + +typedef struct +{ + linkID_t lid; /* input: Link ID for which signal info desired */ + rxMetrics_t sigInfo; +} ioctlRadioSiginfo_t; + + +/* *** Begin SET/GET token support *** */ +enum tokenType +{ + TT_LINK, /* Token Type is Link */ + TT_JOIN /* Token Type is Join */ +}; + +typedef enum tokenType tokenType_t; + +/* Create a union. If either token ever changes type it will make things easier. */ +typedef union +{ + uint32_t linkToken; + uint32_t joinToken; +} token_t; + +typedef struct +{ + tokenType_t tokenType; + token_t token; +} ioctlToken_t; +/* *** End SET/GET token support *** */ + + +/* + * Frequency Agility support + */ +typedef struct +{ + uint8_t logicalChan; +} freqEntry_t; + +typedef struct +{ + uint8_t numChan; + freqEntry_t *freq; +} ioctlScanChan_t; + +/* Security typedefs to make things easier if they change types */ +typedef uint8_t secMAC_t; +typedef uint8_t secFCS_t; + +/*************************************************************************************** + * ** NV Object support ** + * + * The following object supports saving and restoring the information + * necessary to save and restore a device connection context. + * + * On a GET interface populates the IOCTL object with the version and length (in bytes) + * of the current static connection iformation area. In addition it populates the address + * pointed to by 'objPtr' with the base address of the connection context. At this point + * the caller can either copy to or from the address. Note that this is a dangerous + * interface, as the caller is provided with direct access to the connection context. + * + * When restoring the connection context some sanity checks are possible. If the + * version or length elements of the saved context do not match those of the current + * static object the static object should not be populated. If this sanity fails the + * caller is not provided with the pointer to the conneciton ocntext. + * + * This interface is fairly simple and it is possible to get the address of the + * connection context to do a restore by simply doing a GET call. This avoids the + * sanity checks. However, this is not recommended because there may be other side + * effects of doing a SET that are necessary when restoring a context and are done + * only when the proper option is used to restore the connection context. + * + *************************************************************************************/ +typedef struct +{ + uint8_t objVersion; + uint16_t objLen; + uint8_t **objPtr; +} ioctlNVObj_t; + +/* *********************************************** + * End IOCTL Support + * *********************************************** + */ + +enum smplStatus { + SMPL_SUCCESS, + SMPL_TIMEOUT, + SMPL_BAD_PARAM, + SMPL_NOMEM, + SMPL_NO_FRAME, + SMPL_NO_LINK, + SMPL_NO_JOIN, + SMPL_NO_CHANNEL, + SMPL_NO_PEER_UNLINK, + SMPL_TX_CCA_FAIL, + SMPL_NO_PAYLOAD, + SMPL_NO_AP_ADDRESS, + SMPL_NO_ACK +}; + +typedef enum smplStatus smplStatus_t; + +/* NWK application frame handling status codes */ +enum fhStatus +{ + FHS_RELEASE, /* handled in interrupt thread */ + FHS_KEEP, /* handled by background application */ + FHS_REPLAY /* non-ED case: NWK frame not for me that should be replayed */ +}; + +typedef enum fhStatus fhStatus_t; + +/******** BEGIN: Object support for parameter context in queue management *********/ +enum rcvType +{ + RCV_NWK_PORT, + RCV_APP_LID, + RCV_RAW_POLL_FRAME +}; + +typedef enum rcvType rcvType_t; + +/* Tx options type */ +typedef uint16_t txOpt_t; + +typedef struct +{ + rcvType_t type; + union + { + linkID_t lid; + uint8_t port; + mrfiPacket_t *pkt; + } t; +} rcvContext_t; +/******** END: Object support for parameter context in queue management *********/ + +#define SMPL_FWVERSION_SIZE 4 + +typedef struct +{ + uint8_t protocolVersion; + uint8_t fwVerString[SMPL_FWVERSION_SIZE]; +} smplVersionInfo_t; + +/* The following typedef is used to standardize the application Transaction ID field. + * This field can be used for detection of out-of-order application payloads if this + * is an issue. There is no real reason to use more than a byte for this support. But + * if this typedef is anything other than uint8_t be sure to attend to alignment and + * endian issues. + */ +typedef uint8_t appPTid_t; + +#ifdef ACCESS_POINT +/* Store-and-forward client info object */ +typedef struct +{ + addr_t clientAddr; + appPTid_t lastTID; +} sfClientInfo_t; + +typedef struct +{ + uint8_t curNumSFClients; + sfClientInfo_t sfClients[NUM_STORE_AND_FWD_CLIENTS]; +} sfInfo_t; +#endif + +/**************************************************************************************** + * SOME USEFUL MACROS + ****************************************************************************************/ + +/* Delay loop support. Requires mrfi.h */ +#define NWK_DELAY(spin) MRFI_DelayMs(spin) +#define NWK_REPLY_DELAY() MRFI_ReplyDelay(); + +/* Network applications may need to remember radio state because the user + * application may choose to turn Rx off. These macros help get and restore + * the radio Rx state. The macros should be in the same code block at the same level. + * The argument 's' is the 'current' radio state and should be set in the code block + * with a call to MRFI_GetRadioState() _before_ using the macros. + * + * Used extensively by NWK but user applications may use them as well. But it is + * much more liekly that an application will know the radio state since it likely + * will have set it with IOCTL calls. Requires mrfi.h. + */ +#define NWK_CHECK_FOR_SETRX(s) if (MRFI_RADIO_STATE_RX != s) \ + { \ + if (MRFI_RADIO_STATE_OFF == s) \ + { \ + MRFI_WakeUp(); \ + } \ + MRFI_RxOn(); \ + } + +#define NWK_CHECK_FOR_RESTORE_STATE(s) if (MRFI_RADIO_STATE_RX != s) \ + { \ + if (MRFI_RADIO_STATE_OFF == s) \ + { \ + MRFI_Sleep(); \ + } \ + else \ + { \ + MRFI_RxIdle(); \ + } \ + } +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.c new file mode 100755 index 0000000..2a93c39 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.c @@ -0,0 +1,619 @@ +/************************************************************************************************** + Filename: nwk_freq.c + Revised: $Date: 2008-12-10 13:50:46 -0800 (Wed, 10 Dec 2008) $ + Revision: $Revision: 18594 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Freq network application. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk.h" +#include "nwk_frame.h" +#include "nwk_freq.h" +#include "nwk_globals.h" +#include "nwk_api.h" +#include "nwk_security.h" + +#if defined( FREQUENCY_AGILITY ) +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static freqEntry_t sCurLogicalChan; +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +static fhStatus_t handle_freq_cmd(mrfiPacket_t *); +static fhStatus_t send_ping_reply(mrfiPacket_t *); +#ifndef ACCESS_POINT +static uint8_t change_channel_cmd_is_valid(mrfiPacket_t *); +#endif +#ifdef RANGE_EXTENDER +/* REs must replay frame before changing channels */ +static void replayFirst(mrfiPacket_t *); +#endif +#ifdef ACCESS_POINT +/* only the AP can broadcast this command */ +static void broadcast_channel_change(uint8_t); +#else +/* APs do not process this frame */ +static void change_channel_cmd(mrfiPacket_t *); +#endif + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_freqInit + * + * @brief Initialize NWK Frequency application. + * + * @return none. + */ +void nwk_freqInit(void) +{ + + memset(&sCurLogicalChan, 0x0, sizeof(sCurLogicalChan)); + + /* pick a random value to start the transaction ID for this app. */ + sTid = MRFI_RandomByte(); + + return; +} + +/*************************************************************************** + * @fn nwk_setChannel + * + * @brief Set requested logical channel. Accessed by application + * through IOCTL interface + * + * input parameters + * @param chan - pointer to channel object of requested channel + * + * @return status of operation: + * SMPL_SUCCESS if channel set + * SMPL_BAD_PARAM if requested channel is out of range + */ +smplStatus_t nwk_setChannel(freqEntry_t *chan) +{ + smplStatus_t rc = SMPL_BAD_PARAM; + + if (chan->logicalChan < NWK_FREQ_TBL_SIZE) + { + MRFI_SetLogicalChannel(chan->logicalChan); + sCurLogicalChan = *chan; + rc = SMPL_SUCCESS; + } + return rc; +} + +/****************************************************************************** + * @fn nwk_getChannel + * + * @brief Get current logical channel. Accessed by application through + * IOCTL interface + * + * input parameters + * @param chan - pointer to channel object of requested channel + * + * output parameters + * @param chan - populated channel object + * + * @return none. + */ +void nwk_getChannel(freqEntry_t *chan) +{ + *chan = sCurLogicalChan; + + return; +} + +/****************************************************************************** + * @fn handle_freq_cmd + * + * @brief Handle a Frequency application command. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return Return FHS_RELEASE if caller should release frame otherwise + * return FHS_REPLAY. + */ +static fhStatus_t handle_freq_cmd(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS)) + { + case FREQ_REQ_PING: + rc = send_ping_reply(frame); + break; + +#ifndef ACCESS_POINT + case FREQ_REQ_MOVE: +#ifdef RANGE_EXTENDER + replayFirst(frame); +#endif + /* Make sure the change channel Freq command came from + * a valid source before obeying. + */ + if (change_channel_cmd_is_valid(frame)) + { + change_channel_cmd(frame); + } + break; +#endif + +#ifdef ACCESS_POINT + case FREQ_REQ_REQ_MOVE: + break; +#endif + default: + break; + } + + return rc; +} + +#ifndef ACCESS_POINT +/****************************************************************************** + * @fn change_channel_cmd_is_valid + * + * @brief Check validity of a change channel command frame. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return Returns non-zero if command is valid, otherwise returns 0. + * Command is valid if either: + * - frame is directed + * - frame is from an AP and we know about that AP + * + * It is possible that either we don't know about an AP or that + * we do but this frame comes from another AP in range. + */ +static uint8_t change_channel_cmd_is_valid(mrfiPacket_t *frame) +{ + uint8_t rc = 0; + addr_t const *apAddr; + + /* If this was a directed frame obey the command. */ + if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + rc = 1; + } + else + { + /* Do we know about an AP? If not assume frame bogus. */ + apAddr = nwk_getAPAddress(); + if (apAddr) + { + /* Yes, we know about an AP. Is that who sent it? */ + if (!memcmp(apAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + /* OK. We obey. */ + rc = 1; + } + } + } + + return rc; +} +#endif /* !ACCESS_POINT */ + +#ifdef RANGE_EXTENDER +/****************************************************************************** + * @fn replayFirst + * + * @brief Range Extenders must replay the change-channel boradcast + * frame before actually changing its own channel. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return void + */ + +/* This routine takes care of some awkwardness. From the dispatch thread all + * we have is a pointer to the mrfiPacket_t element in the frame buffer into + * which the frame was retrieved. But to call the replay routine we need the + * entire frame information structure frameInfo_t. This routine regenerates + * the frame information structure pointer and then calls the replay routine. + * + * This approach requires that the disptach thread guarantee that it will + * always pass a pointer to the mrfiPacket_t structure in the frame + * information structure and not a copy of the mrfipacket_t element. It is + * either the approach here or change all the NWK application dispatch routine + * argument types. This latter has the downside of interfering with any + * user-implemented NWK applications. It also needlessly complicates the argument + * handling: except for this instance all any routine needs is the mrfiPacket_t + * pointer. + */ +static void replayFirst(mrfiPacket_t *frame) +{ + frameInfo_t *fiptr; + uint16_t offset = (uint16_t)&(((frameInfo_t *)0)->mrfiPkt); + + fiptr = (frameInfo_t *)(((uint8_t *)frame) - ((uint8_t *)offset)); + + nwk_replayFrame(fiptr); + + return; +} +#endif /* RANGE_EXTENDER */ + +#ifndef ACCESS_POINT +/******************************************************************************** + * @fn change_channel_cmd + * + * @brief Change to channel specified in received frame. Polling devices + * might be awake when the broadcast occurs but we want the channel + * change recovery to occur in a disciplined manner using the + * polling code. Also, with certain Test sceanrios in which a + * sleeping device is emulated we want to emulate 'missing' the + * broadcast change-channel command. + * + * input parameters + * @param frame - pointer to frame containing target logical channel. + * + * @return none. + */ +static void change_channel_cmd(mrfiPacket_t *frame) +{ +#if !defined( RX_POLLS ) + freqEntry_t chan; + + chan.logicalChan = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+F_CHAN_OS); + + nwk_setChannel(&chan); +#endif + return; +} +#endif /* !ACCESS_POINT */ + +/****************************************************************************** + * @fn send_ping_reply + * + * @brief Send Frequency application ping reply. + * + * input parameters + * @param frame - pointer to frame from pinger. + * + * @return FHS_RELEASE unless this isn't an Access Point. In this case for + * flow to et this far it is a Range Extender, so replay the frame + * by returning FHW_REPLAY + */ +static fhStatus_t send_ping_reply(mrfiPacket_t *frame) +{ +#ifdef ACCESS_POINT + uint8_t msg[FREQ_REQ_PING_FRAME_SIZE]; + frameInfo_t *pOutFrame; + + /* original request with reply bit on */ + msg[FB_APP_INFO_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS) | NWK_APP_REPLY_BIT; + msg[FB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+FB_TID_OS); + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_FREQ, msg, sizeof(msg), MAX_HOPS_FROM_AP)) + { + /* destination address is the source address of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + /* must use transaction ID of source frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_TRACTID_OS, (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS))); +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + + return FHS_RELEASE; +#else + return FHS_REPLAY; +#endif /* ACCESS_POINT */ +} + +/**************************************************************************************** + * @fn nwk_processFreq + * + * @brief Process a Frequency application frame. + * + * input parameters + * @param frame - pointer to frame + * + * @return Disposition for frame: either release (FHS_RELEASE) or replay (FHS_REPLAY). + */ +fhStatus_t nwk_processFreq(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + uint8_t replyType; + + /* Make sure this is a reply and see if we sent this. Validate the + * packet for reception by client app. + */ + if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, FB_APP_INFO_OS, FB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else if (SMPL_NOT_REPLY == replyType) + { + rc = handle_freq_cmd(frame); + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_scanForChannels + * + * @brief Scan for channels by sending a ping frame on each channel in the + * channel table and listen for a reply. + * + * input parameters + * @param channels - pointer to area to receive list of channels from which + * ping replies were received. + * + * output parameters + * @param channels - populated list of channels. + * + * @return statuis of operation.. + */ +uint8_t nwk_scanForChannels(freqEntry_t *channels) +{ + uint8_t msg[FREQ_REQ_PING_FRAME_SIZE], i, num=0, notBcast = 1; + addr_t *apAddr, retAddr; + uint8_t radioState = MRFI_GetRadioState(); + freqEntry_t chan; + freqEntry_t curChan; + + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + nwk_getChannel(&curChan); + + /* send to AP. If we don't know AP address, broadcast. */ + apAddr = (addr_t *)nwk_getAPAddress(); + if (!apAddr) + { + apAddr = (addr_t *)nwk_getBCastAddress(); + notBcast = 0; + } + + for (i=0; ilogicalChan); +#endif /* ACCESS_POINT */ + rc = nwk_setChannel((freqEntry_t *)val); + break; + + case IOCTL_ACT_GET: + nwk_getChannel((freqEntry_t *)val); + rc = SMPL_SUCCESS; + break; + + case IOCTL_ACT_SCAN: + { + ioctlScanChan_t *sc = (ioctlScanChan_t *)val; + + sc->numChan = nwk_scanForChannels(sc->freq); + rc = SMPL_SUCCESS; + } + break; + + default: + rc = SMPL_BAD_PARAM; + break; + } + + return rc; +} + +/****************************************************************************** + * @fn broadcast_channel_change + * +* @brief For Access Point only: broadcast a channel change frame. + * + * input parameters + * @param idx - index into channel table of new (logical) channel + * + * @return none. + */ +#ifdef ACCESS_POINT +#define CC_REDUNDANCY 1 /* Change-channel redundancy count */ +static void broadcast_channel_change(uint8_t idx) +{ + ioctlRawSend_t send; + uint8_t msg[FREQ_REQ_MOVE_FRAME_SIZE]; + uint8_t repeat = CC_REDUNDANCY; + + if (idx >= NWK_FREQ_TBL_SIZE) + { + return; + } + + msg[FB_APP_INFO_OS] = FREQ_REQ_MOVE; + msg[F_CHAN_OS] = idx; + + send.addr = (addr_t *)nwk_getBCastAddress(); + send.msg = msg; + send.len = sizeof(msg); + send.port = SMPL_PORT_FREQ; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); + /* Redundancy addresses the fact that an RE (or any always-listening + * device) might miss the command + */ + while (repeat--) + { + NWK_DELAY(250); + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); + } +} +#endif /* ACCESS_POINT */ + +#else /* FREQUENCY_AGILITY */ + +/********************************************************************************** + * @fn nwk_freqInit + * + * @brief Initialize NWK Frequency application. Stub when Frequency Agility + * not supported. + * + * @return none. + */ +void nwk_freqInit(void) +{ + return; +} + +/**************************************************************************************** + * @fn nwk_processFreq + * + * @brief Process a Frequency application frame. Stub when Frequency Agility + * not supported. + * + * input parameters + * @param frame - pointer to frame + * + * @return Disposition for frame: either release (FHS_RELEASE) or replay (FHS_REPLAY). + */ +fhStatus_t nwk_processFreq(mrfiPacket_t *frame) +{ + return FHS_RELEASE; +} + +#endif /* FREQUENCY_AGILITY */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.h new file mode 100755 index 0000000..4cc5f11 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_freq.h @@ -0,0 +1,72 @@ +/************************************************************************************************** + Filename: nwk_freq.h + Revised: $Date: 2008-05-06 16:48:33 -0700 (Tue, 06 May 2008) $ + Revision: $Revision: 17025 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI Freq network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_FREQ_H +#define NWK_FREQ_H + +/* application payload offsets */ +/* both */ +#define FB_APP_INFO_OS 0 +#define FB_TID_OS 1 + +/* Logical channel number for MOVE request. Frame brodcast so no TID + * is used. Channel number can occupy the TID location. Same offset + * used for channel change request. No reply to that frame. + */ +#define F_CHAN_OS 1 + +/* MGMT frame application requests */ +#define FREQ_REQ_MOVE 0x01 +#define FREQ_REQ_PING 0x02 +#define FREQ_REQ_REQ_MOVE 0x03 + +/* change the following as protocol developed */ +#define MAX_FREQ_APP_FRAME 2 + +/* set the out frame sizes */ +#define FREQ_REQ_MOVE_FRAME_SIZE 2 +#define FREQ_REQ_PING_FRAME_SIZE 2 + +/* prototypes */ +void nwk_freqInit(void); +fhStatus_t nwk_processFreq(mrfiPacket_t *); +#if defined( FREQUENCY_AGILITY ) +smplStatus_t nwk_setChannel(freqEntry_t *); +void nwk_getChannel(freqEntry_t *); +uint8_t nwk_scanForChannels(freqEntry_t *); +smplStatus_t nwk_freqControl(ioctlAction_t, void *); +#endif + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.c new file mode 100755 index 0000000..0dcd14a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.c @@ -0,0 +1,349 @@ + +/************************************************************************************************** + Filename: nwk_ioctl.c + Revised: $Date: 2009-01-13 11:31:14 -0800 (Tue, 13 Jan 2009) $ + Revision: $Revision: 18744 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI IOCTL implmentation. This interface + gives applications access to the "driver" network level functions + when necessary. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_ioctl.h" +#include "nwk_globals.h" +#include "nwk_security.h" +#ifdef ACCESS_POINT +#include "nwk_join.h" +#endif + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + + +/****************************************************************************** + * @fn nwk_rawSend + * + * @brief Builds an outut frame based on information provided by the + * caller. This function allows a raw transmission to the target + * if the network address is known. this function is used a lot + * to support NWK applications. + * + * input parameters + * @param info - pointer to strcuture containing info on how to build + * the outgoing frame. + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_NOMEM - no room in output frame queue + * SMPL_TX_CCA_FAIL - CCA failure + */ +smplStatus_t nwk_rawSend(ioctlRawSend_t *info) +{ + frameInfo_t *pOutFrame; + uint8_t hops; + + /* If we know frame is going to or from the AP then we can reduce the hop + * count. + */ + switch (info->port) + { + case SMPL_PORT_JOIN: + case SMPL_PORT_FREQ: + case SMPL_PORT_MGMT: + hops = MAX_HOPS_FROM_AP; + break; + + default: + hops = MAX_HOPS; + break; + } + + if (pOutFrame = nwk_buildFrame(info->port, info->msg, info->len, hops)) + { + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), info->addr, NET_ADDR_SIZE); +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, info->len, 0); +#endif /* SMPL_SECURE */ + return nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_CCA); + } + return SMPL_NOMEM; +} + +/****************************************************************************** + * @fn nwk_rawReceive + * + * @brief Retriievs specified from from the input frame queue. Additional + * information such as source address and hop count may also be + * retrieved + * + * input parameters + * @param info - pointer to structure containing info on what to retrieve + * + * output parameters - actually populated by nwk_retrieveFrame() + * info->msg - application payload copied here + * info->len - length of received application payload + * info->addr - if non-NULL points to memory to be populated with + * source address of retrieved frame. + * info->hopCount - if non-NULL points to memory to be populated with + * hop count of retrieved frame. + * + * @return Status of operation. + */ +smplStatus_t nwk_rawReceive(ioctlRawReceive_t *info) +{ + rcvContext_t rcv; + + rcv.type = RCV_NWK_PORT; + rcv.t.port = info->port; + + return nwk_retrieveFrame(&rcv, info->msg, &info->len, info->addr, &info->hopCount); +} + +/****************************************************************************** + * @fn nwk_radioControl + * + * @brief Handle radio control functions. + * + * input parameters + * @param action - radio operation to perform. currently suppoerted: + * sleep/unsleep + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_radioControl(ioctlAction_t action, void *val) +{ + smplStatus_t rc = SMPL_SUCCESS; + + if (IOCTL_ACT_RADIO_SLEEP == action) + { + /* go to sleep mode. */ + MRFI_RxIdle(); + MRFI_Sleep(); + } + else if (IOCTL_ACT_RADIO_AWAKE == action) + { + MRFI_WakeUp(); + +#if !defined( END_DEVICE ) + MRFI_RxOn(); +#endif + + } + else if (IOCTL_ACT_RADIO_SIGINFO == action) + { + ioctlRadioSiginfo_t *pSigInfo = (ioctlRadioSiginfo_t *)val; + connInfo_t *pCInfo = nwk_getConnInfo(pSigInfo->lid); + + if (!pCInfo) + { + return SMPL_BAD_PARAM; + } + memcpy(&pSigInfo->sigInfo, &pCInfo->sigInfo, sizeof(pCInfo->sigInfo)); + } + else if (IOCTL_ACT_RADIO_RSSI == action) + { + *((rssi_t *)val) = MRFI_Rssi(); + } + else if (IOCTL_ACT_RADIO_RXON == action) + { + MRFI_RxOn(); + } + else if (IOCTL_ACT_RADIO_RXIDLE == action) + { + MRFI_RxIdle(); + } +#ifdef EXTENDED_API + else if (IOCTL_ACT_RADIO_SETPWR == action) + { + uint8_t idx; + + switch (*(ioctlLevel_t *)val) + { + case IOCTL_LEVEL_2: + idx = 2; + break; + + case IOCTL_LEVEL_1: + idx = 1; + break; + + case IOCTL_LEVEL_0: + idx = 0; + break; + + default: + return SMPL_BAD_PARAM; + } + MRFI_SetRFPwr(idx); + return SMPL_SUCCESS; + } +#endif /* EXTENDED_API */ + else + { + rc = SMPL_BAD_PARAM; + } + return rc; +} + +/****************************************************************************** + * @fn nwk_joinContext + * + * @brief For Access Points we need a way to support changing the Join + * context. This will allow arbitration bewteen potentially nearby + * Access Points when a new device is joining. + * + * input parameters + * @param action - Join context is either on or off. + * + * output parameters + * + * @return Status of operation. Currently always succeeds. + */ +#ifdef ACCESS_POINT +smplStatus_t nwk_joinContext(ioctlAction_t action) +{ + nwk_setJoinContext((IOCTL_ACT_ON == action) ? JOIN_CONTEXT_ON : JOIN_CONTEXT_OFF); + + return SMPL_SUCCESS; +} +#endif + +/****************************************************************************** + * @fn nwk_deviceAddress + * + * @brief Set or Get this device address. The Set must be done before + * SMPL_Init() for it to take effect. The Get is always legal but + * the value could be invalid if it is called before a valid set + * call is made. + * + * input parameters + * @param action - Gte or Set + * @param addr - pointer to address object containing value on Set + * + * output parameters + * @param addr - pointer to address object to receive value on Get. + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Action request illegal or a Set request + * was not respected. + */ +smplStatus_t nwk_deviceAddress(ioctlAction_t action, addr_t *addr) +{ + smplStatus_t rc = SMPL_BAD_PARAM; + + if (IOCTL_ACT_GET == action) + { + memcpy(addr, nwk_getMyAddress(), sizeof(addr_t)); + rc = SMPL_SUCCESS; + } + else if (IOCTL_ACT_SET == action) + { + if (nwk_setMyAddress(addr)) + { + rc = SMPL_SUCCESS; + } + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_connectionControl + * + * @brief Access to connection table. Currently supports only deleting + * a connection from the table. + * + * input parameters + * @param action - Connection control action (only delete is curently valid). + * @param val - pointer to Link ID of connection on which to operate. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Action is not delete + * Link ID is the UUD Link ID + * No connection table info for Link ID + */ +smplStatus_t nwk_connectionControl(ioctlAction_t action, void *val) +{ + connInfo_t *pCInfo; + linkID_t lid = *((linkID_t *)val); + + if (IOCTL_ACT_DELETE != action) + { + return SMPL_BAD_PARAM; + } + + if ((SMPL_LINKID_USER_UUD == lid) || + (!(pCInfo=nwk_getConnInfo(lid)))) + { + return SMPL_BAD_PARAM; + } + + nwk_freeConnection(pCInfo); + + return SMPL_SUCCESS; +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.h new file mode 100755 index 0000000..fa5b961 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ioctl.h @@ -0,0 +1,53 @@ +/************************************************************************************************** + Filename: nwk_ioctl.h + Revised: $Date: 2008-04-29 15:47:05 -0700 (Tue, 29 Apr 2008) $ + Revision: $Revision: 16972 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI IOCTL implmentation. This interface + gives applications access to the "driver" network level functions + when necessary. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + + +#ifndef NWK_IOCTL_H +#define NWK_IOCTL_H + +/* prototypes */ +smplStatus_t nwk_rawSend(ioctlRawSend_t *); +smplStatus_t nwk_rawReceive(ioctlRawReceive_t *); +smplStatus_t nwk_radioControl(ioctlAction_t, void *); +smplStatus_t nwk_deviceAddress(ioctlAction_t, addr_t *); +smplStatus_t nwk_connectionControl(ioctlAction_t, void *); +#ifdef ACCESS_POINT +smplStatus_t nwk_joinContext(ioctlAction_t); +#endif + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_join.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_join.c new file mode 100755 index 0000000..b96325f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_join.c @@ -0,0 +1,583 @@ +/************************************************************************************************** + Filename: nwk_join.c + Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ + Revision: $Revision: 18697 $ + + Description: This file supports the SimpliciTI Join network application. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_link.h" +#include "nwk_join.h" +#include "nwk_globals.h" +#include "nwk_freq.h" +#include "nwk_security.h" +#include "nwk_mgmt.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +static uint32_t sJoinToken = 0; +static uint8_t (*spCallback)(linkID_t) = NULL; +static volatile uint8_t sTid = 0; + +#ifdef ACCESS_POINT +static sfInfo_t *spSandFContext = NULL; +static uint8_t sJoinOK = 0; +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +#ifdef ACCESS_POINT +static void smpl_send_join_reply(mrfiPacket_t *frame); +static uint32_t generateLinkToken(void); +static void handleJoinRequest(mrfiPacket_t *); +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_joinInit + * + * @brief Initialize Join application. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_joinInit(uint8_t (*pf)(linkID_t)) +{ + if (!sJoinToken) + { + sJoinToken = DEFAULT_JOIN_TOKEN; + } + + spCallback = pf; + (void) spCallback; /* keep compiler happy if we don't use this */ + + sTid = MRFI_RandomByte() ; + +#ifdef ACCESS_POINT + /* set link token to something other than deafult if desired */ + nwk_setLinkToken(generateLinkToken()); +#if defined(STARTUP_JOINCONTEXT_ON) + sJoinOK = 1; +#elif defined(STARTUP_JOINCONTEXT_OFF) + sJoinOK = 0; +#else +#error ERROR: Must define either STARTUP_JOINCONTEXT_ON or STARTUP_JOINCONTEXT_OFF +#endif + spSandFContext = nwk_getSFInfoPtr(); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_setJoinToken + * + * @brief Sets the join token. + * + * input parameters + * @param token - join token to be used on this network. + * + * output parameters + * no room in output queue. + * + * @return void + */ +void nwk_setJoinToken(uint32_t token) +{ + /* only set if the supplied token is non-zero. */ + if (token) + { + sJoinToken = token; + } + + return; +} + +/****************************************************************************** + * @fn nwk_getJoinToken + * + * @brief Gets the current join token. + * + * input parameters + * + * output parameters + * @param pToken - pointer to the returned value. + * + * @return Current link token + */ +void nwk_getJoinToken(uint32_t *pToken) +{ + /* only set if the supplied token is non-zero. */ + if (pToken) + { + *pToken = sJoinToken; + } + + return; +} + +/****************************************************************************** + * @fn generateLinkToken + * + * @brief Generate the link token to be used for the network controlled + * by this Access Point. + * + * input parameters + * + * output parameters + * + * @return void + */ +#ifdef ACCESS_POINT +static uint32_t generateLinkToken(void) +{ + return 0xDEADBEEF; +} + +/****************************************************************************** + * @fn smpl_send_join_reply + * + * @brief Send the Join reply. Include the Link token. If the device is + * a polling sleeper put it into the list of store-and-forward + * clients. + * + * input parameters + * @param frame - join frame for which a reply is needed...maybe + * + * output parameters + * + * @return void + */ +static void smpl_send_join_reply(mrfiPacket_t *frame) +{ + frameInfo_t *pOutFrame; + uint8_t msg[JOIN_REPLY_FRAME_SIZE]; + + /* Is this a legacy frame? If so continue. Otherwise check verion.*/ + if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > JOIN_LEGACY_MSG_LENGTH) + { + /* see if protocol version is correct... */ + if (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_PROTOCOL_VERSION_OS) != nwk_getProtocolVersion()) + { + /* Accommodation of protocol version differences can be noted or accomplished here. + * Otherwise, no match and the board goes back + */ + return; + } + } + + + /* see if join token is correct */ + { + uint32_t jt; + + nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_JOIN_TOKEN_OS, &jt, sizeof(jt)); + if (jt != sJoinToken) + { + return; + } + } + + /* send reply with tid, the link token, and the encryption context */ + { + uint32_t linkToken; + + nwk_getLinkToken(&linkToken); + nwk_putNumObjectIntoMsg((void *)&linkToken, msg+JR_LINK_TOKEN_OS, sizeof(linkToken)); + } + msg[JR_CRYPTKEY_SIZE_OS] = SEC_CRYPT_KEY_SIZE; + msg[JB_REQ_OS] = JOIN_REQ_JOIN | NWK_APP_REPLY_BIT; + /* sender's tid... */ + msg[JB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+JB_TID_OS); + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_JOIN, msg, sizeof(msg), MAX_HOPS_FROM_AP)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + +#ifdef AP_IS_DATA_HUB + /* if source device supports ED objects save source address to detect duplicate joins */ + if (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_NUMCONN_OS)) + { + if (nwk_saveJoinedDevice(frame) && spCallback) + { + spCallback(0); + } + } +#endif + } + else + { + /* oops -- no room left for Tx frame. Don't send reply. */ + return; + } + + /* If this device polls we need to provide store-and-forward support */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame),F_RX_TYPE) == F_RX_TYPE_POLLS) + { + uint8_t loc; + + /* Check duplicate status */ + if (!nwk_isSandFClient(MRFI_P_SRC_ADDR(frame), &loc)) + { + uint8_t *pNumc = &spSandFContext->curNumSFClients; + sfClientInfo_t *pClient = &spSandFContext->sfClients[*pNumc]; + + /* It's not a duplicate. Save it if there's room */ + if (*pNumc < NUM_STORE_AND_FWD_CLIENTS) + { + memcpy(pClient->clientAddr.addr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + *pNumc = *pNumc + 1; + } + else + { + /* No room left. Just return and don't send reply. */ + return; + } + } + else + { + /* We get here if it's a duplicate. We drop through and send reply. + * Reset the S&F marker in the Management application -- we should + * assume that the Client reset so the TID will be random. If this is + * simply a duplicate frame it causes no harm. + */ + nwk_resetSFMarker(loc); + } + } + +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + + /* It's not S&F or it is but we're OK to send reply. */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +/****************************************************************************** + * @fn nwk_join + * + * @brief Stub Join function for Access Points. + * + * input parameters + * + * output parameters + * + * @return Always returns SMPL_SUCCESS. + */ +smplStatus_t nwk_join(void) +{ + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_isSandFClient + * + * @brief Helper function to see if the destination of a frame we have is + * one of AP's store-and-forward clients. + * + * input parameters + * @param fPtr - pointer to address in frame in question + * + * output parameters + * @param entLoc - pointer to receive entry location in array of clients. + * + * @return Returns client info structure pointer if the destination is a + * store-and-forward client, else 0. + */ +sfClientInfo_t *nwk_isSandFClient(uint8_t *pAddr, uint8_t *entLoc) +{ + uint8_t i; + sfClientInfo_t *pSFClient = spSandFContext->sfClients; + + for (i=0; icurNumSFClients; ++i, ++pSFClient) + { + if (!memcmp(&pSFClient->clientAddr.addr, pAddr, NET_ADDR_SIZE)) + { + *entLoc = i; + return pSFClient; + } + } + + return 0; +} + +/****************************************************************************** + * @fn nwk_setJoinContext + * + * @brief Helper function to set Join context for Access Point. This will + * allow arbitration bewteen potentially nearby Access Points when + * a new device is joining. + * + * input parameters + * @param which - Join context is either off or on + * + * output parameters + * + * @return void + */ +void nwk_setJoinContext(uint8_t which) +{ + sJoinOK = (JOIN_CONTEXT_ON == which) ? 1 : 0; + + return; +} + +/****************************************************************************** + * @fn handleJoinRequest + * + * @brief Dispatches handler for specfic join request + * + * input parameters + * + * @param frame - Join frame received + * + * output parameters + * + * @return void + */ +static void handleJoinRequest(mrfiPacket_t *frame) +{ + if (JOIN_LEGACY_MSG_LENGTH == (MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS)) + { + /* Legacy frame. Spoof a join request */ + *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS) = JOIN_REQ_JOIN; + } + + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS)) + { + case JOIN_REQ_JOIN: + smpl_send_join_reply(frame); + break; + + default: + break; + } + + return; +} + +#else /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_join + * + * @brief Join functioanlity for non-AP devices. Send the Join token + * and wait for the reply. + * + * input parameters + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_join(void) +{ + uint8_t msg[JOIN_FRAME_SIZE]; + uint32_t linkToken; + addr_t apAddr; + uint8_t radioState = MRFI_GetRadioState(); + smplStatus_t rc = SMPL_NO_JOIN; + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + +#if defined( FREQUENCY_AGILITY ) + uint8_t i, numChan; + freqEntry_t channels[NWK_FREQ_TBL_SIZE]; + + if (!(numChan=nwk_scanForChannels(channels))) + { + return SMPL_NO_CHANNEL; + } + + for (i=0; i +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_link.h" +#include "nwk_globals.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static uint32_t sLinkToken = 0; +static volatile uint8_t sListenActive = 0; +#if NUM_CONNECTIONS > 0 +static volatile linkID_t sServiceLinkID[NUM_CONNECTIONS]; +#endif +static volatile uint8_t sNumLinkers = 0; +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +#define SENT_REPLY 1 +#define SENT_NO_REPLY 2 +static uint8_t smpl_send_link_reply(mrfiPacket_t *); +static fhStatus_t handleLinkRequest(mrfiPacket_t *); +#if defined(EXTENDED_API) +static void smpl_send_unlink_reply(mrfiPacket_t *); +#endif + + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_linkInit + * + * @brief Initialize link app. Set link token to the default. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_linkInit(void) +{ + if (!sLinkToken) + { + /* if the link token has not been set externally by the time we get here + * (such as by the ioctl token-setting interface) assign the default + */ + sLinkToken = DEFAULT_LINK_TOKEN; + } + + /* set a non-zero TID. */ + while (!(sTid = MRFI_RandomByte())) ; + +#if NUM_CONNECTIONS > 0 + memset((void *)&sServiceLinkID, 0x0, sizeof(sServiceLinkID)); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_setLinkToken + * + * @brief Sets the link token received in a Join reply. + * + * input parameters + * @param token - Link token to be used on this network to link to any peer. + * + * output parameters + * + * @return void + */ +void nwk_setLinkToken(uint32_t token) +{ + /* only set if the supplied token is non-zero. */ + if (token) + { + sLinkToken = token; + } + + return; +} + +/****************************************************************************** + * @fn nwk_getLinkToken + * + * @brief Gets the current link token. + * + * input parameters + * + * output parameters + * @param pToken - pointer to the returned value. + * + * @return Current link token + */ +void nwk_getLinkToken(uint32_t *pToken) +{ + /* only set if the supplied token is non-zero. */ + if (pToken) + { + *pToken = sLinkToken; + } + + return; +} + +#if defined(EXTENDED_API) +/****************************************************************************** + * @fn nwk_unlink + * + * @brief Called from the application level to tear down a link. + * + * input parameters + * + * output parameters + * @param lid - Link ID assigned for this link + * + * @return Status of the operation. + * SMPL_SUCCESS + * SMPL_BAD_PARAM No connection table entry for this Link ID; + * SMPL_LINKID_USER_UUD not valid since it is not + * connection-based. + * SMPL_TIMEOUT No reply from peer. + * SMPL_NO_PEER_UNLINK Peer did not have a Connection Table entry for me. + */ +smplStatus_t nwk_unlink(linkID_t lid) +{ + uint8_t msg[UNLINK_FRAME_SIZE]; + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_SUCCESS; + addr_t addr; + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + /* is there connection info? */ + if (!pCInfo || (lid == SMPL_LINKID_USER_UUD)) + { + return SMPL_BAD_PARAM; + } + + /* set request byte */ + msg[LB_REQ_OS] = LINK_REQ_UNLINK; + + /* set the transaction ID. this allows target to figure out duplicates */ + msg[LB_TID_OS] = sTid; + + /* remote port to be sent in message to help match connection */ + msg[UL_RMT_PORT_OS] = pCInfo->portRx; + + /* setup for ioctl raw I/O */ + memcpy(addr.addr, pCInfo->peerAddr, NET_ADDR_SIZE); + ioctl_info.send.addr = &addr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_LINK; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + { + uint8_t spin = NWK_RX_RETRY_COUNT; + uint8_t radioState = MRFI_GetRadioState(); + + ioctl_info.recv.port = SMPL_PORT_LINK; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = (addr_t *)0; + + do + { + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + if ((msg[LB_REQ_OS] & (~NWK_APP_REPLY_BIT)) == LINK_REQ_UNLINK) + { + rc = (smplStatus_t)msg[ULR_RESULT_OS]; + break; + } + } + if (!spin) + { + rc = SMPL_TIMEOUT; + break; + } + --spin; + } while (1); + + /* it's ok to unconditionally invalidate connection object */ + nwk_freeConnection(pCInfo); + } + return rc; +} +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn nwk_link + * + * @brief Called from the application level to accomplish the link + * + * input parameters + * + * output parameters + * @param lid - pointer to Link ID (port) assigned for this link + * + * @return Status of the operation. + */ +smplStatus_t nwk_link(linkID_t *lid) +{ + uint8_t msg[LINK_FRAME_SIZE]; + connInfo_t *pCInfo = nwk_getNextConnection(); + smplStatus_t rc; + + if (pCInfo) + { + addr_t addr; + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + if (!nwk_allocateLocalRxPort(LINK_SEND, pCInfo)) + { + nwk_freeConnection(pCInfo); + return SMPL_NOMEM; + } + + memcpy(addr.addr, nwk_getBCastAddress(), NET_ADDR_SIZE); + ioctl_info.send.addr = &addr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_LINK; + + /* Put link token in */ + nwk_putNumObjectIntoMsg((void *)&sLinkToken, msg+L_LINK_TOKEN_OS, sizeof(sLinkToken)); + + /* set port to which the remote device should send */ + msg[L_RMT_PORT_OS] = pCInfo->portRx; + + /* set the transaction ID. this allows target to figure out duplicates */ + msg[LB_TID_OS] = sTid; + + /* set my Rx type */ + msg[L_MY_RXTYPE_OS] = nwk_getMyRxType(); + + /* set request byte */ + msg[LB_REQ_OS] = LINK_REQ_LINK; + + /* protocol version number */ + msg[L_PROTOCOL_VERSION_OS] = nwk_getProtocolVersion(); + +#if defined(SMPL_SECURE) + pCInfo->connTxCTR = MRFI_RandomByte() | \ + ((uint32_t)(MRFI_RandomByte())<<8) | \ + ((uint32_t)(MRFI_RandomByte())<<16) | \ + ((uint32_t)(MRFI_RandomByte())<<24); + + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[L_CTR_OS], 4); +#endif + + + if (SMPL_SUCCESS != (rc=SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send))) + { + return rc; + } + + { + uint8_t radioState = MRFI_GetRadioState(); + + ioctl_info.recv.port = SMPL_PORT_LINK; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = (addr_t *)pCInfo->peerAddr; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + uint8_t firstByte = msg[LB_REQ_OS] & (~NWK_APP_REPLY_BIT); + + /* Sanity check for correct reply frame. Older version + * has the length instead of the request as the first byte. + */ + if ((firstByte != LINK_REQ_LINK) && + (firstByte != LINK_REPLY_LEGACY_MSG_LENGTH) + ) + { + /* invalidate connection object */ + nwk_freeConnection(pCInfo); + return SMPL_NO_LINK; + + } + } + else + { + /* no successful receive */ + nwk_freeConnection(pCInfo); + return SMPL_TIMEOUT; + } + + pCInfo->connState = CONNSTATE_CONNECTED; + pCInfo->portTx = msg[LR_RMT_PORT_OS]; /* link reply returns remote port */ + *lid = pCInfo->thisLinkID; /* return our local port number */ + + /* Set hop count. If it's a polling device set the count to the + * distance to the AP. Otherwise, set it to the max less the remaining + * which will be the path taken for this frame. It will be no worse + * then tha max and probably will be better. + */ + if (F_RX_TYPE_POLLS == msg[LR_MY_RXTYPE_OS]) + { + pCInfo->hops2target = MAX_HOPS_FROM_AP; + } + else + { + /* Can't really use this trick because the device could move. If the + * devices are all static this may work unless the initial reception + * was marginal. + */ +#if defined(DEVICE_DOES_NOT_MOVE) + pCInfo->hops2target = MAX_HOPS - ioctl_info.recv.hopCount; +#else + pCInfo->hops2target = MAX_HOPS; +#endif + } + +#if defined(SMPL_SECURE) + nwk_getNumObjectFromMsg((void *)&msg[LR_CTR_OS], (void *)&pCInfo->connRxCTR, 4); +#endif + } + + /* guard against duplicates... */ + ++sTid; + if (!sTid) + { + sTid = 1; + } + return SMPL_SUCCESS; + } + + return SMPL_NOMEM; +} + +#if defined(EXTENDED_API) +/****************************************************************************** + * @fn smpl_send_unlink_reply + * + * @brief Send the unlink reply to the device trying to unlink + * + * input parameters + * @param frame - frame received from linker + * + * output parameters + * + * @return void + */ +static void smpl_send_unlink_reply(mrfiPacket_t *frame) +{ + connInfo_t *pCInfo; + frameInfo_t *pOutFrame; + uint8_t msg[UNLINK_REPLY_FRAME_SIZE]; + smplStatus_t rc = SMPL_NO_PEER_UNLINK; + + /* match the remote port and source address with a connection table entry */ + if (pCInfo = nwk_findPeer((addr_t *)MRFI_P_SRC_ADDR(frame), *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+UL_RMT_PORT_OS))) + { + /* Note we unconditionally free the connection resources */ + nwk_freeConnection(pCInfo); + rc = SMPL_SUCCESS; + } + + /* set reply bit */ + msg[LB_REQ_OS] = LINK_REQ_UNLINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+LB_TID_OS); + + /* result of freeing local connection */ + msg[ULR_RESULT_OS] = rc; + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +#if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } +} +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn smpl_send_link_reply + * + * @brief Send the link reply to the device trying to link. This routine + * will handle duplicates. + * + * input parameters + * @param frame - frame received from linker + * + * output parameters + * + * @return Returns SENT_REPLY if reply sent, else SENT_NO_REPLY. + * The return value is used as this routine unwinds to know + * whether to replay the frame. An RE or AP can host an ED + * object in which case it might send a reply (possibly from + * a duplicate frame). If we do reply we do not want to replay. + */ +static uint8_t smpl_send_link_reply(mrfiPacket_t *frame) +{ +#if NUM_CONNECTIONS > 0 + frameInfo_t *pOutFrame; + connInfo_t *pCInfo; + uint8_t remotePort; + uint8_t msg[LINK_REPLY_FRAME_SIZE]; + + /* Is this a legacy frame? If so continue. Otherwise check version.*/ + if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > LINK_LEGACY_MSG_LENGTH) + { + /* see if protocol version is correct... */ + if (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_PROTOCOL_VERSION_OS) != nwk_getProtocolVersion()) + { + /* Accommodation of protocol version differences can be noted or accomplished here. + * This field was also checked in the join transaction but it is checked again here + * because that check may not have occurred if thre is no AP in this topology. + * Otherwise, no match and the board goes back + */ + return SENT_NO_REPLY; + } + } + + /* see if token is correct */ + { + uint32_t lt; + + nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_LINK_TOKEN_OS, <, sizeof(lt)); + if (lt != sLinkToken) + { + return SENT_NO_REPLY; + } + } + + /* if we get here the token matched. */ + + /* is this a duplicate request? */ + remotePort = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_RMT_PORT_OS); + if (pCInfo=nwk_isLinkDuplicate(MRFI_P_SRC_ADDR(frame), remotePort)) + { + /* resend reply */ + msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+LB_TID_OS); + + /* Send reply with the local port number so the remote device knows where to + * send packets. + */ + msg[LR_RMT_PORT_OS] = pCInfo->portRx; + + /* put my Rx type in there. used to know how to set hops when sending back. */ + msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); +#if defined(SMPL_SECURE) + /* Set the Tx counter value for peer's Rx counter object */ + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); + /* We also need to save the newly generated Rx counter value. */ + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_CTR_OS), (void *)&pCInfo->connRxCTR, 4); +#endif + if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS-(GET_FROM_FRAME(MRFI_P_PAYLOAD(frame),F_HOP_COUNT)))) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +#if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + return SENT_REPLY; + } + + if (!sListenActive) + { + /* We've checked for duplicate and resent reply. In that case we weren't listening + * so just go back`. + */ + return SENT_NO_REPLY; + } + + /* room to link? */ +#if defined(AP_IS_DATA_HUB) + pCInfo = nwk_findAlreadyJoined(frame); + + if (!pCInfo) +#endif + { + pCInfo = nwk_getNextConnection(); + } + + if (pCInfo) + { + /* yes there's room and it's not a dup. address. */ + memcpy(&pCInfo->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + if (!nwk_allocateLocalRxPort(LINK_REPLY, pCInfo)) + { + nwk_freeConnection(pCInfo); + /* we're done with the packet */ + return SENT_REPLY; + } + + /* The local Rx port is the one returned in the connection structure. The + * caller is waiting on this to be set. The code here is running in an ISR + * thread so the caller will see this change after RETI. + */ + if (NUM_CONNECTIONS == sNumLinkers) + { + /* Something is wrong -- no room to stack Link request */ + nwk_freeConnection(pCInfo); + /* we're done with the packet */ + return SENT_REPLY; + } + sServiceLinkID[sNumLinkers++] = pCInfo->thisLinkID; + + /* save the remote Tx port */ + pCInfo->portTx = remotePort; + + /* connection is valid... */ + pCInfo->connState = CONNSTATE_CONNECTED; + + /* Set hop count. If it's a polling device set the count to the + * distance to the AP. otherwise, set it to the max less the remaining + * which will be the path taken for this frame. It will be no worse + * then tha max and probably will be better. + */ + if (F_RX_TYPE_POLLS == *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_MY_RXTYPE_OS)) + { + /* It polls. so. we'll be sending to the AP which will store the + * frame. The AP is only MAX_HOPS_FROM_AP hops away from us. + */ + pCInfo->hops2target = MAX_HOPS_FROM_AP; + } + else + { + /* Can't really use this trick because the device could move. If the + * devices are all static this may work unless the initial reception + * was marginal. + */ +#if defined(DEVICE_DOES_NOT_MOVE) + pCInfo->hops2target = MAX_HOPS - GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT); +#else + pCInfo->hops2target = MAX_HOPS; +#endif + } + /* Send reply with the local port number so the remote device knows where to + * send packets. + */ + msg[LR_RMT_PORT_OS] = pCInfo->portRx; + + /* put my Rx type in there. used to know how to set hops when sending back. */ + msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); + + msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+LB_TID_OS); +#if defined(SMPL_SECURE) + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_CTR_OS), (void *)&pCInfo->connRxCTR, 4); + pCInfo->connTxCTR = MRFI_RandomByte() | \ + ((uint32_t)(MRFI_RandomByte())<<8) | \ + ((uint32_t)(MRFI_RandomByte())<<16) | \ + ((uint32_t)(MRFI_RandomByte())<<24); + + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); +#endif + if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS-(GET_FROM_FRAME(MRFI_P_PAYLOAD(frame),F_HOP_COUNT)))) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +#if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif + if (SMPL_SUCCESS != nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED)) + { + /* better release the connection structure */ + nwk_freeConnection(pCInfo); + } + } + else + { + /* better release the connection structure */ + nwk_freeConnection(pCInfo); + } + } + /* we're done with the packet */ + return SENT_REPLY; +#else + return SENT_NO_REPLY; +#endif /* NUM_CONNECTIONS */ +} + +/****************************************************************************** + * @fn nwk_processLink + * + * @brief Process Link frame. Just save the frame for the Link app if it + * a reply. If it isn't a reply, send the reply in this thread. + * + * input parameters + * @param frame - pointer to frame to be processed + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame.. + */ +fhStatus_t nwk_processLink(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. send the reply. + */ + if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, LB_REQ_OS, LB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* No, we didn't send it. Process request assuming it's + * intended for us. + */ + rc = handleLinkRequest(frame); + } + + (void) replyType; /* keep compiler happy when ED built... */ + + return rc; +} + +/****************************************************************************** + * @fn nwk_getLocalLinkID + * + * @brief This routine checks to see if a service port has been assigned + * as a result of a link reply frame being received. It is the means + * by which the user thread knows that the waiting is over for the + * link listen. the value is set in an interrupt thread. + * + * input parameters + * + * output parameters + * + * @return Local port assigned when the link reply was received. + */ +linkID_t nwk_getLocalLinkID(void) +{ + linkID_t lid = 0; +#if NUM_CONNECTIONS > 0 + uint8_t i; + bspIState_t intState; + + + BSP_ENTER_CRITICAL_SECTION(intState); + if (sNumLinkers) + { + sNumLinkers--; + BSP_EXIT_CRITICAL_SECTION(intState); + + nwk_setListenContext(LINK_LISTEN_OFF); + lid = sServiceLinkID[0]; + /* If more than one Link frame has been processed without an intervening + * Listen assume that there will be another Link Listen call that will + * poll for completion which has already occurred. Age any existing entries. + * This code was added to deal with the possibility of mulitple EDs being + * activated simultaneously in the AP-as-data-hub example. This opens a + * window of opportunity for a "typical" scenario to get hosed. But for + * a "typical" scenario to get hosed a number of improbable events have to + * occur. These are deemed far less likely than the multiple-ED-activation + * scenario in the AP-as-dat-hub case. + */ + for (i=0; i +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_mgmt.h" +#include "nwk_join.h" +#include "nwk_globals.h" +#include "nwk_QMgmt.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +#ifndef ACCESS_POINT +static addr_t const *sAPAddr = NULL; +#else +static uint8_t sSFMarker[NUM_STORE_AND_FWD_CLIENTS] = {0}; +#endif + +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static void smpl_send_mgmt_reply(mrfiPacket_t *); +#ifdef ACCESS_POINT +static void send_poll_reply(mrfiPacket_t *); +#endif + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_mgmtInit + * + * @brief Initialize Management functions. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_mgmtInit(void) +{ + sTid = MRFI_RandomByte(); + +#ifdef ACCESS_POINT + memset(&sSFMarker, 0x0, sizeof(sSFMarker)); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_processMgmt + * + * @brief Process Management frame. Just save the frame for the Management + * app it it is a reply. If it isn't a reply, send the reply in this + * thread. + * + * input parameters + * @param frame - pointer to frame to be processed + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ +fhStatus_t nwk_processMgmt(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. send the reply. + */ + if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, MB_APP_INFO_OS, MB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* no, we didn't send it. send reply if it's intended for us */ + if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + smpl_send_mgmt_reply(frame); + + /* we're done with the frame. */ + rc = FHS_RELEASE; + } + else + { + rc = FHS_REPLAY; + } + } + + (void) replyType; /* keep compiler happy */ + + return rc; +} + +/****************************************************************************** + * @fn smpl_send_mgmt_reply + * + * @brief Send appropriate reply to Management frame. + * + * input parameters + * @param frame - Pointer to frame for which reply required. + * + * output parameters + * + * @return void + */ +static void smpl_send_mgmt_reply(mrfiPacket_t *frame) +{ +#ifdef ACCESS_POINT + /* what kind of management frame is this? */ + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+MB_APP_INFO_OS)) + { + case MGMT_REQ_POLL: + send_poll_reply(frame); + break; + + default: + break; + } +#endif /* ACCESS_POINT */ + return; +} + + +#ifdef ACCESS_POINT +/****************************************************************************** + * @fn send_poll_reply + * + * @brief Send reply to polling frame. + * + * input parameters + * @param frame - Pointer to frame for which reply required. + * + * output parameters + * + * @return void + */ +static void send_poll_reply(mrfiPacket_t *frame) +{ + uint8_t msgtid = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+MB_TID_OS); + frameInfo_t *pOutFrame; + sfClientInfo_t *pClientInfo; + uint8_t loc; + + /* Make sure this guy is really a client. We can tell from the source address. */ + if (!(pClientInfo=nwk_isSandFClient(MRFI_P_SRC_ADDR(frame), &loc))) + { + /* TODO: maybe send an error frame? */ + return; + } + + /* If we have to resync the TID then do it based on the first + * poll frame we see + */ + if (!sSFMarker[loc]) + { + /* If the marker flag is null then it has been initialized, i.e., + * there has been a reset. In this case infer that we need to update + * a (probably) stale last TID. The test will always be true the first + * time through after a client is established even when an NV restore + * did not take place but this does no harm. + */ + pClientInfo->lastTID = msgtid; + sSFMarker[loc] = 1; + } + /* If we've seen this poll frame before ignore it. Otherwise we + * may send a stored frame when we shouldn't. + */ + else if (nwk_checkAppMsgTID(pClientInfo->lastTID, msgtid)) + { + pClientInfo->lastTID = msgtid; + } + else + { + return; + } + + if (pOutFrame = nwk_getSandFFrame(frame, M_POLL_PORT_OS)) + { + /* We need to adjust the order in the queue in this case. Currently + * we know it is in the input queue and that this adjustment is safe + * because we're in an ISR thread. This is a fragile fix, though, and + * should be revisited when time permits. + */ + nwk_QadjustOrder(INQ, pOutFrame->orderStamp); + + /* reset hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_HOP_COUNT, MAX_HOPS_FROM_AP); + /* It's gonna be a forwarded frame. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_FWD_FRAME, 0x80); + + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + else + { + nwk_SendEmptyPollRspFrame(frame); + } + + return; +} + +/****************************************************************************** + * @fn nwk_resetSFMarker + * + * @brief Reset S&F cklient marker so the TIDs resync. + * + * input parameters + * @param idx - index of the client that should be reset. + * + * output parameters + * + * @return void + */ +void nwk_resetSFMarker(uint8_t idx) +{ + sSFMarker[idx] = 0; + + return; +} + +#else /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_poll + * + * @brief Poll S&F server for any waiting frames. + * + * input parameters + * @param port - Port on peer. + * @param addr - SimpliciTI address of peer. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_NO_AP_ADDRESS - We don't know Access Point's address + * SMPL_NOMEM - no room in output frame queue + * SMPL_TX_CCA_FAIL - CCA failure + */ +smplStatus_t nwk_poll(uint8_t port, uint8_t *addr) +{ + uint8_t msg[MGMT_POLL_FRAME_SIZE]; + ioctlRawSend_t send; + + msg[MB_APP_INFO_OS] = MGMT_REQ_POLL; + msg[MB_TID_OS] = sTid; + msg[M_POLL_PORT_OS] = port; + memcpy(msg+M_POLL_ADDR_OS, addr, NET_ADDR_SIZE); + + /* it's OK to increment the TID here because the reply will not be + * matched based on this number. The reply to the poll comes back + * to the client port, not the Management port. + */ + sTid++; + + if (!sAPAddr) + { + sAPAddr = nwk_getAPAddress(); + if (!sAPAddr) + { + return SMPL_NO_AP_ADDRESS; + } + } + send.addr = (addr_t *)sAPAddr; + send.msg = msg; + send.len = sizeof(msg); + send.port = SMPL_PORT_MGMT; + + return SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); +} + +#endif /* ACCESS_POINT */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_mgmt.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_mgmt.h new file mode 100755 index 0000000..d913abb --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_mgmt.h @@ -0,0 +1,67 @@ +/************************************************************************************************** + Filename: nwk_mgmt.h + Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ + Revision: $Revision: 18697 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI Mgmt network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_MGMT_H +#define NWK_MGMT_H + +/* MGMT frame application requests */ +#define MGMT_REQ_POLL 0x01 + +/* change the following as protocol developed */ +#define MAX_MGMT_APP_FRAME 7 + +/* application payload offsets */ +/* both */ +#define MB_APP_INFO_OS 0 +#define MB_TID_OS 1 + +/* Poll frame */ +#define M_POLL_PORT_OS 2 +#define M_POLL_ADDR_OS 3 + +/* change the following as protocol developed */ +#define MAX_MGMT_APP_FRAME 7 + +/* frame sizes */ +#define MGMT_POLL_FRAME_SIZE 7 + +/* prototypes */ +void nwk_mgmtInit(void); +fhStatus_t nwk_processMgmt(mrfiPacket_t *); +smplStatus_t nwk_poll(uint8_t, uint8_t *); +void nwk_resetSFMarker(uint8_t); + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.c new file mode 100755 index 0000000..2e55a48 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.c @@ -0,0 +1,314 @@ +/************************************************************************************************** + Filename: nwk_ping.c + Revised: $Date: 2009-01-18 16:01:08 -0800 (Sun, 18 Jan 2009) $ + Revision: $Revision: 18796 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Ping network application. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_ping.h" +#include "nwk_globals.h" +#include "nwk_api.h" +#include "nwk_freq.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static void smpl_send_ping_reply(mrfiPacket_t *); +static void handlePingRequest(mrfiPacket_t *); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_pingInit + * + * @brief Initialize Ping application. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_pingInit(void) +{ + sTid = MRFI_RandomByte(); + + return; +} + +/****************************************************************************** + * @fn nwk_ping + * + * @brief Called from the application level to ping a peer. A small + * payload is sent that includes a tid to detect correct reply. + * Caller does not supply payload. + * + * input parameters + * @param lid - Link ID representing peer to ping + * + * output parameters + * + * @return SMPL_SUCCESS valid reply received + * SMPL_TIMEOUT no valid reply received + * SMPL_NO_CHANNEL no channels returned on a scan + */ +smplStatus_t nwk_ping(linkID_t lid) +{ + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + uint8_t done = 0; + uint8_t repeatIt = 2; + uint8_t msg[MAX_PING_APP_FRAME]; + uint8_t radioState = MRFI_GetRadioState(); + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + if (!pCInfo || (SMPL_LINKID_USER_UUD == lid)) + { + /* either link ID bogus or tried to ping the unconnected user datagram link ID. */ + return rc; + } + + do + { +#if defined(FREQUENCY_AGILITY) && !defined(ACCESS_POINT) + uint8_t i, numChan; + freqEntry_t channels[NWK_FREQ_TBL_SIZE]; + + if (repeatIt == 2) + { + /* If FA enabled, first time through set up so that the 'for' + * loop checks the current channel. This saves time (no scan) + * and is very likely to succeed. Populate the proper strucure. + */ + SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_GET, channels); + numChan = 1; + } + else + { + /* If we get here we must scan for the channel we're now on */ + if (!(numChan=nwk_scanForChannels(channels))) + { + return SMPL_NO_CHANNEL; + } + } + /* Either we scan next time through or we're done */ + repeatIt--; + + /* this loop Pings on each channel (probably only 1) looking + * for peer. + */ + for (i=0; ipeerAddr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_PING; + + /* fill in msg */ + msg[PB_REQ_OS] = PING_REQ_PING; + msg[PB_TID_OS] = sTid; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + ioctl_info.recv.port = SMPL_PORT_PING; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = 0; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + repeatIt = 0; + done = 1; + sTid++; /* guard against duplicates */ + } + } + } while (repeatIt); + + return done ? SMPL_SUCCESS : SMPL_TIMEOUT; + +} + +/****************************************************************************** + * @fn smpl_send_ping_reply + * + * @brief Send a reply to a ping request. + * + * input parameters + * @param frame - pointer to frame containing request + * + * output parameters + * + * @return void + */ +static void smpl_send_ping_reply(mrfiPacket_t *frame) +{ + frameInfo_t *pOutFrame; + + /* Build the reply frame. The application payload is the one included in the + * received frame payload. + */ + if (pOutFrame = nwk_buildFrame(SMPL_PORT_PING, MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS, MRFI_GET_PAYLOAD_LEN(frame)-F_APP_PAYLOAD_OS, MAX_HOPS)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + /* turn on the reply bit in the application payload */ + *(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt)+F_APP_PAYLOAD_OS+PB_REQ_OS) |= NWK_APP_REPLY_BIT; +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, MRFI_GET_PAYLOAD_LEN(frame)-F_APP_PAYLOAD_OS, 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } +} + +/****************************************************************************** + * @fn nwk_processPing + * + * @brief Ping network application frame handler. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ +fhStatus_t nwk_processPing(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. Send the reply. + */ + replyType = nwk_isValidReply(frame, sTid, PB_REQ_OS, PB_TID_OS); + if (SMPL_MY_REPLY == replyType) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. If I'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* No, we didn't send it. Send reply assuming it's a Ping intended for us. */ + handlePingRequest(frame); + + rc = FHS_RELEASE; + } + + return rc; +} + +/****************************************************************************** + * @fn handlePingRequest + * + * @brief Dispatches handler for specfic Ping request + * + * input parameters + * + * @param frame - Ping frame received + * + * output parameters + * + * @return void + */ +static void handlePingRequest(mrfiPacket_t *frame) +{ + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS)) + { + case PING_REQ_PING: + smpl_send_ping_reply(frame); + break; + + default: + break; + } + + return; +} diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.h new file mode 100755 index 0000000..c7dd3be --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_ping.h @@ -0,0 +1,58 @@ +/************************************************************************************************** + Filename: nwk_ping.h + Revised: $Date: 2008-05-14 14:22:31 -0700 (Wed, 14 May 2008) $ + Revision: $Revision: 17075 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Ping network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_PING_H +#define NWK_PING_H + +/* change the following as protocol developed */ +#define MAX_PING_APP_FRAME 2 + +/* application payload offsets */ +/* both */ +#define PB_REQ_OS 0 +#define PB_TID_OS 1 + + +/* ping requests */ +#define PING_REQ_PING 1 + +/* prototypes */ +fhStatus_t nwk_processPing(mrfiPacket_t *); +void nwk_pingInit(void); +smplStatus_t nwk_ping(linkID_t); + + +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.c new file mode 100755 index 0000000..5ee4acc --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.c @@ -0,0 +1,549 @@ +/************************************************************************************************** + Filename: nwk_security.c + Revised: $Date: 2009-01-20 14:05:46 -0800 (Tue, 20 Jan 2009) $ + Revision: $Revision: 18816 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Security network application. + + Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include /* needed for NULL */ +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_security.h" +#include "nwk_frame.h" +#include "nwk.h" + +#ifdef SMPL_SECURE + +/* *** GENERAL SECURITY OUTLINE *** + * + * We are using XTEA (eXtended Tiny Encryption Algorithm) with a fixed + * number of rounds (32). We have removed the parameters from the API + * we harvested from the public domain. + * + * We are using a CTR-like mode. We use the 64-bit block cipher function of the + * XTEA code to encipher a concatenation of the 32-bit initialization vector and + * a 32-bit counter that increments each block. We encrypt using a fixed 128-bit + * key. The resulting 64-bit output is XOR'ed with the message. If the message is + * longer than 64 bits we encipher the next block (incrementing the counter) and + * continue until the message is exhausted. If the last cipher block is longer + * than the message we simply discard the remaining cipher block. + */ + + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/* The counter can be off by quite a bit because the number of cipher + * blocks can easily be more than 1 per frame. Value limited to a + * maximum of 255. + */ +#define CTR_WINDOW 255 + +#if (CTR_WINDOW > 255) || (CTR_WINDOW < 0) +#error ERROR: 0 <= CTR_WINDOW < 256 +#endif + +/* Number of rounds for XTEA algorithm. A parameter in the public domain code + * but we fix it here at 32. + */ +#define NUM_ROUNDS 32 + +/* Key and cipher block size constants */ +#define SMPL_KEYSIZE_BYTES 16 +#define SMPL_KEYSIZE_LONGS 4 + +/****************************************************************************** + * TYPEDEFS + */ +/* Union used to access key as both a string and as unsigned longs */ +typedef union +{ + uint8_t keyS[SMPL_KEYSIZE_BYTES]; + uint32_t keyL[SMPL_KEYSIZE_LONGS]; +} key_t; + + +/****************************************************************************** + * LOCAL VARIABLES + */ +/* 32-bit Initialization vector */ +static uint32_t const sIV = 0x87654321; + +/* 128-bit (16 byte) key. Initialized as string but fetched and used in XTEA + * encryption as 4 unsigned longs. Endianess could count if the peers are on + * two different MCUs. Endianess is rectified in initialization code. + * + * Initialization _MUST_ be done as a string (or character array). Though it + * won't matter how the initialization is done if both peers are the same + * endianness, good prectice will initialize these as a string (or character + * array) so that the endianess reconciliation works properly for all cases. + */ +static key_t sKey = {"SimpliciTI's Key"}; + +/* Constant set as an authentication code. Note that since it is a + * fixed value as opposed to a hash of the message it does not provide + * an integrity check. It will only differentiate two message encryptions + * with the same LSB but different MSB components. Thus it helps guard + * against replays. + */ +static secMAC_t const sMAC = 0xA5; + +/* This is the 64-bit cipher block target. It is this 64-bit block that + * is XOR'ed with the actual message to be encrypted. + */ +static uint32_t sMsg[2] = {0, 0}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static secFCS_t calcFCS(uint8_t *, uint8_t); +static void msg_encipher(uint8_t *, uint8_t, uint32_t *); +static void msg_decipher(uint8_t *, uint8_t, uint32_t *); +static void xtea_encipher(void); + +#endif /* SMPL_SECURE */ + +/****************************************************************************** + * @fn nwk_securityInit + * + * @brief Initialize Security network application. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_securityInit(void) +{ +#ifdef SMPL_SECURE + uint8_t i; + + /* The key is set as a string. But the XTEA routines operate on 32-bit + * unsigned longs. Endianess should be taken into account and we do that + * here by treating the key as being an array of unsigned longs in + * network order. + */ + for (i=0; i= len) + { + /* we're done */ + done = 1; + } + } while (!done); + + /* return counter value start for next time */ + *cntStart = ctr; + + return; +} + +/****************************************************************************** + * @fn msg_decipher + * + * @brief Decipher a message using the XTEA algorithm and the modified + * CTR mode method. + * + * input parameters + * @param msg - pointer to message to decipher + * @param len - length of message + * @param cntStart - pointer to the counter used in the cipher block. + * + * output parameters + * @param cntStart - counter is updated during decryption. + * + * @return void + */ +static void msg_decipher(uint8_t *msg, uint8_t len, uint32_t *cntStart) +{ + msg_encipher(msg, len, cntStart); + + return; +} + +/****************************************************************************** + * @fn xtea_encipher + * + * @brief XTEA encipher algorithm. Calling arguments removed from public + * domain code and static-scope values used instead. + * + * input parameters + * + * output parameters + * + * @return void + */ +void xtea_encipher(void) +{ + uint32_t v0=sMsg[0], v1=sMsg[1]; + uint16_t i; + uint32_t sum=0, delta=0x9E3779B9; + + for(i=0; i> 5)) + v1) ^ (sum + sKey.keyL[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + sKey.keyL[(sum>>11) & 3]); + } + + sMsg[0]=v0; + sMsg[1]=v1; +} + +/****************************************************************************** + * @fn nwk_setSecureFrame + * + * @brief Called from NWK to secure a frame. + * + * input parameters + * @param frame - pointer to frame to secure + * @param msglen - length of message + * @param ctr - pointer to the counter used in the cipher block. This will + * be NULL if a network application is sending a frame. Since + * these are not connection-based there is no counter sync + * issue but we still need a counter value. A random value + * is used. + * + * output parameters + * @param cntStart - counter is updated during encryption. + * + * @return void + */ +void nwk_setSecureFrame(mrfiPacket_t *frame, uint8_t msglen, uint32_t *ctr) +{ + uint32_t locCnt; + + /* If an encrypted frame is to be sent to a non-connection based port use a + * random number as the lsb counter value. In this case only the lsb is used + * for a counter value during decryption. Not as secure but there are still + * the 32 bits in the IV. + */ + locCnt = ctr ? *ctr : MRFI_RandomByte(); + + /* place counter value into frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(frame), F_SEC_CTR_OS, (uint8_t)(locCnt & 0xFF)); + + /* Put MAC value in */ + nwk_putNumObjectIntoMsg((void *)&sMAC, (void *)(MRFI_P_PAYLOAD(frame)+F_SEC_MAC_OS), sizeof(secMAC_t)); + + /* Put FCS value in */ + { + secFCS_t fcs = calcFCS(MRFI_P_PAYLOAD(frame)+F_SEC_MAC_OS, msglen+sizeof(secMAC_t)); + + nwk_putNumObjectIntoMsg((void *)&fcs, (void *)(MRFI_P_PAYLOAD(frame)+F_SEC_ICHK_OS), sizeof(secFCS_t)); + } + + /* Encrypt frame */ + msg_encipher(MRFI_P_PAYLOAD(frame)+F_SEC_ICHK_OS, msglen+sizeof(secMAC_t)+sizeof(secFCS_t), &locCnt); + + /* Set the Encryption bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(frame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + + /* Update the counter if it was a "real" counter. */ + if (ctr) + { + *ctr = locCnt; + } + + return; +} + +/****************************************************************************** + * @fn calcFCS + * + * @brief Calculate the frame check sequence. Currently it's just a + * cumulative XOR of each byte starting with the MAC byte. The + * FCS is placed in front of the MAC after the counter hint and is + * included in the encryption. + * + * input parameters + * @param msg - pointer to message + * @param len - length of message + * + * output parameters + * + * @return Returns the FCS using the typedef. + */ +static secFCS_t calcFCS(uint8_t *msg, uint8_t len) +{ + uint8_t i; + secFCS_t result = 0; + + for (i=0; i locCnt) + { + /* frameCnt is bigger. Second part of test below takes care of + * the unlikely case of a complete counter wrap (msb's all 0) in + * which case the test will incorrectly fail when the count is + * actually within the (wrapped) window. #ifdef'ed to avoid compiler + * warning in case user sets CNT_WINDOW to 0 (pointless comparison of + * unsigned value). + */ + if (((frameCnt-CTR_WINDOW) <= locCnt) +#if CTR_WINDOW > 0 + || (frameCnt < CTR_WINDOW) +#endif + ) + { + /* Value within window. We probably missed something. Adjust and decipher. + * If locCnt is less because it wrapped and frameCnt didn't it means that + * it's a duplicate or late frame. In that case the following will lead to + * a decryption that fails sanity checks which is OK because the frame will + * be correctly rejected. + */ + locCnt = frameCnt; + } + else + { + /* It's either a rogue or a really old duplicate packet. In either case + * we dismiss the frame. + */ + rc = 0; + done = 1; + } + } + else + { + /* locCnt is bigger. The only way the frame can be valid is if the + * counter wrapped causing frameCnt to appear to be smaller. Wrap the + * counter and decrypt. If the frame isn't valid, i.e., it's late, + * a duplicate, or a rogue, the decryption will fail sanity checks and + * the frame will be correctly rejected. The following arithmetic works + * correctly without a special test for the complete counter wrap case. + */ + frameCnt += 0x100; /* wrap the hint-based counter */ + if (((frameCnt-CTR_WINDOW) <= locCnt)) + { + /* An lsb wrap but still within window. We probably missed something. + * Adjust (with wrap) and decrypt. + */ + locCnt = frameCnt; + } + else + { + /* rogue frame */ + rc = 0; + done = 1; + } + } + } + } while (!done); + + if (ctr && rc) + { + /* Only update the counter if the count was a "real" one and the + * decryption succeeded. + */ + *ctr = locCnt; + } + + return rc; +} + +#endif /* SMPL_SECURE */ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.h new file mode 100755 index 0000000..212ce8f --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/Components/nwk_applications/nwk_security.h @@ -0,0 +1,48 @@ +/************************************************************************************************** + Filename: nwk_security.h + Revised: $Date: 2009-01-09 15:02:17 -0800 (Fri, 09 Jan 2009) $ + Revision: $Revision: 18728 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Security network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_SECURITY_H +#define NWK_SECURITY_H + +/* change the following as Security application is developed */ +#define MAX_SEC_APP_FRAME 0 + +/* prototypes */ +void nwk_securityInit(void); +fhStatus_t nwk_processSecurity(mrfiPacket_t *); +void nwk_setSecureFrame(mrfiPacket_t *, uint8_t, uint32_t *); +uint8_t nwk_getSecureFrame(mrfiPacket_t *, uint8_t, uint32_t *); +#endif diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/simpliciti.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/simpliciti.h new file mode 100755 index 0000000..f528db8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/simpliciti.h @@ -0,0 +1,163 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// +// SimpliciTI packet size (TX only mode) +// ------------------------------------- +// +// * packet rate (100/3) packets/second = 33.3 packets/second +// * packet length 28 bytes +// * packet structure 4 bytes preamble +// 4 bytes sync +// 1 bytes length +// 1 bytes address +// 16 bytes data +// 12 byte network data +// 4 byte user data +// 2 bytes crc +// +// SimpliciTI frequency overview +// ----------------------------- +// +// CC430_End_Device_433MHz.lib (433MHz ISM band) +// +// * base frequency 433.92 MHz +// * deviation 32 kHz +// * channel spacing 25 kHz +// * used channel number 0 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.4 dBm +// * duty 9,6% (TX only mode, 32 packets / second) +// +// CC430_End_Device_868MHz.lib (868MHz ISM band) +// +// * base frequency 869.525 MHz +// * deviation 32 kHz +// * channel spacing 25 kHz +// * used channel number 0 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.1 dBm +// * duty 9,6% (TX only mode, 32 packets / second) +// +// CC430_End_Device_915MHz.lib (915MHz ISM band) +// +// * base frequency 902.000 MHz +// * deviation 32 kHz +// * channel spacing 200 kHz +// * used channel number 20 (frequency agility/hopping disabled) +// * data rate 76.8 kBaud +// * output power 1.3 dBm +// * duty 9.6% (TX only mode, 32 packets / second) +// +// ************************************************************************************************* + +// --------------------------------------------------------------- +// Generic defines and variables + +// Entry point into SimpliciTI library +extern unsigned char simpliciti_link(void); + +// 4 byte device address overrides device address set during compile time +extern unsigned char simpliciti_ed_address[4]; + +// Maximum data length +#define SIMPLICITI_MAX_PAYLOAD_LENGTH (32u) + +// Data to send / receive +extern unsigned char simpliciti_data[SIMPLICITI_MAX_PAYLOAD_LENGTH]; + +// Flag contains status information and triggers to send data or to exit SimpliciTI library +// Control is done from outside SimpliciTI library +extern unsigned char simpliciti_flag; +#define SIMPLICITI_STATUS_LINKING (BIT0) +#define SIMPLICITI_STATUS_LINKED (BIT1) +#define SIMPLICITI_STATUS_ERROR (BIT2) +#define SIMPLICITI_TRIGGER_SEND_DATA (BIT3) +#define SIMPLICITI_TRIGGER_RECEIVED_DATA (BIT4) +#define SIMPLICITI_TRIGGER_STOP (BIT5) + +// Radio frequency offset read from calibration memory +// Compensates crystal deviation from 26MHz nominal value +extern unsigned char rf_frequoffset; + +// Macros +#define getFlag(val, flag) ((val&flag)==flag) +#define setFlag(val, flag) (val|=flag) +#define clearFlag(val, flag) (val&=(~flag)) +#define toggleFlag(val, flag) (val^=flag) + + +// --------------------------------------------------------------- +// SimpliciTI RX only + +// Entry point into SimpliciTI library +extern void simpliciti_main_tx_only(void); + +// Callback function to read data from acceleration sensor or buttons and trigger sending +extern void simpliciti_get_ed_data_callback(void); + + +// --------------------------------------------------------------- +// SimpliciTI Sync + +// Sync data length +#define BM_SYNC_DATA_LENGTH (19u) + +// Device data (0)TYPE (1) - (18) DATA +#define SYNC_ED_TYPE_R2R (1u) +#define SYNC_ED_TYPE_MEMORY (2u) +#define SYNC_ED_TYPE_STATUS (3u) + +// Host data (0)CMD (1) - (18) DATA +#define SYNC_AP_CMD_NOP (1u) +#define SYNC_AP_CMD_GET_STATUS (2u) +#define SYNC_AP_CMD_SET_WATCH (3u) +#define SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_1 (4u) +#define SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_2 (5u) +#define SYNC_AP_CMD_ERASE_MEMORY (6u) +#define SYNC_AP_CMD_EXIT (7u) + + +// Entry point into SimpliciTI library +extern void simpliciti_main_sync(void); + +// Callback function to decode access point command +extern void simpliciti_sync_decode_ap_cmd_callback(void); + +// Callback function to read data from application and trigger sending +extern void simpliciti_sync_get_data_callback(unsigned int index); + +// Send reply packets (>0), 0=no need to reply +extern unsigned char simpliciti_reply_count; + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/simpliciti_readme.txt b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/simpliciti_readme.txt new file mode 100755 index 0000000..d1ff81d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Sports Watch/simpliciti/simpliciti_readme.txt @@ -0,0 +1,46 @@ +Some notes about the SimpliciTI configuration used in this project + +- The source code is based on the SimpliciTI 1.1.1 release. + +- A full SimpliciTI installation contains configurations for many targets and device types. To avoid confusion, + only the configuration (End Device) and target files (CC430EM) required for the eZ430-Chronos have been used. + +- All source code files have been copied into the project physically. Symbolic links have been replaced with + the real source code file. + +- Due to the indirect inclusion scheme of hardware-dependent source code, some source code files have been + excluded from build. However, they will be included through higher level source code. + +- Some modifications where required to the original source code. All these changes have been marked with [BM]. + + bsp_board.c/BSP_InitBoard(void) Changed from TA0 to TA1 for delay function, because TA0 is already occupied. + + bsp_msp430_defs.h/BSP_EarlyInit(void) Function removed, because SimpliciTI must run in watch context + + mrfi_radio_interface.c/mrfiRadioInterfaceCmdStrobe(uint8_t addr) + Added code to properly synchronize with radio interface. Otherwise + interface could get stuck. + + mrfi_radio.c Changed channel assignment (mrfiLogicalChanTable) for three ISM bands + Changed power output settings (mrfiRFPowerTable) for three ISM bands + + mrfi_radio.c/MRFI_Init(void) Added frequency offset correction to use calibrated frequency offset + when starting RF communication + + mrfi_radio.c/MRFI_RadioIsr(void) Changed radio ISR to normal function, since we have a shared radio ISR + + nwk_api.c Made variable sInit_done globally available to allow SimpliciTI to shutdown + and restart multiple times + + nwk.c/nwk_nwkInit Added workaround to allow allow SimpliciTI to shutdown + and restart multiple times + +- If you (for whatever reason) want to upgrade to a newer version of SimpliciTI, please bear in mind that + + a) the access point SimpliciTI version is 1.1.1 (and cannot be updated) + + b) the workarounds used here to enable SimpliciTI to shutdown and restart multiple times might not necessarily + work when used with later revisions + + + \ No newline at end of file diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/RFBSL_Low_Level_Init.s43 b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/RFBSL_Low_Level_Init.s43 new file mode 100755 index 0000000..6d20311 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/RFBSL_Low_Level_Init.s43 @@ -0,0 +1,58 @@ +//************************************************************** +// BSL SW low level functions +//************************************************************** +#include + +#ifndef RAM_BASED_RFBSL + + +#define RET_low R12 +#define RET_high r13 + +EXTERN __program_start + + COMMON ZAREA +;-------------------------------------------------------------- + ;BSL Z-Area +;-------------------------------------------------------------- +BSL_Entry_JMP:JMP __program_start ; BSL ENTRY AREA + JMP __port2_isr ; BSL_ACTION1 unused + JMP $ ; BSL_ACTION0 unused + + RSEG ZAREA_CODE + +__port2_isr: + BIT.B #01h, P2IFG + JNC isr_return + BIC #LPM4,0(SP) // Wake from sleep upon returning from the ISR +isr_return: MOV.B #00h, P2IFG + RETI + + +BSL_REQ_APP_CALL EQU 0x0002 ;Return Value for BSLUNLOCK Function to Call BSL again +BSL_Protect: + CLR RET_low ;lock (keep JTAGLOCK_KEY state) + + BIS #SYSBSLPE+SYSBSLSIZE0+SYSBSLSIZE1 , &SYSBSLC ; protects BSL + CMP.W #0FFFFh, &0FFFEh // Check if device is not programmed, go to recovery procedure + JNZ BCC2BSL + BIS.W #BSL_REQ_APP_CALL, RET_low +BCC2BSL RETA + + COMMON BSLSIG + DW 0xFFFF +BslProtectVecLoc DW BSL_Protect ;address of function +PBSLSigLoc DW 03CA5h ;1st BSL signature +SBSLSigLoc DW 0C35Ah ;2nd BSL signature + DW 0xFFFF +BslEntryLoc DW BSL_Entry_JMP + + + COMMON JTAGLOCK_KEY +PJTAGLOCK_KEY DW 0xFFFF ; Primary Key Location +SJTAGLOCK_KEY DW 0xFFFF ; Secondary Key Location + ; set default unlock JTAG with option to lock with writting + ; a value <> 0x0000 or 0xFFFF + +#endif +END \ No newline at end of file diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/Wireless_Update.ewd b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/Wireless_Update.ewd new file mode 100755 index 0000000..3a79d78 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/Wireless_Update.ewd @@ -0,0 +1,1311 @@ + + + + 2 + + RAM Based Updater + + MSP430 + + 1 + + C-SPY + 4 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 915MHz Flash Based Updater + + MSP430 + + 1 + + C-SPY + 4 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 868MHz Flash Based Updater + + MSP430 + + 1 + + C-SPY + 4 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 433MHz Flash Based Updater + + MSP430 + + 1 + + C-SPY + 4 + + 24 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 430FET + 1 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SIM430 + 1 + + 4 + 1 + 1 + + + + + + + + + + + $TOOLKIT_DIR$\plugins\Lcd\lcd.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/Wireless_Update.ewp b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/Wireless_Update.ewp new file mode 100755 index 0000000..150168e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/Wireless_Update.ewp @@ -0,0 +1,3580 @@ + + + + 2 + + RAM Based Updater + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 915MHz Flash Based Updater + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 868MHz Flash Based Updater + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + 433MHz Flash Based Updater + + MSP430 + + 1 + + General + 7 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC430 + 4 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A430 + 4 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 4 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 4 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + $PROJ_DIR$\display.c + + + $PROJ_DIR$\display.h + + + $PROJ_DIR$\display1.c + + + $PROJ_DIR$\project_defs.h + + + $PROJ_DIR$\radio.c + + + $PROJ_DIR$\radio.h + + + $PROJ_DIR$\rf1a.c + + + $PROJ_DIR$\rf1a.h + + + $PROJ_DIR$\RFBSL_Low_Level_Init.s43 + + + $PROJ_DIR$\wbsl.c + + + $PROJ_DIR$\wbsl.h + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/Wireless_Update.eww b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/Wireless_Update.eww new file mode 100755 index 0000000..8f632ca --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/Wireless_Update.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\Wireless_Update.ewp + + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/display.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/display.c new file mode 100755 index 0000000..b505154 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/display.c @@ -0,0 +1,316 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Display functions. +// ************************************************************************************************* + + +// ************************************************************************************************* +// Include section + +// system +#include "project_defs.h" + +#ifdef RAM_BASED_RFBSL +# include + +// driver +# include "display.h" + +// ************************************************************************************************* +// Prototypes section +void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state); +void display_symbol(u8 symbol, u8 mode); +void display_char(u8 segment, u8 chr, u8 mode); +void display_chars(u8 line, u8 * str); + + +// ************************************************************************************************* +// Defines section + + + +// ************************************************************************************************* +// Global Variable section + +// Global return string for itoa function +u8 itoa_str[4]; + +// ************************************************************************************************* +// @fn lcd_init +// @brief Erase LCD memory. Init LCD peripheral. +// @param none +// @return none +// ************************************************************************************************* +void lcd_init(void) +{ + // Clear entire display memory + LCDBMEMCTL |= LCDCLRBM + LCDCLRM; + + // LCD_FREQ = ACLK/16/8 = 256Hz + // Frame frequency = 256Hz/4 = 64Hz, LCD mux 4, LCD on + LCDBCTL0 = (LCDDIV0 + LCDDIV1 + LCDDIV2 + LCDDIV3) | (LCDPRE0 + LCDPRE1) | LCD4MUX | LCDON; + + // LCB_BLK_FREQ = ACLK/8/4096 = 1Hz + LCDBBLKCTL = LCDBLKPRE0 | LCDBLKPRE1 | LCDBLKDIV0 | LCDBLKDIV1 | LCDBLKDIV2 | LCDBLKMOD0; + + // I/O to COM outputs + P5SEL |= (BIT5 | BIT6 | BIT7); + P5DIR |= (BIT5 | BIT6 | BIT7); + + // Activate LCD output + LCDBPCTL0 = 0xFFFF; // Select LCD segments S0-S15 + LCDBPCTL1 = 0x00FF; // Select LCD segments S16-S22 + +# ifdef USE_LCD_CHARGE_PUMP + // Charge pump voltage generated internally, internal bias (V2-V4) generation + LCDBVCTL = LCDCPEN | VLCD_2_72; +# endif +} + +// ************************************************************************************************* +// @fn clear_display +// @brief Erase LINE1 and LINE2 segments. Keep icons. +// @param none +// @return none +// ************************************************************************************************* +void clear_display(void) +{ + display_chars(LINE1, (u8 *)" "); + display_chars(LINE2, (u8 *)" "); +} + +// ************************************************************************************************* +// @fn write_segment +// @brief Write to one or multiple LCD segments +// @param lcdmem Pointer to LCD byte memory +// bits Segments to address +// bitmask Bitmask for particular display item +// mode On, off or blink segments +// @return +// ************************************************************************************************* +void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state) +{ + if (state == SEG_ON) + { + // Clear segments before writing + *lcdmem = (u8)(*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (u8)(*lcdmem | bits); + } + else if (state == SEG_OFF) + { + // Clear segments + *lcdmem = (u8)(*lcdmem & ~bitmask); + } + else if (state == SEG_ON_BLINK_ON) + { + // Clear visible / blink segments before writing + *lcdmem = (u8)(*lcdmem & ~bitmask); + *(lcdmem + 0x20) = (u8)(*(lcdmem + 0x20) & ~bitmask); + + // Set visible / blink segments + *lcdmem = (u8)(*lcdmem | bits); + *(lcdmem + 0x20) = (u8)(*(lcdmem + 0x20) | bits); + } + else if (state == SEG_ON_BLINK_OFF) + { + // Clear visible segments before writing + *lcdmem = (u8)(*lcdmem & ~bitmask); + + // Set visible segments + *lcdmem = (u8)(*lcdmem | bits); + + // Clear blink segments + *(lcdmem + 0x20) = (u8)(*(lcdmem + 0x20) & ~bitmask); + } + else if (state == SEG_OFF_BLINK_OFF) + { + // Clear segments + *lcdmem = (u8)(*lcdmem & ~bitmask); + + // Clear blink segments + *(lcdmem + 0x20) = (u8)(*(lcdmem + 0x20) & ~bitmask); + } +} + +// ************************************************************************************************* +// @fn itoa +// @brief Generic integer to array routine. Converts integer n to string. +// Default conversion result has leading zeros, e.g. "01" +// Option to convert leading '0' into whitespace (blanks) +// @param u32 n integer to convert +// u8 digits number of digits +// u8 blanks fill up result string with number of whitespaces instead of leading +// zeros +// @return u8 string +// ************************************************************************************************* +u8 *itoa(u32 n, u8 digits, u8 blanks) +{ + // Preset result string + memcpy(itoa_str, "00", 2); + + // Return empty string if number of digits is invalid (valid range for digits: 1-7) + if ((digits == 0) || (digits > 2) || n > 99) return (itoa_str); + + // Numbers 0 .. 99 can be copied from itoa_conversion_table without conversion + memcpy(itoa_str, itoa_conversion_table[n] + (2 - digits), digits); + + return (itoa_str); +} + +// ************************************************************************************************* +// @fn display_symbol +// @brief Switch symbol on or off on LCD. +// @param u8 symbol A valid LCD symbol (index 0..42) +// u8 state SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_symbol(u8 symbol, u8 mode) +{ + u8 * lcdmem; + u8 bits; + u8 bitmask; + + if (symbol <= LCD_SEG_L2_DP) + { + // Get LCD memory address for symbol from table + lcdmem = (u8 *)segments_lcdmem[symbol]; + + // Get bits for symbol from table + bits = segments_bitmask[symbol]; + + // Bitmask for symbols equals bits + bitmask = bits; + + // Write LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + +// ************************************************************************************************* +// @fn display_char +// @brief Write to 7-segment characters. +// @param u8 segment A valid LCD segment +// u8 chr Character to display +// u8 mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +void display_char(u8 segment, u8 chr, u8 mode) +{ + u8 * lcdmem; // Pointer to LCD memory + u8 bitmask; // Bitmask for character + u8 bits, bits1; // Bits to write + + // Write to single 7-segment character + if ((segment >= LCD_SEG_L1_3) && (segment <= LCD_SEG_L2_DP)) + { + // Get LCD memory address for segment from table + lcdmem = (u8 *)segments_lcdmem[segment]; + + // Get bitmask for character from table + bitmask = segments_bitmask[segment]; + + // Get bits from font set + if ((chr >= 0x30) && (chr <= 0x5A)) + { + // Use font set + bits = lcd_font[chr - 0x30]; + } + else if (chr == 0x2D) + { + // '-' not in font set + bits = BIT1; + } + else + { + // Other characters map to ' ' (blank) + bits = 0; + } + // When addressing LINE2 7-segment characters need to swap high- and low-nibble, + // because LCD COM/SEG assignment is mirrored against LINE1 + if (segment >= LCD_SEG_L2_5) + { + bits1 = ((bits << 4) & 0xF0) | ((bits >> 4) & 0x0F); + bits = bits1; + + // When addressing LCD_SEG_L2_5, need to convert ASCII '1' and 'L' to 1 bit, + // because LCD COM/SEG assignment is special for this incomplete character + if (segment == LCD_SEG_L2_5) + { + if ((chr == '1') || (chr == 'L')) bits = BIT7; + } + } + + // Physically write to LCD memory + write_lcd_mem(lcdmem, bits, bitmask, mode); + } +} + +// ************************************************************************************************* +// @fn display_chars +// @brief Write to consecutive 7-segment characters. +// @param u8 segments LCD segment array +// u8 * str Pointer to a string +// u8 mode SEG_ON, SEG_OFF, SEG_BLINK +// @return none +// ************************************************************************************************* +//void display_chars(u8 segments, u8 * str, u8 mode) +void display_chars(u8 line, u8 * str) +{ + u8 i; + u8 char_start; // Starting point for consecutive write + u8 length = 0; + + if (line == LINE2) + { + char_start = LCD_SEG_L2_5; + length = 6; + } + else + { + char_start = LCD_SEG_L1_1; + length = 2; + } + + // Write consecutive characters + for (i = 0; i < length; i++) + { + // Use single character routine to write display memory + display_char(char_start + i, *(str + i), SEG_ON); + } +} + +#endif // RAM_BASED_RFBSL diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/display.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/display.h new file mode 100755 index 0000000..f17cb1c --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/display.h @@ -0,0 +1,226 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef __DISPLAY_H +#define __DISPLAY_H + + +// ************************************************************************************************* +// Include section + +#include "project_defs.h" + +#ifdef RAM_BASED_RFBSL + +// ************************************************************************************************* +// Extern section + +// Constants defined in library +extern const u8 lcd_font[]; +extern const u8 * segments_lcdmem[]; +extern const u8 segments_bitmask[]; +extern const u8 itoa_conversion_table[][2]; + + +// ************************************************************************************************* +// Global Variable section + +// Definitions for line access +# define LINE1 (1u) +# define LINE2 (2u) + +// LCD display modes +# define SEG_OFF (0u) +# define SEG_ON (1u) +# define SEG_ON_BLINK_ON (2u) +# define SEG_ON_BLINK_OFF (3u) +# define SEG_OFF_BLINK_OFF (4u) + +// 7-segment character bit assignments +# define SEG_A (BIT4) +# define SEG_B (BIT5) +# define SEG_C (BIT6) +# define SEG_D (BIT7) +# define SEG_E (BIT2) +# define SEG_F (BIT0) +# define SEG_G (BIT1) + +// ------------------------------------------ +// LCD symbols for easier access +// +// xxx_SEG_xxx = Seven-segment character (sequence 5-4-3-2-1-0) +// xxx_SYMB_xxx = Display symbol, e.g. "AM" for ante meridiem +// xxx_UNIT_xxx = Display unit, e.g. "km/h" for kilometers per hour +// xxx_ICON_xxx = Display icon, e.g. heart to indicate reception of heart rate data +// xxx_L1_xxx = Item is part of Line1 information +// xxx_L2_xxx = Item is part of Line2 information + +// Symbols for Line1 +# define LCD_SYMB_PERCENT 0 + +# define LCD_ICON_BEEPER1 1 +# define LCD_ICON_BEEPER2 2 +# define LCD_ICON_BEEPER3 3 + +// Line1 7-segments +# define LCD_SEG_L1_3 4 +# define LCD_SEG_L1_2 5 +# define LCD_SEG_L1_1 6 +# define LCD_SEG_L1_0 7 +# define LCD_SEG_L1_COL 8 +# define LCD_SEG_L1_DP1 9 +# define LCD_SEG_L1_DP0 10 + +// Line2 7-segments +# define LCD_SEG_L2_5 11 +# define LCD_SEG_L2_4 12 +# define LCD_SEG_L2_3 13 +# define LCD_SEG_L2_2 14 +# define LCD_SEG_L2_1 15 +# define LCD_SEG_L2_0 16 +# define LCD_SEG_L2_COL1 17 +# define LCD_SEG_L2_COL0 18 +# define LCD_SEG_L2_DP 19 + + +// Line1 7-segment arrays +# define LCD_SEG_L1_3_0 70 +# define LCD_SEG_L1_2_0 71 +# define LCD_SEG_L1_1_0 72 +# define LCD_SEG_L1_3_1 73 +# define LCD_SEG_L1_3_2 74 + +// Line2 7-segment arrays +# define LCD_SEG_L2_5_0 90 +# define LCD_SEG_L2_4_0 91 +# define LCD_SEG_L2_3_0 92 +# define LCD_SEG_L2_2_0 93 +# define LCD_SEG_L2_1_0 94 +# define LCD_SEG_L2_5_2 95 +# define LCD_SEG_L2_3_2 96 +# define LCD_SEG_L2_5_4 97 +# define LCD_SEG_L2_4_2 98 + + +// LCD controller memory map +# define LCD_MEM_1 ((u8*)0x0A20) +# define LCD_MEM_2 ((u8*)0x0A21) +# define LCD_MEM_3 ((u8*)0x0A22) +# define LCD_MEM_4 ((u8*)0x0A23) +# define LCD_MEM_5 ((u8*)0x0A24) +# define LCD_MEM_6 ((u8*)0x0A25) +# define LCD_MEM_7 ((u8*)0x0A26) +# define LCD_MEM_8 ((u8*)0x0A27) +# define LCD_MEM_9 ((u8*)0x0A28) +# define LCD_MEM_10 ((u8*)0x0A29) +# define LCD_MEM_11 ((u8*)0x0A2A) +# define LCD_MEM_12 ((u8*)0x0A2B) + + +// Memory assignment +# define LCD_SEG_L1_0_MEM (LCD_MEM_6) +# define LCD_SEG_L1_1_MEM (LCD_MEM_4) +# define LCD_SEG_L1_2_MEM (LCD_MEM_3) +# define LCD_SEG_L1_3_MEM (LCD_MEM_2) +# define LCD_SEG_L1_COL_MEM (LCD_MEM_1) +# define LCD_SEG_L1_DP1_MEM (LCD_MEM_1) +# define LCD_SEG_L1_DP0_MEM (LCD_MEM_5) +# define LCD_SEG_L2_0_MEM (LCD_MEM_8) +# define LCD_SEG_L2_1_MEM (LCD_MEM_9) +# define LCD_SEG_L2_2_MEM (LCD_MEM_10) +# define LCD_SEG_L2_3_MEM (LCD_MEM_11) +# define LCD_SEG_L2_4_MEM (LCD_MEM_12) +# define LCD_SEG_L2_5_MEM (LCD_MEM_12) +# define LCD_SEG_L2_COL1_MEM (LCD_MEM_1) +# define LCD_SEG_L2_COL0_MEM (LCD_MEM_5) +# define LCD_SEG_L2_DP_MEM (LCD_MEM_9) + +# define LCD_SYMB_PERCENT_MEM (LCD_MEM_5) +# define LCD_ICON_BEEPER1_MEM (LCD_MEM_5) +# define LCD_ICON_BEEPER2_MEM (LCD_MEM_6) +# define LCD_ICON_BEEPER3_MEM (LCD_MEM_7) + +// Bit masks for write access +# define LCD_SEG_L1_0_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +# define LCD_SEG_L1_1_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +# define LCD_SEG_L1_2_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +# define LCD_SEG_L1_3_MASK (BIT2 + BIT1 + BIT0 + BIT7 + BIT6 + BIT5 + BIT4) +# define LCD_SEG_L1_COL_MASK (BIT5) +# define LCD_SEG_L1_DP1_MASK (BIT6) +# define LCD_SEG_L1_DP0_MASK (BIT2) +# define LCD_SEG_L2_0_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +# define LCD_SEG_L2_1_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +# define LCD_SEG_L2_2_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +# define LCD_SEG_L2_3_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +# define LCD_SEG_L2_4_MASK (BIT3 + BIT2 + BIT1 + BIT0 + BIT6 + BIT5 + BIT4) +# define LCD_SEG_L2_5_MASK (BIT7) +# define LCD_SEG_L2_COL1_MASK (BIT4) +# define LCD_SEG_L2_COL0_MASK (BIT0) +# define LCD_SEG_L2_DP_MASK (BIT7) + +# define LCD_SYMB_PERCENT_MASK (BIT4) +# define LCD_ICON_BEEPER1_MASK (BIT3) +# define LCD_ICON_BEEPER2_MASK (BIT3) +# define LCD_ICON_BEEPER3_MASK (BIT3) + +# define LCD_DISPLAY_DONE (1u) +# define LCD_DISPLAY_RFBSL (2u) +# define LCD_DISPLAY_FAIL (3u) + +// ************************************************************************************************* +// API section + +// Physical LCD memory write +extern void write_lcd_mem(u8 * lcdmem, u8 bits, u8 bitmask, u8 state); + +// Display init / clear +extern void lcd_init(void); +extern void clear_display(void); + + +// Character / symbol draw functions +extern void display_char(u8 segment, u8 chr, u8 mode); +extern void display_chars(u8 line, u8 * str); +extern void display_symbol(u8 symbol, u8 mode); + +// Integer to string conversion +extern u8 *itoa(u32 n, u8 digits, u8 blanks); + +// Segment index helper function +extern u8 switch_seg(u8 line, u8 index1, u8 index2); + +#endif // RAM_BASED_RFBSL + +#endif // __DISPLAY_ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/display1.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/display1.c new file mode 100755 index 0000000..a29da5e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/display1.c @@ -0,0 +1,174 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Basic display functions. +// ************************************************************************************************* + + +// ************************************************************************************************* +// Include section +// system +#include "project_defs.h" + +#ifdef RAM_BASED_RFBSL + + +// driver +# include "display.h" + + +// ************************************************************************************************* +// Prototypes section + + +// ************************************************************************************************* +// Defines section + +// ************************************************************************************************* +// Global Variable section + +// Table with memory bit assignment for digits "0" to "9" and characters "A" to "Z" +const u8 lcd_font[] = +{ + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F, // Displays "0" + SEG_B + SEG_C, // Displays "1" + SEG_A + SEG_B + SEG_D + SEG_E + SEG_G, // Displays "2" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_G, // Displays "3" + SEG_B + SEG_C + SEG_F + SEG_G, // Displays "4" + SEG_A + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "5" + SEG_A + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "6" + SEG_A + SEG_B + SEG_C, // Displays "7" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "8" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "9" + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + 0, // Displays " " + SEG_D + SEG_E + SEG_G, // Displays "c" + 0, // Displays " " + SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G, // Displays "A" + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "b" + SEG_A + SEG_D + SEG_E + SEG_F, // Displays "C" + SEG_B + SEG_C + SEG_D + SEG_E + SEG_G, // Displays "d" + SEG_A + +SEG_D + SEG_E + SEG_F + SEG_G, // Displays "E" + SEG_A + SEG_E + SEG_F + SEG_G, // Displays "F" + // SEG_A+ SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "G" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "g" + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G, // Displays "H" + SEG_E + SEG_F, // Displays "I" + SEG_A + SEG_B + SEG_C + SEG_D, // Displays "J" + // SEG_B+SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "k" + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "k" + SEG_D + SEG_E + SEG_F, // Displays "L" + SEG_A + SEG_B + SEG_C + SEG_E + SEG_F, // Displays "M" + SEG_C + SEG_E + SEG_G, // Displays "n" + SEG_C + SEG_D + SEG_E + SEG_G, // Displays "o" + SEG_A + SEG_B + SEG_E + SEG_F + SEG_G, // Displays "P" + SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F, // Displays "Q" + SEG_E + SEG_G, // Displays "r" + SEG_A + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "S" + SEG_D + SEG_E + SEG_F + SEG_G, // Displays "t" + SEG_C + SEG_D + SEG_E, // Displays "u" + SEG_C + SEG_D + SEG_E, // Displays "u" + SEG_G, // Displays "-" + SEG_B + SEG_C + +SEG_E + SEG_F + SEG_G, // Displays "X" + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G, // Displays "Y" + SEG_A + SEG_B + SEG_D + SEG_E + SEG_G, // Displays "Z" +}; + + +// Table with memory address for each display element +const u8 * segments_lcdmem[] = +{ + LCD_SYMB_PERCENT_MEM, + LCD_ICON_BEEPER1_MEM, + LCD_ICON_BEEPER2_MEM, + LCD_ICON_BEEPER3_MEM, + LCD_SEG_L1_3_MEM, + LCD_SEG_L1_2_MEM, + LCD_SEG_L1_1_MEM, + LCD_SEG_L1_0_MEM, + LCD_SEG_L1_COL_MEM, + LCD_SEG_L1_DP1_MEM, + LCD_SEG_L1_DP0_MEM, + LCD_SEG_L2_5_MEM, + LCD_SEG_L2_4_MEM, + LCD_SEG_L2_3_MEM, + LCD_SEG_L2_2_MEM, + LCD_SEG_L2_1_MEM, + LCD_SEG_L2_0_MEM, + LCD_SEG_L2_COL1_MEM, + LCD_SEG_L2_COL0_MEM, + LCD_SEG_L2_DP_MEM, +}; + +// Table with bit mask for each display element +const u8 segments_bitmask[] = +{ + LCD_SYMB_PERCENT_MASK, + LCD_ICON_BEEPER1_MASK, + LCD_ICON_BEEPER2_MASK, + LCD_ICON_BEEPER3_MASK, + LCD_SEG_L1_3_MASK, + LCD_SEG_L1_2_MASK, + LCD_SEG_L1_1_MASK, + LCD_SEG_L1_0_MASK, + LCD_SEG_L1_COL_MASK, + LCD_SEG_L1_DP1_MASK, + LCD_SEG_L1_DP0_MASK, + LCD_SEG_L2_5_MASK, + LCD_SEG_L2_4_MASK, + LCD_SEG_L2_3_MASK, + LCD_SEG_L2_2_MASK, + LCD_SEG_L2_1_MASK, + LCD_SEG_L2_0_MASK, + LCD_SEG_L2_COL1_MASK, + LCD_SEG_L2_COL0_MASK, + LCD_SEG_L2_DP_MASK, +}; + +// Quick integer to array conversion table for most common integer values +const u8 itoa_conversion_table[][2] = +{ + "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", + "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", + "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", + "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", + "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", + "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", + "96", "97", "98", "99", +}; + +#endif //RAM_BASED_RFBSL diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/flash_based_lnkcc430F6137.xcl b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/flash_based_lnkcc430F6137.xcl new file mode 100755 index 0000000..b12b0ab --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/flash_based_lnkcc430F6137.xcl @@ -0,0 +1,161 @@ +//***************************************************************** +// +// XLINK command file for IAR Embedded Workbench for MSP430. +// +// This file should be used with the CC430F6137 microprocessor. +// +// Copyright 1996-2007 IAR Systems. All rights reserved. +// +// Usage: xlink your_file(s) -f lnkcc430f6137 library +// +// $Revision: 1.30 $ +// +//***************************************************************** + +//***************************************************************** +// +// The memory areas of the CC430F6137 microprocessor: +// +// Peripheral units: 0 - 01FF +// +// Information memory (FLASH): 1800 - 19FF +// +// Read-write memory (RAM): 1C00 - 2BFD +// +// Read-only memory (FLASH): 8000 - FF7F +// +// +//***************************************************************** + +//***************************************************************** +// +// The following segments are defined in this linker command file: +// +// Data read/write segments (RAM) +// ============================== +// +// segment Restrictions Usage +// ------- ------------ -------------------------- +// DATA16_I < 10000 Data16 initialized variables +// DATA16_Z < 10000 Data16 zero initialized variables +// DATA16_N < 10000 Data16 uninitialized variables +// DATA16_HEAP < 10000 Data16 heap used by malloc and free +// DATA20_I Data20 initialized variables +// DATA20_Z Data20 zero initialized variables +// DATA20_N Data20 uninitialized variables +// DATA20_HEAP Data20 heap used by malloc and free +// CSTACK < 10000 Runtime stack +// +// +// Program and data read-only segments (FLASH) +// =========================================== +// +// segment Restrictions Usage +// ------- ------------ -------------------------- +// INFO Information memory +// CSTART < 10000 Program startup code +// CODE Program code +// ISR_CODE < 10000 Program code for interrupt service routines +// DATA16_C < 10000 Data16 constant data and string literals +// DATA16_ID < 10000 Data16 initializers for DATA16_I +// DATA20_C Data20 constant data and string literals +// DATA20_ID Data20 initializers for DATA20_I +// DIFUNCT < 10000 Dynamic initialization vector used by C++ +// CHECKSUM Checksum byte(s) generated by the -J option +// INTVEC FF80-FFFF Interrupt vectors +// RESET FFFE-FFFF The reset vector +// +//***************************************************************** + + +// --------------------------------------------------------- +// Stack and heap sizes. +// --------------------------------------------------------- + +// Uncomment for command line use +//-D_STACK_SIZE=80 +//-D_DATA16_HEAP_SIZE=80 + + +// --------------------------------------------------------- +// Define cpu. +// --------------------------------------------------------- + +-cmsp430 + + +// --------------------------------------------------------- +// Read-write memory. +// --------------------------------------------------------- + +-Z(DATA)DATA16_I,DATA16_Z,DATA16_N,DATA16_HEAP+_DATA16_HEAP_SIZE=1C00-2B79 +-Z(DATA)CSTACK+_STACK_SIZE# + +-Z(DATA)RAM_INTERRUPT_VECTOR=2B80-2BFF + + +// --------------------------------------------------------- +// Read only memory + + +// --------------------------------------------------------- +// Information memory +// --------------------------------------------------------- + +-Z(CODE)INFO=1800-19FF +-Z(CODE)INFOA=1980-19FF +-Z(CODE)INFOB=1900-197F +-Z(CODE)INFOC=1880-18FF +-Z(CODE)INFOD=1800-187F + +// ------------------------------------------------------------------- +// BSL Memory +// ------------------------------------------------------------------- +-Z(CODE)ZAREA=1000-1005 +-Z(CODE)ZAREA_CODE=1006-102F +-Z(CODE)BSL0=1006-11FF +-Z(CODE)BSL1=1200-13FF +-Z(CODE)BSL2=1400-15FF +-Z(CODE)BSL3=1600-17EF + + +// --------------------------------------------------------- +// Code +// --------------------------------------------------------- + +-Z(CODE)CSTART,ISR_CODE=1020-17EF + +// --------------------------------------------------------- +// Constant data +// --------------------------------------------------------- + +-Z(CONST)DATA16_C,DATA16_ID,DIFUNCT,CHECKSUM=1020-17EF + + +// --------------------------------------------------------- +// Code +// --------------------------------------------------------- +-P(CODE)CODE=1006-17EF + + +// --------------------------------------------------------- +// Interrupt vectors +// --------------------------------------------------------- +-Z(CODE)INTVEC=FF80-FFFF +-Z(CODE)RESET=FFD8-FFD9 + +-Z(CONST)BSLSIG=0x17F0-17FB + // contains: + // BSL Start Vector + // BSL Unlock Function Vector + // BSL Unlock Signature 1 + // BSL Unlock Signature 2 + +-Z(CONST)JTAGLOCK_KEY=0x17FC-17FF + // if it contains: + // 0x0000 0x0000 or + // 0xFFFF 0xFFFF the JTAG will be unlocked otherwise JTAG is locked + +// --------------------------------------------------------- +// The end +// --------------------------------------------------------- diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/project_defs.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/project_defs.h new file mode 100755 index 0000000..a495a8a --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/project_defs.h @@ -0,0 +1,35 @@ +#ifndef PROJECT_DEFS_H_ +#define PROJECT_DEFS_H_ + +#include + +#define u8 unsigned char +#define u16 unsigned int +#define u32 unsigned long int + +// Conversion from usec to ACLK timer ticks +#define CONV_US_TO_TICKS(usec) (((usec) * 32768) / 1000000) + +// Conversion from msec to ACLK timer ticks +#define CONV_MS_TO_TICKS(msec) (((msec) * 32768) / 1000) + +#define st(x) do { x } while (__LINE__ == -1) +#define ENTER_CRITICAL_SECTION(x) st( \ + x = __get_interrupt_state(); __disable_interrupt(); ) +#define EXIT_CRITICAL_SECTION(x) __set_interrupt_state(x) + +#define BV(x) (1 << (x)) + +// Use CCA to sense the traffic before transmitting +#define CCA + + +// This Macro is defined of undefined using the active configuration of CCS, if not implemented this +// way define it here +//#define RAM_BASED_RFBSL + +// Testing +//#define TESTING_INTERRUPT_CATCHER + + +#endif /*PROJECT_DEFS_H_*/ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/radio.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/radio.c new file mode 100755 index 0000000..f0ef0c0 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/radio.c @@ -0,0 +1,191 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// system +#include "project_defs.h" + +// driver +#include "rf1a.h" +#include "radio.h" + +// logic +#include "wbsl.h" + + +//RF Test Values +const u8 RF1A_REG_SMARTRF_SETTING[][2] = +{ + /* internal radio configuration */ + { IOCFG0, SMARTRF_SETTING_IOCFG0 }, /* Configure GDO_0 to output PA_PD signal (low during + *TX, high otherwise). */ + { IOCFG1, SMARTRF_SETTING_IOCFG1 }, /* Configure GDO_1 to output RSSI_VALID signal (high + *when RSSI is valid, low otherwise). */ + { IOCFG2, SMARTRF_SETTING_IOCFG2 }, + { MCSM2, SMARTRF_SETTING_MCSM2 }, + { MCSM1, SMARTRF_SETTING_MCSM1 }, /* CCA mode, RX_OFF_MODE and TX_OFF_MODE */ + { MCSM0, SMARTRF_SETTING_MCSM0 }, /* AUTO_CAL and XOSC state in sleep */ + { SYNC1, 0xD3 }, + { SYNC0, 0x91 }, + { PKTLEN, SMARTRF_SETTING_PKTLEN }, + { PKTCTRL1, SMARTRF_SETTING_PKTCTRL1 }, + { PKTCTRL0, SMARTRF_SETTING_PKTCTRL0 }, + { ADDR, SMARTRF_SETTING_ADDR }, + { FIFOTHR, SMARTRF_SETTING_FIFOTHR }, + { WOREVT1, SMARTRF_SETTING_WOREVT1 }, + { WOREVT0, SMARTRF_SETTING_WOREVT0 }, + { WORCTRL, SMARTRF_SETTING_WORCTL }, + /* imported SmartRF radio configuration */ + { CHANNR, SMARTRF_SETTING_CHANNR }, + { FSCTRL1, SMARTRF_SETTING_FSCTRL1 }, + { FSCTRL0, SMARTRF_SETTING_FSCTRL0 }, + { FREQ2, SMARTRF_SETTING_FREQ2 }, + { FREQ1, SMARTRF_SETTING_FREQ1 }, + { FREQ0, SMARTRF_SETTING_FREQ0 }, + { MDMCFG4, SMARTRF_SETTING_MDMCFG4 }, + { MDMCFG3, SMARTRF_SETTING_MDMCFG3 }, + { MDMCFG2, SMARTRF_SETTING_MDMCFG2 }, + { MDMCFG1, SMARTRF_SETTING_MDMCFG1 }, + { MDMCFG0, SMARTRF_SETTING_MDMCFG0 }, + { DEVIATN, SMARTRF_SETTING_DEVIATN }, + + { FOCCFG, SMARTRF_SETTING_FOCCFG }, + { BSCFG, SMARTRF_SETTING_BSCFG }, + { AGCCTRL2, SMARTRF_SETTING_AGCCTRL2 }, + { AGCCTRL1, SMARTRF_SETTING_AGCCTRL1 }, + { AGCCTRL0, SMARTRF_SETTING_AGCCTRL0 }, + { FREND1, SMARTRF_SETTING_FREND1 }, + { FREND0, SMARTRF_SETTING_FREND0 }, + { FSCAL3, SMARTRF_SETTING_FSCAL3 }, + { FSCAL2, SMARTRF_SETTING_FSCAL2 }, + { FSCAL1, SMARTRF_SETTING_FSCAL1 }, + { FSCAL0, SMARTRF_SETTING_FSCAL0 }, + { AGCTEST, SMARTRF_SETTING_AGCTEST }, + { PTEST, SMARTRF_SETTING_PTEST }, + { FSTEST, SMARTRF_SETTING_FSTEST }, + { TEST2, SMARTRF_SETTING_TEST2 }, + { TEST1, SMARTRF_SETTING_TEST1 }, + { TEST0, SMARTRF_SETTING_TEST0 }, +}; +// ************************************************************************************************* +// @fn radio_reset +// @brief Reset radio core. +// @param none +// @return none +// ************************************************************************************************* +void radio_reset(void) +{ + volatile u16 i; + u8 x; + + // Clear any radio pending interrupt + RF1AIFG = 0; + + // Reset radio core + Strobe(RF_SRES); + // Wait before checking IDLE + for (i = 0; i < 100; i++) ; + + do { + x = Strobe(RF_SIDLE); + } while ((x & 0x70) != 0x00); + + // Clear radio error register + RF1AIFERR = 0; +} + +// ************************************************************************************************* +// @fn WriteSmartRFReg +// @brief Writes all the Radio Settings to the Radio module +// @param none +// @return none +// ************************************************************************************************* +void WriteSmartRFReg(const u8 SmartRFSetting[][2], u8 size) +{ + u8 i; + + for (i = 0; i < (size); i++) + WriteSingleReg(SmartRFSetting[i][0], SmartRFSetting[i][1]); +} + +// ************************************************************************************************* +// @fn config_radio_wbsl +// @brief Configure the RF Module to start the WBSL Process +// @param none +// @return none +// ************************************************************************************************* +void config_radio_wbsl(void) +{ + WritePATable(WBSL_SETTING_PATABLE); + WriteSmartRFReg(RF1A_REG_SMARTRF_SETTING, sizeof(RF1A_REG_SMARTRF_SETTING) / 2); +} + +// ************************************************************************************************* +// @fn ReceiveOn +// @brief Put Radio in RX Mode +// @param none +// @return none +// ************************************************************************************************* +void ReceiveOn(void) +{ + RF1AIFG = 0; //&= ~BIT9; // Clear a pending interrupt + // Update Mode Flag + wbslMode_flag = WBSL_RX_MODE; + Strobe(RF_SRX); +} + +// ************************************************************************************************* +// @fn ReceiveOff +// @brief Put Radio in Idle Mode +// @param none +// @return none +// ************************************************************************************************* +void ReceiveOff(void) +{ + u8 x; + + // Update Mode Flag + wbslMode_flag = WBSL_IDLE_MODE; + do { + x = Strobe(RF_SIDLE); + } while (x & 0x70); + /* Wait for XOSC to be stable and radio in IDLE state */ + + Strobe(RF_SFRX); /* Flush the receive FIFO of any residual data */ + + RF1AIFG = 0; // Clear pending IFG +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/radio.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/radio.h new file mode 100755 index 0000000..6f9d0e2 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/radio.h @@ -0,0 +1,150 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef RADIO_H_ +#define RADIO_H_ + +#define SMARTRF_RADIO_CC430 + +#define SMARTRF_SETTING_FSCTRL1 0x0C // +#define SMARTRF_SETTING_FSCTRL0 0x00 // + + +#ifdef ISM_EU +/* #define SMARTRF_SETTING_FREQ2 0x21 // 868 Mhz + #define SMARTRF_SETTING_FREQ1 0x62 // + #define SMARTRF_SETTING_FREQ0 0x76 // + #define SMARTRF_SETTING_CHANNR 0 // + #define WBSL_SETTING_PATABLE 0x8C // +*/ + #define SMARTRF_SETTING_FREQ2 0x21 // 869.525 Mhz + #define SMARTRF_SETTING_FREQ1 0x71 // + #define SMARTRF_SETTING_FREQ0 0x7A // + #define SMARTRF_SETTING_CHANNR 0 // + #define WBSL_SETTING_PATABLE 0x8C // + +#else + #ifdef ISM_US +/* #define SMARTRF_SETTING_FREQ2 0x23 // 915 Mhz + #define SMARTRF_SETTING_FREQ1 0x31 // + #define SMARTRF_SETTING_FREQ0 0x3B // + #define SMARTRF_SETTING_CHANNR 20 // + #define WBSL_SETTING_PATABLE 0x8B // +*/ + #define SMARTRF_SETTING_FREQ2 0x22 // 902 Mhz --> 906 MHz (CHANNR = 20) + #define SMARTRF_SETTING_FREQ1 0xB1 // + #define SMARTRF_SETTING_FREQ0 0x3B // + #define SMARTRF_SETTING_CHANNR 20 // + #define WBSL_SETTING_PATABLE 0x8B // + + #else + #ifdef ISM_LF + // 433.92MHz + #define SMARTRF_SETTING_FREQ2 0x10 + #define SMARTRF_SETTING_FREQ1 0xB0 + #define SMARTRF_SETTING_FREQ0 0x71 + #define SMARTRF_SETTING_CHANNR 0 + #define WBSL_SETTING_PATABLE 0x8D + + #else + #ifdef RAM_BASED_RFBSL // We don't need these values on the RAM_BASED_RFBSL, but need to define STUBS to make it compile + #define SMARTRF_SETTING_FREQ2 0x00 // + #define SMARTRF_SETTING_FREQ1 0x00 // + #define SMARTRF_SETTING_FREQ0 0x00 // + #define SMARTRF_SETTING_CHANNR 0x00 // + #define WBSL_SETTING_PATABLE 0x00 // + #else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" + #endif // RAM_BASED_RFBSL + #endif // ISM_LF + #endif // ISM_US +#endif // ISM_EU + + +#define SMARTRF_SETTING_MDMCFG4 0x2D // +#define SMARTRF_SETTING_MDMCFG3 0x3B // +#define SMARTRF_SETTING_MDMCFG2 0x13 // +#define SMARTRF_SETTING_MDMCFG1 0x22 // +#define SMARTRF_SETTING_MDMCFG0 0xF8 // + + + +#define SMARTRF_SETTING_DEVIATN 0x62 // +#define SMARTRF_SETTING_FREND1 0xB6 // +#define SMARTRF_SETTING_FREND0 0x10 // +#define SMARTRF_SETTING_MCSM0 0x18 // +#define SMARTRF_SETTING_MCSM1 0x3C // +#define SMARTRF_SETTING_MCSM2 0x07 // +#define SMARTRF_SETTING_WOREVT1 0x87 // +#define SMARTRF_SETTING_WOREVT0 0x6B // +#define SMARTRF_SETTING_WORCTL 0xF8 /* Note: WOR not supported on CC430 */ +#define SMARTRF_SETTING_FOCCFG 0x1D // +#define SMARTRF_SETTING_BSCFG 0x1C // +#define SMARTRF_SETTING_AGCCTRL2 0xC7 // +#define SMARTRF_SETTING_AGCCTRL1 0x00 // +#define SMARTRF_SETTING_AGCCTRL0 0xB0 // +#define SMARTRF_SETTING_FSCAL3 0xEA // +#define SMARTRF_SETTING_FSCAL2 0x2A // +#define SMARTRF_SETTING_FSCAL1 0x00 // +#define SMARTRF_SETTING_FSCAL0 0x1F // +#define SMARTRF_SETTING_FSTEST 0x59 // +#define SMARTRF_SETTING_TEST2 0x88 // +#define SMARTRF_SETTING_TEST1 0x31 // +#define SMARTRF_SETTING_TEST0 0x09 // +#define SMARTRF_SETTING_PTEST 0x7F // +#define SMARTRF_SETTING_AGCTEST 0x88 // +#define SMARTRF_SETTING_FIFOTHR 0x07 // +#define SMARTRF_SETTING_IOCFG2 0x29 // +#define SMARTRF_SETTING_IOCFG1 0x1E // +#define SMARTRF_SETTING_IOCFG0 0x1B // +#define SMARTRF_SETTING_PKTCTRL1 0x05 // Address Check and Append Status +#define SMARTRF_SETTING_PKTCTRL0 0x45 // +#define SMARTRF_SETTING_ADDR WBSL_ED_ADDRESS // +#define SMARTRF_SETTING_PKTLEN 0xFE // + + +extern void radio_reset(void); +extern void radio_sxoff(void); +extern void open_radio(void); +extern void close_radio(void); + + +void config_radio_wbsl(void); +void stop_radio_wbsl(void); +void WriteSmartRFReg(const u8 SmartRFSetting[][2], u8 size); +void ReceiveOn(void); +void ReceiveOff(void); + +#endif /*RADIO_H_*/ diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/ram_based_lnkcc430F6137.xcl b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/ram_based_lnkcc430F6137.xcl new file mode 100755 index 0000000..1032924 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/ram_based_lnkcc430F6137.xcl @@ -0,0 +1,145 @@ +//***************************************************************** +// +// XLINK command file for IAR Embedded Workbench for MSP430. +// +// This file should be used with the CC430F6137 microprocessor. +// +// Copyright 1996-2007 IAR Systems. All rights reserved. +// +// Usage: xlink your_file(s) -f lnkcc430f6137 library +// +// $Revision: 1.30 $ +// +//***************************************************************** + +//***************************************************************** +// +// The memory areas of the CC430F6137 microprocessor: +// +// Peripheral units: 0 - 01FF +// +// Information memory (FLASH): 1800 - 19FF +// +// Read-write memory (RAM): 1C00 - 2BFD +// +// Read-only memory (FLASH): 8000 - FF7F +// +// +//***************************************************************** + +//***************************************************************** +// +// The following segments are defined in this linker command file: +// +// Data read/write segments (RAM) +// ============================== +// +// segment Restrictions Usage +// ------- ------------ -------------------------- +// DATA16_I < 10000 Data16 initialized variables +// DATA16_Z < 10000 Data16 zero initialized variables +// DATA16_N < 10000 Data16 uninitialized variables +// DATA16_HEAP < 10000 Data16 heap used by malloc and free +// DATA20_I Data20 initialized variables +// DATA20_Z Data20 zero initialized variables +// DATA20_N Data20 uninitialized variables +// DATA20_HEAP Data20 heap used by malloc and free +// CSTACK < 10000 Runtime stack +// +// +// Program and data read-only segments (FLASH) +// =========================================== +// +// segment Restrictions Usage +// ------- ------------ -------------------------- +// INFO Information memory +// CSTART < 10000 Program startup code +// CODE Program code +// ISR_CODE < 10000 Program code for interrupt service routines +// DATA16_C < 10000 Data16 constant data and string literals +// DATA16_ID < 10000 Data16 initializers for DATA16_I +// DATA20_C Data20 constant data and string literals +// DATA20_ID Data20 initializers for DATA20_I +// DIFUNCT < 10000 Dynamic initialization vector used by C++ +// CHECKSUM Checksum byte(s) generated by the -J option +// INTVEC FF80-FFFF Interrupt vectors +// RESET FFFE-FFFF The reset vector +// +//***************************************************************** + + +// --------------------------------------------------------- +// Stack and heap sizes. +// --------------------------------------------------------- + +// Uncomment for command line use +//-D_STACK_SIZE=80 +//-D_DATA16_HEAP_SIZE=80 + + +// --------------------------------------------------------- +// Define cpu. +// --------------------------------------------------------- + +-cmsp430 + + +// --------------------------------------------------------- +// Read-write memory. +// --------------------------------------------------------- + +-Z(DATA)DATA16_I,DATA16_Z,DATA16_N,DATA16_HEAP+_DATA16_HEAP_SIZE=2951-2BFE +-Z(DATA)CSTACK+_STACK_SIZE# + + +// --------------------------------------------------------- +// Read only memory + + +// --------------------------------------------------------- +// Information memory +// --------------------------------------------------------- + +-Z(CODE)INFO=1800-19FF +-Z(CODE)INFOA=1980-19FF +-Z(CODE)INFOB=1900-197F +-Z(CODE)INFOC=1880-18FF +-Z(CODE)INFOD=1800-187F + +// --------------------------------------------------------- +// Code +// --------------------------------------------------------- + +-Z(CODE)CSTART,ISR_CODE=1D30-2950 + +// --------------------------------------------------------- +// Constant data +// --------------------------------------------------------- + +-Z(CONST)DATA16_C,DATA16_ID,DIFUNCT,CHECKSUM=1D30-2950 + +// ------------------------------------------------------------------- +// BSL Memory +// ------------------------------------------------------------------- +//-Z(CODE)ZAREA=1000-100F +//-Z(CODE)ZAREA_CODE=1010-102F + + +// --------------------------------------------------------- +// Code +// --------------------------------------------------------- + +-P(CODE)CODE=1D30-2950 + + +// --------------------------------------------------------- +// Interrupt vectors +// --------------------------------------------------------- + +-Z(CODE)INTVEC=FF80-FFFF +-Z(CODE)RESET=FFFE-FFFF + + +// --------------------------------------------------------- +// The end +// --------------------------------------------------------- diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/rf1a.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/rf1a.c new file mode 100755 index 0000000..b191f8d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/rf1a.c @@ -0,0 +1,214 @@ +// ************************************************************************************************* +// +// Actual revision: $Revision: $ +// Revision label: $Name: $ +// Revision state: $State: $ +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + + +// ************************************************************************************************* +// Include section + +// system +#include "project_defs.h" + +// driver +#include "rf1a.h" +#include "wbsl.h" +// ************************************************************************************************* +// Global section + + +// ************************************************************************************************* +// @fn Strobe +// @brief Send command to radio. +// @param none +// @return none +// ************************************************************************************************* +u8 Strobe(u8 strobe) +{ + u8 statusByte = 0; + u16 int_state, gdo_state; + + // Check for valid strobe command + if ((strobe == 0xBD) || ((strobe > RF_SRES) && (strobe < RF_SNOP))) + { + ENTER_CRITICAL_SECTION(int_state); + + // Clear the Status read flag + RF1AIFCTL1 &= ~(RFSTATIFG); + + // Wait for radio to be ready for next instruction + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + + // Write the strobe instruction + if ((strobe > RF_SRES) && (strobe < RF_SNOP)) + { + + gdo_state = ReadSingleReg(IOCFG2); // buffer IOCFG2 state + WriteSingleReg(IOCFG2, 0x29); // c-ready to GDO2 + + RF1AINSTRB = strobe; + if ((RF1AIN & 0x04) == 0x04) // chip at sleep mode + { + if ((strobe == RF_SXOFF) || (strobe == RF_SPWD) || (strobe == RF_SWOR)){ } + else + { + while ((RF1AIN & 0x04) == 0x04) ; // c-ready ? + __delay_cycles(9800); // Delay for ~810usec at 12MHz CPU clock + } + } + WriteSingleReg(IOCFG2, gdo_state); // restore IOCFG2 setting + } + else // chip active mode + { + RF1AINSTRB = strobe; + } + statusByte = RF1ASTATB; + + EXIT_CRITICAL_SECTION(int_state); + } + return statusByte; +} + +// ************************************************************************************************* +// @fn ResetRadioCore +// @brief Software reset radio core. +// @param none +// @return none +// ************************************************************************************************* + +/* + * void ResetRadioCore(void) + * { + * Strobe(RF_SRES); // Reset the Radio Core + * Strobe(RF_SNOP); // Reset Radio Pointer + * } + */ + +// ************************************************************************************************* +// @fn ReadSingleReg +// @brief Read byte from register. +// @param none +// @return none +// ************************************************************************************************* +u8 ReadSingleReg(u8 addr) +{ + u8 x; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + + if ((addr <= 0x2E) || (addr == 0x3E)) + { + RF1AINSTR1B = (addr | RF_SNGLREGRD); + } + else + { + RF1AINSTR1B = (addr | RF_REGRD); + } + + x = RF1ADOUTB; + //RF1ADINB = 0; //dummy write + EXIT_CRITICAL_SECTION(int_state); + + return x; +} + +// ************************************************************************************************* +// @fn WriteSingleReg +// @brief Write byte to register. +// @param none +// @return none +// ************************************************************************************************* +void WriteSingleReg(u8 addr, u8 value) +{ + volatile u16 i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for the next + // instruction + + RF1AINSTRW = ((addr | RF_REGWR) << 8) + value; // Send address + Instruction + while (!(RFDINIFG & RF1AIFCTL1)) ; + + i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status + // byte + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn WriteBurstReg +// @brief Write sequence of bytes to register. +// @param none +// @return none +// ************************************************************************************************* +void WriteBurstReg(u8 addr, u8 *buffer, u8 count) +{ + // Write Burst works wordwise not bytewise - bug known already + u8 i; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; // Wait for the Radio to be ready for next + // instruction + RF1AINSTRW = ((addr | RF_REGWR) << 8) + buffer[0]; // Send address + Instruction + + for (i = 1; i < count; i++) + { + while (!(RFDINIFG & RF1AIFCTL1)) ; // Wait for TX to finish + RF1ADINB = buffer[i]; // Send data + } + i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status + // byte + + EXIT_CRITICAL_SECTION(int_state); +} + +// ************************************************************************************************* +// @fn WritePATable +// @brief Write data to power table +// @param u8 value Value to write +// @return none +// ************************************************************************************************* +void WritePATable(u8 value) +{ + u8 readbackPATableValue = 0; + u16 int_state; + + ENTER_CRITICAL_SECTION(int_state); + + while (readbackPATableValue != value) + { + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRW = 0x7E00 + value; // PA Table write (burst) + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; // reset pointer + + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = 0xFE; // PA Table read (burst) + + while (!(RF1AIFCTL1 & RFDINIFG)) ; + RF1ADINB = 0x00; //dummy write + + while (!(RF1AIFCTL1 & RFDOUTIFG)) ; + readbackPATableValue = RF1ADOUT0B; + + while (!(RF1AIFCTL1 & RFINSTRIFG)) ; + RF1AINSTRB = RF_SNOP; + } + + EXIT_CRITICAL_SECTION(int_state); +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/rf1a.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/rf1a.h new file mode 100755 index 0000000..64f7fa8 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/rf1a.h @@ -0,0 +1,21 @@ +// ************************************************************************************************* +// +// Actual revision: $Revision: $ +// Revision label: $Name: $ +// Revision state: $State: $ +// +// ************************************************************************************************* +// Radio core access functions. Taken from TI reference code for CC430. +// ************************************************************************************************* + +// ************************************************************************************************* +// Prototype section +u8 Strobe(u8 strobe); +u8 ReadSingleReg(u8 addr); +void WriteSingleReg(u8 addr, u8 value); +void ReadBurstReg(u8 addr, u8 *buffer, u8 count); +void WriteBurstReg(u8 addr, u8 *buffer, u8 count); +void ResetRadioCore(void); +void WritePATable(u8 value); +void WaitForXT2(void); +void Transmit(u8 *buffer, u8 length); diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.cspy.bat b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.cspy.bat new file mode 100755 index 0000000..04d300e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.cspy.bat @@ -0,0 +1,15 @@ +@REM This batch file has been generated by the IAR Embedded Workbench +@REM C-SPY Debugger, as an aid to preparing a command line for running +@REM the cspybat command line utility using the appropriate settings. +@REM +@REM You can launch cspybat by typing the name of this batch file followed +@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). +@REM Note that this file is generated every time a new debug session +@REM is initialized, so you may want to move or rename the file before +@REM making changes. +@REM + + +"C:\Program Files\IAR Systems\Embedded Workbench 6.0\common\bin\cspybat" "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\bin\430proc.dll" "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\bin\430sim.dll" %1 --plugin "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\bin\430bat.dll" --backend -B "-p" "C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\config\CC430F6137.ddf" "--core=430Xv2" "--data_model=small" "--iv_base" "0xFF80" "--no_wrap_around" "--odd_word_check" "-d" "sim" "--derivativeSim" "CC430F6137" + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.dbgdt b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.dbgdt new file mode 100755 index 0000000..40b907d --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.dbgdt @@ -0,0 +1,89 @@ + + + + + + + + + 201222 + + 20 + 916 + 244 + 61 + + + + + + + + 124272727 + + + + + + 100 + + + + + + + + + TabID-21663-24053 + Debug Log + Debug-Log + + + + TabID-9346-24079 + Build + Build + + + + + 0 + + + TabID-32411-24056 + Workspace + Workspace + + + Wireless_UpdateWireless_Update/Output + + + + 0 + + + TabID-10392-24059 + Disassembly + Disassembly + + + + + 0 + + + + + + TextEditor$WS_DIR$\RFBSL_Low_Level_Init.s430314571457TextEditor$WS_DIR$\868MHz Flash Based Updater\List\flash_based_rfbsl_ism_eu.map01312683686836810100000010000001 + + + + + + + iaridepm.enu1debuggergui.enu1430fet1-2-2668198-2-2200200156250208768156250699374-2-2668198-2-2200200156250208768156250699374-2-21981282-2-212842001003125208768156250208768 + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.dni b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.dni new file mode 100755 index 0000000..3602a0e --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.dni @@ -0,0 +1,81 @@ +[State Storage] +Control Register=0 +[Sequencer] +Control Register=0 +NextState0=0 +NextState1=0 +[Action Register] +Break=0 +State Storage=0 +[DebugChecksum] +Checksum=1750648671 +[DisAssemblyWindow] +NumStates=_ 1 +State 1=_ 1 +[InstructionProfiling] +Enabled=_ 0 +[CodeCoverage] +Enabled=_ 0 +[Profiling] +Enabled=0 +[StackPlugin] +Enabled=1 +OverflowWarningsEnabled=1 +WarningThreshold=90 +SpWarningsEnabled=1 +WarnHow=0 +UseTrigger=1 +TriggerName=main +LimitSize=0 +ByteLimit=50 +[Log file] +LoggingEnabled=_ 0 +LogFile=_ "" +Category=_ 0 +[TermIOLog] +LoggingEnabled=_ 0 +LogFile=_ "" +[FET] +Clock mode=14 +Extended Clock mode=-1 +Secure Password= +Extended Clock Control Enable=1 +Advanced Extended Clock Control=0 +Emulation mode=0 +Free running=0 +Shutting Down=3 +[Memory Dump] +Start address= +Lenghth= +Address info=0 +Format=0 +Dump registers=0 +PC=0 +SP=0 +SR=0 +all registers=0 +File name= +[InterruptLog] +LogEnabled=0 +SumEnabled=0 +GraphEnabled=0 +ShowTimeLog=1 +ShowTimeSum=1 +SumSortOrder=0 +[Breakpoints] +Count=0 +[Interrupts] +Enabled=1 +[MemoryMap] +Enabled=0 +Base=0 +UseAuto=0 +TypeViolation=1 +UnspecRange=1 +ActionState=1 +[Aliases] +Count=0 +SuppressDialog=0 +[TraceHelper] +Enabled=0 +ShowSource=1 diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.wsdt b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.wsdt new file mode 100755 index 0000000..6e957a1 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/Wireless_Update.wsdt @@ -0,0 +1,66 @@ + + + + + + Wireless_Update/433MHz Flash Based Updater + + + + + + + + + 25727271242260 + + + + + + + 2091524461 + 211221 + + + + + + + TabID-13995-11954 + Workspace + Workspace + + + Wireless_Update + + + + 0 + + + TabID-11903-11993 + Build + Build + + + TabID-6546-5487Debug LogDebug-LogTabID-24855-28189Tool OutputTool-Output + + 0 + + + + + + TextEditor$WS_DIR$\radio.c01386412641200100000010000001 + + + + + + + iaridepm.enu1-2-2460331-2-2200202156250210856260156482255-2-24541282-2-212844561003125475992156250210856 + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.cspy.bat b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.cspy.bat new file mode 100755 index 0000000..14f4adc --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.cspy.bat @@ -0,0 +1,34 @@ +@REM This bat file has been generated by the IAR Embeddded Workbench +@REM C-SPY interactive debugger,as an aid to preparing a command +@REM line for running the cspybat command line utility with the +@REM appropriate settings. +@REM +@REM After making some adjustments to this file, you can launch cspybat +@REM by typing the name of this file followed by the name of the debug +@REM file (usually an ubrof file). Note that this file is generated +@REM every time a new debug session is initialized, so you may want to +@REM move or rename the file before making changes. +@REM +@REM Note: some command line arguments cannot be properly generated +@REM by this process. Specifically, the plugin which is responsible +@REM for the Terminal I/O window (and other C runtime functionality) +@REM comes in a special version for cspybat, and the name of that +@REM plugin dll is not known when generating this file. It resides in +@REM the $TOOLKIT_DIR$\bin folder and is usually called XXXbat.dll or +@REM XXXlibsupportbat.dll, where XXX is the name of the corresponding +@REM tool chain. Replace the '' parameter +@REM below with the appropriate file name. Other plugins loaded by +@REM C-SPY are usually not needed by, or will not work in, cspybat +@REM but they are listed at the end of this file for reference. + + +"C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\common\bin\cspybat" "C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\430\bin\430proc.dll" "C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\430\bin\430fet.dll" %1 --plugin "C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\430\bin\" --backend -B "-p" "C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\430\config\CC430F6137.ddf" "--core=430Xv2" "--data_model=small" "--iv_base" "0xFF80" "--no_wrap_around" "-d" "fet" "--erase_main" "--derivative" "CC430F6137" "--protocol" "spy-bi-wire" "--eem" "EMEX_LOW" "--port" "HID0012" "--connection" "ti_usb" "--settlingtime=0" "--allow_access_to_BSL" + + +@REM Loaded plugins: +@REM C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\430\bin\430libsupport.dll +@REM C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\430\plugins\lcd\lcd.dll +@REM C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\common\plugins\CodeCoverage\CodeCoverage.dll +@REM C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\common\plugins\Profiling\Profiling.dll +@REM C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\common\plugins\stack\stack.dll +@REM C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\common\plugins\SymList\SymList.dll diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.dbgdt b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.dbgdt new file mode 100755 index 0000000..00f7214 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.dbgdt @@ -0,0 +1,89 @@ + + + + + + + + + 201221 + + 20 + 915 + 244 + 61 + + + + + + + + 156272727 + + + + + + 100 + 200{W}Watch-0:RxBufferLength3{W}Watch-1:*((unsigned int *)0x294E)4{W}Watch-1:*((unsigned int *)0x294F)4{W}Watch-1:*((unsigned int *)0x2950)4{W}Watch-1:*((unsigned int *)0x2951)4{W}Watch-1:*((unsigned int *)0x2953)4{W}Watch-1:*((unsigned int *)0x2955)4{W}Watch-1:*((unsigned int *)0x2957)4{W}Watch-1:*((unsigned int *)0x2959)4{W}Watch-1:*((unsigned int *)0x295B)4{W}Watch-1:*((unsigned int *)0x29FE)4{W}Watch-1:*((unsigned int *)0x8000)4{W}Watch-1:*data4{W}Watch-1:P2IFG1{W}Watch-1:RxBufferLength3{W}Watch-1:size3200Locals10010010010010200Watch10010010010021630370 + + + + + + + + TabID-8687-22903 + Debug Log + Debug-Log + + + + TabID-18912-22916 + Build + Build + + + TabID-20193-4795BreakpointsBreakpointsTabID-3275-21487Find in FilesFind-in-Files + + 0 + + + TabID-19435-22906 + Workspace + Workspace + + + flash_based_rfbslflash_based_rfbsl/Output + + + + 0 + + + TabID-30183-22909 + Disassembly + Disassembly + + + + + 0TabID-5377-26173MemoryMemory0409640961000002470TabID-6016-9768WatchWatchpacketSizepayloadStartptrRamstartAddrsizedataiRxBufferpayloadBuffertotalPacketscurrentPacketdiscoveryReplyibuffer+7lengthmax_link_attemptsinitOkrxtx_flagRxBufferLengthackReplymax_link_attemptsRxBufferptrMemoryP2IFGP2IE11001001001000TabID-24163-19464RegisterRegister00000 + + + + + + 0100000010000001 + + + + + + + iaridepm.enu1debuggergui.enu1-2-2514230-2-2081098301161111626214-2-2514381-2-2081098301265972626214-2379514619379-261144167138350166667626214-2617514858617-25414937500180825167361626214-2-2242722-2-27242445027782961170983010002720-27222445013892961170104369 + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.dni b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.dni new file mode 100755 index 0000000..5dbb325 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.dni @@ -0,0 +1,77 @@ +[DebugChecksum] +Checksum=326321235 +[State Storage] +Control Register=0 +[Sequencer] +Control Register=0 +NextState0=0 +NextState1=0 +[Action Register] +Break=3 +State Storage=0 +[DisAssemblyWindow] +NumStates=_ 1 +State 1=_ 1 +[InstructionProfiling] +Enabled=_ 0 +[CodeCoverage] +Enabled=_ 0 +[Profiling] +Enabled=0 +[StackPlugin] +Enabled=1 +OverflowWarningsEnabled=1 +WarningThreshold=90 +SpWarningsEnabled=1 +WarnHow=0 +UseTrigger=1 +TriggerName=main +LimitSize=0 +ByteLimit=50 +[TermIOLog] +LoggingEnabled=_ 0 +LogFile=_ "" +[DriverProfiling] +Enabled=0 +Source=1 +Graph=0 +[Interrupts] +Enabled=1 +[MemoryMap] +Enabled=0 +Base=0 +UseAuto=0 +TypeViolation=1 +UnspecRange=1 +ActionState=1 +[TraceHelper] +Enabled=0 +ShowSource=1 +[Log file] +LoggingEnabled=_ 0 +LogFile=_ "" +Category=_ 0 +[Breakpoints] +Bp0=_ "STD_CODE" "{$PROJ_DIR$\wbsl.c}.145.3@1" 0 0 0 0 "" 0 "" +Bp1=_ "STD_CODE" "{$PROJ_DIR$\RFBSL_Low_Level_Init.s43}.25.1@1" 0 0 0 0 "" 0 "" +Count=2 +[FET] +Clock mode=14 +Extended Clock mode=61663 +Secure Password= +Extended Clock Control Enable=1 +Advanced Extended Clock Control=0 +Emulation mode=0 +Free running=0 +Shutting Down=3 +[Memory Dump] +Start address= +Lenghth= +Address info=0 +Format=0 +Dump registers=0 +PC=0 +SP=0 +SR=0 +all registers=0 +File name= diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.wsdt b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.wsdt new file mode 100755 index 0000000..44c7243 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/settings/flash_based_rfbsl.wsdt @@ -0,0 +1,61 @@ + + + + + + flash_based_rfbsl/FLASH_BASED_RFBSL_ISM_EU + + + + + + + + + 40121801242260 + + + + + + + 2091524461 + 19122244062754100 + + + + + + + + TabID-2601-19128 + Build + Build + + TabID-17364-20199Find in FilesFind-in-FilesTabID-6287-8523Debug LogDebug-Log + + 2 + TabID-32336-18161 + Workspace + Workspace + + + flash_based_rfbsl + 0 + + + + + + 0100000010000001 + + + + + + + iaridepm.enu1-2-2557522-2-2460198319444240291363889678398-2-22231442-2-214442251002778273058549306813107 + + + + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/wbsl.c b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/wbsl.c new file mode 100755 index 0000000..7c3b6ea --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/wbsl.c @@ -0,0 +1,1154 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// WBSL functions. +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section + +// system +#include "project_defs.h" +#include +#include "intrinsics.h" + +#ifdef RAM_BASED_RFBSL +# include "display.h" +#endif + +// driver +#include "radio.h" +#include "rf1a.h" + +// logic +#include "wbsl.h" + +// ************************************************************************************************* +// Global Variable section +struct RFwbsl sRFwbsl = { WBSL_OFF, 0, 0 }; + +// Rx Buffer to store Received Packages, make sure it starts on an even address so that the payload +// can be written to flash +// with no issues +#pragma data_alignment=2 +u8 RxBuffer[258] = {0}; + +u8 RxBufferLength = 0; + +// Pointer to write to RAM/Flash +u8 *ptrMemory = (u8 *) 0x0; + +//Address to branch to start RAM Based BSL +u16 start_ram_bsl_address = 0; + +//u8 discoveryPayload[4] = {0xDE,0xAD,0xBE,0xEF}; +u8 discoveryPayload[4] = {0xBA, 0x5E, 0xBA, 0x11}; + +/*Length*/ /*Ap Address*/ /*My Address*/ /*Batt Volt*/ /*Discovery Payload*/ +u8 discoveryReply[8] = { 7, 0, WBSL_ED_ADDRESS, 0, 0xBA, 0x5E, 0xBA, 0x11}; +// flag contains status information, trigger to receive data and trigger to exit WBSL +volatile u8 wbsl_flag = 0; +// RF Mode Flag +volatile u8 wbslMode_flag = 0; +// RX Flag +volatile u8 rxtx_flag = 0; +// ACK Reply Package Format Size / Dongle ID / Watch ID / ACK Status / Package Number / +// Package Numer 2 +u8 ackReply[6] = { 5, 0, WBSL_ED_ADDRESS, 0, 0, 0 }; +// How far along is the Update procedure Range: 0 - 100 +volatile u8 wbsl_progress = 0; +// This is the Address of the Access point which we receive during the linking phase +u8 AP_address = 0; +// Handle number of ACKs sent for an indivudual packet +u8 wbsl_number_of_retries = 0; +// Variable to see if the Init Packet has been successfully sent +u8 initOk = 0; +// Store the total number of packets to be sent to the Watch +u16 totalPackets = 0; +// Keep track of which packet needs to be sent to the Watch +u16 currentPacket = 0; + +#ifndef RAM_BASED_RFBSL +# pragma location=0x2BE0 +__no_init u16 port2_isrAddress; // Interrupt Vector Address for PORT2 in RAM +#endif + +// Function Prototypes for Local Functions +void start_wbsl(void); +void config_radio_wbsl(void); +void stop_radio_wbsl(void); +u8 wbsl_receivePackets(void); +void wbsl_replyAck(u8 status, u16 packetNummer); +void init_watch(void); +u8 wbsl_link(void); + +#ifndef RAM_BASED_RFBSL +void init_watchButtons(void); + +#endif + +#ifdef RAM_BASED_RFBSL +void massEraseFlash(void); +void wbsl_openFlashForWrite(void); +void wbsl_lockFlash(void); +void init_interrupt_vector(void); + +#endif + +// ************************************************************************************************* +// @fn main +// @brief Starting point of the RFBSL, calls the needed routines prior to starting +// communication +// @param none +// @return u8 exit status +// ************************************************************************************************* +int main(){ + WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer + +#ifndef RAM_BASED_RFBSL + if (*((u16*)(0xFFFE)) == 0xFFFF) // Check if recovery procedure needs to be started + { + port2_isrAddress = 0x1002; // Move the address of the Port2_ISR to the address of the + // Port2 interrupt vector in RAM + SYSCTL |= SYSRIVECT; // Move interrupt vector to RAM + init_watchButtons(); // Initialize button S2 so that we wait until is pressed to + // continue + _BIS_SR(LPM4_bits + GIE); // Wait until Button is pressed to go to ISR + } +#endif + + //Disable all interrupts + __disable_interrupt(); + + // Initialize clocks and the LCD only in the case of the RAM_BASED_RFBSL + init_watch(); + +#ifdef RAM_BASED_RFBSL + display_wbsl(LINE2, 0); +#endif + + while (1){ + +#ifdef RAM_BASED_RFBSL + // Wait for AP/GUI to be ready to send update image + wbsl_setTimer(CONV_MS_TO_TICKS(900)); + while (!(TA0CCTL1 & CCIFG)) ; + wbsl_resetTimer(); +#endif + + start_wbsl(); + + // If no AP was found during discovery phase, reset the device + PMMCTL0 = PMMPW | PMMSWBOR; // generate BOR + + } +} + +// ************************************************************************************************* +// @fn init_watchButtons +// @brief Inits the S2 (Down) button so that it triggers the interrupt to wake up in the case +// of +// of a recovery procedure +// @param none +// @return none +// ************************************************************************************************* +#ifndef RAM_BASED_RFBSL +void init_watchButtons(void) +{ + // Set button ports to input + BUTTONS_DIR &= ~BUTTON_S2_PIN; + + // Enable internal pull-downs + BUTTONS_OUT &= ~BUTTON_S2_PIN; + BUTTONS_REN |= BUTTON_S2_PIN; + + // IRQ triggers on rising edge + BUTTONS_IES &= ~BUTTON_S2_PIN; + + // Reset IRQ flags + BUTTONS_IFG &= ~BUTTON_S2_PIN; + + // Enable button S2 interrupts + BUTTONS_IE |= BUTTON_S2_PIN; +} + +#endif + +// ************************************************************************************************* +// @fn wbsl_openFlashForWrite +// @brief Opens the Flash for writing by setting the appropriate bits +// @param none +// @return none +// ************************************************************************************************* +#ifdef RAM_BASED_RFBSL +void wbsl_openFlashForWrite() +{ + FCTL3 = FWKEY; // Clear Lock bit + FCTL1 = FWKEY + WRT; // Set write bit +} + +#endif + +// ************************************************************************************************* +// @fn wbsl_lockFlash +// @brief Locks the Flash by setting the appropriate bits +// @param none +// @return none +// ************************************************************************************************* +#ifdef RAM_BASED_RFBSL +void wbsl_lockFlash(void) +{ + FCTL1 = FWKEY; // Clear WRT bit + FCTL3 = FWKEY + LOCK; // Set LOCK bit +} + +#endif + +// ************************************************************************************************* +// @fn wbsl_writeByte +// @brief writes a byte to Memory and checks if it was correctly written +// @param u8 *address Address to which you want to write the byte +// u8 data The data to be written at the given address +// @return u8 status +// WBSL_OPERATION_SUCC Byte successfully written +// WBSL_OPERATION_FAIL Write Check failed +// ************************************************************************************************* +u8 wbsl_writeByte(u8 *address, u8 data) +{ + u8 ret_status = WBSL_OPERATION_SUCC; + +#ifdef RAM_BASED_RFBSL + while (FCTL3 & BUSY) ; +#endif + *address = data; +#ifdef RAM_BASED_RFBSL + while (FCTL3 & BUSY) ; +#endif + // Check if write was successfull + if (*address != data) + { + ret_status = WBSL_OPERATION_FAIL; + } + return ret_status; +} + +u8 wbsl_writeWord(u16 *addr, u16 data) +{ + u8 ret_status = WBSL_OPERATION_SUCC; + +#ifdef RAM_BASED_RFBSL + while (FCTL3 & BUSY) ; +#endif + *addr = data; +#ifdef RAM_BASED_RFBSL + while (FCTL3 & BUSY) ; +#endif + if (*addr != data) + { + ret_status = WBSL_OPERATION_FAIL; + } + return ret_status; +} + +// ************************************************************************************************* +// @fn wbsl_writeBytes +// @brief writes a byte to Memory and checks if it was correctly written +// the function will write in word mode if possible +// @param u8 *address Address to which you want to write the byte +// u8 size The number of bytes to be written +// u8 data The data to be written at the given address (must be even aligned) +// @return u8 status +// WBSL_OPERATION_SUCC Bytes successfully written +// WBSL_OPERATION_FAIL Write Check failed +// ************************************************************************************************* +u8 wbsl_writeBytes(u8 *startAddr, u8 size, u8 *data) +{ + //u8 *i; + u32 i; + u8 ret_status = WBSL_OPERATION_SUCC; + + // Make sure that the comparison doesn't overflow at the End of the 16 bit address, make the + // comparison in 32bit + for (i = (u32)startAddr; i < ((u32)startAddr) + ((u32)size); i++) + { +#ifdef RAM_BASED_RFBSL + if ((((u16)startAddr) & 0x01) || i == (u32)startAddr + (u32)size - 1) +#endif + { + ret_status = wbsl_writeByte((u8 *)((u16)i), *data); + data += 1; + } +#ifdef RAM_BASED_RFBSL + else + { + ret_status = wbsl_writeWord((u16 *)((u16)i), *((u16 *)(data))); + data += 2; + i++; + } +#endif + if (ret_status != WBSL_OPERATION_SUCC) + { + return ret_status; + } // if + + } // for + return ret_status; + +} + +// ************************************************************************************************* +// @fn wbsl_writePacket +// @brief writes the packet which is in the global RxBuffer to the address pointed by +// the global ptrMemory address +// @param none +// @return u8 status +// WBSL_OPERATION_SUCC Packet successfully written +// WBSL_OPERATION_FAIL Write Check failed for some byte of the packet +// ************************************************************************************************* +u8 wbsl_writePacket(void){ + + u16 packetSize; + u8 payloadStart; + u8 ret_status = WBSL_OPERATION_SUCC; + + packetSize = RxBuffer[0] - WBSL_PACKET_OVERHEAD; + payloadStart = FIRST_PAYLOAD_BYTE; + + // Write to flash the packet + if (RxBuffer[WBSL_OPCODE_OFFSET] == ADDRESS_PACKET_OPCODE) + { + ptrMemory = (u8 *)((RxBuffer[FIRST_PAYLOAD_BYTE] << 8) + RxBuffer[FIRST_PAYLOAD_BYTE + 1]); + packetSize -= 2; // Substract the address length + payloadStart += 2; // Move Offset to compensate for the Address Length + +#ifndef RAM_BASED_RFBSL // This is only for the flash based BSL, for the RAM Based the address + // should be written to flash + if (ptrMemory == (u8 *)(0xFFFE)) + { + start_ram_bsl_address = RxBuffer[payloadStart] + (RxBuffer[payloadStart + 1] << 8); + packetSize -= 2; + } +#endif + } + +#ifdef RAM_BASED_RFBSL + wbsl_openFlashForWrite(); +#endif + // Only if there is something to write + if (packetSize) + { +#ifdef RAM_BASED_RFBSL + // Check memory write boundaries Main Memory 0x8000 - 0xFFFF + if ((u16)ptrMemory < LOWER_BOUND_MAIN_MEMORY || ((u32)ptrMemory + (u32)packetSize) > + (u32)UPPER_BOUND_MAIN_MEMORY) +#else + // Check memory write boundaries Main Memory 0x1D30 - 0x2AFE (Depends on how you set up + // the linker file for the flash based RFBSL) + if ((u16)ptrMemory < LOWER_BOUND_RAM_MEMORY || ((u32)ptrMemory + (u32)packetSize) > + (u32)UPPER_BOUND_RAM_MEMORY) +#endif + { + ret_status = WBSL_OPERATION_FAIL; + } + else + { + ret_status = wbsl_writeBytes(ptrMemory, packetSize, &RxBuffer[payloadStart]); + } + + if (ret_status == WBSL_OPERATION_SUCC) + { + ptrMemory += packetSize; + } + } + +#ifdef RAM_BASED_RFBSL + wbsl_lockFlash(); +#endif + + return ret_status; +} + +// ************************************************************************************************* +// @fn start_wbsl +// @brief This is the main body of the RFBSL, this functions calls all the auxiliary functions +// of the RFBSL and handles some of the state flags +// @param none +// @return none +// ************************************************************************************************* +void start_wbsl(void) +{ +#ifdef RAM_BASED_RFBSL + u8 max_link_attempts; + max_link_attempts = 3; + + while (max_link_attempts >= 1 && !initOk) + { +#endif + //Reset all WBSL Variables + reset_wbsl(); + + /* Select Interrupt edge for PA_PD and SYNC signal: + * Interrupt Edge select register: 0 == Interrupt on Low to High transition. + * SYNC word Detected + */ + RF1AIES = 0; + +#ifdef RAM_BASED_RFBSL + // Clear LINE1 Display + clear_display(); + display_wbsl(LINE1, 0); + + // Turn on beeper icon to show activity + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON); + +#endif // RAM_BASED_RFBSL + + // Prepare radio for RF communication + radio_reset(); + +#ifndef RAM_BASED_RFBSL + // It only needs to be configured when the Flash Based RFBSL is running since when the RAM RFBSL + // runs, the radio registers are already configured + config_radio_wbsl(); +#endif + +#ifdef RAM_BASED_RFBSL + display_symbol(LCD_SYMB_PERCENT, SEG_ON); +#endif + // Set WBSL smode + sRFwbsl.mode = WBSL_SEARCHING; + wbsl_flag = WBSL_STATUS_LINKING; + + // Try to link once only to save watch battery + if (wbsl_link() == WBSL_LINK_SUCC) + { + wbsl_flag = WBSL_STATUS_LINKED; + +#ifdef RAM_BASED_RFBSL + // Turn off blinking on beeper icon to show that the device is linked + display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF); + + //Erase all memory main memory + massEraseFlash(); + +#endif // RAM_BASED_RFBSL + + while (currentPacket < totalPackets || !initOk) + { + if (wbsl_receivePackets() == WBSL_RECEIVE_SUCC) + { +#ifdef RAM_BASED_RFBSL + if (wbsl_progress < 100) + { + display_chars(LINE1, itoa(wbsl_progress, 2, 0)); + } + else + { + display_chars(LINE1, " "); + display_symbol(LCD_SYMB_PERCENT, SEG_OFF); + display_chars(LINE2, (u8 *)" DONE"); + } +#endif + } + + // If image has been completely received or the RFBSL was triggered to stop + if (wbsl_flag == WBSL_TRIGGER_STOP || (currentPacket >= totalPackets && initOk)) + { + break; + } + + } + } + + +#ifdef RAM_BASED_RFBSL + // Clear icons + display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF); + display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF); + + // Powerdown radio + radio_reset(); + + // Clear the LCD segments + display_symbol(LCD_SYMB_PERCENT, SEG_OFF); + +#endif // RAM_BASED_RFBSL + + // Set WBSL state to OFF + sRFwbsl.mode = WBSL_OFF; + + + if (currentPacket >= totalPackets && initOk) + { +#ifdef RAM_BASED_RFBSL + // Reset the device so that the application which was just downloaded starts from the RESET + // VECTOR + PMMCTL0 = PMMPW | PMMSWBOR; // generate BOR +#else //Only for the Flash Based RFBSL, jump to the address at which the RAM_RFBSL starts + asm (" mov.w &start_ram_bsl_address,PC"); +#endif + } +#ifdef RAM_BASED_RFBSL + else if (max_link_attempts < 1) + { + display_chars(LINE1, (u8 *)" "); + display_chars(LINE2, (u8 *)" FAIL"); + break; + } + + // Link Failed, decrement link attempts to keep track of how many times we've tried + max_link_attempts--; +} + +#endif +} + +// ************************************************************************************************* +// @fn transmitPacket +// @brief This functions handles the transmission of a packet by filling the +// TXFIFO and Strobing the Radio with TX, it uses CCA if is defined in +// the project, if not, it forces the transmit +// @param u8 *buffer Buffer containing the bytes to be transmitted +// u8 length Length of the buffer to be transmitted +// @return none +// ************************************************************************************************* +void transmitPacket(u8 *buffer, u8 length) +{ +#ifdef CCA + u8 ccaRetries; + u8 x; +#endif + // Turn off receiver + ReceiveOff(); + // Write the Buffer to the Transmit FIFO + WriteBurstReg(RF_TXFIFOWR, buffer, length); + +#ifdef CCA + ccaRetries = 4; + + while (1){ + /* Radio must be in RX mode for CCA to happen. + * Otherwise it will transmit without CCA happening. + * We don't use the RxModeOn because it turns the RX interrupt + * which we don't need + */ + Strobe(RF_SRX); + + //Wait for valid RSSI + while (!(RF1AIN & BV(1))) ; + + /* + * Clear the PA_PD pin interrupt flag. This flag, not the interrupt itself, + * is used to capture the transition that indicates a transmit was started. + * The pin level cannot be used to indicate transmit success as timing may + * prevent the transition from being detected. The interrupt latch captures + * the event regardless of timing. + */ + RF1AIFG &= ~BV(0); + + Strobe(RF_STX); // Strobe STX to initiate transfer + + /* Found out that we need a delay of atleast 25 us on CC1100 to see + * the PA_PD signal change. Hence keeping the same for CC430 + */ + wbsl_setTimer(25); + while (!(TA0CCTL1 & CCIFG)) ; + wbsl_resetTimer(); + + if (RF1AIFG & BV(0)) + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment passed. + * ---------------------------------- + */ + + //Clear the PA_PD pin interrupt flag. + RF1AIFG &= ~BV(0); + + /* wait for transmit to complete */ + while (!(RF1AIN & BV(0))) ; + // Transmit done, break of loop + break; + } + else + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment failed. + * ---------------------------------- + */ + // Turn off radio to save power + do { + x = Strobe(RF_SIDLE); + } while (x & 0x70); + /* Wait for XOSC to be stable and radio in IDLE state */ + + // Flush receive FIFO of residual Data + Strobe(RF_SFRX); + + if (ccaRetries != 0) + { + /* delay for a number of us */ + wbsl_setTimer(15); + while (!(TA0CCTL1 & CCIFG)) ; + wbsl_resetTimer(); + + /* decrement CCA retries before loop continues */ + ccaRetries--; + } + else /* No CCA retries are left, abort */ + { + /* set return value for failed transmit and break */ + return; + } + } + } +#else // Forced TX + + Strobe(RF_STX); + + while (!(RF1AIFG & BIT9)) ; //Wait until packet has been sent + + // Clear the interrupt flag + RF1AIFG &= ~BIT9; +#endif // CCA + + // Flush transmit FIFO, Radio is already in IDLE state due to Register configuration + Strobe(RF_SFTX); +} + +// ************************************************************************************************* +// @fn wbsl_link +// @brief Tries to link with a AP by sending a discovery packet and waiting for +// a discovery reply or TIMEOUT_FOR_ACK time +// @param none +// @return u8 link_Status +// WBSL_LINK_SUCC The watch found an AP and they're both linked +// WBSL_LINK_FAIL The watch didn't find any AP which responded to +// the discovery packet +// ************************************************************************************************* +u8 wbsl_link(void){ + u8 crcOk = 0; + u8 retStatus = WBSL_LINK_FAIL; + + //u8 temp_PKTCTRL1; + // Already Set + //discoveryReply[AP_ADDRESS_OFFSET_TX] = 0x00; // Broadcast so that any AP listening receives + // the package + + transmitPacket((u8*)discoveryReply, sizeof discoveryReply); + + // Activate RX Mode to wait for ACK of pairing from the AP + ReceiveOn(); + + // Wait for a packet to be received or timeout + wbsl_setTimer(TIMEOUT_FOR_ACK); + + // Go to LPM3 and wait for either the interrupt from the timer or the RX Interrupt + //_BIS_SR(LPM3_bits); + + while (!(TA0CCTL1 & CCIFG) && rxtx_flag != WBSL_RXTX_RECEIVED) + { + if (RF1AIFG & BIT9) // Check for the SYNC WORD detected flag + RadioIsr_wbsl(); // Call the ISR to retrieve the received packet + + //Here we should sleep to wait for either Timeout or Radio + //_BIS_SR(LPM0_bits); + } + + // Reset the timer so that next time it starts from fresh state. + wbsl_resetTimer(); + + // Turn radio off during the decoding of the package + ReceiveOff(); + + if (rxtx_flag == WBSL_RXTX_RECEIVED) + { + // Clear RX Flag + rxtx_flag = 0; + + crcOk = RxBuffer[RxBuffer[0] + WBSL_CRC_STATUS_OFFSET] & CRC_STATUS; //CRC status is + // appended at the end + // of RXFIFO + + if ( //RxBuffer[ED_ADDRESS_OFFSET_RX]!= + // WBSL_ED_ADDRESS || + RxBuffer[LINK_ACK_OFFSET] != WBSL_LINK_SUCC || + !crcOk) // Check the package is + // from the AP, the + // Address check is + // done in hardware + { + return retStatus; + } + else + { + //Save AP_address + AP_address = RxBuffer[AP_ADDRESS_OFFSET_RX]; + + // Set the Link as succesfull so the actual communication can start + retStatus = WBSL_LINK_SUCC; + } + } + return retStatus; +} + +// ************************************************************************************************* +// @fn wbsl_replyAck +// @brief Replies with an ACK or NACK to the AP +// @param u8 status ACK or NACK +// u16 packetNummer The packet number for which the ACK is +// @return none +// ************************************************************************************************* +void wbsl_replyAck(u8 status, u16 packetNummer){ + // Delay to let AP Dongle be in RX Mode + // Set the timeout + wbsl_setTimer(CONV_US_TO_TICKS(300)); + // Wait for a timeout + while (!(TA0CCTL1 & CCIFG)) ; + // Reset the timer + wbsl_resetTimer(); + //Fill the ACK Reply Buffer + ackReply[AP_ADDRESS_OFFSET_TX] = AP_address; + //ackReply[ED_ADDRESS_OFFSET_TX] = WBSL_ED_ADDRESS; // This is put on declaration + ackReply[ED_ADDRESS_OFFSET_TX + 1] = status; + + ackReply[ED_ADDRESS_OFFSET_TX + 2] = (packetNummer >> 8) & 0x7F; + ackReply[ED_ADDRESS_OFFSET_TX + 3] = packetNummer; + + transmitPacket((u8*)ackReply, sizeof(ackReply)); + +} + +// ************************************************************************************************* +// @fn wbsl_receivePackets +// @brief This functions puts the radio in RX Mode to listen for new packages +// and waits for TIMEOUT, if packet is received, check for CRC, +// if packet was sent from AP and addressed to us, if everything +// checks out, it calls the write packet function +// @param none +// @return u8 status +// WBSL_ERROR No packet was received or error during writing +// WBSL_SUCC Packet was received and written to memory +// ************************************************************************************************* +u8 wbsl_receivePackets(void){ + u8 crcOk = 0; + u16 tempCurrentPacket = 0; + u8 retStatus = WBSL_LINK_FAIL; + + // Increment the number of retries to send the ACK + wbsl_number_of_retries++; + + // Check if too many retries for one packet have been already made + if (wbsl_number_of_retries >= WBSL_MAXIMUM_RETRIES) + { + // Trigger the stop of the WBSL Update procedure + wbsl_flag = WBSL_TRIGGER_STOP; + return retStatus; + } + // Activate RX Mode to listen to new packets + ReceiveOn(); + + // Set the timeout so we don't get stuck waiting for a packet + wbsl_setTimer(TIMEOUT_FOR_ACK); + + // Wait for a packet to be received or timeout + while (!(TA0CCTL1 & CCIFG) && rxtx_flag != WBSL_RXTX_RECEIVED) + { + // Check the SYNC Word detected flag + if (RF1AIFG & BIT9) + RadioIsr_wbsl(); + + //Here we should sleep to wait for either Timeout or Radio + //_BIS_SR(LPM0_bits); + } + + // Reset the timer so that next time it starts from fresh state. + wbsl_resetTimer(); + // Turn radio off during the decoding of the package + ReceiveOff(); + + // If the was no packet received, then a TIMEOUT happened, we need to send + // an ack for previous pkt, but just in the case it was a regular packet and not a init Packet + if (rxtx_flag != WBSL_RXTX_RECEIVED && initOk) + { + //Reply Positive ACK for previous packet, in case AP didn't receive last ACK + wbsl_replyAck(WBSL_LINK_SUCC, currentPacket - 1); + } + else if (rxtx_flag == WBSL_RXTX_RECEIVED) + { + // Clear RX Flag + rxtx_flag = 0; + + crcOk = RxBuffer[RxBuffer[0] + WBSL_CRC_STATUS_OFFSET] & CRC_STATUS; //CRC status is + // appended at the end + // of RXFIFO + + if ( //RxBuffer[ED_ADDRESS_OFFSET_RX] + // == WBSL_ED_ADDRESS + // && // Address check + // is now done in + // hardware + RxBuffer[AP_ADDRESS_OFFSET_RX] == AP_address) // Check that the + // packet comes from + // the AP we're linked + // to + { + // If we're not initialized for communication, this should be an Init packet, treat it + // as such + if (!initOk) + { + if (crcOk) + { + // Reset the retry counter for ACKs + wbsl_number_of_retries = 0; + // Total number of packets to be sent during the update process + totalPackets = RxBuffer[3] + (RxBuffer[4] << 8); + + //Reply Positive ACK + wbsl_replyAck(WBSL_LINK_SUCC, 0xFFFF); + + initOk = 1; + } + else + { + // CRC ERROR Reply Negative ACK + wbsl_replyAck(WBSL_LINK_FAIL, 0xFFFF); + } + } + else + { + // Delay to let AP Dongle be in RX Mode + // Set the timeout + //wbsl_setTimer(CONV_US_TO_TICKS(500)); + // Wait for a packet to be received or timeout + //while(!(TA0CCTL1 & CCIFG)); + // Reset the timer + //wbsl_resetTimer(); + + if (crcOk) + { + tempCurrentPacket = RxBuffer[4] + (RxBuffer[3] << 8 & 0xFF00); // + // Keep + // track + // of + // which + // packet + // is + // being + // sent + + //Check that we are receiving the next packet needed + if (tempCurrentPacket == currentPacket) + { + if (wbsl_writePacket() == WBSL_OPERATION_SUCC) + { + // Reset the retry counter for ACKs + wbsl_number_of_retries = 0; + //Reply Positive ACK + wbsl_replyAck(WBSL_LINK_SUCC, currentPacket); + //Increment the currentPacket to keep track of which packets we have + // received + currentPacket++; + wbsl_progress = (currentPacket * 100) / totalPackets; + retStatus = WBSL_LINK_SUCC; + } + else + { + // Write Error ask AP to send package again. + wbsl_replyAck(WBSL_LINK_FAIL, currentPacket); + } + } + else + { + //There is an error on the flow of packets DEAL with it + //Reply Positive ACK for previous packet, in case AP didn't receive last ACK + wbsl_replyAck(WBSL_LINK_SUCC, currentPacket - 1); + } + } + else + { + // CRC Error reply with a NACK + wbsl_replyAck(WBSL_LINK_FAIL, currentPacket); + } + } + } + } + + return retStatus; +} + +// ************************************************************************************************* +// @fn RadioIsr_wbsl +// @brief Retrieves the packet waiting on the RXFIFO of the Radio +// @param none +// @return none +// ************************************************************************************************* +void RadioIsr_wbsl(void) +{ + u8 rxBytes; + u8 tL; + u8 *tmpRxBuffer; + u16 coreIntSource = RF1AIV; + + // Clear RX Interrupt Flag + RF1AIFG &= ~BIT9; + + // We should only be here in RX mode, not in TX mode, nor if RX mode was turned on during CCA + if (wbslMode_flag != WBSL_RX_MODE) + { + return; + } + + // Clean Buffer to help protect against spurios frames + memset(RxBuffer, 0x00, sizeof(RxBuffer)); + + // Use a pointer to move through the Buffer + tmpRxBuffer = RxBuffer; + + // Read the number of bytes ready on the FIFO + rxBytes = ReadSingleReg(RXBYTES); + + do { + tL = rxBytes; + rxBytes = ReadSingleReg(RXBYTES); + } while (tL != rxBytes); // Due to a chip bug, the RXBYTES has to read the same + // value twice for it to be correct + + if (rxBytes == 0) // Check if the RX FIFO is empty, this may happen if + // address check is enabled and the FIFO is flushed + // when address doesn't match + { + return; + } + + *tmpRxBuffer++ = ReadSingleReg(RXFIFO); + RxBufferLength = *(tmpRxBuffer - 1) + 2; // Add 2 for the status bytes which are appended by the + // Radio + + + // Check if number of bytes in Fifo exceed the FIFO Size, if so, assume FIFO overflow due to + // something + // gone wrong with radio, and the only way to fix it, is to force IDLE mode and then back to RX + // Mode + if (rxBytes > MAX_RXFIFO_SIZE) + { + ReceiveOff(); + ReceiveOn(); + return; + } + // else: everything matches continue + + //Copy Rest of packet + while (RxBufferLength > 1){ + + rxBytes = ReadSingleReg(RXBYTES); + + do { + tL = rxBytes; + rxBytes = ReadSingleReg(RXBYTES); + } while (tL != rxBytes); // Due to a chip bug, the RXBYTES has to read the same value twice + // for it to be correct + + while (rxBytes > 1) + { + *tmpRxBuffer++ = ReadSingleReg(RXFIFO); + RxBufferLength--; rxBytes--; + } + } + *tmpRxBuffer++ = ReadSingleReg(RXFIFO); + + // Signal main program that packet has been received and ready in RxBuffer + rxtx_flag = WBSL_RXTX_RECEIVED; +} + +// ************************************************************************************************* +// @fn massEraseFlash +// @brief Erases the main memory flash of the watch +// @param none +// @return none +// ************************************************************************************************* +#ifdef RAM_BASED_RFBSL +void massEraseFlash(void) +{ + volatile char *Flash_ptr; //Flash pointer + + while (FCTL3 & BUSY) ; + FCTL3 = FWKEY; + while (FCTL3 & BUSY) ; + Flash_ptr = (char *)INTERRUPT_VECTOR_START_ADDRESS; //Interrupt Vector Start + FCTL1 = FWKEY + MERAS + ERASE; // Set Mass Erase Bits + *Flash_ptr = 0; + while (FCTL3 & BUSY) ; + FCTL3 = FWKEY + LOCK; +} + +#endif // RAM_BASED_RFBSL + +// ************************************************************************************************* +// @fn init_watch +// @brief Inits basic options in the watch and depending of the type of RFBSL +// being compiled it choses which components to initialize +// @param none +// @return none +// ************************************************************************************************* +void init_watch(void){ + + + // Initialize Clocks + // --------------------------------------------------------------------- + // Enable 32kHz ACLK + P5SEL |= 0x03; // Select XIN, XOUT on P5.0 and P5.1 + UCSCTL6 &= ~(XT1OFF + XT1DRIVE_3); // XT1 On, Lowest drive strength + UCSCTL6 |= XCAP_3; // Internal load cap + + UCSCTL3 = SELA__XT1CLK; // Select XT1 as FLL reference + UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; + // --------------------------------------------------------------------- + // Configure CPU clock for 12MHz + _BIS_SR(SCG0); // Disable the FLL control loop + UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx + UCSCTL1 = DCORSEL_5; // Select suitable range + UCSCTL2 = FLLD_1 + 0x16E; // Set DCO Multiplier + _BIC_SR(SCG0); // Enable the FLL control loop + + // Worst-case settling time for the DCO when the DCO range bits have been + // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx + // UG for optimization. + // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle + __delay_cycles(250000); + + // Loop until XT1 & DCO stabilizes, use do-while to insure that + // body is executed at least once + do + { + UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); + SFRIFG1 &= ~OFIFG; // Clear fault flags + } while ((SFRIFG1 & OFIFG)); + +#ifdef RAM_BASED_RFBSL + lcd_init(); +#endif + +} + +// ************************************************************************************************* +// @fn display_wbsl +// @brief WBSL display routine. +// @param u8 line LINE2 +// u8 update DISPLAY_LINE_UPDATE_FULL +// @return none +// ************************************************************************************************* +#ifdef RAM_BASED_RFBSL +void display_wbsl(u8 line, u8 update) +{ + display_chars(LINE2, (u8 *)" RFBSL"); +} + +#endif + +// ************************************************************************************************* +// @fn reset_wbsl +// @brief Reset WBSL data. +// @param none +// @return none +// ************************************************************************************************* +void reset_wbsl(void) +{ + // No connection + sRFwbsl.mode = WBSL_OFF; + + //Reset the progress variables + wbsl_progress = 0; + currentPacket = 0; + totalPackets = 0; + + // Reset the number of retries to send the ACK + wbsl_number_of_retries = 0; + + // Clear init flag to send the total number of packets on the first transmission packet + initOk = 0; + RF1AIFG = 0; // Clear Radio Flags +} + +// ************************************************************************************************* +// @fn wbsl_resetTimer +// @brief Resets the timer TA0 and stops it +// @param none +// @return none +// ************************************************************************************************* +void wbsl_resetTimer(void){ + + // Reset IRQ flag + TA0CCTL1 &= ~CCIFG; + + // Stop Timer0 + TA0CTL &= ~(MC1 + MC0); + + // Set Timer0 count register to 0x0000 + TA0R = 0; +} + +// ************************************************************************************************* +// @fn wbsl_setTimer +// @brief Set the timer for the Packet timeouts the timeout param is in ticks 1 tick = 1 / +// 32768 sec +// @param u16 ticks Value in ticks (1 tick = 1 / 32768 secs) that wants the timeout to run +// must +// be less than 32768 if greater than 32768 it is set to 32767 +// @return none +// ************************************************************************************************* +void wbsl_setTimer(u16 ticks) +{ + + if (ticks > 32767) + ticks = 32767; + + // Update CCR + TA0CCR1 = ticks; + + // Reset IRQ flag + TA0CCTL1 &= ~CCIFG; + + // Clear and start timer now + // Continuous mode: Count to 0xFFFF and restart from 0 again - 1sec timing will be generated by + // ISR + TA0CTL |= TASSEL0 + MC1 + TACLR; + +} + diff --git a/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/wbsl.h b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/wbsl.h new file mode 100755 index 0000000..546c667 --- /dev/null +++ b/chronos-ti/Software Projects/Chronos Watch/IAR/Wireless Update/wbsl.h @@ -0,0 +1,241 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +#ifndef WBSL_H_ +#define WBSL_H_ + +#include "project_defs.h" + +//Temporal Defines + +/* + * Product = CC430 + * Chip version (VERSION = 0x06) + * Crystal accuracy = 10 ppm + * X-tal frequency = 26 MHz + * RF output power = 0 dBm + * RX filterbandwidth = 101.562500 kHz + * Deviation = 19 kHz + * Datarate = 38.383484 kBaud + * Modulation = (1) GFSK + * Manchester enable = (0) Manchester disabled + * RF Frequency = 914.999 MHz + * Channel spacing = 199.951172 kHz + * Channel number = 0 + * Optimization = - + * Sync mode = (3) 30/32 sync word bits detected + * Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX + * CRC operation = (1) CRC calculation in TX and CRC check in RX disabled + * Forward Error Correction = (0) FEC disabled + * Length configuration = (1) Variable length packets, packet length configured by the first + * received byte after sync word. + * Packetlength = 10 + * Preamble count = 0 bytes - sync word is always accepted + * Append status = 0 + * Address check = (0) No Address check + * FIFO autoflush = 0 + * Device address = 0 + * GDO0 signals on PA power down signal to control RX/TX switch + * GDO1 signals on RSSI_VALID + * GDO2 signal selection = (41) CHIP_RDY + */ + +//#include "cc430x613x.cmd" + +//Watch ports +#define BUTTONS_IN (P2IN) +#define BUTTONS_OUT (P2OUT) +#define BUTTONS_DIR (P2DIR) +#define BUTTONS_REN (P2REN) +#define BUTTONS_IE (P2IE) +#define BUTTONS_IES (P2IES) +#define BUTTONS_IFG (P2IFG) +#define BUTTONS_IRQ_VECT2 (PORT2_VECTOR) + +// Button ports +#define BUTTON_M1_PIN (BIT2) +#define BUTTON_M2_PIN (BIT1) +#define BUTTON_S1_PIN (BIT4) +#define BUTTON_S2_PIN (BIT0) +#define BUTTON_BL_PIN (BIT3) +#define ALL_BUTTONS (BUTTON_M1_PIN + BUTTON_M2_PIN + BUTTON_S1_PIN + \ + BUTTON_S2_PIN + BUTTON_BL_PIN) + + +#define FLASH_RFSBL_ENTRY (0x1000) +#define RESET_VECTOR_ADDRESS (0xFFFE) +#define PORT2_VECTOR_ADDRESS (0xFFE0) + +#ifdef RAM_BASED_RFBSL +extern void wbsl_vector_write(void); + +#endif + +// --------------------------------------------------------------- +// Generic Defines and variables +// Maximum data length +#define WBSL_MAX_PAYLOAD_LENGTH (253u) +#define WBSL_ED_ADDRESS (0xAD) +#define WBSL_CRC_STATUS_OFFSET (2) +#define DISCOVERY_PAYLOAD_LENGTH (4u) +#define DISCOVERY_OVERHEAD_LENGTH (3u) +#define AP_ADDRESS_OFFSET_TX (1u) +#define ED_ADDRESS_OFFSET_TX (2u) +#define BATTERY_VOLTAGE_OFFSET (3u) +#define LINK_ACK_OFFSET (3u) +#define AP_ADDRESS_OFFSET_RX (2u) +#define ED_ADDRESS_OFFSET_RX (1u) +#define WBSL_OPCODE_OFFSET (5u) + +#define MAX_RXFIFO_SIZE (64u) + +#define WBSL_PACKET_OVERHEAD (5u) +#define WBSL_LENGTH_FIELD_SIZE (1u) +#define PACKET_HEADER_OFFSET (3u) +//#define IS_ADDRESS (0x80) +//#define MSB_PACKET_NUMBER (0x7F) +//#define LSB_PACKET_NUMBER (0xFF) + +#define INIT_PACKET_OPCODE (0u) +#define ADDRESS_PACKET_OPCODE (1u) +#define NORMAL_PACKET_OPCODE (2u) + +#define FIRST_PAYLOAD_BYTE (WBSL_PACKET_OVERHEAD + WBSL_LENGTH_FIELD_SIZE) + +#define WBSL_LAST_FLASH_WORD_ADDRESS ((u8 *)0xFFFE) + +#define WBSL_ACK_PKT_SIZE (5u) + +#define WBSL_LINK_FAIL (0u) +#define WBSL_LINK_SUCC (1u) + +#define WBSL_RECEIVE_FAIL (0u) +#define WBSL_RECEIVE_SUCC (1u) + +#define WBSL_INIT_ACK (0) +#define WBSL_PKT_ACK (1u) + +#define CRC_STATUS (0x80) + +#define WBSL_MAXIMUM_RETRIES (5u) + +#define START_USER_FLASH_MEMORY (0x8000) +#define END_USER_FLASH_MEMORY (0xFFFE) +#define FLASH_SEGMENT_SIZE (0x200) +#define INTERRUPT_VECTOR_START_ADDRESS (0xFFE0) +#define RESET VECTOR_SIZE(0x80) + +#define WBSL_STATUS_LINKING (BIT0) +#define WBSL_STATUS_LINKED (BIT1) +#define WBSL_STATUS_ERROR (BIT2) +#define WBSL_TRIGGER_SEND_DATA (BIT3) +#define WBSL_TRIGGER_RECEIVED_DATA (BIT4) +#define WBSL_TRIGGER_STOP (BIT5) +#define WBSL_TRIGGER_SEND_CMD (BIT6) +#define WBSL_ILLEGAL_MEMORY_ERROR (BIT7) + +// Flag for status information, to see if WBSL is in RX/TX/IDLE mode +extern volatile u8 wbslMode_flag; +#define WBSL_IDLE_MODE (BIT0) +#define WBSL_RX_MODE (BIT1) +#define WBSL_TX_MODE (BIT2) + + +#define WBSL_RXTX_RECEIVED (BIT0) +#define WBSL_RXTX_SEND (BIT1) + +#define WBSL_PACKET_WRITTEN_FAIL (0u) +#define WBSL_PACKET_WRITTEN_SUCC (1u) + +#define WBSL_OPERATION_FAIL (0u) +#define WBSL_OPERATION_SUCC (1u) + +#define TIMEOUT_FOR_ACK (CONV_MS_TO_TICKS(500)) // 500 milliseconds in ticks + +#define LOWER_BOUND_MAIN_MEMORY (0x8000) +#define UPPER_BOUND_MAIN_MEMORY (0x10000) + +#define LOWER_BOUND_RAM_MEMORY (0x1D30) +#define UPPER_BOUND_RAM_MEMORY (0x2AFE) + +// SimpliciTI connection states +typedef enum +{ + WBSL_OFF = 0, // Not connected + WBSL_SEARCHING, // Trying to pair with End Device + WBSL_ERROR, // Connection Error + WBSL_TIMEOUT, // Packet timeout during WBSL + // transfer + WBSL_CONNECTED // Bsl Update +} wbsl_mode_t; + +// ************************************************************************************************* +// Global Variable section +struct RFwbsl +{ + // Different WBSL Modes + volatile wbsl_mode_t mode; + //Watch ID + volatile u32 wId; + // Timeout until WBSL is automatically stopped + volatile u16 timeout; +}; +//Prototypes +extern void sx_wbsl(u8 line); + +#ifdef RAM_BASED_RFBSL +extern void display_wbsl(u8 line, u8 update); + +#endif + +extern void reset_wbsl(void); +extern void RadioIsr_wbsl(void); + +extern void wbsl_resetTimer(void); +extern void wbsl_setTimer(u16 ticks); + +extern void init_watchButtons(void); +extern u8 wbsl_writeWord(u16 *addr, u16 data); + +extern struct RFwbsl sRFwbsl; + +extern volatile u8 wbsl_progress; +extern u8 AP_address; + +extern volatile u8 wbsl_flag; +// Flag to signal a packet received to the main program +extern volatile u8 rxtx_flag; + + +#endif /*WBSL_H_*/ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/BM_API.h b/chronos-ti/Software Projects/RF Access Point/IAR/BM_API.h new file mode 100755 index 0000000..a1647d5 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/BM_API.h @@ -0,0 +1,112 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Defines required for USB communication +// ************************************************************************************************* + +// USB packet length +#define PACKET_OVERHEAD_BYTES 3 +#define PACKET_DATA_BYTES 2 +#define PACKET_TOTAL_BYTES (PACKET_OVERHEAD_BYTES + PACKET_DATA_BYTES) + +// Packet bytes +// +// Byte 0 Start marker (0xFF) +#define PACKET_BYTE_START (0u) +// Byte 1 Command code +#define PACKET_BYTE_CMD (1u) +// Byte 2 Packet size (including overhead) +#define PACKET_BYTE_SIZE (2u) +// Byte 3..packet_size Data +#define PACKET_BYTE_FIRST_DATA (3u) + + +// Command codes +#define BM_GET_STATUS 0x00 +#define BM_GET_PRODUCT_ID 0x20 + +// BlueRobin +#define BM_RESET 0x01 +#define BM_START_BLUEROBIN 0x02 +#define BM_SET_BLUEROBIN_ID 0x03 +#define BM_GET_BLUEROBIN_ID 0x04 +#define BM_SET_HEARTRATE 0x05 +#define BM_STOP_BLUEROBIN 0x06 +#define BM_SET_SPEED 0x0A + +// Simpliciti +#define BM_START_SIMPLICITI 0x07 +#define BM_GET_SIMPLICITIDATA 0x08 +#define BM_STOP_SIMPLICITI 0x09 + +// Sync +#define BM_SYNC_START 0x30 +#define BM_SYNC_SEND_COMMAND 0x31 +#define BM_SYNC_GET_BUFFER_STATUS 0x32 +#define BM_SYNC_READ_BUFFER 0x33 + +//Wireless BSL +#define BM_START_WBSL 0x40 +#define BM_GET_WBSL_STATUS 0x41 +#define BM_INIT_OK_WBSL 0x42 +#define BM_INIT_INVALID_WBSL 0x43 +#define BM_TRANSFER_OK_WBSL 0x44 +#define BM_TRANSFER_INVALID_WBSL 0x45 +#define BM_STOP_WBSL 0x46 +#define BM_SEND_DATA_WBSL 0x47 +#define BM_GET_PACKET_STATUS_WBSL 0x48 +#define BM_GET_MAX_PAYLOAD_WBSL 0x49 + +// Test +#define BM_INIT_TEST 0x70 +#define BM_NEXT_TEST 0x71 +#define BM_WRITE_BYTE 0x72 +#define BM_GET_TEST_RESULT 0x73 + +// System states +#define HW_IDLE 0x00 +#define HW_SIMPLICITI_STOPPED 0x01 +#define HW_SIMPLICITI_TRYING_TO_LINK 0x02 +#define HW_SIMPLICITI_LINKED 0x03 +#define HW_BLUEROBIN_STOPPED 0x04 +#define HW_BLUEROBIN_TRANSMITTING 0x05 +#define HW_ERROR 0x05 +#define HW_NO_ERROR 0x06 +#define HW_NOT_CONNECTED 0x07 +#define HW_SIMPLICITI_LINK_TIMEOUT 0x08 +#define HW_WBSL_TRYING_TO_LINK 0x09 +#define HW_WBSL_LINKED 0x0A +#define HW_WBSL_ERROR 0x0B +#define HW_WBSL_STOPPED 0x0C +#define HW_WBSL_LINK_TIMEOUT 0x0D \ No newline at end of file diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal.h b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal.h new file mode 100755 index 0000000..0fc37a3 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal.h @@ -0,0 +1,2363 @@ +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +| File: hal.h +| Target: cc2430, cc2431, cc1110, cc2510, cc2511, cc1111 +| Author: EFU/ KJA / TBR +| Revised: 2007-09-21 +| Revision: 1.0 +| Description: +| Hardware Abstraction Layer, Utility Library. +******************************************************************************/ + +#ifndef HAL_H +#define HAL_H + +#include "project.h" + +#if(chip == 2430) +#include "ioCC2430.h" +#endif + +#if(chip == 2431) +#include "ioCC2431.h" +#endif + +#if(chip == 1110) +#include "ioCC1110.h" +#endif + +#if(chip == 1111) +#include "ioCC1111.h" +#endif + +#if(chip == 2510) +#include "ioCC2510.h" +#endif + +#if(chip == 2511) +#include "ioCC2511.h" +#endif + +/****************************************************************************** +******************* Chip revisions ******************* +******************************************************************************/ +#define REV_A 0x00 +#define REV_B 0x01 +#define REV_C 0x02 +#define REV_D 0x03 +#define REV_E 0x04 + + +/****************************************************************************** +******************* Commonly used types ******************* +******************************************************************************/ +typedef unsigned char BOOL; + +// Data +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; + +// Unsigned numbers +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned long UINT32; + +// Signed numbers +typedef signed char INT8; +typedef signed short INT16; +typedef signed long INT32; + +// Common values +#ifndef FALSE + #define FALSE 0 +#endif + +#ifndef TRUE + #define TRUE 1 +#endif + +#ifndef NULL + #define NULL 0 +#endif + +#ifndef HIGH + #define HIGH 1 +#endif + +#ifndef LOW + #define LOW 0 +#endif + +// Typedef void pointer +//typedef void (*VFPTR)(void); + +/****************************************************************************** +******************* Bit, byte and word macros ******************* +******************************************************************************/ + +// bit mask +#define BM( b ) ( 0x01 << ( b )) + +#define HIBYTE(a) (BYTE) ((WORD)(a) >> 8 ) +#define LOBYTE(a) (BYTE) (WORD)(a) + +#define SET_WORD(regH, regL, word) \ + do{ \ + (regH) = HIBYTE( word ); \ + (regL) = LOBYTE( word ); \ + }while(0) + +#define GET_WORD(regH, regL, word) \ + do{ \ + word = (WORD)regH << 8; \ + word |= regL; \ + }while(0) + +/****************************************************************************** +******************* Port functions/macros ******************* +******************************************************************************* + +Macros for simplifying access to I/O pin setup and usage. + +MCU pin configuration: +--------------------------------------------- +| Peripheral I/O signal | Alt1 | Alt2 | +--------------------------------------------- +| Timer1 channel0 | P0.2 | P1.2 | +| Timer1 channel1 | P0.3 | P1.1 | +| Timer1 channel2 | P0.4 | P1.0 | +| Timer3 channel0 | P1.3 | P1.6 | +| Timer3 channel1 | P1.4 | P1.7 | +| Timer4 channel0 | P1.0 | P2.0 | +| Timer4 channel1 | P1.1 | P2.3 | +| USART0 TXD/MOSI | P0.3 | P1.5 | +| USART0 RXD/MISO | P0.2 | P1.4 | +| USART0 RTS/SCK | P0.5 | P1.3 | +| USART0 CTS/SS_N | P0.4 | P1.2 | +| USART1 TXD/MOSI | P0.4 | P1.6 | +| USART1 RXD/MISO | P0.5 | P1.7 | +| USART1 RTS/SCK | P0.3 | P1.5 | +| USART1 CTS/SS_N | P0.2 | P1.4 | +--------------------------------------------- + +******************************************************************************/ + + +// Macros for configuring IO peripheral location: +// Example usage: +// IO_PER_LOC_TIMER1_AT_PORT0_PIN234(); +// IO_PER_LOC_TIMER4_AT_PORT2_PIN03(); +// IO_PER_LOC_USART1_AT_PORT0_PIN2345(); + +#define IO_PER_LOC_TIMER1_AT_PORT0_PIN234() do { PERCFG = (PERCFG&~0x40)|0x00; } while (0) +#define IO_PER_LOC_TIMER1_AT_PORT1_PIN012() do { PERCFG = (PERCFG&~0x40)|0x40; } while (0) + +#define IO_PER_LOC_TIMER3_AT_PORT1_PIN34() do { PERCFG = (PERCFG&~0x20)|0x00; } while (0) +#define IO_PER_LOC_TIMER3_AT_PORT1_PIN67() do { PERCFG = (PERCFG&~0x20)|0x20; } while (0) + +#define IO_PER_LOC_TIMER4_AT_PORT1_PIN01() do { PERCFG = (PERCFG&~0x10)|0x00; } while (0) +#define IO_PER_LOC_TIMER4_AT_PORT2_PIN03() do { PERCFG = (PERCFG&~0x10)|0x10; } while (0) + +#define IO_PER_LOC_USART1_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x02)|0x00; } while (0) +#define IO_PER_LOC_USART1_AT_PORT1_PIN4567() do { PERCFG = (PERCFG&~0x02)|0x02; } while (0) + +#define IO_PER_LOC_USART0_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x01)|0x00; } while (0) +#define IO_PER_LOC_USART0_AT_PORT1_PIN2345() do { PERCFG = (PERCFG&~0x01)|0x01; } while (0) + + + +// Macros for configuring IO direction: +// Example usage: +// IO_DIR_PORT_PIN(0, 3, IO_IN); // Set P0_3 to input +// IO_DIR_PORT_PIN(2, 1, IO_OUT); // Set P2_1 to output + +#define IO_DIR_PORT_PIN(port, pin, dir) \ + do { \ + if (dir == IO_OUT) \ + P##port##DIR |= BM( pin ); \ + else \ + P##port##DIR &= ~BM( pin ); \ + }while(0) + +// Where port={0,1,2}, pin={0,..,7} and dir is one of: +#define IO_IN 0 +#define IO_OUT 1 + +// Macros for configuring IO input mode: +// Example usage: +// IO_IMODE_PORT_PIN(0, 0, IO_IMODE_PUD); +// IO_IMODE_PORT_PIN(2, 0, IO_IMODE_TRI); +// IO_IMODE_PORT_PIN(1, 3, IO_IMODE_PUD); + +#define IO_IMODE_PORT_PIN(port, pin, imode) \ + do { \ + if (imode == IO_IMODE_TRI) \ + P##port##INP |= BM( pin ); \ + else \ + P##port##INP &= ~BM( pin ); \ + } while (0) + +// where imode is one of: +#define IO_IMODE_PUD 0 // Pull-up/pull-down +#define IO_IMODE_TRI 1 // Tristate + +// Macro for configuring IO drive mode: +// Example usage: +// IIO_PUD_PORT(0, IO_PULLUP); +// IIO_PUD_PORT(1, IO_PULLDOWN); +// IIO_PUD_PORT(2, IO_PULLUP); + +#define IO_PUD_PORT(port, pud) \ + do { \ + if (pud == IO_PULLDOWN) \ + P2INP |= BM( port + 5 ); \ + else \ + P2INP &= ~BM( port + 5 ); \ + } while (0) + +#define IO_PULLUP 0 +#define IO_PULLDOWN 1 + +// Macros for function select (General purpose I/O / Peripheral function): +// Example usage: +// IO_FUNC_PORT0_PIN0(0, 0, IO_FUNC_PERIPH); +// IO_FUNC_PORT0_PIN1(0, 1, IO_FUNC_GIO); +// IO_FUNC_PORT2_PIN3(2, 3, IO_FUNC_PERIPH); + +#define IO_FUNC_PORT_PIN(port, pin, func) \ + do { \ + if((port == 2) && (pin == 3)){ \ + if (func) { \ + P2SEL |= 0x02; \ + } else { \ + P2SEL &= ~0x02; \ + } \ + } \ + else if((port == 2) && (pin == 4)){ \ + if (func) { \ + P2SEL |= 0x04; \ + } else { \ + P2SEL &= ~0x04; \ + } \ + } \ + else{ \ + if (func) { \ + P##port##SEL |= BM( pin ); \ + } else { \ + P##port##SEL &= ~BM( pin ); \ + } \ + } \ + } while (0) + +// where func is one of: +#define IO_FUNC_GIO 0 // General purpose I/O +#define IO_FUNC_PERIPH 1 // Peripheral function + +// Macros for configuring the ADC input: +// Example usage: +// IO_ADC_PORT0_PIN(0, IO_ADC_EN); +// IO_ADC_PORT0_PIN(4, IO_ADC_DIS); +// IO_ADC_PORT0_PIN(6, IO_ADC_EN); + +#define IO_ADC_PORT0_PIN(pin, adcEn) \ + do { \ + if (adcEn) \ + ADCCFG |= BM( pin ); \ + else \ + ADCCFG &= ~BM( pin ); \ + }while (0) + +// where adcEn is one of: +#define IO_ADC_EN 1 // ADC input enabled +#define IO_ADC_DIS 0 // ADC input disab + + +/****************************************************************************** +******************* Interrupt functions/macros ******************* +******************************************************************************* + +Macros which simplify access to interrupt enables, interrupt flags and +interrupt priorities. Increases code legibility. + +******************************************************************************/ + +#define INT_ON 1 +#define INT_OFF 0 +#define INT_SET 1 +#define INT_CLR 0 + +// Global interrupt enables +#define INT_GLOBAL_ENABLE(on) EA = (!!on) + +#define DISABLE_ALL_INTERRUPTS() (IEN0 = IEN1 = IEN2 = 0x00) + +#if(chip == 2430 || chip == 2431) +#define INUM_RFERR 0 +#endif +#if(chip == 1110 || chip == 1111 || chip == 2510 || chip == 2511) +#define INUM_RFTXRX 0 +#endif +#define INUM_ADC 1 +#define INUM_URX0 2 +#define INUM_URX1 3 +#define INUM_ENC 4 +#define INUM_ST 5 +#define INUM_P2INT 6 +#define INUM_UTX0 7 +#define INUM_DMA 8 +#define INUM_T1 9 +#define INUM_T2 10 +#define INUM_T3 11 +#define INUM_T4 12 +#define INUM_P0INT 13 +#define INUM_UTX1 14 +#define INUM_P1INT 15 +#define INUM_RF 16 +#define INUM_WDT 17 + +#define NBR_OF_INTERRUPTS 18 + +// Macro used together with the INUM_* constants +// to enable or disable certain interrupts. +// Example usage: +// INT_ENABLE(INUM_RFERR, INT_ON); +// INT_ENABLE(INUM_URX0, INT_OFF); +// INT_ENABLE(INUM_T1, INT_ON); +// INT_ENABLE(INUM_T2, INT_OFF); +#if(chip == 2430 || chip == 2431) +#define INT_ENABLE(inum, on) \ + do { \ + if (inum==INUM_RFERR) { RFERRIE = on; } \ + else if (inum==INUM_ADC) { ADCIE = on; } \ + else if (inum==INUM_URX0) { URX0IE = on; } \ + else if (inum==INUM_URX1) { URX1IE = on; } \ + else if (inum==INUM_ENC) { ENCIE = on; } \ + else if (inum==INUM_ST) { STIE = on; } \ + else if (inum==INUM_P2INT) { (on) ? (IEN2 |= 0x02) : (IEN2 &= ~0x02); } \ + else if (inum==INUM_UTX0) { (on) ? (IEN2 |= 0x04) : (IEN2 &= ~0x04); } \ + else if (inum==INUM_DMA) { DMAIE = on; } \ + else if (inum==INUM_T1) { T1IE = on; } \ + else if (inum==INUM_T2) { T2IE = on; } \ + else if (inum==INUM_T3) { T3IE = on; } \ + else if (inum==INUM_T4) { T4IE = on; } \ + else if (inum==INUM_P0INT) { P0IE = on; } \ + else if (inum==INUM_UTX1) { (on) ? (IEN2 |= 0x08) : (IEN2 &= ~0x08); } \ + else if (inum==INUM_P1INT) { (on) ? (IEN2 |= 0x10) : (IEN2 &= ~0x10); } \ + else if (inum==INUM_RF) { (on) ? (IEN2 |= 0x01) : (IEN2 &= ~0x01); } \ + else if (inum==INUM_WDT) { (on) ? (IEN2 |= 0x20) : (IEN2 &= ~0x20); } \ + } while (0) +#endif + +#if(chip == 1110 || chip == 1111 || chip == 2510 || chip == 2511) +#define INT_ENABLE(inum, on) \ + do { \ + if (inum==INUM_RFTXRX) { RFTXRXIE = on; } \ + else if (inum==INUM_ADC) { ADCIE = on; } \ + else if (inum==INUM_URX0) { URX0IE = on; } \ + else if (inum==INUM_URX1) { URX1IE = on; } \ + else if (inum==INUM_ENC) { ENCIE = on; } \ + else if (inum==INUM_ST) { STIE = on; } \ + else if (inum==INUM_P2INT) { (on) ? (IEN2 |= 0x02) : (IEN2 &= ~0x02); } \ + else if (inum==INUM_UTX0) { (on) ? (IEN2 |= 0x04) : (IEN2 &= ~0x04); } \ + else if (inum==INUM_DMA) { DMAIE = on; } \ + else if (inum==INUM_T1) { T1IE = on; } \ + else if (inum==INUM_T2) { T2IE = on; } \ + else if (inum==INUM_T3) { T3IE = on; } \ + else if (inum==INUM_T4) { T4IE = on; } \ + else if (inum==INUM_P0INT) { P0IE = on; } \ + else if (inum==INUM_UTX1) { (on) ? (IEN2 |= 0x08) : (IEN2 &= ~0x08); } \ + else if (inum==INUM_P1INT) { (on) ? (IEN2 |= 0x10) : (IEN2 &= ~0x10); } \ + else if (inum==INUM_RF) { (on) ? (IEN2 |= 0x01) : (IEN2 &= ~0x01); } \ + else if (inum==INUM_WDT) { (on) ? (IEN2 |= 0x20) : (IEN2 &= ~0x20); } \ + } while (0) +#endif + + +// Macro for setting interrupt group priority +// Example usage: +// INT_PRIORITY(RFERR_RF_DMA, 3); +#define INT_PRIORITY(group, pri) \ + do { \ + if (pri == 0) { IP0 &= ~group; IP1 &= ~group; } \ + if (pri == 1) { IP0 |= group; IP1 &= ~group; } \ + if (pri == 2) { IP0 &= ~group; IP1 |= group; } \ + if (pri == 3) { IP0 |= group; IP1 |= group; } \ + } while (0) +// Where pri is one of: +// 0 = Level 0 (lowest priority) +// 1 = Level 1 +// 2 = Level 2 +// 3 = Level 3 (highest priority) + +// Where group is one of +#define RFERR_RF_DMA 0x01 // Group IP0 +#define ADC_P2INT_T1 0x02 // Group IP1 +#define URX0_UTX0_T2 0x04 // Group IP2 +#define URX1_UTX1_T3 0x08 // Group IP3 +#define ENC_P1INT_T4 0x10 // Group IP4 +#define ST_WDT_P0INT 0x20 // Group IP5 + + +// Macro used together with the INUM_* constants +// to read the interrupt flags. +// Example usage: +// if (INT_GETFLAG(INUM_URX0)) +// ... +// while (!INT_GETFLAG(INUM_URX0)); + +#if(chip == 2430 || chip == 2431) +#define INT_GETFLAG(inum) ( \ + (inum==INUM_RFERR) ? RFERRIF : \ + (inum==INUM_ADC) ? ADCIF : \ + (inum==INUM_URX0) ? URX0IF : \ + (inum==INUM_URX1) ? URX1IF : \ + (inum==INUM_ENC) ? ENCIF_0 : \ + (inum==INUM_ST) ? STIF : \ + (inum==INUM_P2INT) ? P2IF : \ + (inum==INUM_UTX0) ? UTX0IF : \ + (inum==INUM_DMA) ? DMAIF : \ + (inum==INUM_T1) ? T1IF : \ + (inum==INUM_T2) ? T2IF : \ + (inum==INUM_T3) ? T3IF : \ + (inum==INUM_T4) ? T4IF : \ + (inum==INUM_P0INT) ? P0IF : \ + (inum==INUM_UTX1) ? UTX1IF : \ + (inum==INUM_P1INT) ? P1IF : \ + (inum==INUM_RF) ? S1CON &= ~0x03 : \ + (inum==INUM_WDT) ? WDTIF : \ + 0 \ +) +#endif +#if(chip == 1110 || chip == 1111 || chip == 2510 || chip == 2511) +#define INT_GETFLAG(inum) ( \ + (inum==INUM_RFTXRX) ? RFTXRXIF : \ + (inum==INUM_ADC) ? ADCIF : \ + (inum==INUM_URX0) ? URX0IF : \ + (inum==INUM_URX1) ? URX1IF : \ + (inum==INUM_ENC) ? ENCIF_0 : \ + (inum==INUM_ST) ? STIF : \ + (inum==INUM_P2INT) ? P2IF : \ + (inum==INUM_UTX0) ? UTX0IF : \ + (inum==INUM_DMA) ? DMAIF : \ + (inum==INUM_T1) ? T1IF : \ + (inum==INUM_T2) ? T2IF : \ + (inum==INUM_T3) ? T3IF : \ + (inum==INUM_T4) ? T4IF : \ + (inum==INUM_P0INT) ? P0IF : \ + (inum==INUM_UTX1) ? UTX1IF : \ + (inum==INUM_P1INT) ? P1IF : \ + (inum==INUM_RF) ? S1CON &= ~0x03 : \ + (inum==INUM_WDT) ? WDTIF : \ + 0 \ +) + +#endif + + +// Macro used to set or clear certain interrupt flags. +// Example usage: +// INT_SETFLAG(INUM_URX0, INT_SET; +// INT_SETFLAG(INUM_T3, INT_CLR); +#if(chip == 2430 || chip == 2431) +#define INT_SETFLAG(inum, f) \ + do { \ + if (inum==INUM_RFERR) { RFERRIF= f; } \ + else if (inum==INUM_ADC) { ADCIF = f; } \ + else if (inum==INUM_URX0) { URX0IF = f; } \ + else if (inum==INUM_URX1) { URX1IF = f; } \ + else if (inum==INUM_ENC) { (f) ? (S0CON |= 0x03) : (S0CON &= ~0x03); } \ + else if (inum==INUM_ST) { STIF = f; } \ + else if (inum==INUM_P2INT) { P2IF = f; } \ + else if (inum==INUM_UTX0) { UTX0IF= f; } \ + else if (inum==INUM_DMA) { DMAIF = f; } \ + else if (inum==INUM_T1) { T1IF = f; } \ + else if (inum==INUM_T2) { T2IF = f; } \ + else if (inum==INUM_T3) { T3IF = f; } \ + else if (inum==INUM_T4) { T4IF = f; } \ + else if (inum==INUM_P0INT) { P0IF = f; } \ + else if (inum==INUM_UTX1) { UTX1IF= f; } \ + else if (inum==INUM_P1INT) { P1IF = f; } \ + else if (inum==INUM_RF) { (f) ? (S1CON |= 0x03) : (S1CON &= ~0x03); } \ + else if (inum==INUM_WDT) { WDTIF = f; } \ + } while (0) +#endif +#if(chip == 1110 || chip == 1111 || chip == 2510 || chip == 2511) +#define INT_SETFLAG(inum, f) \ + do { \ + if (inum==INUM_RFTXRX){ RFTXRXIF = f; } \ + else if (inum==INUM_ADC) { ADCIF = f; } \ + else if (inum==INUM_URX0) { URX0IF = f; } \ + else if (inum==INUM_URX1) { URX1IF = f; } \ + else if (inum==INUM_ENC) { ENCIF_1 = ENCIF_0 = f; } \ + else if (inum==INUM_ST) { STIF = f; } \ + else if (inum==INUM_P2INT) { P2IF = f; } \ + else if (inum==INUM_UTX0) { UTX0IF= f; } \ + else if (inum==INUM_DMA) { DMAIF = f; } \ + else if (inum==INUM_T1) { T1IF = f; } \ + else if (inum==INUM_T2) { T2IF = f; } \ + else if (inum==INUM_T3) { T3IF = f; } \ + else if (inum==INUM_T4) { T4IF = f; } \ + else if (inum==INUM_P0INT) { P0IF = f; } \ + else if (inum==INUM_UTX1) { UTX1IF= f; } \ + else if (inum==INUM_P1INT) { P1IF = f; } \ + else if (inum==INUM_RF) { (f) ? (S1CON |= 0x03) : (S1CON &= ~0x03); } \ + else if (inum==INUM_WDT) { WDTIF = f; } \ + } while (0) +#endif + + + +/****************************************************************************** +************************** DMA structures / macros ************************* +******************************************************************************* + +The macros and structs in this section simplify setup and usage of DMA. + +******************************************************************************/ + +#define DMA_CHANNEL_0 0x01 +#define DMA_CHANNEL_1 0x02 +#define DMA_CHANNEL_2 0x04 +#define DMA_CHANNEL_3 0x08 +#define DMA_CHANNEL_4 0x10 + +#define VLEN_USE_LEN 0x00 // Use LEN for transfer count +#define VLEN_FIXED 0x00 // Use LEN for transfer count +#define VLEN_1_P_VALOFFIRST 0x01 // Transfer the first byte + the number of bytes indicated by the first byte +#define VLEN_VALOFFIRST 0x02 // Transfer the number of bytes indicated by the first byte (starting with the first byte) +#define VLEN_1_P_VALOFFIRST_P_1 0x03 // Transfer the first byte + the number of bytes indicated by the first byte + 1 more byte +#define VLEN_1_P_VALOFFIRST_P_2 0x04 // Transfer the first byte + the number of bytes indicated by the first byte + 2 more bytes + +#define WORDSIZE_BYTE 0x00 // Transfer a byte at a time +#define WORDSIZE_WORD 0x01 // Transfer a 16-bit word at a time + +#define TMODE_SINGLE 0x00 // Transfer a single byte/word after each DMA trigger +#define TMODE_BLOCK 0x01 // Transfer block of data (length len) after each DMA trigger +#define TMODE_SINGLE_REPEATED 0x02 // Transfer single byte/word (after len transfers, rearm DMA) +#define TMODE_BLOCK_REPEATED 0x03 // Transfer block of data (after len transfers, rearm DMA) + +#define DMATRIG_NONE 0 // No trigger, setting DMAREQ.DMAREQx bit starts transfer +#define DMATRIG_PREV 1 // DMA channel is triggered by completion of previous channel +#define DMATRIG_T1_CH0 2 // Timer 1, compare, channel 0 +#define DMATRIG_T1_CH1 3 // Timer 1, compare, channel 1 +#define DMATRIG_T1_CH2 4 // Timer 1, compare, channel 2 +#define DMATRIG_T2_COMP 5 // Timer 2, compare +#define DMATRIG_T2_OVFL 6 // Timer 2, overflow +#define DMATRIG_T3_CH0 7 // Timer 3, compare, channel 0 +#define DMATRIG_T3_CH1 8 // Timer 3, compare, channel 1 +#define DMATRIG_T4_CH0 9 // Timer 4, compare, channel 0 +#define DMATRIG_T4_CH1 10 // Timer 4, compare, channel 1 +#define DMATRIG_ST 11 // Sleep Timer compare +#define DMATRIG_IOC_0 12 // Port 0 I/O pin input transition +#define DMATRIG_IOC_1 13 // Port 1 I/O pin input transition +#define DMATRIG_URX0 14 // USART0 RX complete +#define DMATRIG_UTX0 15 // USART0 TX complete +#define DMATRIG_URX1 16 // USART1 RX complete +#define DMATRIG_UTX1 17 // USART1 TX complete +#define DMATRIG_FLASH 18 // Flash data write complete +#define DMATRIG_RADIO 19 // RF packet byte received/transmit +#define DMATRIG_ADC_CHALL 20 // ADC end of a conversion in a sequence, sample ready +#define DMATRIG_ADC_CH0 21 // ADC end of conversion channel 0 in sequence, sample ready +#define DMATRIG_ADC_CH1 22 // ADC end of conversion channel 1 in sequence, sample ready +#define DMATRIG_ADC_CH2 23 // ADC end of conversion channel 2 in sequence, sample ready +#define DMATRIG_ADC_CH3 24 // ADC end of conversion channel 3 in sequence, sample ready +#define DMATRIG_ADC_CH4 25 // ADC end of conversion channel 4 in sequence, sample ready +#define DMATRIG_ADC_CH5 26 // ADC end of conversion channel 5 in sequence, sample ready +#define DMATRIG_ADC_CH6 27 // ADC end of conversion channel 6 in sequence, sample ready +#define DMATRIG_ADC_CH7 28 // ADC end of conversion channel 7 in sequence, sample ready +#define DMATRIG_ENC_DW 29 // AES encryption processor requests download input data +#define DMATRIG_ENC_UP 30 // AES encryption processor requests upload output data + +#define SRCINC_0 0x00 // Increment source pointer by 0 bytes/words after each transfer +#define SRCINC_1 0x01 // Increment source pointer by 1 bytes/words after each transfer +#define SRCINC_2 0x02 // Increment source pointer by 2 bytes/words after each transfer +#define SRCINC_M1 0x03 // Decrement source pointer by 1 bytes/words after each transfer + +#define DESTINC_0 0x00 // Increment destination pointer by 0 bytes/words after each transfer +#define DESTINC_1 0x01 // Increment destination pointer by 1 bytes/words after each transfer +#define DESTINC_2 0x02 // Increment destination pointer by 2 bytes/words after each transfer +#define DESTINC_M1 0x03 // Decrement destination pointer by 1 bytes/words after each transfer + +#define IRQMASK_DISABLE 0x00 // Disable interrupt generation +#define IRQMASK_ENABLE 0x01 // Enable interrupt generation upon DMA channel done + +#define M8_USE_8_BITS 0x00 // Use all 8 bits for transfer count +#define M8_USE_7_BITS 0x01 // Use 7 LSB for transfer count + +#define PRI_LOW 0x00 // Low, CPU has priority +#define PRI_GUARANTEED 0x01 // Guaranteed, DMA at least every second try +#define PRI_HIGH 0x02 // High, DMA has priority +#define PRI_ABSOLUTE 0x03 // Highest, DMA has priority. Reserved for DMA port access. + + +#pragma bitfields=reversed +typedef struct { + BYTE SRCADDRH; + BYTE SRCADDRL; + BYTE DESTADDRH; + BYTE DESTADDRL; + BYTE VLEN : 3; + BYTE LENH : 5; + BYTE LENL : 8; + BYTE WORDSIZE : 1; + BYTE TMODE : 2; + BYTE TRIG : 5; + BYTE SRCINC : 2; + BYTE DESTINC : 2; + BYTE IRQMASK : 1; + BYTE M8 : 1; + BYTE PRIORITY : 2; +} DMA_DESC; +#pragma bitfields=default + + +#define DMA_SET_ADDR_DESC0(a) \ + do{ \ + DMA0CFGH = HIBYTE( a ); \ + DMA0CFGL = LOBYTE( a ); \ + } while(0) + +#define DMA_SET_ADDR_DESC1234(a) \ + do{ \ + DMA1CFGH = HIBYTE( a ); \ + DMA1CFGL = LOBYTE( a ); \ + } while(0) + +#if(chip == 2430 || chip == 2431) +#define DMA_ARM_CHANNEL(ch) \ + DMAARM = ((0x01 << ch) & 0x1F); +#endif + +#if(chip == 0000) +//Todo: remove NOPs +#endif +#if(chip == 1110 || chip == 1111 || chip == 2510 || chip == 2511) +#define DMA_ARM_CHANNEL(ch) \ + do{ \ + asm("NOP"); \ + asm("NOP"); \ + asm("NOP"); \ + asm("NOP"); \ + asm("NOP"); \ + asm("NOP"); \ + asm("NOP"); \ + asm("NOP"); \ + DMAARM = ((0x01 << ch) & 0x1F); \ + asm("NOP"); \ + asm("NOP"); \ + asm("NOP"); \ + asm("NOP"); \ + asm("NOP"); \ + asm("NOP"); \ + asm("NOP"); \ + } while(0) +#endif + +#define DMA_ABORT_CHANNEL(ch) DMAARM = (0x80 | ( BM( ch ) & 0x1F) ) +#define DMA_MAN_TRIGGER(ch) DMAREQ = BM( ch ) +#define DMA_START_CHANNEL(ch) DMA_MAN_TRIGGER( ch ) + +// Macro for quickly setting the destination address of a DMA structure +#define SET_DMA_DEST(pDmaDesc, dest) \ + do{ \ + pDmaDesc->DESTADDRH = HIBYTE( dest ); \ + pDmaDesc->DESTADDRL = LOBYTE( dest ); \ + } while (0) + +// Macro for quickly setting the source address of a DMA structure +#define SET_DMA_SOURCE(pDmaDesc, source) \ + do{ \ + pDmaDesc->SRCADDRH = HIBYTE( source ); \ + pDmaDesc->SRCADDRL = LOBYTE( source ); \ + } while (0) + +// Macro for quickly setting the number of bytes to be transferred by the DMA. +// Max lenght is 0x1FFF +#define SET_DMA_LENGTH(pDmaDesc, length) \ + do{ \ + pDmaDesc->LENH = HIBYTE( length ); \ + pDmaDesc->LENL = LOBYTE( length ); \ + } while (0) + +// Macro for getting the destination address of a DMA channel +#define GET_DMA_DEST(pDmaDesc) \ + ( (WORD)pDmaDesc->DESTADDRL | ( (WORD)pDmaDesc->DESTADDRH << 8 )) + +// Macro for getting the source address of a DMA channel +#define GET_DMA_SOURCE(pDmaDesc) \ + ( (WORD)pDmaDesc->SRCADDRL | ( (WORD)pDmaDesc->SRCADDRH << 8 )) + + +/****************************************************************************** +******************* Common USART functions/macros ******************* +******************************************************************************* + +The macros in this section are available for both SPI and UART operation. + +******************************************************************************/ + +// Example usage: +// USART0_FLUSH(); +#define USART_FLUSH(num) (U##num##UCR |= 0x80) +#define USART0_FLUSH() USART_FLUSH(0) +#define USART1_FLUSH() USART_FLUSH(1) + +// Example usage: +// if (USART0_BUSY()) +// ... +#define USART_BUSY(num) (U##num##CSR & 0x01) +#define USART0_BUSY() USART_BUSY(0) +#define USART1_BUSY() USART_BUSY(1) + +// Example usage: +// while(!USART1_BYTE_RECEIVED()) +// ... +#define USART_BYTE_RECEIVED(num) (U##num##CSR & 0x04) +#define USART0_BYTE_RECEIVED() USART_BYTE_RECEIVED(0) +#define USART1_BYTE_RECEIVED() USART_BYTE_RECEIVED(1) + +// Example usage: +// if(USART1_BYTE_TRANSMITTED()) +// ... +#define USART_BYTE_TRANSMITTED(num) (U##num##CSR & 0x02) +#define USART0_BYTE_TRANSMITTED() USART_BYTE_TRANSMITTED(0) +#define USART1_BYTE_TRANSMITTED() USART_BYTE_TRANSMITTED(1) + + +/****************************************************************************** +******************* USART-UART specific functions/macros ******************* +******************************************************************************/ +#if (chip == 2430 || chip == 2431) +// The macros in this section simplify UART operation. +#define BAUD_E(baud, clkDivPow) ( \ + (baud==2400) ? 6 +clkDivPow : \ + (baud==4800) ? 7 +clkDivPow : \ + (baud==9600) ? 8 +clkDivPow : \ + (baud==14400) ? 8 +clkDivPow : \ + (baud==19200) ? 9 +clkDivPow : \ + (baud==28800) ? 9 +clkDivPow : \ + (baud==38400) ? 10 +clkDivPow : \ + (baud==57600) ? 10 +clkDivPow : \ + (baud==76800) ? 11 +clkDivPow : \ + (baud==115200) ? 11 +clkDivPow : \ + (baud==153600) ? 12 +clkDivPow : \ + (baud==230400) ? 12 +clkDivPow : \ + (baud==307200) ? 13 +clkDivPow : \ + 0 ) + + +#define BAUD_M(baud) ( \ + (baud==2400) ? 59 : \ + (baud==4800) ? 59 : \ + (baud==9600) ? 59 : \ + (baud==14400) ? 216 : \ + (baud==19200) ? 59 : \ + (baud==28800) ? 216 : \ + (baud==38400) ? 59 : \ + (baud==57600) ? 216 : \ + (baud==76800) ? 59 : \ + (baud==115200) ? 216 : \ + (baud==153600) ? 59 : \ + (baud==230400) ? 216 : \ + (baud==307200) ? 59 : \ + 0) +#endif + + +#if (chip == 1110 || chip == 2510) +#define BAUD_E(baud, clkDivPow)( \ + (baud == 2400) ? 6 +clkDivPow : \ + (baud == 4800) ? 7 +clkDivPow : \ + (baud == 9600) ? 8 +clkDivPow : \ + (baud == 14400) ? 9 +clkDivPow : \ + (baud == 19200) ? 9 +clkDivPow : \ + (baud == 28800) ? 10 +clkDivPow : \ + (baud == 38400) ? 10 +clkDivPow : \ + (baud == 57600) ? 11 +clkDivPow : \ + (baud == 76800) ? 11 +clkDivPow : \ + (baud == 115200) ? 12 +clkDivPow : \ + (baud == 230400) ? 13 +clkDivPow : \ + (baud == 307200) ? 13 +clkDivPow : \ + (baud == 460800) ? 14 +clkDivPow : \ + 0) + +#define BAUD_M(baud) ( \ + (baud == 2400) ? 131 : \ + (baud == 4800) ? 131 : \ + (baud == 9600) ? 131 : \ + (baud == 14400) ? 34 : \ + (baud == 19200) ? 131 : \ + (baud == 28800) ? 34 : \ + (baud == 38400) ? 131 : \ + (baud == 57600) ? 34 : \ + (baud == 76800) ? 131 : \ + (baud == 115200) ? 34 : \ + (baud == 230400) ? 34 : \ + (baud == 307200) ? 131 : \ + (baud == 460800) ? 34 : \ + 0) +#endif + +#if (chip == 1111 || chip == 2511) +#define BAUD_E(baud, clkDivPow)( \ + (baud == 2400) ? 6 +clkDivPow : \ + (baud == 4800) ? 7 +clkDivPow : \ + (baud == 9600) ? 8 +clkDivPow : \ + (baud == 14400) ? 9 +clkDivPow : \ + (baud == 19200) ? 9 +clkDivPow : \ + (baud == 28800) ? 10 +clkDivPow : \ + (baud == 38400) ? 10 +clkDivPow : \ + (baud == 57600) ? 11 +clkDivPow : \ + (baud == 76800) ? 11 +clkDivPow : \ + (baud == 115200) ? 12 +clkDivPow : \ + (baud == 230400) ? 13 +clkDivPow : \ + (baud == 307200) ? 13 +clkDivPow : \ + (baud == 460800) ? 14 +clkDivPow : \ + 0) + +#define BAUD_M(baud) ( \ + (baud == 2400) ? 163 : \ + (baud == 4800) ? 163 : \ + (baud == 9600) ? 163 : \ + (baud == 14400) ? 59 : \ + (baud == 19200) ? 163 : \ + (baud == 28800) ? 59 : \ + (baud == 38400) ? 163 : \ + (baud == 57600) ? 59 : \ + (baud == 76800) ? 163 : \ + (baud == 115200) ? 59 : \ + (baud == 230400) ? 59 : \ + (baud == 307200) ? 163 : \ + (baud == 460800) ? 59 : \ + 0) +#endif + +// Macro for setting up a UART transfer channel. The macro sets the appropriate +// pins for peripheral operation, sets the baudrate, and the desired options of +// the selected uart. _uart_ indicates which uart to configure and must be +// either 0 or 1. _baudRate_ must be one of 2400, 4800, 9600, 14400, 19200, +// 28800, 38400, 57600, 76800, 115200, 153600, 230400 or 307200. Possible +// options are defined below. +// +// Example usage: +// +// UART_SETUP(0,115200,HIGH_STOP); +// +// This configures uart 0 for contact with "hyperTerminal", setting: +// Baudrate: 115200 +// Data bits: 8 +// Parity: None +// Stop bits: 1 +// Flow control: None +// + +#define UART_SETUP(uart, baudRate, options) \ + do { \ + if ((options) & FLOW_CONTROL_ENABLE){ \ + if((uart) == 0){ /* USART0 */\ + if(PERCFG & 0x01){ /* Alt 2 */\ + P1SEL |= 0x3C; \ + } else { /* Alt 1 */\ + P0SEL |= 0x3C; \ + } \ + } \ + else { /* USART1 */\ + if(PERCFG & 0x02){ /* Alt 2 */\ + P1SEL |= 0xF0; \ + } else { /* Alt 1 */\ + P0SEL |= 0x3C; \ + } \ + } \ + } \ + else{ /* Flow Ctrl Dis*/\ + if((uart) == 0){ /* USART0 */\ + if(PERCFG & 0x01){ /* Alt 2 */\ + P1SEL |= 0x30; \ + } else { /* Alt 1 */\ + P0SEL |= 0x0C; \ + } \ + } \ + else { /* USART1 */\ + if(PERCFG & 0x02){ /* Alt 2 */\ + P1SEL |= 0xC0; \ + } else { /* Alt 1 */\ + P0SEL |= 0x30; \ + } \ + } \ + } \ + \ + U##uart##GCR = BAUD_E((baudRate), CLKSPD); \ + U##uart##BAUD = BAUD_M(baudRate); \ + \ + U##uart##CSR |= 0x80; \ + \ + U##uart##UCR |= ((options) | 0x80); \ + \ + if((options) & TRANSFER_MSB_FIRST){ \ + U##uart##GCR |= 0x20; \ + } \ + } while(0) + + +// Options for UART_SETUP macro +#define FLOW_CONTROL_ENABLE 0x40 +#define FLOW_CONTROL_DISABLE 0x00 +#define EVEN_PARITY 0x20 +#define ODD_PARITY 0x00 +#define NINE_BIT_TRANSFER 0x10 +#define EIGHT_BIT_TRANSFER 0x00 +#define PARITY_ENABLE 0x08 +#define PARITY_DISABLE 0x00 +#define TWO_STOP_BITS 0x04 +#define ONE_STOP_BITS 0x00 +#define HIGH_STOP 0x02 +#define LOW_STOP 0x00 +#define HIGH_START 0x01 +#define TRANSFER_MSB_FIRST 0x80 +#define TRANSFER_MSB_LAST 0x00 + + +// Example usage: +// if(UART0_PARERR()) +// ... +#define UART_PARERR(num) (U##num##CSR & 0x08) +#define UART0_PARERR() UART_PARERR(0) +#define UART1_PARERR() UART_PARERR(1) + +// Example usage: +// if(UART1_FRAMEERR()) +// ... +#define UART_FRAMEERR(num) (U ##num## CSR & 0x10) +#define UART0_FRAMEERR() UART_FRAMEERR(0) +#define UART1_FRAMEERR() UART_FRAMEERR(1) + + +// Example usage: +// char ch = 'A'; +// UART1_SEND(ch); +// ... +// UART1_RECEIVE(ch); +#define UART_SEND(num, x) U##num##DBUF = x +#define UART0_SEND(x) UART_SEND(0, x) +#define UART1_SEND(x) UART_SEND(1, x) + +#define UART_RECEIVE(num, x) x = U##num##DBUF +#define UART0_RECEIVE(x) UART_RECEIVE(0, x) +#define UART1_RECEIVE(x) UART_RECEIVE(1, x) + + + +/****************************************************************************** +******************* USART-SPI specific functions/macros ******************* +******************************************************************************* + +The macros in this section simplify SPI operation. + +******************************************************************************/ + +// Macro for setting up an SPI connection. The macro configures the appropriate +// pins for peripheral operation, sets the baudrate if the chip is configured +// to be SPI master, and sets the desired clock polarity and phase. Whether to +// transfer MSB or LSB first is also determined. _spi_ indicates whether +// to use spi 0 or 1. _baudRate_ must be one of 2400, 4800, 9600, 14400, 19200, +// 28800, 38400, 57600, 76800, 115200, 153600, 230400 or 307200. +// Possible options are defined below. + +#define SPI_SETUP(spi, baudRate, options) \ + do { \ + U##spi##UCR = 0x80; \ + U##spi##CSR = 0x00; \ + \ + if((options) & SPI_SLAVE){ /* Slave */\ + if(spi == 0){ /* USART0 */\ + if(PERCFG & 0x01){ /* Alt 2 */\ + P1SEL |= 0x3C; \ + } else { /* Alt 1 */\ + P0SEL |= 0x3C; \ + } \ + } else { /* USART1 */\ + if(PERCFG & 0x02){ /* Alt 2 */\ + P1SEL |= 0xF0; \ + } else { \ + P0SEL |= 0x3C; /* Alt 1 */\ + } \ + } \ + U##spi##CSR = 0x20; \ + } \ + else { /* Master */\ + if(spi == 0){ /* USART0 */\ + if(PERCFG & 0x01){ /* Alt 2 */\ + P1SEL |= 0x38; \ + P1SEL &= ~0x04; \ + } else { /* Alt 1 */\ + P0SEL |= 0x2C; \ + P0SEL &= ~0x10; \ + } \ + } else { /* USART 1 */\ + if(PERCFG & 0x02){ /* Alt 2 */\ + P1SEL |= 0xE0; \ + P1SEL &= ~0x10; \ + } else { /* Alt 1 */\ + P0SEL |= 0x38; \ + P0SEL &= ~0x04; \ + } \ + } \ + U##spi##GCR = BAUD_E(baudRate, CLKSPD); \ + U##spi##BAUD = BAUD_M(baudRate); \ + } \ + U##spi##GCR |= ((options) & 0xE0); \ + } while(0) + + +// Options for the SPI_SETUP macro. +#define SPI_SLAVE 0x01 +#define SPI_MASTER 0x00 +#define SPI_CLOCK_POL_LO 0x00 +#define SPI_CLOCK_POL_HI 0x80 +#define SPI_CLOCK_PHA_0 0x00 +#define SPI_CLOCK_PHA_1 0x40 +#define SPI_TRANSFER_MSB_FIRST 0x20 +#define SPI_TRANSFER_MSB_LAST 0x00 + + + +/****************************************************************************** +******************* FLASH programming functions ******************* +******************************************************************************* + +_halFlashWritePage(...)_ writes a whole flash page. Because code memory cannot +be read during flash write, the writing routines are copied to XDATA RAM. The +function is implemented in assembly code with file extensions .s51 rather than .c + +The Direct Memory Access (DMA) may also be used for flash write. + +******************************************************************************/ + +#if (chip == 2430 || chip == 2431) +//Macro for erasing a given flash page +#define FLASH_ERASE_PAGE(page) \ + do{ \ + FADDRH = (page) << 1; \ + FCTL = 0x01; \ + asm("NOP"); \ + while(FCTL == 0x80); \ + }while (0) + +#define SET_FLASH_WRITE_TIME() \ + FWT = 0x2A >> CLKSPD; + +#endif + +#if (chip == 2510 || chip == 1110 || chip == 1111 || chip == 2511) +//Macro for erasing a given flash page - NOT TESTED/VERIFIED! +#define FLASH_ERASE_PAGE(page) \ + do{ \ + FADDRH = (page) << 1; \ + FADDRL = 0x00; \ + FLASH_CONFIG(0x01); \ + }while (0) + +#define SET_FLASH_WRITE_TIME() \ + FWT = 0x22 >> CLKSPD; + +#endif + +#if (chip == 2510 || chip == 1110 || chip == 1111 || chip == 2511) +#define FLASH_CONFIG(options) \ + do { \ + FWT = ( 0x22 >> CLKSPD ); \ + FCTL = (options); \ + } while (0) +#endif + +#if (chip == 2510 || chip == 1110 || chip == 1111 || chip == 2511) +// _options_ may be the following: +#define READ_WHEN_NEED 0x00 +#define CONTINOUS_READ 0x10 +#define WRITE 0x02 +#define FLASH_BUSY 0x80 +#endif + +/****************************************************************************** +* @fn halFlashDmaTrigger +* +* @brief +* This function gives the first FLASH DMA trigger. +* +* Parameters: +* +* @param void +* +* @return void +* +******************************************************************************/ +void halFlashDmaTrigger(void); + + +/****************************************************************************** +* @fn halFlashWritePage +* +* @brief +* This function writes a byte field in XDATA RAM to a given flash +* page. Normal program execution is run from flash. However during flash +* write, flash memory is not available for reading. To circumvent this +* problem the core operation of this procedure, namely the actual flash +* write procedure, is copied to XDATA RAM and run from there. The flash +* write procedure is copied to a 35 byte XDATA RAM buffer. +* Prior to a write the page is erased. +* +* This function disables interrupts when running, and re-enables interrupt +* if interrupts were enabled at function entry. +* +* Parameters: +* +* @param BYTE* pSrcAddr +* Pointer to first byte in xdata space which is to be written to +* flash. The number of bytes a flash page consists of starting from +* this address will be written to the page _page_. +* @param BYTE* pBuffer +* Pointer to a buffer of 35 bytes in XDATA RAM to which the flash +* write procedure +* can be copied. +* @param BYTE page +* Indicates which of the flash pages the data is to be written to. +* +* @return void +* +******************************************************************************/ +void halFlashWritePage(BYTE *pSrcAddr, BYTE *pBuffer, BYTE page); + + +/****************************************************************************** +******************* Power and clock management ******************** +******************************************************************************* + +These macros are used to set power-mode, clock source and clock speed. + +******************************************************************************/ + +// Macro for getting the clock division factor +#if (chip == 2430 || chip == 2431) +#define CLKSPD ( CLKCON & 0x01 ) +#endif + +#if (chip == 2510 || chip == 2511 || chip == 1110 || chip == 1111) +#define CLKSPD (CLKCON & 0x07) +#endif + +// Macro for getting the timer tick division factor +#define TICKSPD ((CLKCON & 0x38) >> 3) + +// Macro for checking status of the crystal oscillator +#define XOSC_STABLE (SLEEP & 0x40) + +// Macro for checking status of the high frequency RC oscillator. +#define HIGH_FREQUENCY_RC_OSC_STABLE (SLEEP & 0x20) + +// Macro for setting power mode +#define SET_POWER_MODE(mode) \ + do { \ + SLEEP &= ~0x03; \ + SLEEP |= mode; \ + PCON |= 0x01; \ + }while (0) + +// Where _mode_ is one of +#define POWER_MODE_0 0x00 // Clock oscillators on, voltage regulator on +#define POWER_MODE_1 0x01 // 32.768 KHz oscillator on, voltage regulator on +#define POWER_MODE_2 0x02 // 32.768 KHz oscillator on, voltage regulator off +#define POWER_MODE_3 0x03 // All clock oscillators off, voltage regulator off + +// Macro for setting the 32 kHz clock source +// Please not that this macro only can be run when the device run on the RC osc +#define SET_32KHZ_CLOCK_SOURCE(source) \ + do { \ + if( source ) { \ + CLKCON |= 0x80; \ + } else { \ + CLKCON &= ~0x80; \ + } \ + } while (0) + +// Where _source_ is one of +#define CRYSTAL 0x00 +#define RC 0x01 + +// Macro for setting the main clock oscillator source, +// turns off the clock source not used. Settings TICKSPD +// equal CLKSPD +#if (chip == 2430 || chip == 2431 ) +// Use this for CC2430 rev. B +#define REV_B_SET_MAIN_CLOCK_SOURCE(source) \ + do { \ + if(source) { \ + CLKCON |= 0x40; \ + while(!HIGH_FREQUENCY_RC_OSC_STABLE); \ + SLEEP |= 0x04; \ + } \ + else { \ + SLEEP &= ~0x04; \ + while(!XOSC_STABLE); \ + asm("NOP"); \ + CLKCON &= ~0x40; \ + SLEEP |= 0x04; \ + } \ + }while (0) + +// Use this for CC2430 rev. C -> +#define REV_C_SET_MAIN_CLOCK_SOURCE(source) \ + do { \ + if(source) { \ + CLKCON |= 0x40; \ + while( !(CLKCON & 0x40) ); \ + } \ + else { \ + CLKCON &= ~0x40; \ + while( CLKCON & 0x40 ); \ + } \ + }while (0) + +#define SET_MAIN_CLOCK_SOURCE( source ) \ + do { \ + if( CHVER < REV_C ) \ + REV_B_SET_MAIN_CLOCK_SOURCE( source ); \ + else \ + REV_C_SET_MAIN_CLOCK_SOURCE( source ); \ + }while(0) +#endif + +#if (chip == 1110 || chip == 1111 || chip == 2510 || chip == 2511) +#define SET_MAIN_CLOCK_SOURCE( source ) \ + do { \ + if(source) { \ + CLKCON |= 0x40; \ + while(!HIGH_FREQUENCY_RC_OSC_STABLE); \ + SLEEP |= 0x04; \ + } \ + else { \ + SLEEP &= ~0x04; \ + while(!XOSC_STABLE); \ + asm("NOP"); \ + CLKCON &= ~0x47; \ + SLEEP |= 0x04; \ + } \ + }while(0) +#endif + + +#if (chip == 1110 || chip == 2510) +// Macro for setting the main clock division, +#define SET_MAIN_CLOCK_SPEED(frequency) \ + do { \ + CLKCON = ((CLKCON & ~0x07) | (frequency & 0x07)); \ + }while (0) + +// where frequency is one of +#define MHZ_26 0x00 +#define MHZ_13 0x01 +#define MHZ_6_5 0x02 +#define MHZ_3_25 0x03 +#define MHZ_1_62 0x04 +#define MHZ_0_81 0x05 +#define MHZ_0_40 0x06 +#define MHZ_0_20 0x07 +#endif + +#if (chip == 1111 || chip == 2511) +// Macro for setting the main clock division, +#define SET_MAIN_CLOCK_SPEED(frequency) \ + do { \ + CLKCON = ((CLKCON & ~0x07) | (frequency & 0x07)); \ + }while (0) + +// where frequency is one of +#define MHZ_24 0x00 +#define MHZ_12 0x01 +#define MHZ_6 0x02 +#define MHZ_3 0x03 +#define MHZ_1_5 0x04 +#define MHZ_0_75 0x05 +#define MHZ_0_37 0x06 +#define MHZ_0_19 0x07 +#endif + +/****************************************************************************** +******************* Timer macros/functions ******************* +******************************************************************************* +General: +The timers/counters can be configured in a number of ways. The following +functions allow basic configuration of the timers as interrupt timers, +pulse width modulators (PWM) and capture timers. Other uses require manual +configuration of the timers/counters. + +Generally 3 steps are nescessary to start a timer: + + TIMERx_INIT(); + BOOL halSetTimerxPeriod(period); + TIMERx_RUN(TRUE); + +where x is the timer number. Please see the function / macro in question for +details. + +All timers can generate interrupts. The configuration of interrupts is not +included in the HAL. + +******************************************************************************/ + +#define CLR_TIMER34_IF( bitMask )\ + TIMIF = ( TIMIF & 0x40 ) | ( 0x3F & (~bitMask) ) + +#define CLR_TIMER1_IF( bitMask )\ + T1CTL = ( T1CTL & 0x0F ) | ( 0xF0 & (~bitMask) ) + +/****************************************************************************** +* @fn halSetTimer1Period +* +* @brief +* This function sets up timer 1 to run with a given period. If _period_ is +* set to 0, maximum period length will be used. The first time the timer +* is used the macro TIMER1_INIT() should be run to clear all settings. The +* timer is started and stopped with the macro TIMER1_RUN(TRUE / FALSE). +* +* Parameters: +* +* @param DWORD period +* The desired timer period in u-seconds. +* +* @return WORD +* The timer value written to the register if the configuration was +* successful and 0 if the period could not be achieved. This return +* value can be used for determining pulse widths when the timer is +* used in PWM mode. +* +******************************************************************************/ +WORD halSetTimer1Period(DWORD period); + + +// Macro for initialising timer 1. Resets all involved registers and disables +// all interrupt masks +#define TIMER1_INIT() \ + do { \ + T1CTL = 0x00; \ + T1CCTL0 = 0x00; \ + T1CCTL1 = 0x00; \ + T1CCTL2 = 0x00; \ + TIMIF = ~0x40; \ + } while (0) + +// Macro for configuring a channel of timer 1 for PWM. Channel may be +// either 1 or 2 +#define TIMER1_PWM_CONFIG(channel) \ + do { \ + T1CCTL##channel## = 0x24; \ + if(PERCFG&0x40) { \ + if(channel == 0x01){ \ + IO_FUNC_PORT_PIN(1,1,IO_FUNC_PERIPH); \ + } \ + else { \ + IO_FUNC_PORT_PIN(1,0,IO_FUNC_PERIPH); \ + } \ + } \ + else { \ + if(channel == 0x01){ \ + IO_FUNC_PORT_PIN(0,3,IO_FUNC_PERIPH); \ + } \ + else { \ + IO_FUNC_PORT_PIN(0,4,IO_FUNC_PERIPH); \ + } \ + } \ + } while(0) + +// Macro for changing the pulse length of a timer in PWM mode. The value is +// not scaled and the user must verify that it is correct. _channel_ is the +// channel (1 or 2) configured for PWM operation, whereas _value_ is the +// 16 bit word giving the pulse length. This argument should be shorter than +// or equal to the value returned from the function halSetTimer1Period(...). +#define TIMER1_SET_PWM_PULSE_LENGTH(channel, value) \ + do { \ + T1CC##channel##L = LOBYTE( value ); \ + T1CC##channel##H = HIBYTE( value ); \ + } while(0) + + +// Macro for configuring a channel of timer 1 for capture. +#define TIMER1_CAPTURE_CHANNEL(channel, edge) \ + do { \ + T1CCTL ##channel = edge; \ + if(PERCFG&0x40) { \ + if(channel == 0x01){ \ + IO_FUNC_PORT_PIN(1,1,IO_FUNC_PERIPH); \ + } \ + else { \ + IO_FUNC_PORT_PIN(1,0,IO_FUNC_PERIPH); \ + } \ + } \ + else { \ + if(channel == 0x01){ \ + IO_FUNC_PORT_PIN(0,3,IO_FUNC_PERIPH); \ + } \ + else { \ + IO_FUNC_PORT_PIN(0,4,IO_FUNC_PERIPH); \ + } \ + } \ + } while(0) + +// Where _edge_ is either +#define POS_EDGE 0x01 // Capture when a positive edge on the channel input is detected +#define NEG_EDGE 0x02 // Capture when a negative edge on the channel input is detected +#define ANY_EDGE 0x03 // Capture when either a positive or a negative edge on the + // channel input is detected. + +// Macro for enabling or disabling overflow interrupts of timer 1. +#define TIMER1_ENABLE_OVERFLOW_INT(val) \ + (TIMIF = (val) ? TIMIF | 0x40 : TIMIF & ~0x40) + + +#if (chip == 2430 || chip == 2431) +/****************************************************************************** +* @fn halSetTimer2Period +* +* @brief +* This function sets the period and overflow counter value of the MAC timer +* (timer 2). The timer can be set up with 320 u-second periods according to +* IEEE 802.15.4 or as a normal counter with 1 m-second period by using the +* option TIMER2_MAC_TIMER or TIMER2_NORMAL_TIMER respectively. The value of +* _period_ gives the number of periods (320 u-seconds or 1 m-seconds) to +* generate a compare event. The timer is set up to compensate for any clock +* division. The timer is also set up to be synchronised with the 32.768 KHz +* clock when entering or leaving power mode 0. When starting synchronously +* from power mode 1 or 2, the timer value is updated by adding the time +* passed since PM 0 was left. This time is kept by the 32.768 KHz clock. +* This way the time is kept as if the chip had been in power mode 0 the +* whole time. The timer must be started with the macro +* TIMER2_RUN(TRUE) or MAC_TIMER_RUN(TRUE). The macro TIMER2_INIT() should be +* run in advance to reset all register values. +* +* Parameters: +* +* @param BYTE mode +* Determines which time period Timer 2 is to use. The period of Timer 2 +* is either 320 u-seconds (TIMER2_MAC_TIMER) or 1 m-second +* (TIMER2_NORMAL_TIMER). +* @param DWORD period +* This value indicates how many periods (320 u-second or 1 m-second) to +* pass before an overflow compare event is generated. +* +* @return BOOL + Returns 0 if period is too large, 1 otherwise. +* +******************************************************************************/ +BOOL halSetTimer2Period(BYTE mode, DWORD period); + +// _mode_ may be of the following: +#define TIMER2_MAC_TIMER 0x01 // Counts 320 u-second periods +#define TIMER2_NORMAL_TIMER 0x02 // Uses the timer as a normal timer with 1 m-second period. + +// Macro for initialising timer 2 +#define TIMER2_INIT() \ + do { \ + T2THD = 0x00; \ + T2TLD = 0x00; \ + T2CMP = 0x00; \ + T2OF0 = 0x00; \ + T2OF1 = 0x00; \ + T2OF2 = 0x00; \ + T2CAPHPH = 0x00; \ + T2CAPLPL = 0x00; \ + T2PEROF0 = 0x00; \ + T2PEROF1 = 0x00; \ + T2PEROF2 = 0x00; \ + T2CNF = 0x06; \ + } while (0) + +#define TIMER2_ENABLE_OVERFLOW_COMP_INT(val) (T2PEROF2 = (val) ? T2PEROF2 | 0x20 : T2PEROF2 & ~0x20) +#endif + + +#if (chip == 1110 || chip == 1111 || chip == 2510 || chip == 2511) +/****************************************************************************** +* @fn halSetTimer2Period +* +* @brief +* This function sets the period timer 2. The values for the counter, +* prescaler and tick period is calculated and written to the corresponding +* registers. +* +* Parameters: +* +* @param UINT32 period +* Period of the timer in u-seconds. +* @param UINT8* cnt +* The value written to T2CT (counter). This value is returned to enable +* a fast setup (without calculation) using the SET_TIMER2_COUNTER. +* @param UINT8* presc +* The value written to T2PR (prescaler). This value is returned to enable +* a fast setup (without calculation) using the SET_TIMER2_PRESCALER. +* +* @return BOOL + Returns FALSE if period is too large, TRUE otherwise. +* +******************************************************************************/ +BOOL halSetTimer2Period(UINT32 period, UINT8* cnt, UINT8* presc); + +#define TIMER2_INIT() \ + do { \ + T2CTL = 0x00; \ + T2CT = 0x00; \ + T2PR = 0x00; \ + } while (0) + +#define TIMER2_SET_COUNTER(counter) do{ T2CT = counter; }while(0) +#define TIMER2_SET_PRESCALER(prescaler) do{ T2PR = prescaler; }while(0) +#define TIMER2_SET_TICK_PERIOD(tick) do{ T2CTL = ((T2CTL & ~0x03) | tick); }while(0) +#define TIMER2_ENABLE_INTERRUPT() do{ T2CTL |= 0x10; }while(0) +#define TIMER2_DISABLE_INTERRUPT() do{ T2CTL &= ~0x10; }while(0) +#define TIMER2_CLEAR_EXPIRED() do{ T2CTL &= ~0x40; }while(0) +#define TIMER2_EXPIRED (T2CTL & 0x40) +#define TIMER2_SET_MODE(mode) (T2CTL = (mode) ? T2CTL|0x04 : T2CTL&~0x04) + +#define TIMER2_USE_REG FALSE +#define TIMER2_FREE TRUE + +#endif +/****************************************************************************** +* @fn halSetTimer34Period +* +* @brief +* This function sets the period of timer 3 or 4 according to the value of +* _timer_. The two timers are identical. Clock division is used to fit the +* desired period within the timer range. If the period is too short or too +* long the function returns 0. If the period is successfully set, the +* function returns the BYTE value written to the timer register. This +* value can be used to set the pulse length if the timer is used for PWM. +* If _period_ is set to 0, maximum timeout value will be used. +* +* Parameters: +* +* @param BYTE timer +* Indicates which timer to configure. Must be either 3 or 4 +* (0x03 or 0x04). +* @param DWORD period - Describe value. +* The desired period in microseconds. +* +* @return BYTE +* The value written to the TxCC0 register. The timer is incremented up +* to this value before the timer is reset. This value may be used to +* set the pulse length in PWM mode. +* +******************************************************************************/ +BYTE halSetTimer34Period(BYTE timer, DWORD period); + +// Macro for initialising timer 3 or 4 +#define TIMER34_INIT(timer) \ + do { \ + T##timer##CTL = 0x06; \ + T##timer##CCTL0 = 0x00; \ + T##timer##CC0 = 0x00; \ + T##timer##CCTL1 = 0x00; \ + T##timer##CC1 = 0x00; \ + } while (0) + +// Macro for enabling overflow interrupt +#define TIMER34_ENABLE_OVERFLOW_INT(timer, val) \ + (T##timer##CTL = (val) ? T##timer##CTL | 0x08 : T##timer##CTL & ~0x08) + + +// Macro for configuring channel 1 of timer 3 or 4 for PWM mode. +#define TIMER34_PWM_CONFIG(timer) \ + do{ \ + T##timer##CCTL1 = 0x24; \ + if(timer == 3){ \ + if(PERCFG & 0x20) { \ + IO_FUNC_PORT_PIN(1,7,IO_FUNC_PERIPH); \ + } \ + else { \ + IO_FUNC_PORT_PIN(1,4,IO_FUNC_PERIPH); \ + } \ + } \ + else { \ + if(PERCFG & 0x10) { \ + IO_FUNC_PORT_PIN(2,3,IO_FUNC_PERIPH);\ + } \ + else { \ + IO_FUNC_PORT_PIN(1,1,IO_FUNC_PERIPH); \ + } \ + } \ + } while(0) + +// Macro for setting pulse length of the timer in PWM mode +#define TIMER34_SET_PWM_PULSE_LENGTH(timer, value) \ + do { \ + T##timer##CC1 = (BYTE)value; \ + } while (0) + + +// Macros for turning timers on or off +#define TIMER1_RUN(value) (T1CTL = (value) ? T1CTL | 0x02 : T1CTL & ~0x03) +#if (chip == 2430 || chip == 2431) +#define TIMER2_RUN(value) (T2CNF = (value) ? T2CNF | 0x01 : T2CNF & ~0x01) +// MAC-timer == timer 2 +#define MAC_TIMER_RUN(value) do{ TIMER2_RUN(value); }while(0) +#endif +#define TIMER3_RUN(value) (T3CTL = (value) ? T3CTL | 0x10 : T3CTL & ~0x10) +#define TIMER4_RUN(value) (T4CTL = (value) ? T4CTL | 0x10 : T4CTL & ~0x10) + +// Macro for enabling/ disabling interrupts from the channels of timer 1, 3 or 4. +#define TIMER_CHANNEL_INTERRUPT_ENABLE(timer, channel, value) \ + do{ \ + if(value){ \ + T##timer##CCTL##channel## |= 0x40; \ + } else { \ + T##timer##CCTL##channel## &= ~0x40; \ + } \ + } while(0) + +#if (chip == 1110 || chip == 1111 || chip == 2510 || chip == 2511) +// Sleep Timer / Wake On Radio (WOR) Timer + +// Macro for initialising the sleep timer / WOR timer. +#define SLEEP_TIMER_INIT() \ + do{ \ + WOREVT1 = 0x87; \ + WOREVT0 = 0x6B; \ + WORCTL = 0x74; \ + WORIRQ = 0x00; \ + } while(0) + +// Macros for enabling / disabling interrupt for event 0 and 1. +#define SLEEP_TIMER_ENABLE_EVENT0_INT(val) do{ WORIRQ = (val) ? WORIRQ | 0x10 : WORIRQ & ~0x10; }while(0) +#define SLEEP_TIMER_ENABLE_EVENT1_INT(val) do{ WORIRQ = (val) ? WORIRQ | 0x20 : WORIRQ & ~0x20; }while(0) + +// Macro for resetting the Sleep / WOR timer +#define SLEEP_TIMER_RESET() WORCTL |= 0x04 + + +#endif + + +/****************************************************************************** +******************* Watch Dog Timer (WDT) ******************* +******************************************************************************* + +The WDT may be used to prevent the unit from being trapped in a system +stalemate, i.e. an endless waiting state. The WDT must be reset before it times +out. If a timeout occurs, the system is reset. + +The WDT can also be configured as a normal timer which generates interrupt at +each timeout. This must be configured manually. +******************************************************************************/ + +// Macro for turning on the WDT +#define WDT_ENABLE() WDCTL |= 0x08 + +// Macro for setting the WDT timeout interval +#define WDT_SET_TIMEOUT_PERIOD(timeout) \ + do { \ + WDCTL &= ~0x03; \ + WDCTL |= timeout; \ + } while (0) + +// Where _timeout_ is one of +#define SEC_1 0x00 // after 1 second +#define M_SEC_250 0x01 // after 250 ms +#define M_SEC_15 0x02 // after 15 ms +#define M_SEC_2 0x03 // after 2 ms + +// Macro for resetting the WDT. If this is not done before the WDT times out, +// the system is reset +#define WDT_RESET() \ + do { \ + WDCTL = (WDCTL & ~0xF0) | 0xA0; \ + WDCTL = (WDCTL & ~0xF0) | 0x50; \ +} while (0) + + +/****************************************************************************** +******************* ADC macros/functions ******************* +******************************************************************************* + +These functions/macros simplifies usage of the ADC. + +******************************************************************************/ + +// Macro for setting up a single conversion. If ADCCON1.STSEL = 11, using this +// macro will also start the conversion. +#define ADC_SINGLE_CONVERSION(settings) \ + do{ \ + ADCCON3 = (settings); \ + }while(0) + +// Macro for setting up a single conversion +#define ADC_SEQUENCE_SETUP(settings) \ + do{ \ + ADCCON2 = (settings); \ + }while(0) + +// Where _settings_ are the following: +// Reference voltage: +#define ADC_REF_1_25_V 0x00 // Internal 1.25V reference +#define ADC_REF_P0_7 0x40 // External reference on AIN7 pin +#define ADC_REF_AVDD 0x80 // AVDD_SOC pin +#define ADC_REF_P0_6_P0_7 0xC0 // External reference on AIN6-AIN7 differential input + +// Resolution (decimation rate): +#define ADC_8_BIT 0x00 // 64 decimation rate +#define ADC_10_BIT 0x10 // 128 decimation rate +#define ADC_12_BIT 0x20 // 256 decimation rate +#define ADC_14_BIT 0x30 // 512 decimation rate + +// Input channel: +#define ADC_AIN0 0x00 // single ended P0_0 +#define ADC_AIN1 0x01 // single ended P0_1 +#define ADC_AIN2 0x02 // single ended P0_2 +#define ADC_AIN3 0x03 // single ended P0_3 +#define ADC_AIN4 0x04 // single ended P0_4 +#define ADC_AIN5 0x05 // single ended P0_5 +#define ADC_AIN6 0x06 // single ended P0_6 +#define ADC_AIN7 0x07 // single ended P0_7 +#define ADC_GND 0x0C // Ground +#define ADC_TEMP_SENS 0x0E // on-chip temperature sensor +#define ADC_VDD_3 0x0F // (vdd/3) + +// Macro for starting the ADC in continuous conversion mode +#define ADC_SAMPLE_CONTINUOUS() \ + do { \ + ADCCON1 &= ~0x30; \ + ADCCON1 |= 0x10; \ + } while (0) + +// Macro for stopping the ADC in continuous mode +#define ADC_STOP() \ + do { \ + ADCCON1 |= 0x30; \ + } while (0) + +// Macro for initiating a single sample in single-conversion mode (ADCCON1.STSEL = 11). +#define ADC_SAMPLE_SINGLE() \ + do{ \ + ADC_STOP(); \ + ADCCON1 |= 0x40; \ +} while (0) + +// Macro for configuring the ADC to be started from T1 channel 0. (T1 ch 0 must be in compare mode!!) +#define ADC_TRIGGER_FROM_TIMER1() \ + do { \ + ADC_STOP(); \ + ADCCON1 &= ~0x10; \ + } while (0) + +// Expression indicating whether a conversion is finished or not. +#define ADC_SAMPLE_READY() (ADCCON1 & 0x80) + +// Macro for setting/clearing a channel as input of the ADC +#define ADC_ENABLE_CHANNEL(ch) ADCCFG |= (0x01 << ch) +#define ADC_DISABLE_CHANNEL(ch) ADCCFG &= ~(0x01 << ch) + +#define ADC_GET_VALUE( v ) GET_WORD( ADCH, ADCL, v ) + + +/****************************************************************************** +* @fn halAdcSampleSingle +* +* @brief +* This function makes the adc sample the given channel at the given +* resolution with the given reference. +* +* Parameters: +* +* @param BYTE reference +* The reference to compare the channel to be sampled. +* BYTE resolution +* The resolution to use during the sample (8, 10, 12 or 14 bit) +* BYTE input +* The channel to be sampled. +* +* @return INT16 +* The conversion result +* +******************************************************************************/ +INT16 halAdcSampleSingle(BYTE reference, BYTE resolution, UINT8 input); + + + + +/****************************************************************************** +******************* RF communication functions/macros ******************* +******************************************************************************* + +The functions in this section are designed to simplify usage of the radio. +A function for setup, transmitting and receiption are included. In addition, +macros for writing instructions to the Command Stobe Processor are included. + +******************************************************************************/ + +/****************************************************************************** +* @fn halRfSend +* +* @brief +* This function sends the given number of bytes using the radio. The radio +* frequency must be set before sending. Can send a maximum of 125 bytes. +* The function waits until the transfer is complete. +* +* Parameters: +* +* @param BYTE* pData +* Pointer to the start of the data to be transferred. +* @param BYTE length +* The number of bytes to be transferred. +* +* @return BYTE +* Returns the number of transferred bytes. +* +******************************************************************************/ +BYTE halRfSendPacket(BYTE* pData, BYTE length); + + + +/****************************************************************************** +* @fn halRfReceivePacket +* +* @brief +* This function receives a maximum of 128 bytes sent by another radio +* transmitter. The function will wait for _timeOut_ ms before returning +* without receiving any data. +* +* Parameters: +* +* @param BYTE* pData +* Pointer to the received packet is to be stored. +* @param BYTE pRssi +* Pointer to where to store the received signal strength indicator calculation. +* @param BYTE pLqi +* Pointer to where to store the link quality indicator. +* @param BYTE timeOut +* The number of ms the chip will wait for a packet to be received. +* +* @return BYTE +* Returns the number of received bytes. +* +******************************************************************************/ +BYTE halRfReceivePacket(BYTE* pData, BYTE*pRssi, BYTE* pLqi, BYTE timeOut); + +/****************************************************************************** +* @fn halRfConfig +* +* @brief +* This function configures the radio for simple send and receive operation. +* Advanced IEEE 802.15.4 functionality such as Address Decoding, AutoAck +* etc is not employed. CRC value is automatically calculated to enable +* detection of packet corruption. The desired frequency is set. The +* function returns TRUE if the configuration is successful. +* +* Parameters: +* +* @param UINT32 frequency +* The desired Radio Frequency in kHz. +* +* @return BOOL +* Returns TRUE if the configuration is successful and FALSE otherwise. +* +******************************************************************************/ +BOOL halRfConfig(UINT32 frequency); + +/****************************************************************************** +* @fn halRfSetRadioFrequency +* +* @brief +* This function sets the radio frequency of the radio. The requency must +* be within the range of the radio. +* +* Parameters: +* +* @param WORD frequency +* The desired Radio Frequency in kHz. +* +* @return void +* +******************************************************************************/ +void halRfSetRadioFrequency(UINT32 frequency); + +#if (chip == 2430 || chip == 2431) +#define STOP_RADIO() ISRFOFF; + +// RF interrupt flags +#define IRQ_RREG_ON 0x80 +#define IRQ_TXDONE 0x40 +#define IRQ_FIFOP 0x20 +#define IRQ_SFD 0x10 +#define IRQ_CCA 0x08 +#define IRQ_CSP_WT 0x04 +#define IRQ_CSP_STOP 0x02 +#define IRQ_CSP_INT 0x01 + +// RF status flags +#define TX_ACTIVE_FLAG 0x10 +#define FIFO_FLAG 0x08 +#define FIFOP_FLAG 0x04 +#define SFD_FLAG 0x02 +#define CCA_FLAG 0x01 + +// Radio status states +#define TX_ACTIVE (RFSTATUS & TX_ACTIVE_FLAG) +#define FIFO (RFSTATUS & FIFO_FLAG) +#define FIFOP (RFSTATUS & FIFOP_FLAG) +#define SFD (RFSTATUS & SFD_FLAG) +#define CCA (RFSTATUS & CCA_FLAG) + +// Various radio settings +#define ADR_DECODE 0x08 +#define AUTO_CRC 0x20 +#define AUTO_TX2RX_OFF 0x08 +#define RX2RX_TIME_OFF 0x04 +#define ACCEPT_ACKPKT 0x01 +#endif + + +#if (chip == 1110 || chip == 1111 || chip == 2510 || chip == 2511) +#define STOP_RADIO() SIDLE(); +// RF interrupt flags +#define IRQ_TXUNF 0x80 +#define IRQ_RXOVF 0x40 +#define IRQ_TIMEOUT 0x20 +#define IRQ_DONE 0x10 +#define IRQ_CS 0x08 +#define IRQ_PQT 0x04 +#define IRQ_CCA 0x02 +#define IRQ_SFD 0x01 + +// RF status flags +#define CRC_OK_FLAG 0x80 +#define CS_FLAG 0x40 +#define PQT_REACHED_FLAG 0x20 +#define CCA_FLAG 0x10 +#define SFD_FLAG 0x08 + +// Radio status flags +#define CRC_OK_FLAG 0x80 +#define CS_FLAG 0x40 +#define PQT_REACHED_FLAG 0x20 +#define CCA_FLAG 0x10 +#define SFD_FLAG 0x08 + +// Radio status states +#define CRC_OK (PKTSTATUS & CRC_OK_FLAG) +#define CS (PKTSTATUS & CS_FLAG) +#define PQT_REACHED (PKTSTATUS & PQT_REACHED_FLAG) +#define CCA (PKTSTATUS & CCA_FLAG) +#define SFD (PKTSTATUS & SFD_FLAG) + +// Various radio settings +#define APPEND_STATUS 0x04 +#define WHITE_DATA 0x40 +#define CRC_EN 0x04 +#define VARIABLE_PKT_LEN 0x01 +#define STAY_INR_RX_AFTER_RX 0x0C +#define RX_AFTER_TX 0x03 +#define CALIBRATE_WHEN_COMING_FROM_IDLE 0x10 +#define CALIBRATE_EVERY_4TH 0x30 +#define PA_POWER_7 0x07 +#define PA_POWER_0 0x00 +#endif + + + +#if (chip == 1110 || chip == 1111 || chip == 2510 || chip == 2511) +//----------------------------------------------------------------------------- +// Command Strobes +//----------------------------------------------------------------------------- +#define SFSTXON() do{RFST = 0x00;}while(0) +#define SCAL() do{RFST = 0x01;}while(0) +#define SRX() do{RFST = 0x02;}while(0) +#define STX() do{RFST = 0x03;}while(0) +#define SIDLE() do{RFST = 0x04;}while(0) +#define SAFC() do{RFST = 0x05;}while(0) +#define SNOP() do{RFST = 0xFF;}while(0) +//----------------------------------------------------------------------------- +#endif + +#if (chip == 2430 || chip == 2431) +//----------------------------------------------------------------------------- +// Command Strobe Processor (CSP) instructions +//----------------------------------------------------------------------------- +#define DECZ do{RFST = 0xBF; }while(0) +#define DECY do{RFST = 0xBE; }while(0) +#define INCY do{RFST = 0xBD; }while(0) +#define INCMAXY(m) do{RFST = (0xB8 | m); }while(0) // m < 8 !! +#define RANDXY do{RFST = 0xBC; }while(0) +#define INT do{RFST = 0xB9; }while(0) +#define WAITX do{RFST = 0xBB; }while(0) +#define WAIT(w) do{RFST = (0x80 | w); }while(0) // w < 64 !! +#define WEVENT do{RFST = 0xB8; }while(0) +#define LABEL do{RFST = 0xBA; }while(0) +#define RPT(n,c) do{RFST = (0xA0 | (n << 3) | c); }while(0) // n = TRUE/FALSE && (c < 8) +#define SKIP(s,n,c) do{RFST = ((s << 4) | (n << 3) | c); }while(0) // && (s < 8) +#define STOP do{RFST = 0xDF; }while(0) +#define SNOP do{RFST = 0xC0; }while(0) +#define STXCALN do{RFST = 0xC1; }while(0) +#define SRXON do{RFST = 0xC2; }while(0) +#define STXON do{RFST = 0xC3; }while(0) +#define STXONCCA do{RFST = 0xC4; }while(0) +#define SRFOFF do{RFST = 0xC5; }while(0) +#define SFLUSHRX do{RFST = 0xC6; }while(0) +#define SFLUSHTX do{RFST = 0xC7; }while(0) +#define SACK do{RFST = 0xC8; }while(0) +#define SACKPEND do{RFST = 0xC9; }while(0) +#define ISSTOP do{RFST = 0xFF; }while(0) +#define ISSTART do{RFST = 0xFE; }while(0) +#define ISTXCALN do{RFST = 0xE1; }while(0) +#define ISRXON do{RFST = 0xE2; }while(0) +#define ISTXON do{RFST = 0xE3; }while(0) +#define ISTXONCCA do{RFST = 0xE4; }while(0) +#define ISRFOFF do{RFST = 0xE5; }while(0) +#define ISFLUSHRX do{RFST = 0xE6; }while(0) +#define ISFLUSHTX do{RFST = 0xE7; }while(0) +#define ISACK do{RFST = 0xE8; }while(0) +#define ISACKPEND do{RFST = 0xE9; }while(0) +#endif + + +// Conditions _c_ for the RPT and SKIP instructions of the CSP +#define CCA_TRUE 0x00; +#define RECEIVING 0x01; +#define MCU_BIT_IS_1 0x02; +#define COMMAND_BUF_EMPT 0x03; +#define REGX_IS_0 0x04; +#define REGY_IS_0 0x05; +#define REGZ_IS_0 0x06; +#define NO_OP 0x07; + + + +/****************************************************************************** +******************* Memory space mapping macros/functions ******************** +*******************************************************************************/ + +// Macros for enabling or disabling unified code space. +// Unified code space is generally used when executing programs from RAM. +#define ENABLE_UINIFIED_CODE_SPACE() do { MEMCTR |= 0x40; } while (0) +#define DISABLE_UINIFIED_CODE_SPACE() do { MEMCTR &= ~0x40; } while (0) + + +/****************************************************************************** +******************* AES encryption / decryption functions ******************* +******************************************************************************* + +Functions for performing a encryption or decryption using the Advanced +Encryption Standard. A unique 16 byte key must be loaded prior to the +encryption or decryption process. + +The Direct Memory Access (DMA) may also be used for data transfer to and from +the AES module. + +******************************************************************************/ + + +/****************************************************************************** +* @fn halAesLoadKeyOrInitVector +* +* @brief +* This function Loads an AES key or an initialisation vector. The data +* (key or vector) must be 16 bytes long (128 bit). +* +* Parameters: +* +* @param BYTE* pData +* Pointer to the start of the 16 bit key or the 16 bit initialisation +* vector to be loaded. +* @param BOOL key +* Boolean value. Set to TRUE if a key is to be loaded and FALSE if an +* initialisation vector is to be loaded. +* +* @return void +* +******************************************************************************/ +void halAesLoadKeyOrInitVector(BYTE* pData, BOOL key); + + +/****************************************************************************** +* @fn halAesEncrDecr +* +* @brief +* Encrypts or decrypts a given number of bytes and stores the result at a +* given location. +* +* Parameters: +* +* @param BYTE* pDataIn +* Pointer to the start of the data to be decrypted or encrypted +* @param UINT16 length +* The number of bytes to be encrypted/decrypted. Should be a multiplum +* of 16 bytes. +* @param BYTE* pDataOut. +* Pointer to the location at which the converted data is to be stored. +* @param BYTE* pInitVector +* Initialisation vector to fill the AES module at startup. Must be +* identical for encryption +* and decryption. +* @param BOOL decr +* Indicates whether an encryption or decryption is to be performed. +* 0 indicates encryption whereas 1 indicates decryption. +* +* @return void +* +******************************************************************************/ +void halAesEncrDecr(BYTE* pDataIn, UINT16 length, BYTE* pDataOut, BYTE* pInitVector, BOOL decr); + +#define AES_BUSY 0x08 +#define ENCRYPT 0x00 +#define DECRYPT 0x01 + +// Macro for setting the mode of the AES operation +#define AES_SETMODE(mode) \ + do { \ + ENCCS &= ~0x70; \ + ENCCS |= mode; \ + } while (0) + +// _mode_ is one of +#define CBC 0x00 +#define CFB 0x10 +#define OFB 0x20 +#define CTR 0x30 +#define ECB 0x40 +#define CBC_MAC 0x50 + +// Macro for starting or stopping encryption or decryption +#define AES_SET_ENCR_DECR_KEY_IV(mode) \ + do { \ + ENCCS &= ~0x07; \ + ENCCS |= mode; \ + } while(0) + +// Where _mode_ is one of +#define AES_ENCRYPT 0x00 +#define AES_DECRYPT 0x02 +#define AES_LOAD_KEY 0x04 +#define AES_LOAD_IV 0x06 + + +// Macro for starting the AES module for either encryption, decryption, +// key or initialisation vector loading. +#define AES_START() ENCCS |= 0x01 + + +/****************************************************************************** +************* Random Generator macros / functions ************ +******************************************************************************* + +Example usage: + +First initialise the random generator: + halInitRandomGenerator(); + +Each time the random generator is read, the following sequence should +be used (clock the random generator for each read): + CLOCK_RANDOM_GENERATOR(); + rnd = GET_RANDOM_VALUE(); + +******************************************************************************/ + +// Macro for enabling the random generator +#define ENABLE_RANDOM_GENERATOR() \ + do{ ADCCON1 &= ~0x0C; } while(0) + +// Macro for clocking the random generator +#define CLOCK_RANDOM_GENERATOR() \ + do{ ADCCON1 |= 0x04; } while(0) + +// Macro for getting a random byte +#define GET_RANDOM_BYTE(a) \ + do{ \ + CLOCK_RANDOM_GENERATOR(); \ + a = RNDH; \ + }while(0) + +// Macro for getting a random word +#define GET_RANDOM_WORD(a) \ + do{ \ + CLOCK_RANDOM_GENERATOR(); \ + GET_WORD( RNDH, RNDL, a ); \ + }while(0) + + +/****************************************************************************** +* @fn halInitRandomGenerator +* +* @brief +* This function generates a random sequence using the radio. The radio is +* turned on and data is sampled from the receiver. This data is used to +* seed the random generator. This seeding forms the basis for generating +* new random bytes by clocking the random generator. +* +* Parameters: +* +* @param void +* +* @return void +* +******************************************************************************/ +void halInitRandomGenerator(void); + +#if (chip == 2431) +/****************************************************************************** +******************* Location Engine ******************* +******************************************************************************/ + +//Location engine enable +#define LOC_ENABLE() do { LOCENG |= 0x10; } while(0) +#define LOC_DISABLE() do { LOCENG &= ~0x10; } while(0) + +//Location engine load parameters +#define LOC_PARAMETER_LOAD( on )\ + do { \ + if(on) LOCENG |= 0x04; \ + else LOCENG &= ~0x04; \ + } while(0) + +//Location engine load reference coordinates +#define LOC_REFERENCE_LOAD( on )\ + do { \ + if(on) LOCENG |= 0x02; \ + else LOCENG &= ~0x02; \ +} while(0) + +//Location engine run +#define LOC_RUN() LOCENG |= 0x01 + +//Location engine done +#define LOC_DONE() (LOCENG & 0x08) + +#endif + +/****************************************************************************** +******************* Utility functions ******************* +******************************************************************************/ + +/****************************************************************************** +* @fn halWait +* +* @brief +* This function waits approximately a given number of m-seconds +* regardless of main clock speed. +* +* Parameters: +* +* @param BYTE wait +* The number of m-seconds to wait. +* +* @return void +* +******************************************************************************/ +void halWait(BYTE wait); + + + +/****************************************************************************** +* @fn getkey +* +* @brief +* This function gets a char from UART0. It waits for URX0IF to be set before +* reading the value and return. If URX0IF is not set, the function will +* never return. +* +* Parameters: +* +* @param void +* +* @return char +* The received byte. +******************************************************************************/ +char getkey(void); + +/****************************************************************************** +* @fn putchar +* +* @brief +* This writes a byte to the UART. +* +* NOTE: This function is adapted to the printf() function of IAR (in +* accordance with ANSI C). This is the reason for the apparently +* contradictory castings/type conversions (int <-> char). +* +* NOTE: A condition for using this function is that the +* UART0 TX flag is set before usage. If this requirement is +* not met, the function will never return. +* +* Parameters: +* +* @param int i +* The value to be written to the UART +* @return int +* +******************************************************************************/ +int putchar(int i); + +#if (chip == 2510 || chip == 2511 || chip==1110 || chip==1111) +/****************************************************************************** +* @fn utilEnterCriticalSection +* +* @brief +* Turn off global interrupts and return the previous state of EA. +* +* +* +* Parameters: +* +* @param void +* +* @return BOOL +* +******************************************************************************/ +__near_func BOOL utilEnterCriticalSection(void); + +/****************************************************************************** +* @fn utilEnterCriticalSection +* +* @brief +* Restore the previous EA state from the value provided in the function parameter +* +* +* +* Parameters: +* +* @param BOOL +* +* @return void +* +******************************************************************************/ +__near_func void utilLeaveCriticalSection(BOOL oldStatus); +#endif + +#endif //HAL_H diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_defs.h b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_defs.h new file mode 100755 index 0000000..ca0c274 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_defs.h @@ -0,0 +1,189 @@ +/*********************************************************************************** + Filename: hal_defs.h + + Description: HAL defines + +***********************************************************************************/ + +#ifndef HAL_DEFS_H +#define HAL_DEFS_H + +/*********************************************************************************** +* CONSTANTS AND DEFINES +*/ + +#ifndef TRUE +#define TRUE 1 +#else +#ifdef __IAR_SYSTEMS_ICC__ +#warning "Macro TRUE already defined" +#endif +#endif + +#ifndef FALSE +#define FALSE 0 +#else +#ifdef __IAR_SYSTEMS_ICC__ +#warning "Macro FALSE already defined" +#endif +#endif + +#ifndef NULL +#define NULL (void *)0 +#else +#ifdef __IAR_SYSTEMS_ICC__ +#warning "Macro NULL already defined" +#endif +#endif + +#ifndef SUCCESS +#define SUCCESS 0 +#else +#warning "Macro SUCCESS already defined" +#endif + +#ifndef FAILED +#ifndef WIN32 +#define FAILED 1 +#endif +#else +#ifdef __IAR_SYSTEMS_ICC__ +#warning "Macro FAILED already defined" +#endif +#endif + +/*********************************************************************************** +* MACROS +*/ + +#ifndef BV +#define BV(n) (1 << (n)) +#endif + +#ifndef BM +#define BM(n) (1 << (n)) +#endif + +#ifndef BF +#define BF(x,b,s) (((x) & (b)) >> (s)) +#endif + +#ifndef MIN +#define MIN(n,m) (((n) < (m)) ? (n) : (m)) +#endif + +#ifndef MAX +#define MAX(n,m) (((n) < (m)) ? (m) : (n)) +#endif + +#ifndef ABS +#define ABS(n) (((n) < 0) ? -(n) : (n)) +#endif + + +/* uint32 processing */ +#define BREAK_UINT32( var, ByteNum ) \ + (uint8)((uint32)(((var) >>((ByteNum) * 8)) & 0x00FF)) + +#define BUILD_UINT32(Byte0, Byte1, Byte2, Byte3) \ + ((uint32)((uint32)((Byte0) & 0x00FF) \ + + ((uint32)((Byte1) & 0x00FF) << 8) \ + + ((uint32)((Byte2) & 0x00FF) << 16) \ + + ((uint32)((Byte3) & 0x00FF) << 24))) + +#define HI_UINT32(a) ((uint16) (((uint32)(a)) >> 16)) +#define LO_UINT32(a) ((uint16) ((uint32)(a))) + + +/* uint16 processing */ +#define BUILD_UINT16(loByte, hiByte) \ + ((uint16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8))) + +#define HI_UINT16(a) (((uint16)(a) >> 8) & 0xFF) +#define LO_UINT16(a) ((uint16)(a) & 0xFF) + + +/* uint16 processing */ +#define BUILD_UINT8(hiByte, loByte) \ + ((uint8)(((loByte) & 0x0F) + (((hiByte) & 0x0F) << 4))) + +#define HI_UINT8(a) (((uint8)(a) >> 4) & 0x0F) +#define LO_UINT8(a) ((uint8)(a) & 0x0F) + +/*********************************************************************************** + * Host to network byte order macros + */ +#ifdef BIG_ENDIAN +#define UINT16_HTON(x) st( utilReverseBuf((uint8*)&x, sizeof(uint16)); ) +#define UINT16_NTOH(x) st( utilReverseBuf((uint8*)&x, sizeof(uint16)); ) + +#define UINT32_HTON(x) st( utilReverseBuf((uint8*)&x, sizeof(uint32)); ) +#define UINT32_NTOH(x) st( utilReverseBuf((uint8*)&x, sizeof(uint32)); ) +#else +#define UINT16_HTON(x) +#define UINT16_NTOH(x) + +#define UINT32_HTON(x) +#define UINT32_NTOH(x) +#endif + + +/* +* This macro is for use by other macros to form a fully valid C statement. +* Without this, the if/else conditionals could show unexpected behavior. +* +* For example, use... +* #define SET_REGS() st( ioreg1 = 0; ioreg2 = 0; ) +* instead of ... +* #define SET_REGS() { ioreg1 = 0; ioreg2 = 0; } +* or +* #define SET_REGS() ioreg1 = 0; ioreg2 = 0; +* The last macro would not behave as expected in the if/else construct. +* The second to last macro will cause a compiler error in certain uses +* of if/else construct +* +* It is not necessary, or recommended, to use this macro where there is +* already a valid C statement. For example, the following is redundant... +* #define CALL_FUNC() st( func(); ) +* This should simply be... +* #define CALL_FUNC() func() +* +* (The while condition below evaluates false without generating a +* constant-controlling-loop type of warning on most compilers.) +*/ +#define st(x) do { x } while (__LINE__ == -1) + + +/*********************************************************************************** + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +***********************************************************************************/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_int.h b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_int.h new file mode 100755 index 0000000..1f8d2df --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_int.h @@ -0,0 +1,125 @@ +/****************************************************************************** + Filename: hal_int.h + + Description: HAL interrupt control header file + +******************************************************************************/ + + +#ifndef HAL_INT_H +#define HAL_INT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * INCLUDES + */ +#include "hal_types.h" + + +/****************************************************************************** + * MACROS + */ + +#if (defined __ICC430__) || defined(__MSP430__) + +// Use the macros below to reduce function call overhead for common +// global interrupt control functions + + +#if (defined __ICC430__) +#define HAL_INT_ON(x) st( __enable_interrupt(); ) +#define HAL_INT_OFF(x) st( __disable_interrupt(); ) +#define HAL_INT_LOCK(x) st( (x) = __get_interrupt_state(); \ + __disable_interrupt(); ) +#define HAL_INT_UNLOCK(x) st( __set_interrupt_state(x); ) +#endif + +#if (defined __MSP430__) +#define HAL_INT_ON(x) st( _enable_interrupts(); ) +#define HAL_INT_OFF(x) st( _disable_interrupts(); ) +#define HAL_INT_LOCK(x) st( (x) = _get_SR_register(); \ + _disable_interrupts(); ) +#define HAL_INT_UNLOCK(x) st( _enable_interrupts(); /*_bis_SR_register(x);*/ ) +#endif + +#elif defined __ICC8051__ + +#define HAL_INT_ON(x) st( EA = 1; ) +#define HAL_INT_OFF(x) st( EA = 0; ) +#define HAL_INT_LOCK(x) st( (x) = EA; EA = 0; ) +#define HAL_INT_UNLOCK(x) st( EA = (x); ) + +typedef unsigned short istate_t; + +#elif defined WIN32 + +#define HAL_INT_ON() +#define HAL_INT_OFF() +#define HAL_INT_LOCK(x) st ((x)= 1; ) +#define HAL_INT_UNLOCK(x) + +#elif defined __KEIL__ + +#define HAL_INT_ON(x) st( EA = 1; ) +#define HAL_INT_OFF(x) st( EA = 0; ) +#define HAL_INT_LOCK(x) st( (x) = EA; EA = 0; ) +#define HAL_INT_UNLOCK(x) st( EA = (x); ) + + + +#else +#error "Unsupported compiler" +#endif + + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +void halIntOn(void); +void halIntOff(void); +uint16 halIntLock(void); +void halIntUnlock(uint16 key); + + +#ifdef __cplusplus +} +#endif + + +/*********************************************************************************** + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +***********************************************************************************/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_led.h b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_led.h new file mode 100755 index 0000000..f3b60a7 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_led.h @@ -0,0 +1,66 @@ +/*********************************************************************************** + Filename: hal_led.h + + Description: hal led library header file + +***********************************************************************************/ + +#ifndef HAL_LED_H +#define HAL_LED_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*********************************************************************************** +* INCLUDES +*/ +#include "hal_types.h" + +/*********************************************************************************** + * GLOBAL FUNCTIONS + */ +void halLedInit(void); +void halLedSet(uint8 led_id); +void halLedClear(uint8 led_id); +void halLedToggle(uint8 led_id); + + +#ifdef __cplusplus +} +#endif + + +/*********************************************************************************** + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +***********************************************************************************/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_mcu.h b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_mcu.h new file mode 100755 index 0000000..1fc8c53 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_mcu.h @@ -0,0 +1,90 @@ +/*********************************************************************************** + Filename: hal_mcu.h + + Description: hal mcu library header file + +***********************************************************************************/ + +#ifndef HAL_MCU_H +#define HAL_MCU_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*********************************************************************************** +* INCLUDES +*/ +#include + + +/*********************************************************************************** + * CONSTANTS AND DEFINES + */ +enum { // Input values to halMcuSetLowPowerMode() + HAL_MCU_LPM_0, + HAL_MCU_LPM_1, + HAL_MCU_LPM_2, + HAL_MCU_LPM_3, + HAL_MCU_LPM_4 +}; + + +enum { // Return values of halMcuGetResetCause() + HAL_MCU_RESET_CAUSE_POR, + HAL_MCU_RESET_CAUSE_EXTERNAL, + HAL_MCU_RESET_CAUSE_WATCHDOG +}; + + +/*********************************************************************************** + * GLOBAL FUNCTIONS + */ + +void halMcuInit(void); +void halMcuWaitUs(uint16 usec); +void halMcuWaitMs(uint16 msec); +void halMcuSetLowPowerMode(uint8 mode); +void halMcuReset(void); +uint8 halMcuGetResetCause(void); + + +#ifdef __cplusplus +} +#endif + +/**********************************************************************************/ +#endif + + +/*********************************************************************************** + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +***********************************************************************************/ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_types.h b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_types.h new file mode 100755 index 0000000..e8f58f6 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/include/hal_types.h @@ -0,0 +1,188 @@ +/*********************************************************************************** + Filename: hal_types.h + + Description: HAL type definitions + +***********************************************************************************/ + +#ifndef HAL_TYPES_H +#define HAL_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*********************************************************************************** + * TYPEDEFS + */ + +typedef signed char int8; +typedef unsigned char uint8; + +typedef signed short int16; +typedef unsigned short uint16; + +typedef signed long int32; +typedef unsigned long uint32; + + +typedef void (*ISR_FUNC_PTR)(void); +typedef void (*VFPTR)(void); + + +/*********************************************************************************** + * Compiler abstraction + */ + +/***************************************************** + * IAR MSP430 + */ +#ifdef __IAR_SYSTEMS_ICC__ + +#define _PRAGMA(x) _Pragma(#x) + +#if defined __ICC430__ + +#ifndef CODE +#define CODE +#endif +#ifndef XDATA +#define XDATA +#endif +#define FAR +#define NOP() asm("NOP") + +#define HAL_ISR_FUNC_DECLARATION(f,v) \ + _PRAGMA(vector=v##_VECTOR) __interrupt void f(void) +#define HAL_ISR_FUNC_PROTOTYPE(f,v) \ + _PRAGMA(vector=v##_VECTOR) __interrupt void f(void) +#define HAL_ISR_FUNCTION(f,v) \ + HAL_ISR_FUNC_PROTOTYPE(f,v); HAL_ISR_FUNC_DECLARATION(f,v) + + +/***************************************************** + * IAR 8051 + */ +#elif defined __ICC8051__ + +#ifndef BSP_H +#define CODE __code +#define XDATA __xdata +#endif + +#define FAR +#define NOP() asm("NOP") + +#define HAL_MCU_LITTLE_ENDIAN() __LITTLE_ENDIAN__ +#define HAL_ISR_FUNC_DECLARATION(f,v) \ + _PRAGMA(vector=v) __near_func __interrupt void f(void) +#define HAL_ISR_FUNC_PROTOTYPE(f,v) \ + _PRAGMA(vector=v) __near_func __interrupt void f(void) +#define HAL_ISR_FUNCTION(f,v) \ + HAL_ISR_FUNC_PROTOTYPE(f,v); HAL_ISR_FUNC_DECLARATION(f,v) + +#else +#error "Unsupported architecture" +#endif + + +/***************************************************** + * KEIL 8051 + */ +#elif defined __KEIL__ +#include +#define BIG_ENDIAN + +#define CODE code +#define XDATA xdata +#define FAR +#define NOP() _nop_() + +#define HAL_ISR_FUNC_DECLARATION(f,v) \ + void f(void) interrupt v +#define HAL_ISR_FUNC_PROTOTYPE(f,v) \ + void f(void) +#define HAL_ISR_FUNCTION(f,v) \ + HAL_ISR_FUNC_PROTOTYPE(f,v); HAL_ISR_FUNC_DECLARATION(f,v) + +typedef unsigned short istate_t; + +// Keil workaround +#define __code code +#define __xdata xdata + + +/***************************************************** + * WIN32 + */ +#elif defined WIN32 + +#define CODE +#define XDATA +#include "windows.h" +#define FAR far +#pragma warning (disable :4761) + + +/***************************************************** + * Code Composer Essential + */ + +#elif __TI_COMPILER_VERSION__ +#define CODE +#define XDATA +#define FAR + +typedef unsigned short istate_t; + + +/***************************************************** + * Other compilers + */ +#else +#error "Unsupported compiler" +#endif + + + +#ifdef __cplusplus +} +#endif + + + +/*********************************************************************************** + Copyright 2007-2008 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +***********************************************************************************/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/adcSampleSingle.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/adcSampleSingle.c new file mode 100755 index 0000000..f89f09f --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/adcSampleSingle.c @@ -0,0 +1,61 @@ +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +| File: adcSampleSingle.c +| Target: cc2430, cc2431, cc1110, cc2510, cc2511, cc1111 +| Author: EFU +| Revised: 26/10-2005 +| Revision: 1.0 ++-----------------------------------------------------------------------------*/ + +#include "hal.h" + +//----------------------------------------------------------------------------- +// See hal.h for a description of this function. +//----------------------------------------------------------------------------- +INT16 halAdcSampleSingle(BYTE reference, BYTE resolution, UINT8 input) { + BYTE volatile temp; + INT16 value; + + ADC_ENABLE_CHANNEL(input); + + ADCIF = 0; + ADC_SINGLE_CONVERSION(reference | resolution | input); + while(!ADCIF); + ADC_GET_VALUE( value ); + + ADC_DISABLE_CHANNEL(input); + + resolution >>= 3; + return value >> (8 - resolution); +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/cc8051/hal_cc8051.h b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/cc8051/hal_cc8051.h new file mode 100755 index 0000000..b7c6ffa --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/cc8051/hal_cc8051.h @@ -0,0 +1,122 @@ +/****************************************************************************** + Filename: hal_cc8051.h + + Copyright 2007 Texas Instruments, Inc. +******************************************************************************/ + +#ifndef HAL_CC8051_H +#define HAL_CC8051_H + +/****************************************************************************** + * INCLUDES + */ + +#include +#include + + +/****************************************************************************** + * CONSTANTS + */ +#define BIT0 0x01 +#define BIT1 0x02 +#define BIT2 0x04 +#define BIT3 0x08 +#define BIT4 0x10 +#define BIT5 0x20 +#define BIT6 0x40 +#define BIT7 0x80 + + +/****************************************************************************** + * MACROS + */ + +#define MCU_IO_TRISTATE 1 // Used as "func" for the macros below +#define MCU_IO_PULLUP 2 +#define MCU_IO_PULLDOWN 3 + + +//----------------------------------------------------------------------------- +// Macros for simple configuration of IO pins on TI LPW SoCs +//----------------------------------------------------------------------------- +#define MCU_IO_PERIPHERAL(port, pin) MCU_IO_PERIPHERAL_PREP(port, pin) +#define MCU_IO_INPUT(port, pin, func) MCU_IO_INPUT_PREP(port, pin, func) +#define MCU_IO_OUTPUT(port, pin, val) MCU_IO_OUTPUT_PREP(port, pin, val) +#define MCU_IO_SET(port, pin, val) MCU_IO_SET_PREP(port, pin, val) +#define MCU_IO_SET_HIGH(port, pin) MCU_IO_SET_HIGH_PREP(port, pin) +#define MCU_IO_SET_LOW(port, pin) MCU_IO_SET_LOW_PREP(port, pin) +#define MCU_IO_TGL(port, pin) MCU_IO_TGL_PREP(port, pin) +#define MCU_IO_GET(port, pin) MCU_IO_GET_PREP(port, pin) + +#define MCU_IO_DIR_INPUT(port, pin) MCU_IO_DIR_INPUT_PREP(port, pin) +#define MCU_IO_DIR_OUTPUT(port, pin) MCU_IO_DIR_OUTPUT_PREP(port, pin) + + +//---------------------------------------------------------------------------------- +// Macros for internal use (the macros above need a new round in the preprocessor) +//---------------------------------------------------------------------------------- +#define MCU_IO_PERIPHERAL_PREP(port, pin) st( P##port##SEL |= BM(pin); ) + +#define MCU_IO_INPUT_PREP(port, pin, func) st( P##port##SEL &= ~BM(pin); \ + P##port##DIR &= ~BM(pin); \ + switch (func) { \ + case MCU_IO_PULLUP: \ + P##port##INP &= ~BM(pin); \ + P2INP &= ~BM(port + 5); \ + break; \ + case MCU_IO_PULLDOWN: \ + P##port##INP &= ~BM(pin); \ + P2INP |= BM(port + 5); \ + break; \ + default: \ + P##port##INP |= BM(pin); \ + break; } ) + +#define MCU_IO_OUTPUT_PREP(port, pin, val) st( P##port##SEL &= ~BM(pin); \ + P##port##_##pin## = val; \ + P##port##DIR |= BM(pin); ) + +#define MCU_IO_SET_HIGH_PREP(port, pin) st( P##port##_##pin## = 1; ) +#define MCU_IO_SET_LOW_PREP(port, pin) st( P##port##_##pin## = 0; ) + +#define MCU_IO_SET_PREP(port, pin, val) st( P##port##_##pin## = val; ) +#define MCU_IO_TGL_PREP(port, pin) st( P##port##_##pin## ^= 1; ) +#define MCU_IO_GET_PREP(port, pin) (P##port## & BM(pin)) + +#define MCU_IO_DIR_INPUT_PREP(port, pin) st( P##port##DIR &= ~BM(pin); ) +#define MCU_IO_DIR_OUTPUT_PREP(port, pin) st( P##port##DIR |= BM(pin); ) + + +/**************************************************************************************** + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +***********************************************************************************/ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/clock.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/clock.c new file mode 100755 index 0000000..1b98f81 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/clock.c @@ -0,0 +1,62 @@ +/****************************************************************************** + Filename: clock.c + + This file defines clock related functions for the CC1110/CC2510 family + of RF system-on-chips from Texas Instruments. + +******************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include "clock.h" + + + +/******************************************************************************* + * PUBLIC FUNCTIONS + */ + + +/****************************************************************************** +* @fn clockSetMainSrc +* +* @brief Function for setting the main system clock source. +* The function turns off the clock source that is not being used. +* TICKSPD is set to the same frequency as the source. +* +* @param uint8 source (one of CLOCK_SRC_HFRC or CLOCK_SRC_XOSC) +* +* @return void +* +******************************************************************************/ +void clockSetMainSrc(uint8 source) +{ + register uint8 osc32k_bm = CLKCON & CLKCON_OSC32K_BM; + + // Source can have the following values: + // CLOCK_SRC_XOSC 0x00 /* High speed Crystal Oscillator (XOSC) */ + // CLOCK_SRC_HFRC 0x01 /* Low power RC Oscillator (HFRC) */ + + if (source == CLOCK_SRC_HFRC) + { + SLEEP &= ~SLEEP_OSC_PD_BM; // power up both oscillators + while (!IS_HFRC_STABLE());// wait until the oscillator is stable + + CLKCON = (osc32k_bm | CLKCON_OSC_BM | TICKSPD_DIV_2 | CLKSPD_DIV_2); + while (CLKCON != (osc32k_bm | CLKCON_OSC_BM | TICKSPD_DIV_2 | CLKSPD_DIV_2)); + + SLEEP |= SLEEP_OSC_PD_BM; // power down the unused oscillator + } + else if (source == CLOCK_SRC_XOSC) + { + SLEEP &= ~SLEEP_OSC_PD_BM; // power up both oscillators + while (!IS_XOSC_STABLE());// wait until the XOSC is stable + + CLKCON = (osc32k_bm | TICKSPD_DIV_1 | CLKSPD_DIV_1); + while (CLKCON != (osc32k_bm | TICKSPD_DIV_1 | CLKSPD_DIV_1)); + + SLEEP |= SLEEP_OSC_PD_BM; // power down the unused oscillator + } +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/clock.h b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/clock.h new file mode 100755 index 0000000..85606de --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/clock.h @@ -0,0 +1,113 @@ +/****************************************************************************** + Filename: clock.h + + This file defines interface for clock related functions for the + CC1110/CC2510 family of RF system-on-chips from Texas Instruments. + + Copyright 2007 Texas Instruments, Inc. +******************************************************************************/ +#ifndef _CLOCK_H +#define _CLOCK_H + + +/******************************************************************************* + * INCLUDES + */ + +#include "hal_types.h" + +// Include chip specific IO definition file +#if (chip == 2510) +#include "ioCC2510.h" +#endif +#if (chip == 1110) +#include "ioCC1110.h" +#endif +#if (chip == 2511) +#include "ioCC2511.h" +#endif +#if (chip == 1111) +#include "ioCC1111.h" +#endif + + + +/******************************************************************************* + * CONSTANTS + */ + +/* SEE DATA SHEET FOR DETAILS ABOUT THE FOLLOWING BIT MASKS */ + +/* Pre defined values for main clock source, used in cc2510ClockSetMainSrc() */ +#define CLOCK_SRC_XOSC 0x00 /* High speed Crystal Oscillator Control */ +#define CLOCK_SRC_HFRC 0x01 /* Low power RC Oscillator */ + +// Bit masks to check CLKCON register +#define CLKCON_OSC32K_BM 0x80 // bit mask, for the slow 32k clock oscillator +#define CLKCON_OSC_BM 0x40 // bit mask, for the system clock oscillator +#define CLKCON_TICKSPD_BM 0x38 // bit mask, for timer ticks output setting +#define CLKCON_CLKSPD_BM 0x07 // bit maks, for the clock speed + +#define TICKSPD_DIV_1 (0x00 << 3) +#define TICKSPD_DIV_2 (0x01 << 3) +#define TICKSPD_DIV_4 (0x02 << 3) +#define TICKSPD_DIV_8 (0x03 << 3) +#define TICKSPD_DIV_16 (0x04 << 3) +#define TICKSPD_DIV_32 (0x05 << 3) +#define TICKSPD_DIV_64 (0x06 << 3) +#define TICKSPD_DIV_128 (0x07 << 3) + +#define CLKSPD_DIV_1 (0x00) +#define CLKSPD_DIV_2 (0x01) +#define CLKSPD_DIV_4 (0x02) +#define CLKSPD_DIV_8 (0x03) +#define CLKSPD_DIV_16 (0x04) +#define CLKSPD_DIV_32 (0x05) +#define CLKSPD_DIV_64 (0x06) +#define CLKSPD_DIV_128 (0x07) + +// Bit masks to check SLEEP register +#define SLEEP_XOSC_STB_BM 0x40 // bit mask, check the stability of XOSC +#define SLEEP_HFRC_STB_BM 0x20 // bit maks, check the stability of the High-frequency RC oscillator +#define SLEEP_OSC_PD_BM 0x04 // bit mask, power down system clock oscillator(s) + +/******************************************************************************* + * TYPEDEFS + */ + +/******************************************************************************* + * MACROS + */ + +// Macro for checking status of the high frequency RC oscillator. +#define IS_HFRC_STABLE() (SLEEP & SLEEP_HFRC_STB_BM) + +// Macro for checking status of the crystal oscillator +#define IS_XOSC_STABLE() (SLEEP & SLEEP_XOSC_STB_BM) + +// Macro for getting the clock division factor +#define CLKSPD_GET() (CLKCON & CLKCON_CLKSPD_BM) + +// Macro for getting the timer tick division factor. +#define TICKSPD_GET() ((CLKCON & CLKCON_TICKSPD_BM) >> 3) + +// Macro for setting the timer division factor, x value from 0b000 to 0b111 +#define TICKSPD_SET(x) do { CLKCON = ((((x) << 3) & 0x38) \ + | (CLKCON & 0xC7)); \ + } while (0) + +// Macro for setting the clock tick division factor, x value from 0b000 to 0b111 +#define CLKSPD_SET(x) do { CLKCON = (((x) & 0x07) \ + | (CLKCON & 0xF8)); \ + } while (0) + + +/******************************************************************************* + * FUNCTIONS + */ + +void clockSetMainSrc(uint8 source); + + +/*****************************************************************************/ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_assert.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_assert.c new file mode 100755 index 0000000..274b031 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_assert.c @@ -0,0 +1,74 @@ + +/*********************************************************************************** + Filename: hal_assert.c + + Description: Assert functionality + +***********************************************************************************/ + +/*********************************************************************************** +* INCLUDES +*/ +#include "hal_assert.h" +#include "hal_led.h" +#include "hal_mcu.h" +#include "hal_defs.h" + + +/*********************************************************************************** +* GLOBAL FUNCTIONS +*/ + +/*********************************************************************************** +* @fn halAssertHandler +* +* @brief Logic to handle an assert. +* +* @param none +* +* @return none +*********************************************************************************** +*/ +void halAssertHandler(void) +{ + // execute code that handles asserts + // blink all leds + while(TRUE){ + halLedToggle(1); + halMcuWaitMs(50); + } +} + + +/*********************************************************************************** + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +***********************************************************************************/ + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_board.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_board.c new file mode 100755 index 0000000..4a7383a --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_board.c @@ -0,0 +1,51 @@ +/*********************************************************************************** + Filename: hal_board.c + + Copyright 2007 Texas Instruments, Inc. +***********************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ + +#include "hal_types.h" +#include "hal_mcu.h" +#include "hal_board.h" + + + +/******************************************************************************* + * GLOBAL FUNCTIONS + */ + + +/****************************************************************************** + * @fn halBoardInit + * + * @brief Sets up board. Initialize MCU with HS XOSC, configure I/O pins + * and user interface. + * + * @param none + * + * @return none + *****************************************************************************/ +void halBoardInit(void) +{ + + // Enable HS XOSC and set maximum clock speed + halMcuInit(); + + // LED + MCU_IO_OUTPUT(HAL_BOARD_IO_LED_PORT, HAL_BOARD_IO_LED_PIN, 0); // Turn off + +} + + + + + + + + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_board.h b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_board.h new file mode 100755 index 0000000..a0eecb6 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_board.h @@ -0,0 +1,133 @@ +/****************************************************************************** + Filename: hal_board.h + + Description: HAL board peripherals header file for the + CCxx11 USB MCU on the USB dongle. + + Copyright 2007 Texas Instruments, Inc. +******************************************************************************/ +#ifndef HAL_BOARD_H +#define HAL_BOARD_H + + +/****************************************************************************** + * INCLUDES + */ + +#include "hal_types.h" +#include "hal_defs.h" + +#if chip==2511 +#include +#elif chip==1111 +#include +#else +#error "chip not defined!" +#endif +#include + +#ifdef USB_UART +#include "usb_uart.h" +#endif + +/****************************************************************************** + * CONSTANTS + */ + +// Board properties +#define BOARD_NAME "RFUSBXX11" +#define NUM_LEDS 1 +#define NUM_BUTTONS 1 +#define NUM_JSTKS 0 +#define NUM_POTS 0 + + +//----------------------------------------------------------------------------- +// Define ports and pins used by CCxx11 on USB dongle +//----------------------------------------------------------------------------- +// USB +#define HAL_BOARD_IO_USB_ENABLE_PORT 1 +#define HAL_BOARD_IO_USB_ENABLE_PIN 0 + +// LED +#define HAL_BOARD_IO_LED_PORT 1 +#define HAL_BOARD_IO_LED_PIN 1 + +// Button +#define HAL_BOARD_IO_BTN_PORT 1 +#define HAL_BOARD_IO_BTN_PIN 2 + + +/****************************************************************************** + * MACROS + */ + +//----------------------------------------------------------------------------- +// Some simple macros +//----------------------------------------------------------------------------- + +#ifdef CC1111EM + #define HAL_LED_SET() MCU_IO_SET_HIGH(HAL_BOARD_IO_LED_PORT, HAL_BOARD_IO_LED_PIN) + #define HAL_LED_CLR() MCU_IO_SET_LOW(HAL_BOARD_IO_LED_PORT, HAL_BOARD_IO_LED_PIN) + #define HAL_LED_TGL() MCU_IO_TGL(HAL_BOARD_IO_LED_PORT, HAL_BOARD_IO_LED_PIN) +#else + #define HAL_LED_SET() MCU_IO_SET_HIGH(HAL_BOARD_IO_USB_ENABLE_PORT, HAL_BOARD_IO_USB_ENABLE_PIN) + #define HAL_LED_CLR() MCU_IO_SET_LOW(HAL_BOARD_IO_USB_ENABLE_PORT, HAL_BOARD_IO_USB_ENABLE_PIN) + #define HAL_LED_TGL() MCU_IO_TGL(HAL_BOARD_IO_USB_ENABLE_PORT, HAL_BOARD_IO_USB_ENABLE_PIN) +#endif + +// Push button +#define HAL_BUTTON_ACTIVATE() MCU_IO_INPUT(HAL_BOARD_IO_BTN_PORT, HAL_BOARD_IO_BTN_PIN, MCU_IO_PULLUP) +#define HAL_BUTTON_PUSHED() (!MCU_IO_GET(HAL_BOARD_IO_BTN_PORT, HAL_BOARD_IO_BTN_PIN)) + +#define HAL_DEBOUNCE(expr) { int i; for (i=0; i<500; i++) { if (!(expr)) i = 0; } } + + +// USB +#define HAL_USB_ENABLE() ( SLEEP |= SLEEP_USB_EN ) + +#ifdef CC1111EM + #define HAL_USB_PULLUP_ENABLE() MCU_IO_OUTPUT(HAL_BOARD_IO_USB_ENABLE_PORT, HAL_BOARD_IO_USB_ENABLE_PIN, 1) + #define HAL_USB_PULLUP_DISABLE() MCU_IO_SET_LOW(HAL_BOARD_IO_USB_ENABLE_PORT, HAL_BOARD_IO_USB_ENABLE_PIN) +#else + #define HAL_USB_PULLUP_ENABLE() MCU_IO_OUTPUT(HAL_BOARD_IO_LED_PORT, HAL_BOARD_IO_LED_PIN, 1) + #define HAL_USB_PULLUP_DISABLE() MCU_IO_SET_LOW(HAL_BOARD_IO_LED_PORT, HAL_BOARD_IO_LED_PIN) +#endif + + +#define HAL_USB_INT_ENABLE() st( IEN2|= 0x02; ) +#define HAL_USB_INT_DISABLE() st( IEN2&= ~0x02; ) +#define HAL_USB_INT_CLEAR() st( P2IFG= 0; P2IF= 0; ) + +#define HAL_USB_RESUME_INT_ENABLE() st( P0IE= 1;) +#define HAL_USB_RESUME_INT_DISABLE() st( P0IE= 0;) +#define HAL_USB_RESUME_INT_CLEAR() st(P0IFG= 0; P0IF= 0; ) + + +#define LCD_NOT_SUPPORTED + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef USB_UART +#define HAL_PROCESS() usbUartProcess() +#else +#define HAL_PROCESS() +#endif + + +/****************************************************************************** + * FUNCTIONS + */ + +void halBoardInit(void); +void halButtonInit(void); + + +#ifdef __cplusplus +} +#endif + +/*****************************************************************************/ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_button.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_button.c new file mode 100755 index 0000000..ab50eb4 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_button.c @@ -0,0 +1,59 @@ +/*********************************************************************************** + + Filename: hal_button.c + + Description: HAL button implementation for CCxx11 dongle. + + Copyright 2009 Texas Instruments, Inc. + +***********************************************************************************/ +#include "hal_types.h" +#include "hal_board.h" +#include "hal_button.h" + + +/****************************************************************************** + * @fn halButtonInit + * + * @brief Button is configured as input + * + * @param none + * + * @return none + *****************************************************************************/ +void halButtonInit(void) +{ + MCU_IO_INPUT(HAL_BOARD_IO_BTN_PORT, HAL_BOARD_IO_BTN_PIN, MCU_IO_PULLUP); +} + + +/****************************************************************************** +* @fn halButtonPushed +* +* @brief +* This function detects if 'S1' is being pushed. The function +* implements software debounce. Return true only if previuosly called +* with button not pushed. Return true only once each time the button +* is pressed. +* +* Parameters: +* +* @param void +* +* @return uint8 +* HAL_BUTTON_1: button is being pushed +* HAL_BUTTON_NONE: button is not being pushed +* +******************************************************************************/ +uint8 halButtonPushed(void) +{ + uint8 v; + + v= HAL_BUTTON_NONE; + if (HAL_BUTTON_PUSHED()) { + HAL_DEBOUNCE(!HAL_BUTTON_PUSHED()); + v= HAL_BUTTON_1; + } + + return v; +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_int.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_int.c new file mode 100755 index 0000000..a997384 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_int.c @@ -0,0 +1,115 @@ +/*********************************************************************************** + Filename: hal_int.c + + Description: HAL interrupt control + +***********************************************************************************/ + +/*********************************************************************************** +* INCLUDES +*/ +#include "hal_types.h" +#include "hal_defs.h" +#include "hal_int.h" +#include "hal_board.h" + +/*********************************************************************************** +* GLOBAL FUNCTIONS +*/ + +/*********************************************************************************** +* @fn halIntOn +* +* @brief Enable global interrupts. +* +* @param none +* +* @return none +*/ +void halIntOn(void) +{ + HAL_INT_ON(); +} + + +/*********************************************************************************** +* @fn halIntOff +* +* @brief Turns global interrupts off. +* +* @param none +* +* @return none +*/ +void halIntOff(void) +{ + HAL_INT_OFF(); +} + + +/*********************************************************************************** +* @fn halIntLock +* +* @brief Turns global interrupts off and returns current interrupt state. +* Should always be used together with halIntUnlock(). +* +* @param none +* +* @return uint16 - current interrupt state +*/ +uint16 halIntLock(void) +{ + istate_t key; + HAL_INT_LOCK(key); + return(key); +} + + +/*********************************************************************************** +* @fn halIntUnlock +* +* @brief Set interrupt state back to the state it had before calling halIntLock(). +* Should always be used together with halIntLock(). +* +* @param key +* +* @return none +*/ +void halIntUnlock(uint16 key) +{ + HAL_INT_UNLOCK(key); +} + + +/*********************************************************************************** + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +***********************************************************************************/ + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_led.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_led.c new file mode 100755 index 0000000..4aaaf6c --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_led.c @@ -0,0 +1,46 @@ +/*********************************************************************************** + Filename: hal_led.c + + Copyright 2007 Texas Instruments, Inc. +***********************************************************************************/ + +#include "hal_types.h" +#include "hal_led.h" +#include "hal_board.h" + + + +//---------------------------------------------------------------------------------- +// void halLedSet(uint8 id) +// +// DESCRIPTION: +// Turn LED on. +//---------------------------------------------------------------------------------- +void halLedSet(uint8 id) +{ + HAL_LED_SET(); +} + +//---------------------------------------------------------------------------------- +// void halLedClear(uint8 id) +// +// DESCRIPTION: +// Turn LED off. +//---------------------------------------------------------------------------------- +void halLedClear(uint8 id) +{ + HAL_LED_CLR(); +} + +//---------------------------------------------------------------------------------- +// void halLedToggle(uint8 id) +// +// DESCRIPTION: +// Change state of LED. If on, turn it off. Else turn on. +//---------------------------------------------------------------------------------- +void halLedToggle(uint8 id) +{ + HAL_LED_TGL(); +} + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_mcu.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_mcu.c new file mode 100755 index 0000000..9cbbdda --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/hal_mcu.c @@ -0,0 +1,160 @@ +/*********************************************************************************** + Filename: hal_mcu.c + + Description: hal mcu library + +***********************************************************************************/ + + +#include "hal_types.h" +#include "hal_mcu.h" + +#include "clock.h" + +/*********************************************************************************** +* @fn halMcuInit +* +* @brief Set system clock +* +* @param none +* +* @return none +*/ +void halMcuInit(void) +{ + clockSetMainSrc(CLOCK_SRC_XOSC); +} + + +/*********************************************************************************** +* @fn halMcuWaitUs +* +* @brief Busy wait function. Waits the specified number of microseconds. Use +* assumptions about number of clock cycles needed for the various +* instructions. +* +* NB! This function is highly dependent on architecture and compiler! +* +* @param uint16 usec - number of microseconds delay +* +* @return none +*/ +#pragma optimize=none +void halMcuWaitUs(uint16 usec) +{ + usec>>= 1; // Divide by 2 to achieve better resolution + + while(usec > 1) // compare: ~13 cycles + { + asm("NOP"); // 1 cycle/NOP + asm("NOP"); + asm("NOP"); + asm("NOP"); + asm("NOP"); + asm("NOP"); + asm("NOP"); + asm("NOP"); + asm("NOP"); + asm("NOP"); + + usec--; // decr: ~7 cycles + } +} + +/*********************************************************************************** +* @fn halMcuWaitMs +* +* @brief Busy wait function. Waits the specified number of milliseconds. Use +* assumptions about number of clock cycles needed for the various +* instructions. +* +* NB! This function is highly dependent on architecture and compiler! +* +* @param uint16 millisec - number of milliseconds delay +* +* @return none +*/ +#pragma optimize=none +void halMcuWaitMs(uint16 msec) +{ + while(msec--) + halMcuWaitUs(1000); +} + +/*********************************************************************************** +* @fn halMcuSetLowPowerMode +* +* @brief Sets the MCU in a low power mode. Will turn global interrupts on at +* the same time as entering the LPM mode. The MCU must be waken from +* an interrupt (status register on stack must be modified). +* +* NB! This function is highly dependent on architecture and compiler! +* +* @param uint8 mode - power mode +* +* @return none +*/ +void halMcuSetLowPowerMode(uint8 mode) +{ + // comment: not yet implemented + //HAL_ASSERT(FALSE); +} + + +/****************************************************************************** +* @fn halMcuReset +* +* @brief +* Resets the MCU. This utilize the watchdog timer as there is no other way +* for a software reset. The reset will not occur until ~2 ms. +* NB: The function will not return! (hangs until reset) +* +* Parameters: +* +* @param void +* +* @return void +* +******************************************************************************/ +void halMcuReset(void) +{ + const uint8 WDT_INTERVAL_MSEC_2= 0x03; // after ~2 ms + + WDCTL = ((WDCTL & 0xFC) | (WDT_INTERVAL_MSEC_2 & 0x03)); + // Start watchdog + WDCTL &= ~0x04; // Select watchdog mode + WDCTL |= 0x08; // Enable timer + while(1); // Halt here until reset +} + +/*********************************************************************************** + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights + granted under the terms of a software license agreement between the user + who downloaded the software, his/her employer (which must be your employer) + and Texas Instruments Incorporated (the "License"). You may not use this + Software unless you agree to abide by the terms of the License. The License + limits your use, and you acknowledge, that the Software may not be modified, + copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio + frequency transceiver, which is integrated into your product. Other than for + the foregoing purpose, you may not use, reproduce, copy, prepare derivative + works of, modify, distribute, perform, display or sell this Software and/or + its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +***********************************************************************************/ \ No newline at end of file diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/rfConfig.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/rfConfig.c new file mode 100755 index 0000000..143be44 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/rfConfig.c @@ -0,0 +1,466 @@ +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +Filename: rfConfig.c +Target: cc2430, cc2431, cc1110, cc2510, cc2511 +Author: EFU +Revised: 26/10-2005 +Revision: 0.1 +******************************************************************************/ + +#include "hal.h" + +//----------------------------------------------------------------------------- +// See hal.h for a description of this function. +//----------------------------------------------------------------------------- +BOOL halRfConfig(UINT32 frequency) +{ + BOOL status; + + //Turning on crystal oscillator + SET_MAIN_CLOCK_SOURCE(CRYSTAL); + + // Setting the frequency + halRfSetRadioFrequency(frequency); + +#if (chip == 2430 || chip == 2431) + // Checking that the entered frequency is valid + if (frequency > 2047000) + { + + // turning on power to analog part of radio and waiting for voltage regulator. + RFPWR = 0x04; + while( RFPWR & 0x10 ); + + // Turning off Address Decoding + MDMCTRL0H &= ~ADR_DECODE; + + // Setting for AUTO CRC + MDMCTRL0L |= AUTO_CRC; + + // Turning on AUTO_TX2RX + FSMTC1 = ((FSMTC1 & (~AUTO_TX2RX_OFF & ~RX2RX_TIME_OFF)) | ACCEPT_ACKPKT); + + // Turning off abortRxOnSrxon. + FSMTC1 &= ~0x20; + +#endif +#if (chip == 1110) + if (frequency < 1000000) + { + // 315 MHz band + if (frequency < 400000) + { + PA_TABLE0 = 0x63; + } + // 433 MHz band + else if (frequency < 800000) + { + PA_TABLE0 = 0x33; + } + // 868 MHz band + else if (frequency < 890000) + { + PA_TABLE0 = 0x66; + } + // 915 MHz band + else + { + PA_TABLE0 = 0x66; + } + + /********************************************************************** + * * + * 250 kbps MSK setup (for other data rates or modulation formats, * + * please see SmartRF Studio). * + * * + **********************************************************************/ + + // Dynamic packet length + PKTLEN = 0xFF; + PKTCTRL0 = 0x05; + + // Append status + PKTCTRL1 = 0x84; + + // IF frequency + FSCTRL1 = 0x0B; + + // + // FSCTRL0 = 0x00; + + // filter BW, data rate, + // MDMCFG4 = 0x0E; + MDMCFG4 = 0x2D; + MDMCFG3 = 0x3B; + // Modulation format, detection level + MDMCFG2 = 0x73; + MDMCFG1 = 0x42; + // MDMCFG1 = 0x22; + + // Deviation setting + DEVIATN = 0x00; + + // Calibration synth + MCSM0 = 0x10; + + // Frequency offset compensation configuration + FOCCFG = 0x1D; + + // Bit synchronization + BSCFG = 0x1C; + + // AGC and front end settings (from SmartRf04) + AGCCTRL2 = 0xC7; + // AGCCTRL1 = 0x40; + AGCCTRL1 = 0x00; + AGCCTRL0 = 0xB2; + FREND1 = 0xB6; + + FSCAL3 = 0xEA; + + // Synth calibration + // FSCAL0 = 0x19; + FSCAL0 = 0x11; + // PA_TABLE0 = 0xC3; + + // Calibrating synth. + SIDLE(); + SCAL(); + while(MARCSTATE != 0x01); + + INT_SETFLAG(INUM_RFTXRX,INT_CLR); +#endif + +#if (chip == 1111) + if (frequency < 1000000) + { + // 315 MHz band + if (frequency < 400000) + { + PA_TABLE0 = 0x63; + } + // 433 MHz band + else if (frequency < 800000) + { + PA_TABLE0 = 0x33; + } + // 868 MHz band + else if (frequency < 890000) + { + PA_TABLE0 = 0x66; + } + // 915 MHz band + else + { + PA_TABLE0 = 0x66; + } + + /********************************************************************** + * * + * 250 kbps MSK setup (for other data rates or modulation formats, * + * please see SmartRF Studio). * + * * + **********************************************************************/ + + // Dynamic packet length + PKTLEN = 0xFF; + PKTCTRL0 = 0x05; + // Append status + PKTCTRL1 = 0x04; + + // IF frequency + FSCTRL1 = 0x0A; + FSCTRL0 = 0x00; + + // filter BW, data rate, + MDMCFG4 = 0x1D; + MDMCFG3 = 0x55; + // Modulation format, detection level + MDMCFG2 = 0x73; + MDMCFG1 = 0x23; + MDMCFG0 = 0x11; + + // Deviation setting + DEVIATN = 0x00; + + // Calibration synth + MCSM2 = 0x07; + MCSM1 = 0x30; + MCSM0 = 0x10; + + // Frequency offset compensation configuration + FOCCFG = 0x1D; + + // Bit synchronization + BSCFG = 0x1C; + + // AGC and front end settings (from SmartRf04) + AGCCTRL2 = 0xC7; + AGCCTRL1 = 0x00; + AGCCTRL0 = 0xB2; + FREND1 = 0xB6; + + // Synth calibration + FSCAL3 = 0xEA; + FSCAL0 = 0x11; + + // Are these needed ? + // From Smart RF Studio + FOCCFG = 0x1D; + BSCFG = 0x1C; + FSTEST = 0x59; + PTEST = 0x7F; + AGCTEST = 0x3F; + TEST2 = 0x88; + TEST1 = 0x31; + TEST0 = 0x0B; + + // Calibrating synth. + SIDLE(); + SCAL(); + while(MARCSTATE != 0x01); + + INT_SETFLAG(INUM_RFTXRX,INT_CLR); +#endif + +#if(chip == 2510) + if (frequency > 2400000) + { + /********************************************************************** + * * + * 250 kbps MSK setup (for other data rates or modulation formats, * + * please see SmartRF Studio). * + * * + **********************************************************************/ + + // Dynamic packet length and append status + PKTLEN = 0xFF; + PKTCTRL0 = 0x05; + PKTCTRL1 = 0x04; + + // IF frequency + FSCTRL1 = 0x0A; + FSCTRL0 = 0x00; + + // filter BW, data rate, + MDMCFG4 = 0x2D; + MDMCFG3 = 0x3B; + + // Modulation format, detection level + MDMCFG2 = 0x73; + MDMCFG1 = 0x22; + MDMCFG0 = 0xF8; + + // Deviation setting + DEVIATN = 0x00; + + // Calibration synth + MCSM2 = 0x07; + MCSM1 = 0x30; + MCSM0 = 0x10; + + // Frequency offset compensation configuration + FOCCFG = 0x1D; + + // Bit synchronization + BSCFG = 0x1C; + + // AGC settings + AGCCTRL2 = 0xC7; + AGCCTRL1 = 0x00; + AGCCTRL0 = 0xB2; + + // Front end settings (from SmartRf04) + FREND1 = 0xB6; + FREND0 = 0x10; + + // Synth calibration + FSCAL3 = 0xEA; + FSCAL2 = 0x0A; + FSCAL1 = 0x00; + FSCAL0 = 0x11; + + // From Smart RF Studio + FOCCFG = 0x1D; + BSCFG = 0x1C; + FSTEST = 0x59; + PTEST = 0x7F; + AGCTEST = 0x3F; + TEST2 = 0x88; + TEST1 = 0x31; + TEST0 = 0x0B; + + + // Output power + PA_TABLE0 = 0xFF; + + // Calibrating synth. + SIDLE(); + SCAL(); + while(MARCSTATE != 0x01); + + INT_SETFLAG(INUM_RFTXRX,INT_CLR); + +#endif + +#if(chip == 2511) + if (frequency > 2400000) + { + /********************************************************************** + * * + * 250 kbps MSK setup (for other data rates or modulation formats, * + * please see SmartRF Studio). * + * * + **********************************************************************/ + + // Dynamic packet length and append status + PKTLEN = 0xFF; + PKTCTRL0 = 0x05; + PKTCTRL1 = 0x04; + + // IF frequency + FSCTRL1 = 0x0A; + FSCTRL0 = 0x00; + + // filter BW, data rate, + MDMCFG4 = 0x1D; + MDMCFG3 = 0x55; + + // Modulation format, detection level + MDMCFG2 = 0x73; + MDMCFG1 = 0x23; + MDMCFG0 = 0xF8; + + // Deviation setting + DEVIATN = 0x00; + + // Calibration synth + MCSM0 = 0x07; + MCSM1 = 0x30; + MCSM0 = 0x10; + + // Frequency offset compensation configuration + FOCCFG = 0x1D; + + // Bit synchronization + BSCFG = 0x1C; + + // AGC settings + AGCCTRL2 = 0xC7; + AGCCTRL1 = 0x00; + AGCCTRL0 = 0xB2; + + // Front end settings (from SmartRf04) + FREND1 = 0xB6; + FREND0 = 0x10; + + // Synth calibration + FSCAL3 = 0xEA; + FSCAL2 = 0x0A; + FSCAL1 = 0x00; + FSCAL0 = 0x11; + + // From Smart RF Studio + FOCCFG = 0x1D; + BSCFG = 0x1C; + FSTEST = 0x59; + PTEST = 0x7F; + AGCTEST = 0x3F; + TEST2 = 0x88; + TEST1 = 0x31; + TEST0 = 0x0B; + + + // Output power + PA_TABLE0 = 0xFF; + + // Calibrating synth. + SIDLE(); + SCAL(); + while(MARCSTATE != 0x01); + + INT_SETFLAG(INUM_RFTXRX,INT_CLR); + +#endif + status = TRUE; + } + else { + status = FALSE; + } + + return status; +} + + +//----------------------------------------------------------------------------- +// See hal.h for a description of this function. +//----------------------------------------------------------------------------- +void halRfSetRadioFrequency(UINT32 frequency) +{ +#if (chip == 2430 || chip == 2431) + frequency /= (UINT32)1000; + frequency -= (UINT32)2048; + + FSCTRLL = LOBYTE(frequency); + FSCTRLH &= ~0x03; + FSCTRLH |= (HIBYTE(frequency) & 0x03); +#endif +#if (chip == 0000) + // TODO: make sure casting is done correctly +#endif +#if (chip == 1110 || chip == 2510) + frequency = (frequency << 10); + frequency /= 1000; + frequency = (frequency << 6); + frequency /= 26; + FREQ0 = (BYTE) frequency; + frequency >>= 8; + FREQ1 = (BYTE) frequency; + frequency >>= 8; + FREQ2 = (BYTE) frequency; +#endif +#if (chip == 1111 || chip == 2511) + frequency = (frequency << 10); + frequency /= 1000; + frequency = (frequency << 6); + frequency /= 24; + FREQ0 = (BYTE) frequency; + frequency >>= 8; + FREQ1 = (BYTE) frequency; + frequency >>= 8; + FREQ2 = (BYTE) frequency; +#endif + return; +} + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/setTimer2Period.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/setTimer2Period.c new file mode 100755 index 0000000..057ac0e --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/setTimer2Period.c @@ -0,0 +1,156 @@ +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +Filename: setTimer2Period.c +Target: cc2430, cc2431, cc1110, cc2510, cc2511 +Author: EFU +Revised: 26/10-2005 +Revision: 0.1 +******************************************************************************/ +#include "hal.h" + +//----------------------------------------------------------------------------- +// See hal.h for a description of this function. +//----------------------------------------------------------------------------- +#if (chip == 2430 || chip == 2431) +BOOL halSetTimer2Period(BYTE mode, DWORD period){ + if(mode&TIMER2_MAC_TIMER){ + T2CAPHPH = 0x28; // setting for 320 u-second periods as specified by 802.15.4 + T2CAPLPL = 0x00; // (0x2800) / 32 = 320 u-seconds + } + else { + T2CAPHPH = 0x7D; // Setting timer to have 1 m-second period + T2CAPLPL = 0x00; // (0x7D00) / 32 = 1000 u-seconds + } + + if(period){ + if(period&0xFFF00000) {return 0;}// Setting the number of periods (timer overflows) to generate + T2PEROF0 = (BYTE) period; // an interrupt. + period = (period >> 8); + T2PEROF1 = (BYTE) period; + period = ((period >> 8)&0x0F); + T2PEROF2 = ( T2PEROF2&~0x0F | (BYTE)period ); + } + return 1; +} +#endif +#if (chip == 1110 || chip == 2510) +BOOL halSetTimer2Period(UINT32 period, UINT8* cnt, UINT8* presc) +{ + BYTE tip = 0; + UINT16 prescaler = 1; + UINT16 counter; + + // Times 26 and devided by 64 (crystal clock frequency and minimum tick period of T2). + period = (UINT32)((float)period * 0.40625); + + // Compensating for TICKSPD. + period = (period >> TICKSPD); + + + while(period > 65280) + { + tip++; + if(tip == 3) + { // Step from 256 to 1024 clock cycles + period = period >> 1; + } + period = period >> 1; + } + + if(tip > 3) + { + return FALSE; + } + + while(((counter = (period / prescaler)) > 255)) + { + prescaler++; + } + + TIMER2_SET_COUNTER((UINT8)counter); + TIMER2_SET_PRESCALER((UINT8) prescaler); + TIMER2_SET_TICK_PERIOD(tip); + + *cnt = (UINT8) counter; + *presc = (UINT8) prescaler; + + return TRUE; +} +#endif +#if (chip == 1111 || chip == 2511) +BOOL halSetTimer2Period(UINT32 period, UINT8* cnt, UINT8* presc) +{ + BYTE tip = 0; + UINT16 prescaler = 1; + UINT16 counter; + BYTE temp; + + // Times 24 and devided by 64 (crystal clock frequency and minimum tick period of T2). + period = (UINT32)((float)period * 0.375); + + // Compensating for TICKSPD + temp = TICKSPD;//to avoid IAR warning + if(temp <= CLKSPD) { period >>= TICKSPD; } + else { period >>= CLKSPD; } + + while(period > 65280) + { + tip++; + if(tip == 3) + { // Step from 256 to 1024 clock cycles + period = period >> 1; + } + period = period >> 1; + } + + if(tip > 3) + { + return FALSE; + } + + while(((counter = (period / prescaler)) > 255)) + { + prescaler++; + } + + TIMER2_SET_COUNTER((UINT8)counter); + TIMER2_SET_PRESCALER((UINT8) prescaler); + TIMER2_SET_TICK_PERIOD(tip); + + *cnt = (UINT8) counter; + *presc = (UINT8) prescaler; + + return TRUE; +} +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/setTimer34Period.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/setTimer34Period.c new file mode 100755 index 0000000..c808366 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/setTimer34Period.c @@ -0,0 +1,91 @@ +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ + +Filename: setTimer34Period.c +Target: cc2430, cc2431, cc1110, cc2510, cc2511 +Author: EFU +Revised: 26/10-2005 +Revision: 0.1 +******************************************************************************/ +#include "hal.h" + + +//------------------------------------------------------------------------------------------------------ +// See hal.h for a description of this function. +//------------------------------------------------------------------------------------------------------ +BYTE halSetTimer34Period(BYTE timer, DWORD period){ + BYTE div = 0; + + if(TICKSPD > 5) { // Checking that the period is not too short. + if( (period < 2*(TICKSPD-5)) && (period != 0) ){ + return 0; + } + } + + if(period == 0){ // If period is 0, max period length and max prescaler + div = 7; // division is used. + period = 255; + } else { +#if (chip == 2430 || chip == 2431) + period = ((period*32) >> TICKSPD);// Determining how many timer ticks the period consist of +#endif +#if (chip == 1110 || chip == 2510) + period = ((period*26) >> TICKSPD);// Determining how many timer ticks the period consist of +#endif +#if (chip == 1111 || chip == 2511) + period = ((period*24) >> TICKSPD);// Determining how many timer ticks the period consist of +#endif + while(period > 255){ // If the period is too long, the prescaler division is + period = (period >> 1); // increased. + div++; + if(div > 7){ // If the period is too long when using max prescaler division, + return 0; // 0 is returned. + } + } + } + + if(timer == 4){ + // Timer 4 selected + T4CTL |= (div << 5); // Setting prescaler value + T4CC0 = (BYTE) period; // Setting timer value. + } else if(timer == 3){ + // Timer 3 selected + T3CTL |= (div << 5); // Setting prescaler value + T3CC0 = (BYTE) period; // Setting timer value. + } else { + return 0; + } + + return period; +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/util_critical_section.s51 b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/util_critical_section.s51 new file mode 100755 index 0000000..a5cfbb7 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/util_critical_section.s51 @@ -0,0 +1,82 @@ +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +Filename: flashWritePage.s51 +Target: cc2510, cc2511 +Author: JOL +Revised: 24/03-2006 +Revision: 1.0 +******************************************************************************/ +;;----------------------------------------------------------------------------- +;; See hal.h for a description of this function. +;;----------------------------------------------------------------------------- +//#include "hal.h" +#if (chip == 2510) +#include "ioCC2510.h" +#endif +#if (chip == 2511) +#include "ioCC2511.h" +#endif +#if (chip == 1110) +#include "ioCC1110.h" +#endif +#if (chip == 1111) +#include "ioCC1111.h" +#endif + + MODULE util_critical_section.s51 + + RSEG RCODE + PUBLIC utilEnterCriticalSection; + FUNCTION utilEnterCriticalSection, 0203H + + ; Turn off global interrupts and return the previous state of EA +utilEnterCriticalSection: + MOV A, #01H; + JBC EA, intsTurnedOff; + MOV A, #00H; +intsTurnedOff: MOV R1, A; + RET; + + + PUBLIC utilLeaveCriticalSection; + FUNCTION utilLeaveCriticalSection, 0203H + + ; Restore the previous EA state from the value provided in the function parameter +utilLeaveCriticalSection: + MOV A, R1; + MOV C, ACC^0; + MOV EA, C; + RET; + + END; diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/wait.c b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/wait.c new file mode 100755 index 0000000..cf899ae --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/HAL/source/wait.c @@ -0,0 +1,69 @@ +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +Filename: wait.c +Target: cc2430, cc2431, cc1110, cc2510, cc2511 +Author: EFU +Revised: 26/10-2005 +Revision: 0.1 +******************************************************************************/ +#include "hal.h" + + +//----------------------------------------------------------------------------- +// See hal.h for a description of this function. +//----------------------------------------------------------------------------- +void halWait(BYTE wait){ + UINT32 largeWait; + + if(wait == 0) + {return;} +#if (chip == 2430 || chip == 2431) + largeWait = ((UINT16) (wait << 7)); + largeWait += 114*wait; +#endif + +#if ((chip == 1110) || (chip == 2510)) + largeWait = ((UINT16) (wait << 7)); + largeWait += 59*wait; +#endif +#if ((chip == 1111) || (chip == 2511)) + largeWait = ((UINT16) (wait << 7)); + largeWait += 45*wait; +#endif + + largeWait = (largeWait >> CLKSPD); + while(largeWait--); + + return; +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/BlueRobin_TX_433MHz.r51 b/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/BlueRobin_TX_433MHz.r51 new file mode 100755 index 0000000..de5a918 Binary files /dev/null and b/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/BlueRobin_TX_433MHz.r51 differ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/BlueRobin_TX_868MHz.r51 b/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/BlueRobin_TX_868MHz.r51 new file mode 100755 index 0000000..5ab2ff7 Binary files /dev/null and b/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/BlueRobin_TX_868MHz.r51 differ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/BlueRobin_TX_915MHz.r51 b/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/BlueRobin_TX_915MHz.r51 new file mode 100755 index 0000000..8d37033 Binary files /dev/null and b/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/BlueRobin_TX_915MHz.r51 differ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/bm.h b/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/bm.h new file mode 100755 index 0000000..1c5b63c --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/bm.h @@ -0,0 +1,324 @@ +// ************************************************************************************************* +// +// Copyright 2009 BM innovations GmbH (www.bm-innovations.com), all rights reserved. +// +// This trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC" may be used for non-profit non-commercial purposes only. If you want to use +// BlueRobin(TM) in a commercial project, please contact the copyright holder for a +// separate license agreement. +// +// By using this trial version of the "BlueRobin(TM) receiver library for the Texas Instruments +// CC430 SoC", you implicitly agree that you will not modify, adapt, disassemble, decompile, +// reverse engineer, translate or otherwise attempt to discover the source code of the +// "BlueRobin(TM) receiver library for the Texas Instruments CC430 SoC". +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Standard definitions, have to be included in every source and header file. +// ************************************************************************************************* + +#ifndef __BM_H +#define __BM_H + +#if (defined __IAR_SYSTEMS_ASM) || (defined __IAR_SYSTEMS_ASM__) + #define _ASSEMBLER_USED_ +#endif + +#ifndef _ASSEMBLER_USED_ + // get the null pointer, offsetof ... + #include +#endif + +#ifndef FALSE + /*! the classic false */ + #define FALSE (0 == 1) +#endif + +#ifndef TRUE + /*! the classic true */ + #define TRUE (1 == 1) +#endif + +#ifndef USE_RAW_ATTR + //! per default this feature is disabled + #define USE_RAW_ATTR FALSE +#endif + +// ************************************************************************************************* +// First Section: Basic Data Types +// ************************************************************************************************* + +// Fundamental #definitions +// CPU target idents are used for target dependant compilations + +/*! Intel 8051 */ +#define _INTEL_8051_ (20) + + +// Find the currently running compiler +// and make the related #define's + +// _IAR_TID_ target ID from IAR compilers +// _CPU_TID_ remap to enum of processor target numbers +// _CPU_8BIT_INT_ type for 8 bit int +// _CPU_16BIT_INT_ type for 16 bit int +// _CPU_32BIT_INT_ type for 32 bit int +// _CPU_32BIT_FLOAT_ type for 32 bit float +// _CPU_64BIT_FLOAT_ type for 64 bit float +// INTERRUPT declares an interrupt service routine without an entry in the vector table +// ISR(vector) declares an interrupt service routine which is added in vector table at offset vector +// MONITOR declares a function atomic +// INTERRUPTS_ENABLE remap to the intrinsic for enable interrupts +// INTERRUPTS_DISABLE remap to the intrinsic for disable interrupts +// NO_OPERATION remap to the intrinsic for no operation +// _CPU_DIRECTION_OUT_1_ if TRUE the direction register indicates with an 1: direction is output +// _CPU_EDGE_HIGH_LOW_1_ if TRUE the edge select register indicates with an 1: trigger on high low +// NO_INIT declare a variable as not initialized +// INLINE_FUNC declare a function as inline for release builds + +#if defined __IAR_SYSTEMS_ICC__ + // Found IAR Compiler with EDG frontend + #define _IAR_TID_ ((__TID__ >> 8) & 0x7f) + + #if USE_RAW_ATTR == TRUE + //! use the raw attribute in ISR's + #define _RAW __raw + #else + //! empty define RAW as it is not used + #define _RAW + #endif + #define INTERRUPT _RAW __interrupt + #define MONITOR __monitor + #define NO_INIT __no_init + #define INTERRUPTS_ENABLE() __enable_interrupt() + #define INTERRUPTS_DISABLE() __disable_interrupt() + #define NO_OPERATION() __no_operation() + + #ifndef DEBUG + // force inlining of function in release builds + #define INLINE_FUNC PRAGMA(inline=forced) + #else + // do not force inlining of function in debug builds + #define INLINE_FUNC + #endif + + #if (!defined CODECHECK) && (!defined __DA_C__) + /*! Define to a new way of using #pragmas in preprocessor */ + #define PRAGMA(x) _Pragma(#x) + #define ISR(x) PRAGMA(vector = (x)) INTERRUPT + #endif + + #if ((_IAR_TID_) == 32) + // Found 8051 CPU + #define _CPU_TID_ _INTEL_8051_ + +#else + #error "Unknown new IAR Compiler, the file iar.h has to be expanded !" + #endif + +#else + #error "Unknown Compiler, the file iar.h has to be expanded !" +#endif + +#ifndef _ASSEMBLER_USED_ + // Get the limits to autodetect the size of integral types + #include + // Get floats to autodetect the size of float types + #include + + // *********************************************************************************************** + // + // Common basic datatypes + // + // *********************************************************************************************** + #if UCHAR_MAX == 0xFFu + #define _CPU_8BIT_INT_ char + #else + #error "unable to get size of u8 automatically" + #endif + + #if USHRT_MAX == 0xFFFFu + #define _CPU_16BIT_INT_ short + #elif UINT_MAX == 0xFFFFu + #define _CPU_16BIT_INT_ int + #else + #error "unable to get size of u16 automatically" + #endif + + #if USHRT_MAX == 0xFFFFFFFFu + #define _CPU_32BIT_INT_ short + #elif UINT_MAX == 0xFFFFFFFFu + #define _CPU_32BIT_INT_ int + #elif ULONG_MAX == 0xFFFFFFFFu + #define _CPU_32BIT_INT_ long + #else + #error "unable to get size of u32 automatically" + #endif + + #ifdef __IAR_SYSTEMS_ICC__ + #if __IAR_SYSTEMS_ICC__ > 1 + #define _CPU_32BIT_FLOAT_ float + #if __DOUBLE_SIZE__ == 8 + #define _CPU_64BIT_FLOAT_ double + #endif + #endif + #endif + + #ifndef _CPU_32BIT_FLOAT_ + #if FLT_MANT_DIG == 24 + #define _CPU_32BIT_FLOAT_ float + #elif DBL_MANT_DIG == 24 + #define _CPU_32BIT_FLOAT_ double + #else + #error "unable to get size of f32 automatically" + #endif + + #if DBL_MANT_DIG == 53 + #define _CPU_64BIT_FLOAT_ double + #endif + #endif + + + // *********************************************************************************************** + // + // Following lines #typedef the basic datatypes in a compiler independent way. + // + // *********************************************************************************************** + + #ifdef _CPU_8BIT_INT_ + /*! unsigned 8 bit */ + typedef unsigned _CPU_8BIT_INT_ u8 ; + /*! unsigned 8 bit max value */ + #define U8_MAX (0xFFU) + /*! signed 8 bit max value */ + typedef signed _CPU_8BIT_INT_ s8 ; + /*! signed 8 bit min value */ + #define S8_MIN (-127 - 1) + /*! signed 8 bit max value */ + #define S8_MAX (127) + #endif + + #ifdef _CPU_16BIT_INT_ + /*! unsigned 16 bit */ + typedef unsigned _CPU_16BIT_INT_ u16 ; + /*! unsigned 16 bit max value */ + #define U16_MAX (0xFFFFU) + /*! signed 16 bit */ + typedef signed _CPU_16BIT_INT_ s16 ; + /*! signed 16 bit min value */ + #define S16_MIN (-32767 - 1) + /*! signed 16 bit max value */ + #define S16_MAX (32767) + #endif + + #ifdef _CPU_32BIT_INT_ + /*! unsigned 32 bit */ + typedef unsigned _CPU_32BIT_INT_ u32 ; + /*! unsigned 32 bit max value */ + #define U32_MAX (0xFFFFFFFFUL) + /*! signed 32 bit */ + typedef signed _CPU_32BIT_INT_ s32 ; + /*! signed 32 bit min value */ + #define S32_MIN (-2147483647L - 1L) + /*! signed 32 bit max value */ + #define S32_MAX (2147483647L) + #endif + + #ifdef _CPU_64BIT_INT_ + /*! unsigned 64 bit */ + typedef unsigned _CPU_64BIT_INT_ u64 ; + /*! signed 64 bit */ + typedef signed _CPU_64BIT_INT_ s64 ; + #endif + + #ifdef _CPU_32BIT_FLOAT_ + /*! float 32 bit */ + typedef _CPU_32BIT_FLOAT_ f32 ; + /*! number of digits in mantissa of f32 */ + #define F32_MANT_DIG (24) + /*! epsilon for f32 */ + #define F32_EPSILON (1.192092896e-07) + /*! number of digits of precision of f32 */ + #define F32_DIG (6) + /*! exponent min of f32 */ + #define F32_MIN_EXP (-125) + /*! min positive value of f32 */ + #define F32_MIN (1.175494351e-38) + /*! decimal exponent min of f32 */ + #define F32_MIN_10_EXP (-37) + /*! exponent max of f32 */ + #define F32_MAX_EXP (128) + /*! max value of f32 */ + #define F32_MAX (3.402823466e+38) + /*! decimal exponent max of f32 */ + #define F32_MAX_10_EXP (38) + #endif + + #ifdef _CPU_64BIT_FLOAT_ + /*! float 64 bit */ + typedef _CPU_64BIT_FLOAT_ f64 ; + /*! number of digits in mantissa of f64 */ + #define F64_MANT_DIG (53) + /*! epsilon for f64 */ + #define F64_EPSILON (2.2204460492503131e-016) + /*! number of digits of precision of f64 */ + #define F64_DIG (15) + /*! exponent min of f64 */ + #define F64_MIN_EXP (-1021) + /*! min positive value of f64 */ + #define F64_MIN (2.2250738585072014e-308) + /*! decimal exponent min of f64 */ + #define F64_MIN_10_EXP (-307) + /*! exponent max of f64 */ + #define F64_MAX_EXP (1024) + /*! max value of f64 */ + #define F64_MAX (1.7976931348623158e+308) + /*! decimal exponent max of f64 */ + #define F64_MAX_10_EXP (308) + #endif + +#endif // _ASSMEBLER_USED_ + +#ifndef MONITOR + #define MONITOR +#endif + +#ifndef NO_INIT + #define NO_INIT +#endif + +#ifndef INTERRUPT + #define INTERRUPT +#endif + +#ifndef ISR + #define ISR(ignore) +#endif + +#ifndef INLINE_FUNC + #define INLINE_FUNC +#endif + +#ifndef INTERRUPTS_ENABLE + #define INTERRUPTS_ENABLE() +#endif + +#ifndef INTERRUPTS_DISABLE + #define INTERRUPTS_DISABLE() +#endif + + +/*! Every project has to have its own header file, so it can be included here */ +#include "project.h" + +#endif // __BM_H diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/project.h b/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/project.h new file mode 100755 index 0000000..31c8be2 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/bm-br1/project.h @@ -0,0 +1,130 @@ +// ************************************************************************************************* +// +// Copyright 2009 BM innovations GmbH (www.bm-innovations.com), all rights reserved. +// +// This trial version of the "BlueRobin(TM) transmitter library for the Texas Instruments +// CC1111 SoC" may be used for non-profit non-commercial purposes only. If you want to use +// BlueRobin(TM) in a commercial project, please contact the copyright holder for a +// separate license agreement. +// +// By using this trial version of the "BlueRobin(TM) transmitter library for the Texas Instruments +// CC430 SoC", you implicitly agree that you will not modify, adapt, disassemble, decompile, +// reverse engineer, translate or otherwise attempt to discover the source code of the +// "BlueRobin(TM) transmitter library for the Texas Instruments CC1111 SoC". +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Project setup for USB dongle +// ************************************************************************************************* + + +#ifndef __PROJECT_H +#define __PROJECT_H + + +// ************************************************************************************************* +// Include section + +#include +#include "hal.h" + +// ************************************************************************************************* +// Defines section + +//#define TX_SIMPLE_TEST +//#define TX_MP_TEST + +// Debug +#ifdef CC1111EM + + #define TOGGLE_LED { if ((P1_1 & BIT0) == BIT0) P1_1 &= ~BIT0; else P1_1 |= BIT0; } + #define LED_ON { P1_1 |= BIT0; } + #define LED_OFF { P1_1 &= ~BIT0; } + + #define DEBUG_OUTPUT + #ifdef DEBUG_OUTPUT + #define DBG_PIN_H(port, bit) {port |= bit;} + #define DBG_PIN_L(port, bit) {port &= ~bit;} + #define TOGGLE_P0_5 { if ((P0_5 & BIT0) == BIT0) P0_5 &= ~BIT0; else P0_5 |= BIT0; } + #define TOGGLE_P0_4 { if ((P0_4 & BIT0) == BIT0) P0_4 &= ~BIT0; else P0_4 |= BIT0; } + #define TOGGLE_P0_3 { if ((P0_3 & BIT0) == BIT0) P0_3 &= ~BIT0; else P0_3 |= BIT0; } + #define TOGGLE_P0_2 { if ((P0_2 & BIT0) == BIT0) P0_2 &= ~BIT0; else P0_2 |= BIT0; } + #define TOGGLE_P0_1 { if ((P0_1 & BIT0) == BIT0) P0_1 &= ~BIT0; else P0_1 |= BIT0; } + #define TOGGLE_P0_0 { if ((P0_0 & BIT0) == BIT0) P0_0 &= ~BIT0; else P0_0 |= BIT0; } + #else + #define DBG_PIN_H(port, bit) { } + #define DBG_PIN_L(port, bit) { } + #define TOGGLE_P0_5 { } + #define TOGGLE_P0_4 { } + #define TOGGLE_P0_3 { } + #define TOGGLE_P0_2 { } + #define TOGGLE_P0_1 { } + #define TOGGLE_P0_0 { } + #endif + +#else + + #define TOGGLE_LED { if ((P1_0 & BIT0) == BIT0) P1_0 &= ~BIT0; else P1_0 |= BIT0; } + #define LED_ON { P1_0 |= BIT0; } + #define LED_OFF { P1_0 &= ~BIT0; } + + #define TP_H { P1_4 |= BIT0; } + #define TP_L { P1_4 &= ~BIT0; } + + #define DBG_PIN_H(port, bit) { } + #define DBG_PIN_L(port, bit) { } + #define TOGGLE_P0_5 { } + #define TOGGLE_P0_4 { } + #define TOGGLE_P0_3 { } + #define TOGGLE_P0_2 { } + #define TOGGLE_P0_1 { } + #define TOGGLE_P0_0 { } + +#endif + +// Product ID +#define PRODUCT_ID (0x12345678) + +// BlueRobin TX serial +#define TX_SERIAL_NO (1234567u) + +// Radio to be used +//#define CC2500 +#define CC1100 + + +#define NO (0) +#define YES (1) + + +/************************************************************ +* STANDARD BITS +************************************************************/ +#define BIT0 (0x0001) +#define BIT1 (0x0002) +#define BIT2 (0x0004) +#define BIT3 (0x0008) +#define BIT4 (0x0010) +#define BIT5 (0x0020) +#define BIT6 (0x0040) +#define BIT7 (0x0080) +#define BIT8 (0x0100) +#define BIT9 (0x0200) +#define BITA (0x0400) +#define BITB (0x0800) +#define BITC (0x1000) +#define BITD (0x2000) +#define BITE (0x4000) +#define BITF (0x8000) + +#endif // __PROJECT_H diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/cc1111_usb_dongle.ewd b/chronos-ti/Software Projects/RF Access Point/IAR/cc1111_usb_dongle.ewd new file mode 100755 index 0000000..daec8b6 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/cc1111_usb_dongle.ewd @@ -0,0 +1,3805 @@ + + + + 2 + + 915MHz - Limited IAR Kickstart (USA) + + 8051 + + 1 + + C-SPY + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _3RD_ID + 1 + + 0 + 1 + 1 + + + + + + + + CHIPCON_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + FS2_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + INFINEON_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + + + + NS_ID + 1 + + 0 + 1 + 1 + + + + + + + ROM_ID + 1 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + AD2_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + CYGNAL_ID + 1 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + _SENSIUM_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + SIM_ID + 1 + + 1 + 1 + 1 + + + + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 868MHz - Limited IAR Kickstart (Europe) + + 8051 + + 1 + + C-SPY + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _3RD_ID + 1 + + 0 + 1 + 1 + + + + + + + + CHIPCON_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + FS2_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + INFINEON_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + + + + NS_ID + 1 + + 0 + 1 + 1 + + + + + + + ROM_ID + 1 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + AD2_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + CYGNAL_ID + 1 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + _SENSIUM_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + SIM_ID + 1 + + 1 + 1 + 1 + + + + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 433MHz - Limited IAR Kickstart (Other regions) + + 8051 + + 1 + + C-SPY + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _3RD_ID + 1 + + 0 + 1 + 1 + + + + + + + + CHIPCON_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + FS2_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + INFINEON_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + + + + NS_ID + 1 + + 0 + 1 + 1 + + + + + + + ROM_ID + 1 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + AD2_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + CYGNAL_ID + 1 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + _SENSIUM_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + SIM_ID + 1 + + 1 + 1 + 1 + + + + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 915MHz - Unrestricted IAR Workbench (USA) + + 8051 + + 1 + + C-SPY + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _3RD_ID + 1 + + 0 + 1 + 1 + + + + + + + + CHIPCON_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + FS2_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + INFINEON_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + + + + NS_ID + 1 + + 0 + 1 + 1 + + + + + + + ROM_ID + 1 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + AD2_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + CYGNAL_ID + 1 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + _SENSIUM_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + SIM_ID + 1 + + 1 + 1 + 1 + + + + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 868MHz - Unrestricted IAR Workbench (Europe) + + 8051 + + 1 + + C-SPY + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _3RD_ID + 1 + + 0 + 1 + 1 + + + + + + + + CHIPCON_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + FS2_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + INFINEON_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + + + + NS_ID + 1 + + 0 + 1 + 1 + + + + + + + ROM_ID + 1 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + AD2_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + CYGNAL_ID + 1 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + _SENSIUM_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + SIM_ID + 1 + + 1 + 1 + 1 + + + + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + 433MHz - Unrestricted IAR Workbench (Other regions) + + 8051 + + 1 + + C-SPY + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _3RD_ID + 1 + + 0 + 1 + 1 + + + + + + + + CHIPCON_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + FS2_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + INFINEON_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + + + + + NS_ID + 1 + + 0 + 1 + 1 + + + + + + + ROM_ID + 1 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + AD2_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + CYGNAL_ID + 1 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + _SENSIUM_ID + 1 + + 0 + 1 + 1 + + + + + + + + + + + + SIM_ID + 1 + + 1 + 1 + 1 + + + + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/cc1111_usb_dongle.ewp b/chronos-ti/Software Projects/RF Access Point/IAR/cc1111_usb_dongle.ewp new file mode 100755 index 0000000..3686fbc --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/cc1111_usb_dongle.ewp @@ -0,0 +1,6787 @@ + + + + 2 + + 915MHz - Limited IAR Kickstart (USA) + + 8051 + + 1 + + General + 1 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC8051 + 3 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A8051 + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 3 + + 17 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 1 + + 0 + 1 + 1 + + + + + + + + BILINK + 0 + + + + + 868MHz - Limited IAR Kickstart (Europe) + + 8051 + + 1 + + General + 1 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC8051 + 3 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A8051 + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 3 + + 17 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 1 + + 0 + 1 + 1 + + + + + + + + BILINK + 0 + + + + + 433MHz - Limited IAR Kickstart (Other regions) + + 8051 + + 1 + + General + 1 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC8051 + 3 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A8051 + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 3 + + 17 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 1 + + 0 + 1 + 1 + + + + + + + + BILINK + 0 + + + + + 915MHz - Unrestricted IAR Workbench (USA) + + 8051 + + 1 + + General + 1 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC8051 + 3 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A8051 + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 3 + + 17 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 1 + + 0 + 1 + 1 + + + + + + + + BILINK + 0 + + + + + 868MHz - Unrestricted IAR Workbench (Europe) + + 8051 + + 1 + + General + 1 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC8051 + 3 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A8051 + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 3 + + 17 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 1 + + 0 + 1 + 1 + + + + + + + + BILINK + 0 + + + + + 433MHz - Unrestricted IAR Workbench (Other regions) + + 8051 + + 1 + + General + 1 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICC8051 + 3 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A8051 + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + XLINK + 3 + + 17 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XAR + 1 + + 0 + 1 + 1 + + + + + + + + BILINK + 0 + + + + + BlueRobin + + $PROJ_DIR$\bm-br1\BlueRobin_TX_433MHz.r51 + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + + + + $PROJ_DIR$\bm-br1\BlueRobin_TX_868MHz.r51 + + 915MHz - Limited IAR Kickstart (USA) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\bm-br1\BlueRobin_TX_915MHz.r51 + + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\bm-br1\bm.h + + + $PROJ_DIR$\bm-br1\project.h + + + + HAL + + include + + $PROJ_DIR$\HAL\include\hal.h + + + $PROJ_DIR$\HAL\include\hal_defs.h + + + $PROJ_DIR$\HAL\include\hal_types.h + + + + source + + $PROJ_DIR$\HAL\source\hal_int.c + + + + + SimpliciTI + + Applications + + $PROJ_DIR$\simpliciti\Applications\app_remap_led.h + + + $PROJ_DIR$\simpliciti\Applications\main_AP_BM.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + + Components + + bsp + + boards + + RFUSB + + bsp_external + + $PROJ_DIR$\simpliciti\Components\bsp\boards\RFUSB\bsp_external\mrfi_board_defs.h + + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\RFUSB\bsp_board.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\RFUSB\bsp_board_defs.h + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\RFUSB\bsp_button_defs.h + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\RFUSB\bsp_driver_defs.h + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\RFUSB\bsp_drivers.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\boards\RFUSB\bsp_led_defs.h + + + + + drivers + + code + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_buttons.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_generic_buttons.h + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_generic_leds.h + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\code\bsp_leds.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\bsp_buttons.h + + + $PROJ_DIR$\simpliciti\Components\bsp\drivers\bsp_leds.h + + + + mcus + + $PROJ_DIR$\simpliciti\Components\bsp\mcus\bsp_8051_defs.h + + + + $PROJ_DIR$\simpliciti\Components\bsp\bsp.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\bsp\bsp.h + + + $PROJ_DIR$\simpliciti\Components\bsp\bsp_macros.h + + + + mrfi + + radios + + common + + $PROJ_DIR$\simpliciti\Components\mrfi\radios\common\mrfi_f1f2.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\mrfi\radios\common\mrfi_f1f2.h + + + + family2 + + $PROJ_DIR$\simpliciti\Components\mrfi\radios\family2\mrfi_radio.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + + + smartrf + + CC1111 + + $PROJ_DIR$\simpliciti\Components\mrfi\smartrf\CC1111\smartrf_CC1111.h + + + + + $PROJ_DIR$\simpliciti\Components\mrfi\mrfi.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\mrfi\mrfi.h + + + $PROJ_DIR$\simpliciti\Components\mrfi\mrfi_defs.h + + + + nwk + + $PROJ_DIR$\simpliciti\Components\nwk\nwk.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_api.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_api.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_app.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_frame.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_frame.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_globals.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_globals.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_QMgmt.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_QMgmt.h + + + $PROJ_DIR$\simpliciti\Components\nwk\nwk_types.h + + + + nwk_applications + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_freq.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_freq.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ioctl.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ioctl.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_join.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_join.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_link.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_link.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_mgmt.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_mgmt.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ping.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_ping.h + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_security.c + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + + + + $PROJ_DIR$\simpliciti\Components\nwk_applications\nwk_security.h + + + + + Configuration + + Access Point + + $PROJ_DIR$\simpliciti\Configuration\Access Point\smpl_config.dat + + + + $PROJ_DIR$\simpliciti\Configuration\smpl_nwk_config.dat + + + + $PROJ_DIR$\simpliciti\CC1111 - Access Point - 433MHz.r51 + + 915MHz - Limited IAR Kickstart (USA) + 868MHz - Limited IAR Kickstart (Europe) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\CC1111 - Access Point - 868MHz.r51 + + 915MHz - Limited IAR Kickstart (USA) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\CC1111 - Access Point - 915MHz.r51 + + 868MHz - Limited IAR Kickstart (Europe) + 433MHz - Limited IAR Kickstart (Other regions) + 915MHz - Unrestricted IAR Workbench (USA) + 868MHz - Unrestricted IAR Workbench (Europe) + 433MHz - Unrestricted IAR Workbench (Other regions) + + + + $PROJ_DIR$\simpliciti\simpliciti.h + + + $PROJ_DIR$\simpliciti\simpliciti_readme.txt + + + + USB + + class_cdc + + $PROJ_DIR$\usb\class_cdc\usb_cdc.h + + + $PROJ_DIR$\usb\class_cdc\usb_cdc_descriptor.s51 + + + $PROJ_DIR$\usb\class_cdc\usb_cdc_hooks.c + + + $PROJ_DIR$\usb\class_cdc\usb_firmware_library_config.c + + + $PROJ_DIR$\usb\class_cdc\usb_firmware_library_config.h + + + $PROJ_DIR$\usb\class_cdc\usb_firmware_library_headers.h + + + $PROJ_DIR$\usb\class_cdc\usb_uart.c + + + $PROJ_DIR$\usb\class_cdc\usb_uart.h + + + + library + + $PROJ_DIR$\usb\library\usb_descriptor.h + + + $PROJ_DIR$\usb\library\usb_descriptor_parser.c + + + $PROJ_DIR$\usb\library\usb_descriptor_parser.h + + + $PROJ_DIR$\usb\library\usb_framework.c + + + $PROJ_DIR$\usb\library\usb_framework.h + + + $PROJ_DIR$\usb\library\usb_framework_structs.h + + + $PROJ_DIR$\usb\library\ccxx11\usb_interrupt.c + + + $PROJ_DIR$\usb\library\usb_interrupt.h + + + $PROJ_DIR$\usb\library\usb_reg.h + + + $PROJ_DIR$\usb\library\usb_standard_requests.c + + + $PROJ_DIR$\usb\library\usb_standard_requests.h + + + $PROJ_DIR$\usb\library\ccxx11\usb_suspend.c + + + $PROJ_DIR$\usb\library\usb_suspend.h + + + + + WBSL + + $PROJ_DIR$\wbsl\ioCCxx10_bitdef.h + + + $PROJ_DIR$\wbsl\wbsl.c + + + $PROJ_DIR$\wbsl\wbsl.h + + + + $PROJ_DIR$\BM_API.h + + + $PROJ_DIR$\change_record.txt + + + $PROJ_DIR$\flash.c + + + $PROJ_DIR$\main.c + + + $PROJ_DIR$\rftest.c + + + $PROJ_DIR$\timer1.c + + + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/cc1111_usb_dongle.eww b/chronos-ti/Software Projects/RF Access Point/IAR/cc1111_usb_dongle.eww new file mode 100755 index 0000000..484d16f --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/cc1111_usb_dongle.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\cc1111_usb_dongle.ewp + + + + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/change_record.txt b/chronos-ti/Software Projects/RF Access Point/IAR/change_record.txt new file mode 100755 index 0000000..c8ecbe9 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/change_record.txt @@ -0,0 +1,8 @@ +V1.2 (12.03.2010) +- SimpliciTI Added SimpliciTI sources to project. Upgraded to Version 1.1.1. +- 433MHz support Added ISM_LF support for BlueRobin and SimpliciTI +- Added projects for full and kickstart (16kB code limit) license +- Added RFBSL function + +V1.1 (22.11.2009) +First version released to manufacturing. \ No newline at end of file diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/flash.c b/chronos-ti/Software Projects/RF Access Point/IAR/flash.c new file mode 100755 index 0000000..b1fe148 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/flash.c @@ -0,0 +1,238 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Flash write routines +// ************************************************************************************************* + + +// ************************************************************************************************* +// Include section +#include "project.h" +#include "flash.h" + + +// ************************************************************************************************* +// Defines section + + + +// ************************************************************************************************* +// Global Variable section + +// Reserve XDATA memory for code execution +__no_init u8 __xdata flash_write_code[32] @ FLASH_WRITE_XDATA_ADDR; + +// Flash erase / write routines can be called +u8 flash_update_init = 0; + + +// ************************************************************************************************* +// Static Function prototype section + + +// ************************************************************************************************* +// Implementation + + + +// ************************************************************************************************* +// Modify MCU registers so that flash erase / write functions can be called +// ************************************************************************************************* +void flash_start_update(void) +{ + // stop all IRQ except TIMER4 and USB + IEN0 &= ~(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0); + IEN1 &= ~( BIT3 | BIT2 | BIT1 | BIT0); + IEN2 &= ~(BIT5 | BIT4 | BIT3 | BIT2 | BIT0); + + // Set flash write timing + FWT = ( 0x22 >> CLKSPD ); + + // Copy flash write code to XDATA code + flash_write_code[0] = 0x75; // MOV FCTL, 0x02 + flash_write_code[1] = 0xAE; + flash_write_code[2] = 0x02; + + flash_write_code[3] = 0x00; // NOP + flash_write_code[4] = 0x00; // NOP + + flash_write_code[5] = 0x74; // MOV A, data_lo + flash_write_code[6] = 0xFF; + flash_write_code[7] = 0xF5; // MOV FWDATA, A + flash_write_code[8] = 0xAF; + + flash_write_code[9] = 0x00; // NOP + flash_write_code[10] = 0x00; // NOP + + flash_write_code[11] = 0x74; // MOV A, data_hi + flash_write_code[12] = 0xFF; + flash_write_code[13] = 0xF5; // MOV FWDATA, A + flash_write_code[14] = 0xAF; + + flash_write_code[15] = 0x00; // NOP + flash_write_code[16] = 0x00; // NOP + + flash_write_code[17] = 0xE5; // MOV A, FCTL + flash_write_code[18] = 0xAE; + flash_write_code[19] = 0x54; // loop: ANL A,0x40 + flash_write_code[20] = 0x40; + flash_write_code[21] = 0x70; // JNZ loop + flash_write_code[22] = 0xFA; + + flash_write_code[23] = 0x22; // RET + + // Set init flag to prevent normal code execution + flash_update_init = 1; +} + + +// ************************************************************************************************* +// Read 8-bit byte from flash memory +// ************************************************************************************************* +u8 flash_byte_read(u16 addr) +{ + u8 __code * pcode = (u8 __code *) addr; + u8 data = pcode[0]; + + return (data); + +} + + +// ************************************************************************************************* +// Read 16-bit word from flash memory +// ************************************************************************************************* +u16 flash_word_read(u16 addr) +{ + u8 __code * pcode = (u8 __code *) addr; + u16 data = (u16)(pcode[0] << 8); + data += pcode[1]; + + return (data); + +} + + +// ************************************************************************************************* +// Write 16-bit word to flash memory +// ************************************************************************************************* +u8 flash_word_write(u16 addr, u16 data, u16 key, u8 verify) +{ + u16 readback; + + // Return immediately if wrong key was passed + if (key != FLASH_EW_KEY) return (0); + + // Disable all interrupts + INT_GLOBAL_ENABLE(INT_OFF); + + // Wait until flash write/erase busy bit is cleared + while ((FCTL & BIT7) == BIT7) {} + + // Set address register to flash address in word units + FADDRH = (u8) (addr >> 9); + FADDRL = (u8) (addr >> 1); + + // Copy only flash write data to XDATA code + flash_write_code[6] = (u8) (data >> 8); + flash_write_code[12] = (u8) (data); + + // Branch to XDATA code + asm("LCALL 0xFC00"); + + // Enable all interrupts + INT_GLOBAL_ENABLE(INT_ON); + + // Verify that word was written + if (verify) + { + readback = flash_word_read(addr); + if (readback != data) return (0); + } + + return(1); +} + + + +// ************************************************************************************************* +// Erase 1kB page +// ************************************************************************************************* +u8 page_erase(u8 page, u16 key, u8 verify) +{ + u16 i; + + // Return immediately if wrong key was passed + if (key != FLASH_EW_KEY) return (0); + + // Check if page address is valid + if (page < FLASH_RW_PAGE_MIN || page > FLASH_RW_PAGE_MAX) return (0); + + // Wait until flash write/erase busy bit is cleared + while ((FCTL & BIT7) == BIT7) {} + + // Disable all interrupts + INT_GLOBAL_ENABLE(INT_OFF); + + // Store page in address register + FADDRH = (page) << 1; + FADDRL = 0x00; + + // Set flash write timing + FWT = ( 0x22 >> CLKSPD ); + + // Start page erase + FCTL = 0x01; + asm("nop"); + + // Wait until flash write/erase busy bit is cleared + while ((FCTL & BIT7) == BIT7) {} + + // Enable all interrupts + INT_GLOBAL_ENABLE(INT_ON); + + // Verify that page content is all 0xFF + if (verify) + { + for (i=0; i 30) && (frequoffset < (256-30))) frequoffset = 0; + + // Priority levels: USB, Timer1 (3) -> RF (3) -> Timer4 (1) -> others (0) + IP1 |= BIT5 + BIT1 + BIT0 + BIT4; + IP0 |= BIT5 + BIT1 + BIT0; + +#ifdef TX_SIMPLE_TEST + // TX out only + test_on=1; + rftest_radio_init(); + start_continuous_tx(); + while(1); +#endif +#ifdef TX_MP_TEST + test_on=1; + test_step = 1; + test_step_over = 0; +#endif + + // Init USB driver and enable global IRQ + usbUartInit(115200); + + // Service USB functions normally during enumeration phase + while ( enumeration < ENUMERATION_TIME ) + { + usbUartProcess(); + enumeration++; + } + LED_OFF; + + // After enumeration start Timer4 IRQ to service USB driver from now on + // f=187500Hz/64/5=3kHz/5 --> 1.7ms / IRQ + T4CCTL0 = 0x44; + T4CC0 = 0x04; + T4CTL = 0xDE; + INT_ENABLE(INUM_T4, INT_ON); + + // Enable interrupts + INT_GLOBAL_ENABLE(TRUE); + + // Main control loop + while(1) + { + // For BlueRobin + if ( bluerobin_start_now && !simpliciti_on && !wbsl_on) + { + // Start BlueRobin stack + bluerobin_start(); + system_status = HW_BLUEROBIN_TRANSMITTING; + // Reset start flag + bluerobin_start_now = 0; + } + else if ( bluerobin_on ) + { + // Temporarily suspend USB service when a BlueRobin TX is pending + if (sTimer1.usb_service_disable && !usb_service_is_disabled) + { + T4CTL &= ~BIT4; + usb_service_is_disabled = 1; + } + + if( sTimer1.iflag ) + { + // Call BlueRobin timer ISR + BRTX_OC_IRQ_v(); + + // Allow USB service again + if (usb_service_is_disabled) + { + sTimer1.usb_service_disable = 0; + usb_service_is_disabled = 0; + T4CTL |= BIT4; + } + + // New!!! + sTimer1.iflag = 0; + } + } + // For SimpliciTI AP + else if ( simpliciti_start_now && !wbsl_on ) + { + LED_ON; + // Clear start trigger + simpliciti_start_now = 0; + // Config hardware for SimpliciTI + simpliciti_config(); + // Assign new system status + system_status = HW_SIMPLICITI_LINKED; + simpliciti_on = 1; + // Start access point and stay there until exit flag is set + simpliciti_main(); + // Clear SimpliciTI flags + system_status = HW_SIMPLICITI_STOPPED; + simpliciti_on = 0; + // Clean up after SimpliciTI + simpliciti_data[0] = 0xFF; + LED_OFF; + } + else if( wbsl_start_now && !simpliciti_on) + { + LED_ON; + // Clear start Trigger + wbsl_start_now = 0; + //Config the RF module for WBSL + wbsl_config(); + // Assign new System Status + system_status = HW_WBSL_LINKED; + wbsl_on = 1; + // Start access point and try to pair with an End Device, + // once paired, download the software update then return. + wbsl_main(); + + // Check if there was an error during the Update procedure to alert the GUI + if(getFlag(wbsl_flag,WBSL_STATUS_ERROR)) + { + system_status = HW_WBSL_ERROR; + } + else + { + system_status = HW_WBSL_STOPPED; + } + //Clear WBSL Flags + wbsl_on = 0; + wbsl_data[0] = 0xFF; + + LED_OFF; + } + else if (test_on) + { + if (!test_step_over) + { + // Each test is executed just once + switch (test_step) + { + case 1: test_rf(); + break; + case 2: start_continuous_tx(); + break; + case 3: stop_continuous_tx(); + break; + } + test_step_over = 1; + } + } + } + */ +} + + +// ************************************************************************************************* +// Decode received command, extract data and trigger actions. +// ************************************************************************************************* +void usb_decode(void) +{ + u32 id = 0; + u16 test_pw = 0; + u8 test_byte; + u16 test_addr; + u8 i; + + // Check if start marker is set + if (usb_buffer[PACKET_BYTE_START] != 0xFF) return; + + // Check command code + switch (usb_buffer[PACKET_BYTE_CMD]) + { + // Generic commands + case BM_GET_PRODUCT_ID: usb_buffer[PACKET_BYTE_FIRST_DATA+3] = (u8)(PRODUCT_ID>>24); + usb_buffer[PACKET_BYTE_FIRST_DATA+2] = (u8)(PRODUCT_ID>>16); + usb_buffer[PACKET_BYTE_FIRST_DATA+1] = (u8)(PRODUCT_ID>>8); + usb_buffer[PACKET_BYTE_FIRST_DATA] = (u8)(PRODUCT_ID); + break; + case BM_GET_STATUS: usb_buffer[PACKET_BYTE_FIRST_DATA] = system_status; // + 1; + break; + + // BlueRobin TX commands + case BM_RESET: bluerobin_stop(); + bluerobin_on = 0; + simpliciti_on = 0; + wbsl_on = 0; + system_status = HW_IDLE; + break; + case BM_START_BLUEROBIN: if (simpliciti_on) setFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP); + if (!bluerobin_on) + { + // Can only start once instance + bluerobin_start_now = 1; + } + break; + case BM_STOP_BLUEROBIN: bluerobin_stop(); + system_status = HW_BLUEROBIN_STOPPED; + break; + case BM_SET_BLUEROBIN_ID: id = ((unsigned long)usb_buffer[PACKET_BYTE_FIRST_DATA+3] << 12) << 12; + id += ((unsigned long)usb_buffer[PACKET_BYTE_FIRST_DATA+2] << 8) << 8; + id += (unsigned long)usb_buffer[PACKET_BYTE_FIRST_DATA+1] << 8; + id += (unsigned long)usb_buffer[PACKET_BYTE_FIRST_DATA]; + BRTX__ID_u32 = id; + break; + case BM_GET_BLUEROBIN_ID: id = BRTX__ID_u32; + usb_buffer[PACKET_BYTE_FIRST_DATA+3] = (unsigned char)(id >> 24); + usb_buffer[PACKET_BYTE_FIRST_DATA+2] = (unsigned char)(id >> 16); + usb_buffer[PACKET_BYTE_FIRST_DATA+1] = (unsigned char)(id >> 8); + usb_buffer[PACKET_BYTE_FIRST_DATA] = (unsigned char)(id); + break; + case BM_SET_HEARTRATE: HeartRate_u8 = usb_buffer[PACKET_BYTE_FIRST_DATA]; + break; + case BM_SET_SPEED: Speed_u8 = usb_buffer[PACKET_BYTE_FIRST_DATA]; + Distance_u16 = (unsigned int)(usb_buffer[PACKET_BYTE_FIRST_DATA+2] << 8); + Distance_u16 += usb_buffer[PACKET_BYTE_FIRST_DATA+1]; + break; + + // SimpliciTI RX commands + case BM_START_SIMPLICITI: if (bluerobin_on) bluerobin_stop(); + // Can only start one stack + if (!simpliciti_on) + { + system_status = HW_SIMPLICITI_TRYING_TO_LINK; + // simpliciti_start_rx_only_now = 1; + simpliciti_start_now = 1; + } + break; + case BM_GET_SIMPLICITIDATA: + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_RECEIVED_DATA)) + { + // Assemble IN packet (ID/BTN, DataX, DataY, DataZ) + usb_buffer[PACKET_BYTE_FIRST_DATA+3] = simpliciti_data[3]; + usb_buffer[PACKET_BYTE_FIRST_DATA+2] = simpliciti_data[2]; + usb_buffer[PACKET_BYTE_FIRST_DATA+1] = simpliciti_data[1]; + usb_buffer[PACKET_BYTE_FIRST_DATA] = simpliciti_data[0]; + // Mark buffer as already read + simpliciti_data[0] = 0xFF; + clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_RECEIVED_DATA); + } + else + { + // Return packet with "already read" marker + usb_buffer[PACKET_BYTE_FIRST_DATA] = 0xFF; + } + break; + + // SimpliciTI Sync commands + case BM_SYNC_START: /* if (bluerobin_on) bluerobin_stop(); + // Can only start one stack + if (!simpliciti_on) + { + system_status = HW_SIMPLICITI_TRYING_TO_LINK; + simpliciti_start_sync_now = 1; + }*/ + break; + case BM_SYNC_SEND_COMMAND: + // Copy command data to SimpliciTI buffer + if (simpliciti_on) + { + for (i=0; i> 8) & 0xFF; + packet_ready_flag = WBSL_PACKET_FULL; + ptrTX = 0; + } + else // Regular data packet + { + wbsl_packetLength = usb_buffer[PACKET_BYTE_FIRST_DATA + 1]; + + if(wbsl_OPCode == WBSL_ADDRESS_PACKET) + TxBuffer[WBSL_OPCODE_OFFSET] = WBSL_ADDRESS_PACKET; // Set the address OPCODE + else + TxBuffer[WBSL_OPCODE_OFFSET] = WBSL_NORMAL_PACKET; // Set the packet as a normal packet + + //Update size of packet to be sent and substract Overhead and Length field + TxBuffer[0] = wbsl_packetLength + WBSL_OVERHEAD_LENGTH - 1; + + for(i=0;i= wbsl_packetLength) + { + packet_ready_flag = WBSL_PACKET_FULL; + ptrTX = 0; + } + } + } + else if(packet_ready_flag == WBSL_PACKET_FILLING) + { + wbsl_inc = usb_buffer[PACKET_BYTE_FIRST_DATA - 1] - 3; // Get total of bytes received and substract overhead + + for(i=0;i= WBSL_MAX_PAYLOAD_LENGTH || current_packet_size >= wbsl_packetLength) + { + packet_ready_flag = WBSL_PACKET_FULL; + ptrTX = 0; + } + } + break; + + + // Test commands + case BM_INIT_TEST: test_pw = (u16)usb_buffer[PACKET_BYTE_FIRST_DATA+1] << 8; + test_pw += (u16)usb_buffer[PACKET_BYTE_FIRST_DATA]; + if (test_pw == RFTEST_PW) + { + test_on = 1; + test_step = 0; + test_step_over = 1; + bluerobin_on = 0; + simpliciti_on = 0; + } + else + { + test_on = 0; + } + break; + + case BM_NEXT_TEST: if (test_on) + { + test_result = 0; + test_step_over = 0; + test_step++; + } + break; + + + case BM_GET_TEST_RESULT: if (test_on) + { + usb_buffer[PACKET_BYTE_FIRST_DATA] = (u8)test_result; + usb_buffer[PACKET_BYTE_FIRST_DATA+1] = (u8)(test_result >> 8); + } + break; + + case BM_WRITE_BYTE: if (test_on) + { + test_byte = usb_buffer[PACKET_BYTE_FIRST_DATA]; + test_addr = (u16)usb_buffer[PACKET_BYTE_FIRST_DATA+1]; + test_addr += ((u16)usb_buffer[PACKET_BYTE_FIRST_DATA+2] << 8); + + // Allow flash write access + flash_start_update(); + + // Write calibration data only if memory location empty + if (flash_byte_read(test_addr) == 0xFF) + { + // Write byte to cal page + flash_word_write(test_addr, ((u16)test_byte << 8) + 0xFF, FLASH_EW_KEY, 0); + } + } + break; + + } + + // Return packet with original data, but modified command byte (acknowledge) + usb_sendack = 1; + usb_buffer[PACKET_BYTE_CMD] = HW_NO_ERROR; +} + + + +// ************************************************************************************************* +// Config clock and timers for SimpliciTI +// ************************************************************************************************* +void simpliciti_config(void) +{ + // OSC=XT, TICKSPD=fref/64, CLKSPD=12MHz + CLKCON = BIT7 | BIT5 | BIT4; + + // Reset radio registers to default settings + SYNC1 = 0xD3; /* Sync word, high byte */ + SYNC0 = 0x91; /* Sync word, low byte */ + PKTCTRL1 = 0x04; /* Packet automation control */ + ADDR = 0x00; /* Device address */ + CHANNR = 0x00; /* Channel number */ + MCSM2 = 0x07; /* Main Radio Control State Machine configuration */ + IOCFG2 = 0x00; /* Radio Test Signal Configuration (P1_7) */ + IOCFG1 = 0x00; /* Radio Test Signal Configuration (P1_6) */ + IOCFG0 = 0x00; /* Radio Test Signal Configuration (P1_5) */ + + // Reset RF int mask bits - SimpliciTI will set them + RFIM = 0; +} + + +// ************************************************************************************************* +// Start BlueRobin transmission +// ************************************************************************************************* +void bluerobin_start(void) +{ + // OSC=XT, TICKSPD=fref/128, CLKSPD=24MHz + CLKCON = BIT7 | BIT5 | BIT4 | BIT3; + + // Enable RF IRQs + RFIM |= BIT7 | BIT4; + + // Clear Timer1 + T1CNTL = 0x55; + + // Enable Timer1 interrupt, enable compare mode + T1CCTL0 = 0x44; + + // Start T1 in modulo mode + T1CTL = 0x02; + + // Init hardware and BlueRobin stack + INT_ENABLE(INUM_T1, INT_ON); + + // Init s/w + InitProject_v(); + + // Set FSCTRL0 to calibration value + FSCTRL0 = frequoffset; + + // Set on flag + bluerobin_on = 1; +} + + +// ************************************************************************************************* +// Stop BlueRobin transmission +// ************************************************************************************************* +void bluerobin_stop(void) +{ + BRTX_Stop_v(); + + // Stop Timer1 + INT_ENABLE(INUM_T1, INT_OFF); + T1CTL = 0x00; + + // Clear Timer1 + T1CNTL = 0x55; + + // Clear Timer1 structure + reset_timer1(); + + // Clear on flag + bluerobin_on = 0; +} + + +// ************************************************************************************************* +// Forward RF IRQ to right handler +// ************************************************************************************************* +#pragma vector=RF_VECTOR +__interrupt void rf_ISR(void) +{ + if ( bluerobin_on ) + { + BR_RfIsr(); + } + else if ( simpliciti_on ) + { + MRFI_RfIsr(); + } + else if ( test_on ) + { + rftest_RfIsr(); + } + else if ( wbsl_on ) + { + wbsl_RfIsr(); + } +} + +// ************************************************************************************************* +// Forward RF TX/RX IRQ to right handler +// ************************************************************************************************* +#pragma vector=RFTXRX_VECTOR +__interrupt void ISR_RFTXRX(void) +{ + if ( bluerobin_on ) + { + BR_RfTxRxIsr(); + } + else if ( test_on ) + { + rftest_RfTxRxIsr(); + } +} + + +// ************************************************************************************************* +// Timer1 ISR +// ************************************************************************************************* +#pragma vector=T1_VECTOR +__interrupt void t1Timer_ISR(void) +{ + // Clear IRCON.T1IF + IRCON &= ~0x02; + + // Clear Timer 1 Channel 0-2 + overflow interrupt flag + T1CTL &= ~0xF0; + + // Return immediately if timer not enabled + if (!sTimer1.enable) return; + + // Return immediately if s/w int flag not reset + if (sTimer1.iflag) return; + + // Set timer cycles, and call s/w int handler if no more cycles to set + if (!set_timer1_cycles()) + { + // Call BlueRobin TX function + sTimer1.iflag = 1; + } + + // Increase global cycle count + sTimer1.cycles++; +} + + +// ************************************************************************************************* +// Timer4 ISR +// ************************************************************************************************* +#pragma vector=T4_VECTOR +__interrupt void timer4_ISR(void) +{ + + // If WBSL_ON check if any timeout entry needs to be serviced + if( wbsl_on ){ + //If the timeout entry is enabled + if( timeout_table[WBSL_TIMEOUT_INDEX].timeout > 0){ + //Check if timeout has been reached + if(++timeout_table[WBSL_TIMEOUT_INDEX].counter == timeout_table[WBSL_TIMEOUT_INDEX].timeout) + { + timeout_table[WBSL_TIMEOUT_INDEX].counter = 0; // Reset counter + timeout_table[WBSL_TIMEOUT_INDEX].timeout = 0; // Reset timeout (Disable) + timeout_table[WBSL_TIMEOUT_INDEX].flag = 1; // Set the flag so that WBSL knows that + } + } + } + + // Clear IRQ flag + TIMIF &= ~BIT3; + + // Service USB functions + usbUartProcess(); +} + + +// ************************************************************************************************* +// Assign all unused IRQ +// ************************************************************************************************* +void catch_stray_irq(void) +{ + asm("nop"); +} +#pragma vector=ADC_VECTOR +__interrupt void adc_ISR(void) { catch_stray_irq(); } +#pragma vector=URX0_VECTOR +__interrupt void urx0_ISR(void) { catch_stray_irq(); } +#pragma vector=URX1_VECTOR +__interrupt void urx1_ISR(void) { catch_stray_irq(); } +#pragma vector=ENC_VECTOR +__interrupt void enc_ISR(void) { catch_stray_irq(); } +#pragma vector=ST_VECTOR +__interrupt void st_ISR(void) { catch_stray_irq(); } +#pragma vector=UTX0_VECTOR +__interrupt void utx0_ISR(void) { catch_stray_irq(); } +#pragma vector=DMA_VECTOR +__interrupt void dma_ISR(void) { catch_stray_irq(); } +#pragma vector=T2_VECTOR +__interrupt void t2_ISR(void) { catch_stray_irq(); } +#pragma vector=UTX1_VECTOR +__interrupt void utx1_ISR(void) { catch_stray_irq(); } +#pragma vector=P1INT_VECTOR +__interrupt void p1_ISR(void) { catch_stray_irq(); } +#pragma vector=WDT_VECTOR +__interrupt void wdt_ISR(void) { catch_stray_irq(); } diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/rftest.c b/chronos-ti/Software Projects/RF Access Point/IAR/rftest.c new file mode 100755 index 0000000..2f869cc --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/rftest.c @@ -0,0 +1,538 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Test routines used for calibration during production test +// ************************************************************************************************* + + +// ************************************************************************************************* +// Include section +#include "project.h" +#include "rftest.h" +#include "timer1.h" + + +// ************************************************************************************************* +// Defines section +#define RFTEST_SYNC_WORD (0xCABA) +#define RFTEST_PACKET_LENGTH (10u) +#define RFTEST_PACKET_COUNT (10u) +#define RFTEST_OUTPUT_POWER (0x5A) +#define RFTEST_OUTPUT_POWER_MAX (0xC0) +#define RFTEST_ACLK_DEVIATION_MAX (4u) +#define RFTEST_FREQEST_MIN (-25) +#define RFTEST_FREQEST_MAX (+25) + + +// ************************************************************************************************* +// Global Variable section +u8 rftest_packet[RFTEST_PACKET_LENGTH]; +u8 rftest_packet_ptr; +u8 rftest_count; +u32 rftest_time; + +typedef struct { + u8 valid; + u16 time; + u8 packet_nb; + u8 freqoffset; +} s_rftest; + +s_rftest rftest[RFTEST_PACKET_COUNT]; + +const u8 ref_packet[RFTEST_PACKET_LENGTH] = { 0x00, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 }; + + + +// ************************************************************************************************* +// Extern section +extern u16 test_result; + + +// ************************************************************************************************* +// Static Function prototype section + +void rftest_init(void); +void rftest_radio_init(void); + + +// ************************************************************************************************* +// Implementation + + +// ************************************************************************************************* +// Init test variables +// ************************************************************************************************* +void rftest_init(void) +{ + u8 i; + + // Init and calibrate radio + rftest_radio_init(); + + // Clear RX variables + rftest_count = 0; + for (i=0; i0; i--) + { + if (rftest[i].valid) + { + time2 = rftest[i].time; + packet2 = rftest[i].packet_nb; + break; + } + } + + // Calculate mean freqest + freqest = 0; + div = 0; + for (i=0; i RFTEST_FREQEST_MAX)) + { + test_result = 0x2000 | (u8)freqest0; + continue_test = NO; + } + else + { // FREQEST range ok + + // Calculate distance between 1 and 2 + // TX sends packet each 3276 ACLK ticks (= 1145 T1CLK ticks) + ref = (packet2 - packet1)*3276; + delta = time2 - time1; + + if ((ref - delta) < RFTEST_ACLK_DEVIATION_MAX) + { + // Store ACLK deviation in test result + test_result = ((ref - delta)&0x0F) << 8; + + // Store average FREQEST + if (freqest < 0) + { + freqest1 = (u8)((freqest*(-1))/div); + freqest1 = ~freqest1 + 1; + test_result |= freqest1; + } + else + { + test_result |= (u8)(freqest/div); + } + } + else if ((delta - ref) < RFTEST_ACLK_DEVIATION_MAX) + { + // Store ACLK deviation in test result + test_result = ((delta - ref)&0x0F) << 8; + + // Store average FREQEST + if (freqest < 0) + { + freqest1 = (u8)((freqest*(-1))/div); + freqest1 = ~freqest1 + 1; + test_result |= freqest1; + } + else + { + test_result |= (u8)(freqest/div); + } + } + else + { + // Too high ACLK deviation + test_result = 0x4000; + continue_test = NO; + } + } + } + + // 2nd test stage - use RF offset to catch another few packets + if (continue_test == YES) + { + rftest_count = 0; + + // Clear RX variables + for (i=0; i 0) + { + if (!((rftest[0].freqoffset >= 0xFE) || (rftest[0].freqoffset <= 0x02))) + { + test_result = 0x1000; + } + } + else + { + test_result = 0x1000; + } + } + + // Disable IRQ + INT_ENABLE(INUM_RFTXRX, INT_OFF); + INT_ENABLE(INUM_RF, INT_OFF); + INT_ENABLE(INUM_T1, INT_OFF); + + // Stop Timer1 + T1CTL = 0x00; + T1CNTL = 0x55; + reset_timer1(); +} + + +// ************************************************************************************************* +// Sets the radio hardware to the required initial state. +// ************************************************************************************************* +void rftest_radio_init(void) +{ + u8 FSCAL3_Register_u8; + + SYNC1 = RFTEST_SYNC_WORD >> 8; /* Sync word, high byte */ + SYNC0 = (u8) RFTEST_SYNC_WORD; /* Sync word, low byte */ + PKTLEN = RFTEST_PACKET_LENGTH; /* Packet length */ + PKTCTRL1 = 0x00; /* Packet automation control */ + PKTCTRL0 = 0x00; /* Packet automation control */ + ADDR = 0x00; /* Device address */ + CHANNR = 0x00; /* Channel number */ + FSCTRL1 = 0x12; /* Frequency synthesizer control */ + FSCTRL0 = 0x00; /* Frequency synthesizer control */ +#ifdef ISM_EU + FREQ2 = 0x24; /* Frequency control word, high byte */ + FREQ1 = 0x2D; /* Frequency control word, middle byte */ + FREQ0 = 0x55; /* Frequency control word, low byte */ + MDMCFG4 = 0x3D; /* Modem configuration */ + MDMCFG3 = 0x55; /* Modem configuration */ + MDMCFG2 = 0x15; /* Modem configuration */ + MDMCFG1 = 0x12; /* Modem configuration */ + MDMCFG0 = 0x11; /* Modem configuration */ +#else + #ifdef ISM_US + FREQ2 = 0x26; /* Frequency control word, high byte */ + FREQ1 = 0x19; /* Frequency control word, middle byte */ + FREQ0 = 0x11; /* Frequency control word, low byte */ + MDMCFG4 = 0x3D; /* Modem configuration */ + MDMCFG3 = 0x55; /* Modem configuration */ + MDMCFG2 = 0x15; /* Modem configuration */ + MDMCFG1 = 0x12; /* Modem configuration */ + MDMCFG0 = 0x11; /* Modem configuration */ + #else + #ifdef ISM_LF + FREQ2 = 0x12; /* Frequency control word, high byte */ + FREQ1 = 0x0A; /* Frequency control word, middle byte */ + FREQ0 = 0xAA; /* Frequency control word, low byte */ + MDMCFG4 = 0x3D; /* Modem configuration */ + MDMCFG3 = 0x55; /* Modem configuration */ + MDMCFG2 = 0x15; /* Modem configuration */ + MDMCFG1 = 0x12; /* Modem configuration */ + MDMCFG0 = 0x11; /* Modem configuration */ + #else + #error "No ISM band specified" + #endif + #endif +#endif + DEVIATN = 0x60; /* Modem deviation setting */ + MCSM2 = 0x07; /* Main Radio Control State Machine configuration */ + MCSM1 = 0x02; /* Main Radio Control State Machine configuration */ + MCSM0 = 0x18; /* Main Radio Control State Machine configuration */ + FOCCFG = 0x1D; /* Frequency Offset Compensation configuration */ + BSCFG = 0x1C; /* Bit Synchronization configuration */ + AGCCTRL2 = 0xC7; /* AGC control */ + AGCCTRL1 = 0x10; /* AGC control */ + AGCCTRL0 = 0xB2; /* AGC control */ + FREND1 = 0xB6; /* Front end RX configuration */ + FREND0 = 0x10; /* Front end TX configuration */ + FSCAL3 = 0xEA; /* Frequency synthesizer calibration */ + FSCAL2 = 0x2A; /* Frequency synthesizer calibration */ + FSCAL1 = 0x00; /* Frequency synthesizer calibration */ + FSCAL0 = 0x1F; /* Frequency synthesizer calibration */ + IOCFG2 = 0x00; /* Radio Test Signal Configuration (P1_7) */ + IOCFG1 = 0x00; /* Radio Test Signal Configuration (P1_6) */ + IOCFG0 = 0x00; /* Radio Test Signal Configuration (P1_5) */ + TEST1 = 0x31; + + // Read FSCAL3 register, set bits enabling charge pump calibration and write register again + FSCAL3_Register_u8 = FSCAL3 | 0x20; + FSCAL3 = FSCAL3_Register_u8; + + // Set output power + PA_TABLE0 = RFTEST_OUTPUT_POWER; + + // Start calibration manually + SIDLE(); + SCAL(); + + // Wait until calibration completed + while(MARCSTATE != 0x01); + FSCAL3 &= ~0x30; + + // Enter powerdown mode + SIDLE(); +} + + +// ************************************************************************************************* +// RF TX/RX IRQ providing data handling +// ************************************************************************************************* +void rftest_RfTxRxIsr(void) +{ + u8 pass, i; + u16 time, timeout; + + // First clear pointer to fifo + rftest_packet_ptr = 0; + + // Read first byte + rftest_packet[rftest_packet_ptr++] = RFD; + + // Load timeout counter + timeout = 400; + + // Wait until all 10 bytes have been received + while ( (rftest_packet_ptr < RFTEST_PACKET_LENGTH) && (timeout-- != 0) ) + { + if ((TCON & BIT1) == BIT1) + { + // Read next bytes + rftest_packet[rftest_packet_ptr++] = RFD; + + // Clear IRQ flag + TCON &= ~BIT1; + } + } + + // Indicate that RX is over + if (rftest_packet_ptr == RFTEST_PACKET_LENGTH) + { + // Radio off during decoding + SIDLE(); + + // Store current 16-bit time + time = T1CNTL; + time |= T1CNTH << 8; + time = (sTimer1.cycles*11453) + (u16)(((u32)time*32768)/187500); + + // Check if packet is valid + pass = 1; + for (i=1; i' parameter +@REM below with the appropriate file name. Other plugins loaded by +@REM C-SPY are usually not needed by, or will not work in, cspybat +@REM but they are listed at the end of this file for reference. + + +"C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\common\bin\cspybat" "C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\8051\bin\8051proc.dll" "C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\8051\bin\8051emu_cc.dll" %1 --plugin "C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\8051\bin\" --backend -B "--proc_core" "plain" "--proc_code_model" "near" "--proc_nr_virtual_regs" "8" "--proc_pdata_bank_reg_addr" "0x93" "--proc_dptr_nr_of" "1" "--proc_data_model" "small" "-p" "C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\8051\config\devices\_generic\io8052.ddf" "--proc_driver" "chipcon" "--erase_flash" "--verify_download" "use_crc16" "--reduce_speed" "--stack_overflow" "--number_of_banks" "4" + + +@REM Loaded plugins: +@REM C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\8051\bin\8051libsupport.dll +@REM C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\common\plugins\CodeCoverage\CodeCoverage.dll +@REM C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\common\plugins\Profiling\Profiling.dll +@REM C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\common\plugins\stack\stack.dll +@REM C:\Program Files\IAR Systems\Embedded Workbench 5.4 Kickstart\common\plugins\SymList\SymList.dll diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/settings/cc1111_usb_dongle.dbgdt b/chronos-ti/Software Projects/RF Access Point/IAR/settings/cc1111_usb_dongle.dbgdt new file mode 100755 index 0000000..c27e0cb --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/settings/cc1111_usb_dongle.dbgdt @@ -0,0 +1,64 @@ + + + + + + 300Find-in-FilesWatchBreakpointsWatchMemoryMemoryLocalsRegister + + + + + + 2091524461300Debug-LogBreakpointsWatch + + + + + + + 136272727 + + + + + 20010 + + + + 300Debug-LogFind-in-FilesWatchBreakpointsWatchMemoryLocalsRegister10 + {W}Watch-0:BRTX__ID_u323{W}Watch-0:BRTX__SC_u84{W}Watch-0:HeartRate_u83{W}Watch-0:Offset_u164{W}Watch-0:off4{W}Watch-0:rf_fifo_ptr3{W}Watch-0:rfif_reg4{W}Watch-1:BRTX__BasicPeriodTime_u164{W}Watch-1:FirstPacketTime_u164{W}Watch-1:HeartRate_u83{W}Watch-1:stval4{W}Watch-1:stval14{W}Watch-1:stval24{W}Watch-1:sw_timer_cmp_en3{W}Watch-1:sw_timer_cmp_if3{W}Watch-1:t1_base_period_ptr3{W}Watch-1:temp4{W}Watch-2:FirstPacketTime_u164{W}Watch-2:timediff4{W}Watch-3:BRTX__ID_u323{W}Watch-3:simpliciti_flag1{W}Watch-3:test_addr4{W}Watch-3:test_byte4{W}Watch-3:test_result4300Debug-LogFind-in-FilesWatchBreakpointsMemoryMemoryLocalsRegister1492801001002001001001001001001100300Debug-LogFind-in-FilesWatchBreakpointsWatchMemoryMemoryLocals20088881206075300Debug-LogFind-in-FilesWatchWatchMemoryMemoryLocalsRegister300Debug-LogWatchBreakpointsWatchMemoryMemoryLocalsRegister44062754300Debug-LogFind-in-FilesWatchBreakpointsWatchMemoryMemoryRegister100151100100 + + + + + + + + + TabID-1729-24911 + Workspace + Workspace + + + cc1111_usb_donglecc1111_usb_dongle/Codecc1111_usb_dongle/Libcc1111_usb_dongle/Outputcc1111_usb_dongle/SimpliciTIcc1111_usb_dongle/Synccc1111_usb_dongle/USB + + + + 0TabID-23814-2242DisassemblyDisassemblyTabID-9365-112WatchWatchtest_resultrftestTxBuffertimeout_table3149280100100TabID-2046-249Debug LogDebug-LogTabID-29587-347BreakpointsBreakpointsTabID-5937-5089RegisterRegister002010CLKCONPKTCTRL0RFIFRFIMS1CONT3CCTL0T3CTLT4CTLTCONTIMIFTabID-19947-5850Find in FilesFind-in-FilesTabID-17779-13451MemoryMemory33072030720100001913TabID-18852-8675LocalsLocals1001511001000 + + + + + + TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\wbsl\ioCCxx10_bitdef.h012414819948199TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\flash.c010031543154TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\CC1111 - Access Point - ISM_EU - Full\List\ez430-chronos-AP-ISM_EU.map06399363026363026TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\CC1111 - Access Point - ISM_EU - Full\Exe\ez430-chronos-AP-ISM_EU.hex0171600TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\bm-br1\bm.h08946064606TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\bm-br1\project.h07036883688TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\simpliciti\Components\bsp\boards\RFUSB\bsp_led_defs.h04635043504TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\HAL\source\hal_board.h05518341834TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\wbsl\wbsl.c04641846418464TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\BM_API.h09343794394TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\usb\class_cdc\usb_uart.c025566086608TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\wbsl\wbsl.h012554855507TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\HAL\source\hal_int.c025975986TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\HAL\include\hal_int.h03214281428TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\change_record.txt00234234TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\usb\library\ccxx11\usb_interrupt.c06623862386TextEditorC:\Dokumente und Einstellungen\anton\Eigene Dateien\Projekte\TI CC430 WDK\Software\RF Access Point 1_2\main.c012148074807160100000010000001 + + + + + + + iaridepm.enu1debuggergui.enu1-2-2462227-2-20000178906640884-2-21941282-2-212841961003125270718357031908840 + + + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/settings/cc1111_usb_dongle.dni b/chronos-ti/Software Projects/RF Access Point/IAR/settings/cc1111_usb_dongle.dni new file mode 100755 index 0000000..baef945 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/settings/cc1111_usb_dongle.dni @@ -0,0 +1,58 @@ +[CodeCoverage] +Enabled=_ 0 +[StackPlugin] +Enabled=1 +OverflowWarningsEnabled=1 +WarningThreshold=90 +SpWarningsEnabled=1 +WarnHow=0 +UseTrigger=1 +TriggerName=main +LimitSize=0 +ByteLimit=50 +[DisAssemblyWindow] +NumStates=_ 1 +State 1=_ 1 +[Profiling] +Enabled=0 +[BreakpointUsageDialog] +Placement=_ 1702 373 2139 651 +[Interrupts] +Enabled=1 +[MemoryMap] +Enabled=0 +Base=0 +UseAuto=0 +TypeViolation=1 +UnspecRange=1 +ActionState=1 +[TraceHelper] +Enabled=0 +ShowSource=1 +[TermIOLog] +LoggingEnabled=_ 0 +LogFile=_ "" +[DebugChecksum] +Checksum=-1968684698 +[Log file] +LoggingEnabled=_ 0 +LogFile=_ "" +Category=_ 0 +[Breakpoints] +Bp0=_ "STD_CODE" "{$PROJ_DIR$\rftest.c}.267.3@1" 0 0 0 0 "" 0 "" +Bp1=_ "STD_CODE" "{$PROJ_DIR$\rftest.c}.160.3@1" 0 0 0 0 "" 0 "" +Bp2=_ "STD_CODE" "{$PROJ_DIR$\rftest.c}.209.7@1" 0 0 0 0 "" 0 "" +Bp3=_ "STD_CODE" "{$PROJ_DIR$\usb\class_cdc\usb_uart.c}.214.11@1" 0 0 0 0 "" 0 "" +Bp4=_ "STD_CODE" "{$PROJ_DIR$\main.c}.379.31@1" 0 0 0 0 "" 0 "" +Bp5=_ "STD_CODE" "{$PROJ_DIR$\main.c}.486.31@1" 0 0 0 0 "" 0 "" +Bp6=_ "STD_CODE" "{$PROJ_DIR$\wbsl\wbsl.c}.579.7@1" 0 0 0 0 "" 0 "" +Bp7=_ "STD_CODE" "{$PROJ_DIR$\wbsl\wbsl.c}.654.7@1" 0 0 0 0 "" 0 "" +Bp8=_ "STD_CODE" "{$PROJ_DIR$\main.c}.573.37@1" 0 0 0 0 "" 0 "" +Bp9=_ "STD_CODE" "{$PROJ_DIR$\wbsl\wbsl.c}.701.10@1" 0 0 0 0 "" 0 "" +Count=10 +[ChipconEmu] +Stop timers on halt=1 +Leave target running=1 +[Aliases] +Count=0 +SuppressDialog=0 diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/settings/cc1111_usb_dongle.wsdt b/chronos-ti/Software Projects/RF Access Point/IAR/settings/cc1111_usb_dongle.wsdt new file mode 100755 index 0000000..062b085 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/settings/cc1111_usb_dongle.wsdt @@ -0,0 +1,56 @@ + + + + + + cc1111_usb_dongle/868MHz - Limited IAR Kickstart (Europe) + + + + + + + + + 34312271242140 + + + + + + + 300Find-in-Files2091524061 + 30019264300Build44062754 + + + + + + + TabID-26546-27884 + Workspace + Workspace + + + cc1111_usb_donglecc1111_usb_dongle/Outputcc1111_usb_dongle/USBcc1111_usb_dongle/USB/class_cdccc1111_usb_dongle/USB/library + + + + 0TabID-17759-11906BuildBuildTabID-9414-11171Find in FilesFind-in-Files1TabID-31469-3508Debug LogDebug-Log0 + + + + + + TextEditor$WS_DIR$\usb\class_cdc\usb_firmware_library_config.c06930930TextEditor$WS_DIR$\usb\library\usb_descriptor.h013061986205TextEditor$WS_DIR$\usb\library\usb_suspend.h08251645164TextEditor$WS_DIR$\usb\library\usb_framework.h01931002110021TextEditor$WS_DIR$\868MHz - Limited IAR Kickstart (Europe)\List\usb_framework.lst01391178311783TextEditor$WS_DIR$\868MHz - Limited IAR Kickstart (Europe)\List\usb_cdc_hooks.lst0207150311503150100000010000001 + + + + + + + iaridepm.enu1-2-2489418-2-2-840785-330817-656863280-345320458328125512526-2-22271282-2-21284229100312523904096094101253225-24251282-222512842001003125208768156250208768 + + + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Applications/app_remap_led.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Applications/app_remap_led.h new file mode 100755 index 0000000..2e3e25b --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Applications/app_remap_led.h @@ -0,0 +1,13 @@ +#ifdef BSP_BOARD_EXP461x + + #undef BSP_TURN_ON_LED2 + #undef BSP_TURN_OFF_LED2 + #undef BSP_TOGGLE_LED2 + #undef BSP_LED2_IS_ON + + #define BSP_TURN_ON_LED2() BSP_TURN_ON_LED3() + #define BSP_TURN_OFF_LED2() BSP_TURN_OFF_LED3() + #define BSP_TOGGLE_LED2() BSP_TOGGLE_LED3() + #define BSP_LED2_IS_ON() BSP_LED3_IS_ON() + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Applications/main_AP_BM.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Applications/main_AP_BM.c new file mode 100755 index 0000000..398c51a --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Applications/main_AP_BM.c @@ -0,0 +1,247 @@ +/********************************************************************************************** + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +// ************************************************************************************************* +// Include section +#include +#include "bsp.h" +#include "mrfi.h" +#include "bsp_leds.h" +#include "bsp_buttons.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "app_remap_led.h" +#include "simpliciti.h" + + +// ************************************************************************************************* +// Defines section +#define BIT0 (0x0001) +#define BIT1 (0x0002) +#define BIT2 (0x0004) +#define BIT3 (0x0008) +#define BIT4 (0x0010) +#define BIT5 (0x0020) +#define BIT6 (0x0040) +#define BIT7 (0x0080) +#define BIT8 (0x0100) +#define BIT9 (0x0200) +#define BITA (0x0400) +#define BITB (0x0800) +#define BITC (0x1000) +#define BITD (0x2000) +#define BITE (0x4000) +#define BITF (0x8000) + +// ************************************************************************************************* +// Prototypes section + +/* callback handler */ +uint8_t sCB(linkID_t); + + +// ************************************************************************************************* +// Extern section +extern uint8_t sInit_done; + + +// ************************************************************************************************* +// Global Variable section + +/* reserve space for the maximum possible peer Link IDs */ +static linkID_t linkID0; +static uint8_t sNumCurrentPeers; + +/* work loop semaphores */ +static volatile uint8_t sPeerFrameSem; +static volatile uint8_t sJoinSem; + +volatile unsigned char simpliciti_flag; +unsigned char simpliciti_data[SIMPLICITI_MAX_PAYLOAD_LENGTH]; +unsigned char ed_data[SIMPLICITI_MAX_PAYLOAD_LENGTH]; + +// AP main routine +void simpliciti_main(void) +{ + bspIState_t intState; + uint8_t j; + uint8_t len; + uint32_t led_toggle = 0; + uint8_t pwr; + + // Init variables + simpliciti_flag = SIMPLICITI_STATUS_LINKING; + + // Init SimpliciTI + SMPL_Init(sCB); + + // Set output power to +1.1dBm (868MHz) / +1.3dBm (915MHz) + pwr = IOCTL_LEVEL_2; + SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &pwr); + + // LED off + BSP_TURN_OFF_LED1(); + + /* main work loop */ + while (1) + { + // Wait for the Join semaphore to be set by the receipt of a Join frame from a + //device that supports an End Device. + if (sJoinSem && !sNumCurrentPeers) + { + /* listen for a new connection */ + while (1) + { + if (SMPL_SUCCESS == SMPL_LinkListen(&linkID0)) + { + // We have a connection + simpliciti_flag = SIMPLICITI_STATUS_LINKED; + BSP_TURN_ON_LED1(); + break; + } + /* Implement fail-to-link policy here. otherwise, listen again. */ + } + + sNumCurrentPeers++; + + BSP_ENTER_CRITICAL_SECTION(intState); + sJoinSem--; + BSP_EXIT_CRITICAL_SECTION(intState); + } + + /* Have we received a frame on one of the ED connections? + * No critical section -- it doesn't really matter much if we miss a poll + */ + if (sPeerFrameSem) + { + // Continuously try to receive end device packets + if (SMPL_SUCCESS == SMPL_Receive(linkID0, ed_data, &len)) + { + // Acceleration / ppt data packets are 4 byte long + if (len == 4) + { + BSP_TOGGLE_LED1(); + memcpy(simpliciti_data, ed_data, 4); + setFlag(simpliciti_flag, SIMPLICITI_TRIGGER_RECEIVED_DATA); + } + // Sync packets are either R2R (2 byte) or data (19 byte) long + else if ((len == 2) || (len == 19)) + { + // Indicate received packet + BSP_TOGGLE_LED1(); + + // Decode end device packet + switch (ed_data[0]) + { + case SYNC_ED_TYPE_R2R: + // Send reply + if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_CMD)) + { + // Clear flag + clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_CMD); + // Command data was set by USB buffer previously + len = BM_SYNC_DATA_LENGTH; + } + else // No command currently available + { + simpliciti_data[0] = SYNC_AP_CMD_NOP; + simpliciti_data[1] = 0x55; + len = 2; + } + + // Send reply packet to end device + SMPL_Send(linkID0, simpliciti_data, len); + break; + + case SYNC_ED_TYPE_MEMORY: + case SYNC_ED_TYPE_STATUS: + // If buffer is empty, copy received end device data to intermediate buffer + if (!simpliciti_sync_buffer_status) + { + for (j=0; j150000) + { + BSP_TOGGLE_LED1(); + led_toggle = 0; + } + } + } +} + + + +/* Runs in ISR context. Reading the frame should be done in the */ +/* application thread not in the ISR thread. */ +uint8_t sCB(linkID_t lid) +{ + if (lid) + { + sPeerFrameSem++; + } + else + { + sJoinSem++; + } + + /* leave frame to be read by application. */ + return 0; +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/CC1111 - Access Point - 433MHz.r51 b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/CC1111 - Access Point - 433MHz.r51 new file mode 100755 index 0000000..c92a493 Binary files /dev/null and b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/CC1111 - Access Point - 433MHz.r51 differ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/CC1111 - Access Point - 868MHz.r51 b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/CC1111 - Access Point - 868MHz.r51 new file mode 100755 index 0000000..832c904 Binary files /dev/null and b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/CC1111 - Access Point - 868MHz.r51 differ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/CC1111 - Access Point - 915MHz.r51 b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/CC1111 - Access Point - 915MHz.r51 new file mode 100755 index 0000000..931646b Binary files /dev/null and b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/CC1111 - Access Point - 915MHz.r51 differ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_board.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_board.c new file mode 100755 index 0000000..3562133 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_board.c @@ -0,0 +1,122 @@ +/************************************************************************************************** + Revised: $Date: 2009-03-10 15:21:32 -0700 (Tue, 10 Mar 2009) $ + Revision: $Revision: 19366 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC2430DB + * Top-level board code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : Texas Instruments CC2430DB + * Top-level board code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + + +/* ------------------------------------------------------------------------------------------------ + * Local Variables + * ------------------------------------------------------------------------------------------------ + */ +#if defined(SW_TIMER) +static uint8_t sIterationsPerUsec = 0; +#endif + +/************************************************************************************************** + * @fn BSP_InitBoard + * + * @brief Initialize the board. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitBoard(void) +{ +#if defined(SW_TIMER) +#define MHZ_CLOCKS_PER_USEC BSP_CLOCK_MHZ +#define MHZ_CLOCKS_PER_ITERATION 35 + + sIterationsPerUsec = (uint8_t)(((MHZ_CLOCKS_PER_USEC)/(MHZ_CLOCKS_PER_ITERATION))+.5); + + if (!sIterationsPerUsec) + { + sIterationsPerUsec = 1; + } +#endif /* SW_TIMER */ +} +/************************************************************************************************** + * @fn BSP_Delay + * + * @brief Sleep for the requested amount of time. + * + * @param # of microseconds to sleep. + * + * @return none + ************************************************************************************************** + */ +void BSP_Delay(uint16_t usec) +#if !defined(SW_TIMER) +{ + uint8_t tickCount; + + tickCount = (usec * BSP_TIMER_CLK_MHZ); /* Calculate the tick count. */ + + T3CTL &= ~(BV(4)); /* Stop the timer. */ + TIMIF &= ~(BV(0)); /* Clear the interrupt flag. */ + T3CTL |= BV(2); /* Reset the count value. */ + T3CC0 = tickCount; /* Set the compare value. */ + T3CTL = (T3CTL & (~(0x03))) | 0x02; /* Set modulo mode. */ + T3CTL |= BV(4); /* Start the timer. */ + while( !(TIMIF & BV(0)) ); /* Wait till interrupt flag is set. i.e. count is reached. */ + T3CTL &= ~(BV(4)); /* Stop the timer. */ + TIMIF &= ~(BV(0)); /* Clear the interrupt flag. */ + + return; +} + +#else /* !SW_TIMER */ + +{ + /* Declared 'volatile' in case User optimizes for speed. This will + * prevent the optimizer from eliminating the loop completely. But + * it also generates more code... + */ + volatile uint16_t repeatCount = sIterationsPerUsec*usec; + + while (repeatCount--) ; + + return; +} + +#endif /* !SW_TIMER */ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_board_defs.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_board_defs.h new file mode 100755 index 0000000..27e4664 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_board_defs.h @@ -0,0 +1,86 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : CC1111DK_Dongle/CC2511DK_Dongle + * "RF USB Dongle" + * Board definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BOARD_DEFS_H +#define BSP_BOARD_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Board Unique Define + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BOARD_RFUSB + + +/* ------------------------------------------------------------------------------------------------ + * Mcu + * ------------------------------------------------------------------------------------------------ + */ +#include "mcus/bsp_8051_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Clock + * ------------------------------------------------------------------------------------------------ + */ +/* RFUSB Boards with CC2511/CC1111 have 48 MHz crystals. Fxosc = 48 MHz + * The reference frequency is half the oscillator freq. So Fref = 24 MHz. + * The CLKCON default setting sets the system clock to half of reference clock. + * Thus we have the system clock = 24/2 = 12 MHz. + */ +#define __bsp_CLOCK_MHZ__ 12 /* MHz */ + + +/* ------------------------------------------------------------------------------------------------ + * Board Initialization + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_INIT_BOARD() BSP_InitBoard() +#define BSP_BOARD_C "bsp_board.c" + +#define BSP_TIMER_CLK_MHZ (BSP_CLOCK_MHZ) /* Timer is clocked at same freq */ +#define BSP_DELAY_MAX_USEC (0xFF/BSP_TIMER_CLK_MHZ) /* 8-bit Timer-3 */ + +#define BSP_DELAY_USECS(x) BSP_Delay(x) +void BSP_Delay(uint16_t); +void BSP_InitBoard(void); + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_button_defs.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_button_defs.h new file mode 100755 index 0000000..fd50aef --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_button_defs.h @@ -0,0 +1,86 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : CC1111DK_Dongle/CC2511DK_Dongle + * "RF USB Dongle" + * Button definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BUTTON_DEFS_H +#define BSP_BUTTON_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Button Configuration + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_NUM_BUTTONS__ 1 +#define __bsp_BUTTON_DEBOUNCE_WAIT__(expr) st( int i; for(i=0; i<500; i++) { if (!(expr)) i = 0; } ) + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * BUTTON #1 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : S1 + * Description : Push Button + * Polarity : Active Low + * GPIO : P1.2 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define __bsp_BUTTON1_BIT__ 2 +#define __bsp_BUTTON1_PORT__ P1 +#define __bsp_BUTTON1_IS_ACTIVE_LOW__ 1 + +/* note : by default P1.2 has an internal pull-up resistor enabled */ + + + +/* ------------------------------------------------------------------------------------------------ + * Include Generic Button Macros + * ------------------------------------------------------------------------------------------------ + */ +#include "code/bsp_generic_buttons.h" + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_driver_defs.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_driver_defs.h new file mode 100755 index 0000000..d3c58c9 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_driver_defs.h @@ -0,0 +1,55 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : CC1111DK_Dongle/CC2511DK_Dongle + * "RF USB Dongle" + * Driver definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_DRIVER_DEFS_H +#define BSP_DRIVER_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Driver Initialization + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_DRIVERS_C "bsp_drivers.c" +#define BSP_INIT_DRIVERS() BSP_InitDrivers() +void BSP_InitDrivers(void); + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_drivers.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_drivers.c new file mode 100755 index 0000000..d513d5c --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_drivers.c @@ -0,0 +1,88 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : CC1111DK_Dongle/CC2511DK_Dongle + * "RF USB Dongle" + * Top-level driver file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_driver_defs.h" +#include "bsp_leds.h" +#include "bsp_buttons.h" + + +/************************************************************************************************** + * @fn BSP_InitDrivers + * + * @brief Initialize all enabled BSP drivers. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitDrivers(void) +{ +#if (!defined BSP_NO_LEDS) + BSP_InitLeds(); +#endif + +#if (!defined BSP_NO_BUTTONS) + BSP_InitButtons(); +#endif +} + + +/* ================================================================================================ + * C Code Includes + * ================================================================================================ + */ +#ifndef BSP_NO_LEDS +#include "drivers/code/bsp_leds.c" +#endif + +#ifndef BSP_NO_BUTTONS +#include "drivers/code/bsp_buttons.c" +#endif + + +/************************************************************************************************** +*/ + + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_external/mrfi_board_defs.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_external/mrfi_board_defs.h new file mode 100755 index 0000000..88080e5 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_external/mrfi_board_defs.h @@ -0,0 +1,75 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Board definition file. + * Target : CC1111DK_Dongle/CC2511DK_Dongle + * "RF USB Dongle" + * Radios : CC2511, CC1111 + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_BOARD_DEFS_H +#define MRFI_BOARD_DEFS_H + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + + +/* ------------------------------------------------------------------------------------------------ + * Radio Selection + * ------------------------------------------------------------------------------------------------ + */ +#if (!defined MRFI_CC2511) && (!defined MRFI_CC1111) +#error "ERROR: A compatible radio must be specified for the RF USB Dongle board." +#endif + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ + +/************************************************************************************************** + * Compile Time Integrity Checks + ************************************************************************************************** + */ +#ifndef BSP_BOARD_RFUSB +#error "ERROR: Mismatch between specified board and MRFI configuration." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_led_defs.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_led_defs.h new file mode 100755 index 0000000..370d0a3 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/boards/RFUSB/bsp_led_defs.h @@ -0,0 +1,88 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Target : CC1111DK_Dongle/CC2511DK_Dongle + * "RF USB Dongle" + * LED definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_LED_DEFS_H +#define BSP_LED_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Configuration + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_NUM_LEDS__ 1 +#define __bsp_LED_BLINK_LOOP_COUNT__ 0x34000 + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * LED #1 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Schematic : D2 + * Color : Green + * Polarity : Active High + * GPIO : P1.1 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +// [BM] Need to switch USB pull-up line and LED output on BM-USBD1 vs. CC1111EM board +#ifdef CC1111EM + #define __bsp_LED1_BIT__ 1 +#else + #define __bsp_LED1_BIT__ 0 +#endif +#define __bsp_LED1_PORT__ P1 +#define __bsp_LED1_DDR__ P1DIR +#define __bsp_LED1_IS_ACTIVE_LOW__ 0 + + +/* ------------------------------------------------------------------------------------------------ + * Include Generic LED Macros + * ------------------------------------------------------------------------------------------------ + */ +#include "code/bsp_generic_leds.h" + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/bsp.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/bsp.c new file mode 100755 index 0000000..cee0b33 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/bsp.c @@ -0,0 +1,101 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Top-level BSP code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "bsp_driver_defs.h" + + +/************************************************************************************************** + * @fn BSP_Init + * + * @brief Initialize the board and drivers. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_Init(void) +{ + BSP_INIT_BOARD(); + BSP_INIT_DRIVERS(); + + /*------------------------------------------------------------- + * Run time integrity checks. Perform only if asserts + * are enabled. + */ +#ifdef BSP_ASSERTS_ARE_ON + /* verify endianess is correctly specified */ + { + uint16_t test = 0x00AA; /* first storage byte of 'test' is non-zero for little endian */ + BSP_ASSERT(!(*((uint8_t *)&test)) == !BSP_LITTLE_ENDIAN); /* endianess mismatch */ + } +#endif +} + + +/* ================================================================================================ + * C Code Includes + * ================================================================================================ + */ +#ifdef BSP_BOARD_C +#include BSP_BOARD_C +#endif + +#ifdef BSP_DRIVERS_C +#include BSP_DRIVERS_C +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +BSP_STATIC_ASSERT( sizeof( uint8_t ) == 1 ); +BSP_STATIC_ASSERT( sizeof( int8_t ) == 1 ); +BSP_STATIC_ASSERT( sizeof( uint16_t ) == 2 ); +BSP_STATIC_ASSERT( sizeof( int16_t ) == 2 ); +BSP_STATIC_ASSERT( sizeof( uint32_t ) == 4 ); +BSP_STATIC_ASSERT( sizeof( int32_t ) == 4 ); + + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/bsp.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/bsp.h new file mode 100755 index 0000000..8cff5a0 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/bsp.h @@ -0,0 +1,183 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Include file for core BSP services. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_H +#define BSP_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + +/* ------------------------------------------------------------------------------------------------ + * BSP Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP +#define BSP_VER 100 /* BSP version 1.00a */ +#define BSP_SUBVER a + + +/* ------------------------------------------------------------------------------------------------ + * Clock + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CLOCK_MHZ __bsp_CLOCK_MHZ__ + + +/* ------------------------------------------------------------------------------------------------ + * Memory + * ------------------------------------------------------------------------------------------------ + */ +#ifndef __bsp_LITTLE_ENDIAN__ +#error ERROR: Endianess not defined +#endif + +#define BSP_LITTLE_ENDIAN __bsp_LITTLE_ENDIAN__ + +#define CODE __bsp_CODE_MEMSPACE__ +#define XDATA __bsp_XDATA_MEMSPACE__ + +/* ------------------------------------------------------------------------------------------------ + * Interrupts + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_ISR_FUNCTION(func,vect) __bsp_ISR_FUNCTION__(func,vect) + +#define BSP_ENABLE_INTERRUPTS() __bsp_ENABLE_INTERRUPTS__() +#define BSP_DISABLE_INTERRUPTS() __bsp_DISABLE_INTERRUPTS__() +#define BSP_INTERRUPTS_ARE_ENABLED() __bsp_INTERRUPTS_ARE_ENABLED__() + + +/* ------------------------------------------------------------------------------------------------ + * Critical Sections + * ------------------------------------------------------------------------------------------------ + */ +typedef __bsp_ISTATE_T__ bspIState_t; + +#define BSP_ENTER_CRITICAL_SECTION(x) st( x = __bsp_GET_ISTATE__(); __bsp_DISABLE_INTERRUPTS__(); ) +#define BSP_EXIT_CRITICAL_SECTION(x) __bsp_RESTORE_ISTATE__(x) +#define BSP_CRITICAL_STATEMENT(x) st( bspIState_t s; \ + BSP_ENTER_CRITICAL_SECTION(s); \ + x; \ + BSP_EXIT_CRITICAL_SECTION(s); ) + + +/* ------------------------------------------------------------------------------------------------ + * Asserts + * ------------------------------------------------------------------------------------------------ + */ + +/* + * BSP_ASSERT( expression ) - The given expression must evaluate as "true" or else the assert + * handler is called. From here, the call stack feature of the debugger can pinpoint where + * the problem occurred. + * + * BSP_FORCE_ASSERT() - If asserts are in use, immediately calls the assert handler. + * + * BSP_ASSERTS_ARE_ON - can use #ifdef to see if asserts are enabled + * + * Asserts can be disabled for optimum performance and minimum code size (ideal for + * finalized, debugged production code). + */ + +#if (!defined BSP_NO_DEBUG) +#ifndef BSP_ASSERT_HANDLER +#define BSP_ASSERT_HANDLER() st( __bsp_DISABLE_INTERRUPTS__(); while(1); ) +#endif +#define BSP_ASSERT(expr) st( if (!(expr)) BSP_ASSERT_HANDLER(); ) +#define BSP_FORCE_ASSERT() BSP_ASSERT_HANDLER() +#define BSP_ASSERTS_ARE_ON +#else +#define BSP_ASSERT(expr) /* empty */ +#define BSP_FORCE_ASSERT() /* empty */ +#endif + +/* static assert */ +#define BSP_STATIC_ASSERT(expr) void bspDummyPrototype( char dummy[1/((expr)!=0)] ) + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_Init(void); +/************************************************************************************************** + */ + +/**************************************************************************************** + * BEGIN ENDIAN SUPPORT + * + * Security encrypt/decrypt operates on unsigned long quantities. These must match on + * source and destination platforms. These macros enforce the standard conversions. + * Currently all platforms (CC2520/CC2x30 and MSP430) are little endian. + * + ******************* Network order for encryption is LITTLE ENDIAN ****************** + * + ****************************************************************************************/ + +#if (BSP_LITTLE_ENDIAN != 0) +#define ntohs(x) (x) +#define htons(x) (x) + +#define ntohl(x) (x) +#define htonl(x) (x) + +#else + +#define ntohs(x) (((x>>8) & 0xFF) | ((x & 0xFF)<<8)) +#define htons(x) (((x>>8) & 0xFF) | ((x & 0xFF)<<8)) + +#define ntohl(x) ( ((x>>24) & 0xFF) | ((x>>8) & 0xFF00) | \ + ((x & 0xFF00)<<8) | ((x & 0xFF)<<24) \ + ) +#define htonl(x) ( ((x>>24) & 0xFF) | ((x>>8) & 0xFF00) | \ + ((x & 0xFF00)<<8) | ((x & 0xFF)<<24) \ + ) + +#endif /* (BSP_LITTLE_ENDIAN != 0) */ + +/*************************************************************************************** + * END ENDIAN SUPPORT + ***************************************************************************************/ + + + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/bsp_macros.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/bsp_macros.h new file mode 100755 index 0000000..ee99a19 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/bsp_macros.h @@ -0,0 +1,79 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Include file for BSP utility macros. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_MACROS_H +#define BSP_MACROS_H + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +/* bit value */ +#ifndef BV +#define BV(n) (1 << (n)) +#endif + +/* + * This macro is for use by other macros to form a fully valid C statement. + * Without this, the if/else conditionals could show unexpected behavior. + * + * For example, use... + * #define SET_REGS() st( ioreg1 = 0; ioreg2 = 0; ) + * instead of ... + * #define SET_REGS() { ioreg1 = 0; ioreg2 = 0; } + * or + * #define SET_REGS() ioreg1 = 0; ioreg2 = 0; + * The last macro would not behave as expected in the if/else construct. + * The second to last macro will cause a compiler error in certain uses + * of if/else construct + * + * It is not necessary, or recommended, to use this macro where there is + * already a valid C statement. For example, the following is redundant... + * #define CALL_FUNC() st( func(); ) + * This should simply be... + * #define CALL_FUNC() func() + * + * (The while condition below evaluates false without generating a + * constant-controlling-loop type of warning on most compilers.) + */ +#define st(x) do { x } while (__LINE__ == -1) + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/bsp_buttons.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/bsp_buttons.h new file mode 100755 index 0000000..b73d615 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/bsp_buttons.h @@ -0,0 +1,90 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Button driver include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_BUTTONS_H +#define BSP_BUTTONS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_button_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_NUM_BUTTONS __bsp_NUM_BUTTONS__ + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_BUTTON_DEBOUNCE_WAIT(expr) __bsp_BUTTON_DEBOUNCE_WAIT__(expr) + +#define BSP_BUTTON1() __bsp_BUTTON1__() +#define BSP_BUTTON2() __bsp_BUTTON2__() +#define BSP_BUTTON3() __bsp_BUTTON3__() +#define BSP_BUTTON4() __bsp_BUTTON4__() +#define BSP_BUTTON5() __bsp_BUTTON5__() +#define BSP_BUTTON6() __bsp_BUTTON6__() +#define BSP_BUTTON7() __bsp_BUTTON7__() +#define BSP_BUTTON8() __bsp_BUTTON8__() + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_InitButtons(void); + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +#ifdef BSP_NO_BUTTONS +#error "ERROR: The button driver is disabled. This file should not be included." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/bsp_leds.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/bsp_leds.h new file mode 100755 index 0000000..b01338b --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/bsp_leds.h @@ -0,0 +1,133 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * LED driver include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_LEDS_H +#define BSP_LEDS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_led_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_NUM_LEDS __bsp_NUM_LEDS__ + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ + +/* blink delay loop */ +#define BSP_LED_BLINK_DELAY() st( { volatile uint32_t i; \ + for (i=0; i<__bsp_LED_BLINK_LOOP_COUNT__; i++) { }; } ) + +/* LED1 */ +#define BSP_TURN_ON_LED1() __bsp_LED1_TURN_ON__() +#define BSP_TURN_OFF_LED1() __bsp_LED1_TURN_OFF__() +#define BSP_TOGGLE_LED1() __bsp_LED1_TOGGLE__() +#define BSP_LED1_IS_ON() __bsp_LED1_IS_ON__() + +/* LED2 */ +#define BSP_TURN_ON_LED2() __bsp_LED2_TURN_ON__() +#define BSP_TURN_OFF_LED2() __bsp_LED2_TURN_OFF__() +#define BSP_TOGGLE_LED2() __bsp_LED2_TOGGLE__() +#define BSP_LED2_IS_ON() __bsp_LED2_IS_ON__() + +/* LED3 */ +#define BSP_TURN_ON_LED3() __bsp_LED3_TURN_ON__() +#define BSP_TURN_OFF_LED3() __bsp_LED3_TURN_OFF__() +#define BSP_TOGGLE_LED3() __bsp_LED3_TOGGLE__() +#define BSP_LED3_IS_ON() __bsp_LED3_IS_ON__() + +/* LED4 */ +#define BSP_TURN_ON_LED4() __bsp_LED4_TURN_ON__() +#define BSP_TURN_OFF_LED4() __bsp_LED4_TURN_OFF__() +#define BSP_TOGGLE_LED4() __bsp_LED4_TOGGLE__() +#define BSP_LED4_IS_ON() __bsp_LED4_IS_ON__() + +/* LED5 */ +#define BSP_TURN_ON_LED5() __bsp_LED5_TURN_ON__() +#define BSP_TURN_OFF_LED5() __bsp_LED5_TURN_OFF__() +#define BSP_TOGGLE_LED5() __bsp_LED5_TOGGLE__() +#define BSP_LED5_IS_ON() __bsp_LED5_IS_ON__() + +/* LED6 */ +#define BSP_TURN_ON_LED6() __bsp_LED6_TURN_ON__() +#define BSP_TURN_OFF_LED6() __bsp_LED6_TURN_OFF__() +#define BSP_TOGGLE_LED6() __bsp_LED6_TOGGLE__() +#define BSP_LED6_IS_ON() __bsp_LED6_IS_ON__() + +/* LED7 */ +#define BSP_TURN_ON_LED7() __bsp_LED7_TURN_ON__() +#define BSP_TURN_OFF_LED7() __bsp_LED7_TURN_OFF__() +#define BSP_TOGGLE_LED7() __bsp_LED7_TOGGLE__() +#define BSP_LED7_IS_ON() __bsp_LED7_IS_ON__() + +/* LED8 */ +#define BSP_TURN_ON_LED8() __bsp_LED8_TURN_ON__() +#define BSP_TURN_OFF_LED8() __bsp_LED8_TURN_OFF__() +#define BSP_TOGGLE_LED8() __bsp_LED8_TOGGLE__() +#define BSP_LED8_IS_ON() __bsp_LED8_IS_ON__() + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void BSP_InitLeds(void); + + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ +#ifdef BSP_NO_LEDS +#error "ERROR: The LED driver is disabled. This file should not be included." +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_buttons.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_buttons.c new file mode 100755 index 0000000..b8f2018 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_buttons.c @@ -0,0 +1,97 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic button driver code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_buttons.h" +#include "bsp_button_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CONFIG_BUTTON1() __bsp_BUTTON1_CONFIG__() +#define BSP_CONFIG_BUTTON2() __bsp_BUTTON2_CONFIG__() +#define BSP_CONFIG_BUTTON3() __bsp_BUTTON3_CONFIG__() +#define BSP_CONFIG_BUTTON4() __bsp_BUTTON4_CONFIG__() +#define BSP_CONFIG_BUTTON5() __bsp_BUTTON5_CONFIG__() +#define BSP_CONFIG_BUTTON6() __bsp_BUTTON6_CONFIG__() +#define BSP_CONFIG_BUTTON7() __bsp_BUTTON7_CONFIG__() +#define BSP_CONFIG_BUTTON8() __bsp_BUTTON8_CONFIG__() + +#ifdef __bsp_BUTTON_EXTENDED_CONFIG__ +#define BSP_BUTTON_EXTENDED_CONFIG() __bsp_BUTTON_EXTENDED_CONFIG__() +#else +#define BSP_BUTTON_EXTENDED_CONFIG() +#endif + + +/************************************************************************************************** + * @fn BSP_InitButtons + * + * @brief Initialize button hardware and driver code. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitButtons(void) +{ + /* configure LEDs */ + BSP_CONFIG_BUTTON1(); + BSP_CONFIG_BUTTON2(); + BSP_CONFIG_BUTTON3(); + BSP_CONFIG_BUTTON4(); + BSP_CONFIG_BUTTON5(); + BSP_CONFIG_BUTTON6(); + BSP_CONFIG_BUTTON7(); + BSP_CONFIG_BUTTON8(); + + /* peform extended configuration if needed */ + BSP_BUTTON_EXTENDED_CONFIG(); +} + + +/************************************************************************************************** +*/ + + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h new file mode 100755 index 0000000..e9ae165 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_generic_buttons.h @@ -0,0 +1,203 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic button macro include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_GENERIC_BUTTONS_H +#define BSP_GENERIC_BUTTONS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_board_defs.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_BUTTON__(port,bit,low) ((low) ? (!((port) & BV(bit))) : ((port) & BV(bit)) ) + + +/* ------------------------- populate BUTTON #1 macros ------------------------- */ +#define __bsp_NUM_BUTTON1_DEFINES__ ((defined __bsp_BUTTON1_PORT__) + \ + (defined __bsp_BUTTON1_BIT__) + \ + (defined __bsp_BUTTON1_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON1_DEFINES__ == 3) +#define __bsp_BUTTON1__() __bsp_BUTTON__( __bsp_BUTTON1_PORT__, __bsp_BUTTON1_BIT__, __bsp_BUTTON1_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON1_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON1_DEFINES__ == 0) +#define __bsp_BUTTON1__() /* no button */ 0 +#define __bsp_BUTTON1_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON1." +#endif + +/* ------------------------- populate BUTTON #2 macros ------------------------- */ +#define __bsp_NUM_BUTTON2_DEFINES__ ((defined __bsp_BUTTON2_PORT__) + \ + (defined __bsp_BUTTON2_BIT__) + \ + (defined __bsp_BUTTON2_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON2_DEFINES__ == 3) +#define __bsp_BUTTON2__() __bsp_BUTTON__( __bsp_BUTTON2_PORT__, __bsp_BUTTON2_BIT__, __bsp_BUTTON2_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON2_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON2_DEFINES__ == 0) +#define __bsp_BUTTON2__() /* no button */ 0 +#define __bsp_BUTTON2_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON2." +#endif + +/* ------------------------- populate BUTTON #3 macros ------------------------- */ +#define __bsp_NUM_BUTTON3_DEFINES__ ((defined __bsp_BUTTON3_PORT__) + \ + (defined __bsp_BUTTON3_BIT__) + \ + (defined __bsp_BUTTON3_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON3_DEFINES__ == 3) +#define __bsp_BUTTON3__() __bsp_BUTTON__( __bsp_BUTTON3_PORT__, __bsp_BUTTON3_BIT__, __bsp_BUTTON3_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON3_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON3_DEFINES__ == 0) +#define __bsp_BUTTON3__() /* no button */ 0 +#define __bsp_BUTTON3_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON3." +#endif + +/* ------------------------- populate BUTTON #4 macros ------------------------- */ +#define __bsp_NUM_BUTTON4_DEFINES__ ((defined __bsp_BUTTON4_PORT__) + \ + (defined __bsp_BUTTON4_BIT__) + \ + (defined __bsp_BUTTON4_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON4_DEFINES__ == 3) +#define __bsp_BUTTON4__() __bsp_BUTTON__( __bsp_BUTTON4_PORT__, __bsp_BUTTON4_BIT__, __bsp_BUTTON4_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON4_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON4_DEFINES__ == 0) +#define __bsp_BUTTON4__() /* no button */ 0 +#define __bsp_BUTTON4_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON4." +#endif + +/* ------------------------- populate BUTTON #5 macros ------------------------- */ +#define __bsp_NUM_BUTTON5_DEFINES__ ((defined __bsp_BUTTON5_PORT__) + \ + (defined __bsp_BUTTON5_BIT__) + \ + (defined __bsp_BUTTON5_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON5_DEFINES__ == 3) +#define __bsp_BUTTON5__() __bsp_BUTTON__( __bsp_BUTTON5_PORT__, __bsp_BUTTON5_BIT__, __bsp_BUTTON5_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON5_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON5_DEFINES__ == 0) +#define __bsp_BUTTON5__() /* no button */ 0 +#define __bsp_BUTTON5_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON5." +#endif + +/* ------------------------- populate BUTTON #6 macros ------------------------- */ +#define __bsp_NUM_BUTTON6_DEFINES__ ((defined __bsp_BUTTON6_PORT__) + \ + (defined __bsp_BUTTON6_BIT__) + \ + (defined __bsp_BUTTON6_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON6_DEFINES__ == 3) +#define __bsp_BUTTON6__() __bsp_BUTTON__( __bsp_BUTTON6_PORT__, __bsp_BUTTON6_BIT__, __bsp_BUTTON6_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON6_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON6_DEFINES__ == 0) +#define __bsp_BUTTON6__() /* no button */ 0 +#define __bsp_BUTTON6_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON6." +#endif + +/* ------------------------- populate BUTTON #7 macros ------------------------- */ +#define __bsp_NUM_BUTTON7_DEFINES__ ((defined __bsp_BUTTON7_PORT__) + \ + (defined __bsp_BUTTON7_BIT__) + \ + (defined __bsp_BUTTON7_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON7_DEFINES__ == 3) +#define __bsp_BUTTON7__() __bsp_BUTTON__( __bsp_BUTTON7_PORT__, __bsp_BUTTON7_BIT__, __bsp_BUTTON7_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON7_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON7_DEFINES__ == 0) +#define __bsp_BUTTON7__() /* no button */ 0 +#define __bsp_BUTTON7_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON7." +#endif + +/* ------------------------- populate BUTTON #8 macros ------------------------- */ +#define __bsp_NUM_BUTTON8_DEFINES__ ((defined __bsp_BUTTON8_PORT__) + \ + (defined __bsp_BUTTON8_BIT__) + \ + (defined __bsp_BUTTON8_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_BUTTON8_DEFINES__ == 3) +#define __bsp_BUTTON8__() __bsp_BUTTON__( __bsp_BUTTON8_PORT__, __bsp_BUTTON8_BIT__, __bsp_BUTTON8_IS_ACTIVE_LOW__ ) +#define __bsp_BUTTON8_CONFIG__() /* nothing required */ +#elif (__bsp_NUM_BUTTON8_DEFINES__ == 0) +#define __bsp_BUTTON8__() /* no button */ 0 +#define __bsp_BUTTON8_CONFIG__() /* no button */ +#else +#error "ERROR: Incomplete number of macros for BUTTON8." +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* -------------------- number of buttons defined -------------------- */ +#ifndef __bsp_NUM_BUTTONS__ +#error "ERROR: Number of buttons is not specified." +#else +#if ((__bsp_NUM_BUTTONS__ > 8) || (__bsp_NUM_BUTTONS__ < 0)) +#error "ERROR: Unsupported number of buttons specified. Maximum is eight." +#endif +#endif + +#if (((__bsp_NUM_BUTTON1_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON2_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON3_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON4_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON5_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON6_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON7_DEFINES__ != 0) + \ + (__bsp_NUM_BUTTON8_DEFINES__ != 0)) != __bsp_NUM_BUTTONS__) +#error "ERROR: Inconsistency between defined macros and specified number of buttons." +#endif + +/* -------------------- debounce macro -------------------- */ +#ifndef __bsp_BUTTON_DEBOUNCE_WAIT__ +#error "ERROR: Debounce delay macro is missing." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h new file mode 100755 index 0000000..6e1e42b --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_generic_leds.h @@ -0,0 +1,278 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic LED macro include file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_GENERIC_LEDS_H +#define BSP_GENERIC_LEDS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ + +/* + * Note : The conditionals in the following macros evaulate compile time constants. + * Any compiler worth its salt will optimize these conditionals out for the + * smallest possible code. + */ + +#define __bsp_LED_TURN_ON__(bit,port,ddr,low) \ + st( if (low) { port &= ~BV(bit); } else { port |= BV(bit); } ) + +#define __bsp_LED_TURN_OFF__(bit,port,ddr,low) \ + st( if (low) { port |= BV(bit); } else { port &= ~BV(bit); } ) + +#define __bsp_LED_IS_ON__(bit,port,ddr,low) \ + ( (low) ? (!((port) & BV(bit))) : ((port) & BV(bit)) ) + +#define __bsp_LED_TOGGLE__(bit,port,ddr,low) st( port ^= BV(bit); ) +#define __bsp_LED_CONFIG__(bit,port,ddr,low) st( ddr |= BV(bit); ) + + + +/* ------------------------- populate LED1 macros ------------------------- */ +#define __bsp_NUM_LED1_DEFINES__ ((defined __bsp_LED1_BIT__) + \ + (defined __bsp_LED1_PORT__) + \ + (defined __bsp_LED1_DDR__) + \ + (defined __bsp_LED1_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED1_DEFINES__ == 4) +#define __bsp_LED1_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#define __bsp_LED1_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__, __bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED1_DEFINES__ == 0) +#define __bsp_LED1_TURN_ON__() /* no LED */ +#define __bsp_LED1_TURN_OFF__() /* no LED */ +#define __bsp_LED1_TOGGLE__() /* no LED */ +#define __bsp_LED1_IS_ON__() /* no LED */ 0 +#define __bsp_LED1_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED1." +#endif + + +/* ------------------------- populate LED2 macros ------------------------- */ +#define __bsp_NUM_LED2_DEFINES__ ((defined __bsp_LED2_BIT__) + \ + (defined __bsp_LED2_PORT__) + \ + (defined __bsp_LED2_DDR__) + \ + (defined __bsp_LED2_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED2_DEFINES__ == 4) +#define __bsp_LED2_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#define __bsp_LED2_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED2_BIT__, __bsp_LED2_PORT__, __bsp_LED2_DDR__, __bsp_LED2_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED2_DEFINES__ == 0) +#define __bsp_LED2_TURN_ON__() /* no LED */ +#define __bsp_LED2_TURN_OFF__() /* no LED */ +#define __bsp_LED2_TOGGLE__() /* no LED */ +#define __bsp_LED2_IS_ON__() /* no LED */ 0 +#define __bsp_LED2_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED2." +#endif + + +/* ------------------------- populate LED3 macros ------------------------- */ +#define __bsp_NUM_LED3_DEFINES__ ((defined __bsp_LED3_BIT__) + \ + (defined __bsp_LED3_PORT__) + \ + (defined __bsp_LED3_DDR__) + \ + (defined __bsp_LED3_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED3_DEFINES__ == 4) +#define __bsp_LED3_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#define __bsp_LED3_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED3_BIT__, __bsp_LED3_PORT__, __bsp_LED3_DDR__, __bsp_LED3_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED3_DEFINES__ == 0) +#define __bsp_LED3_TURN_ON__() /* no LED */ +#define __bsp_LED3_TURN_OFF__() /* no LED */ +#define __bsp_LED3_TOGGLE__() /* no LED */ +#define __bsp_LED3_IS_ON__() /* no LED */ 0 +#define __bsp_LED3_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED3." +#endif + + +/* ------------------------- populate LED4 macros ------------------------- */ +#define __bsp_NUM_LED4_DEFINES__ ((defined __bsp_LED4_BIT__) + \ + (defined __bsp_LED4_PORT__) + \ + (defined __bsp_LED4_DDR__) + \ + (defined __bsp_LED4_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED4_DEFINES__ == 4) +#define __bsp_LED4_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#define __bsp_LED4_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED4_BIT__, __bsp_LED4_PORT__, __bsp_LED4_DDR__, __bsp_LED4_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED4_DEFINES__ == 0) +#define __bsp_LED4_TURN_ON__() /* no LED */ +#define __bsp_LED4_TURN_OFF__() /* no LED */ +#define __bsp_LED4_TOGGLE__() /* no LED */ +#define __bsp_LED4_IS_ON__() /* no LED */ 0 +#define __bsp_LED4_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED4." +#endif + +/* ------------------------- populate LED5 macros ------------------------- */ +#define __bsp_NUM_LED5_DEFINES__ ((defined __bsp_LED5_BIT__) + \ + (defined __bsp_LED5_PORT__) + \ + (defined __bsp_LED5_DDR__) + \ + (defined __bsp_LED5_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED5_DEFINES__ == 4) +#define __bsp_LED5_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#define __bsp_LED5_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED5_BIT__, __bsp_LED5_PORT__, __bsp_LED5_DDR__, __bsp_LED5_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED5_DEFINES__ == 0) +#define __bsp_LED5_TURN_ON__() /* no LED */ +#define __bsp_LED5_TURN_OFF__() /* no LED */ +#define __bsp_LED5_TOGGLE__() /* no LED */ +#define __bsp_LED5_IS_ON__() /* no LED */ 0 +#define __bsp_LED5_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED5." +#endif + +/* ------------------------- populate LED6 macros ------------------------- */ +#define __bsp_NUM_LED6_DEFINES__ ((defined __bsp_LED6_BIT__) + \ + (defined __bsp_LED6_PORT__) + \ + (defined __bsp_LED6_DDR__) + \ + (defined __bsp_LED6_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED6_DEFINES__ == 4) +#define __bsp_LED6_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#define __bsp_LED6_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED6_BIT__, __bsp_LED6_PORT__, __bsp_LED6_DDR__, __bsp_LED6_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED6_DEFINES__ == 0) +#define __bsp_LED6_TURN_ON__() /* no LED */ +#define __bsp_LED6_TURN_OFF__() /* no LED */ +#define __bsp_LED6_TOGGLE__() /* no LED */ +#define __bsp_LED6_IS_ON__() /* no LED */ 0 +#define __bsp_LED6_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED6." +#endif + +/* ------------------------- populate LED7 macros ------------------------- */ +#define __bsp_NUM_LED7_DEFINES__ ((defined __bsp_LED7_BIT__) + \ + (defined __bsp_LED7_PORT__) + \ + (defined __bsp_LED7_DDR__) + \ + (defined __bsp_LED7_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED7_DEFINES__ == 4) +#define __bsp_LED7_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#define __bsp_LED7_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED7_BIT__, __bsp_LED7_PORT__, __bsp_LED7_DDR__, __bsp_LED7_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED7_DEFINES__ == 0) +#define __bsp_LED7_TURN_ON__() /* no LED */ +#define __bsp_LED7_TURN_OFF__() /* no LED */ +#define __bsp_LED7_TOGGLE__() /* no LED */ +#define __bsp_LED7_IS_ON__() /* no LED */ 0 +#define __bsp_LED7_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED7." +#endif + +/* ------------------------- populate LED8 macros ------------------------- */ +#define __bsp_NUM_LED8_DEFINES__ ((defined __bsp_LED8_BIT__) + \ + (defined __bsp_LED8_PORT__) + \ + (defined __bsp_LED8_DDR__) + \ + (defined __bsp_LED8_IS_ACTIVE_LOW__)) +#if (__bsp_NUM_LED8_DEFINES__ == 4) +#define __bsp_LED8_TURN_ON__() __bsp_LED_TURN_ON__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_TURN_OFF__() __bsp_LED_TURN_OFF__( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_TOGGLE__() __bsp_LED_TOGGLE__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_IS_ON__() __bsp_LED_IS_ON__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#define __bsp_LED8_CONFIG__() __bsp_LED_CONFIG__ ( __bsp_LED8_BIT__, __bsp_LED8_PORT__, __bsp_LED8_DDR__, __bsp_LED8_IS_ACTIVE_LOW__ ) +#elif (__bsp_NUM_LED8_DEFINES__ == 0) +#define __bsp_LED8_TURN_ON__() /* no LED */ +#define __bsp_LED8_TURN_OFF__() /* no LED */ +#define __bsp_LED8_TOGGLE__() /* no LED */ +#define __bsp_LED8_IS_ON__() /* no LED */ 0 +#define __bsp_LED8_CONFIG__() /* no LED */ +#else +#error "ERROR: Incomplete number of macros for LED8." +#endif + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* -------------------- number of LEDs defined -------------------- */ +#ifndef __bsp_NUM_LEDS__ +#error "ERROR: Number of LEDs is not specified." +#else +#if ((__bsp_NUM_LEDS__ > 8) || (__bsp_NUM_LEDS__ < 0)) +#error "ERROR: Unsupported number of LEDs specified. Maximum is eight." +#endif +#endif + +#if (((__bsp_NUM_LED1_DEFINES__ != 0) + \ + (__bsp_NUM_LED2_DEFINES__ != 0) + \ + (__bsp_NUM_LED3_DEFINES__ != 0) + \ + (__bsp_NUM_LED4_DEFINES__ != 0) + \ + (__bsp_NUM_LED5_DEFINES__ != 0) + \ + (__bsp_NUM_LED6_DEFINES__ != 0) + \ + (__bsp_NUM_LED7_DEFINES__ != 0) + \ + (__bsp_NUM_LED8_DEFINES__ != 0)) != __bsp_NUM_LEDS__) +#error "ERROR: Inconsistency between defined macros and specified number of LEDs." +#endif + +/* -------------------- blink delay loop count -------------------- */ +#ifndef __bsp_LED_BLINK_LOOP_COUNT__ +#error "ERROR: Blink delay count is missing." +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_leds.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_leds.c new file mode 100755 index 0000000..4bc83e0 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/drivers/code/bsp_leds.c @@ -0,0 +1,107 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * Generic LED driver code file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp_leds.h" +#include "bsp_led_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_CONFIG_LED1() __bsp_LED1_CONFIG__() +#define BSP_CONFIG_LED2() __bsp_LED2_CONFIG__() +#define BSP_CONFIG_LED3() __bsp_LED3_CONFIG__() +#define BSP_CONFIG_LED4() __bsp_LED4_CONFIG__() +#define BSP_CONFIG_LED5() __bsp_LED5_CONFIG__() +#define BSP_CONFIG_LED6() __bsp_LED6_CONFIG__() +#define BSP_CONFIG_LED7() __bsp_LED7_CONFIG__() +#define BSP_CONFIG_LED8() __bsp_LED8_CONFIG__() + +#ifdef __bsp_LED_EXTENDED_CONFIG__ +#define BSP_LED_EXTENDED_CONFIG() __bsp_LED_EXTENDED_CONFIG__() +#else +#define BSP_LED_EXTENDED_CONFIG() +#endif + + +/************************************************************************************************** + * @fn BSP_InitLeds + * + * @brief Initialize LED hardware and driver. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void BSP_InitLeds(void) +{ + /* configure LEDs */ + BSP_CONFIG_LED1(); + BSP_CONFIG_LED2(); + BSP_CONFIG_LED3(); + BSP_CONFIG_LED4(); + BSP_CONFIG_LED5(); + BSP_CONFIG_LED6(); + BSP_CONFIG_LED7(); + BSP_CONFIG_LED8(); + + /* peform extended configuration if needed */ + BSP_LED_EXTENDED_CONFIG(); + + /* turn all LEDs off as power-up default */ + BSP_TURN_OFF_LED1(); + BSP_TURN_OFF_LED2(); + BSP_TURN_OFF_LED3(); + BSP_TURN_OFF_LED4(); + BSP_TURN_OFF_LED5(); + BSP_TURN_OFF_LED6(); + BSP_TURN_OFF_LED7(); + BSP_TURN_OFF_LED8(); +} + + +/************************************************************************************************** +*/ + + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/mcus/bsp_8051_defs.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/mcus/bsp_8051_defs.h new file mode 100755 index 0000000..acc2638 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/mcus/bsp_8051_defs.h @@ -0,0 +1,99 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * MCU : 8051 + * Microcontroller definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_8051_DEFS_H +#define BSP_8051_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_MCU_8051 + + +/* ------------------------------------------------------------------------------------------------ + * Compiler Abstraction + * ------------------------------------------------------------------------------------------------ + */ + +/* ---------------------- IAR Compiler ---------------------- */ +#ifdef __IAR_SYSTEMS_ICC__ +#define BSP_COMPILER_IAR +#ifndef MCU_H +#error "ERROR: The MCU include file must be specified. Define MCU_H= at the project level." +#endif +#include MCU_H +#define __bsp_LITTLE_ENDIAN__ 1 +#define __bsp_CODE_MEMSPACE__ __code +#define __bsp_XDATA_MEMSPACE__ __xdata + +#define __bsp_QUOTED_PRAGMA__(x) _Pragma(#x) +#define __bsp_ISR_FUNCTION__(f,v) __bsp_QUOTED_PRAGMA__(vector=v) __interrupt void f(void); \ + __bsp_QUOTED_PRAGMA__(vector=v) __interrupt void f(void) + +/* ------------------ Unrecognized Compiler ------------------ */ +#else +#error "ERROR: Unknown compiler." +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Common + * ------------------------------------------------------------------------------------------------ + */ +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed long int32_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; + +#define __bsp_ENABLE_INTERRUPTS__() st( EA = 1; ) +#define __bsp_DISABLE_INTERRUPTS__() st( EA = 0; ) +#define __bsp_INTERRUPTS_ARE_ENABLED__() EA + +#define __bsp_ISTATE_T__ unsigned char +#define __bsp_GET_ISTATE__() EA +#define __bsp_RESTORE_ISTATE__(x) st( EA = x; ) + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h new file mode 100755 index 0000000..ad66e54 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/bsp/mcus/bsp_msp430_defs.h @@ -0,0 +1,140 @@ +/************************************************************************************************** + Filename: bsp_msp430_defs.h + Revised: $Date: 2009-10-11 18:52:46 -0700 (Sun, 11 Oct 2009) $ + Revision: $Revision: 20897 $ + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * BSP (Board Support Package) + * MCU : Texas Instruments MSP430 family + * Microcontroller definition file. + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +#ifndef BSP_MSP430_DEFS_H +#define BSP_MSP430_DEFS_H + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define BSP_MCU_MSP430 + +/* ------------------------------------------------------------------------------------------------ + * Compiler Abstraction + * ------------------------------------------------------------------------------------------------ + */ + +/* ---------------------- IAR Compiler ---------------------- */ +#ifdef __IAR_SYSTEMS_ICC__ +#define BSP_COMPILER_IAR + +#if (__VER__ < 342) + #error "ERROR: This IAR compiler port requires at least revision v3.42A." +/* + * Compiler versions previous to v3.42A do not have the universal msp430.h include file. + * To use an earlier version of the compiler, replace the above #error statement with + * the appropriate, device specific #include statement. + */ +#endif + +/* Workaround for release v3.42A - the msp430.h file did not include support for some devices */ +#if ((__VER__ == 342) && (__SUBVERSION__ == 'A')) && \ + (defined (__MSP430F1610__) || defined (__MSP430F1611__) || defined (__MSP430F1612__)) +#include +#else +#include +#endif + +#define __bsp_ISTATE_T__ istate_t +#define __bsp_ISR_FUNCTION__(f,v) __bsp_QUOTED_PRAGMA__(vector=v) __interrupt void f(void); \ + __bsp_QUOTED_PRAGMA__(vector=v) __interrupt void f(void) + +/* Initialization call provided in IAR environment before standard C-startup */ +#include +#define BSP_EARLY_INIT(void) __intrinsic int __low_level_init(void) + +/* ---------------------- Code Composer ---------------------- */ +#elif (defined __TI_COMPILER_VERSION__) && (defined __MSP430__) +#define BSP_COMPILER_CODE_COMPOSER + +/* At time of 1.1.0 release, CC430 support not in msp430.h */ +#if (__CC430F6137__) +#include +#else +#include +#endif + +#define __bsp_ISTATE_T__ unsigned short +#define __bsp_ISR_FUNCTION__(f,v) __bsp_QUOTED_PRAGMA__(vector=v) __interrupt void f(void) + +/* Initialization call provided in CCE environment before standard C-startup */ +#define BSP_EARLY_INIT(void) int _system_pre_init(void) + +/* ------------------ Unrecognized Compiler ------------------ */ +#else +#error "ERROR: Unknown compiler." +#endif + +#if (defined BSP_COMPILER_IAR) || (defined BSP_COMPILER_CODE_COMPOSER) +#include +#define __bsp_ENABLE_INTERRUPTS__() __enable_interrupt() +#define __bsp_DISABLE_INTERRUPTS__() __disable_interrupt() +#define __bsp_INTERRUPTS_ARE_ENABLED__() (__get_SR_register() & GIE) + +#define __bsp_GET_ISTATE__() __get_interrupt_state() +#define __bsp_RESTORE_ISTATE__(x) __set_interrupt_state(x) + +#define __bsp_QUOTED_PRAGMA__(x) _Pragma(#x) + +#endif + +/* ------------------------------------------------------------------------------------------------ + * Common + * ------------------------------------------------------------------------------------------------ + */ +#define __bsp_LITTLE_ENDIAN__ 1 +#define __bsp_CODE_MEMSPACE__ /* blank */ +#define __bsp_XDATA_MEMSPACE__ /* blank */ + +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed long int32_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; + +#ifndef NULL +#define NULL 0 +#endif + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/mrfi.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/mrfi.c new file mode 100755 index 0000000..5b7337b --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/mrfi.c @@ -0,0 +1,87 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Top-level code file. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "mrfi_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * C Code Includes + * ------------------------------------------------------------------------------------------------ + */ + +/* ----- Radio Family 1 ----- */ +#if (defined MRFI_RADIO_FAMILY1) +#include "radios/family1/mrfi_radio.c" +#include "radios/family1/mrfi_spi.c" +#include "radios/common/mrfi_f1f2.c" +#include "bsp_external/mrfi_board.c" + +/* ----- Radio Family 2 ----- */ +#elif (defined MRFI_RADIO_FAMILY2) +#include "radios/family2/mrfi_radio.c" +#include "radios/common/mrfi_f1f2.c" + +/* ----- Radio Family 3 ----- */ +#elif (defined MRFI_RADIO_FAMILY3) +#include "bsp_external/mrfi_board.c" +#include "radios/family3/mrfi_spi.c" +#include "radios/family3/mrfi_radio.c" + +/* ----- Radio Family 4 ----- */ +#elif (defined MRFI_RADIO_FAMILY4) +#include "radios/family4/mrfi_radio.c" + +/* ----- Radio Family 5 ----- */ +#elif (defined MRFI_RADIO_FAMILY5) +#include "radios/family5/mrfi_radio.c" +#include "radios/family5/mrfi_radio_interface.c" + +/* ----- Radio Family 6 ----- */ +#elif (defined MRFI_RADIO_FAMILY6) +#include "radios/family6/mrfi_radio.c" + +#else +#error "ERROR: Radio family is not defined." +#endif + + +/************************************************************************************************** + */ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/mrfi.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/mrfi.h new file mode 100755 index 0000000..ca49e02 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/mrfi.h @@ -0,0 +1,182 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Include file for all MRFI services. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +#ifndef MRFI_H +#define MRFI_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" +#include "mrfi_defs.h" + + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_NUM_LOGICAL_CHANS __mrfi_NUM_LOGICAL_CHANS__ + +#define MRFI_NUM_POWER_SETTINGS __mrfi_NUM_POWER_SETTINGS__ + +/* return values for MRFI_Transmit */ +#define MRFI_TX_RESULT_SUCCESS 0 +#define MRFI_TX_RESULT_FAILED 1 + +/* transmit type parameter for MRFI_Transmit */ +#define MRFI_TX_TYPE_FORCED 0 +#define MRFI_TX_TYPE_CCA 1 + +/* Network header size definition */ +/* ********************************* NOTE **************************************** + * There is a dependency here that really shouldn't exist. A reimplementation + * is necessary to avoid it. + * + * MRFI allocates the frame buffer which means it needs to know at compile time + * how big the buffer is. This means in must know the NWK header size, the + * maximum NWK and User application payload sizes and whether Security is enabled. + * ******************************************************************************** + */ +#ifndef SMPL_SECURE +#define NWK_HDR_SIZE 3 +#define NWK_PAYLOAD MAX_NWK_PAYLOAD +#else +#define NWK_HDR_SIZE 6 +#define NWK_PAYLOAD (MAX_NWK_PAYLOAD+4) +#endif + +/* if external code has defined a maximum payload, use that instead of default */ +#ifdef MAX_APP_PAYLOAD +#ifndef MAX_NWK_PAYLOAD +#error ERROR: MAX_NWK_PAYLOAD not defined +#endif +#if MAX_APP_PAYLOAD < NWK_PAYLOAD +#define MAX_PAYLOAD NWK_PAYLOAD +#else +#define MAX_PAYLOAD MAX_APP_PAYLOAD +#endif +#define MRFI_MAX_PAYLOAD_SIZE (MAX_PAYLOAD+NWK_HDR_SIZE) /* SimpliciTI payload size plus six byte overhead */ +#endif + + +/* frame definitions */ +#define MRFI_ADDR_SIZE __mrfi_ADDR_SIZE__ +#ifndef MRFI_MAX_PAYLOAD_SIZE +#define MRFI_MAX_PAYLOAD_SIZE __mrfi_MAX_PAYLOAD_SIZE__ +#endif +#define MRFI_MAX_FRAME_SIZE (MRFI_MAX_PAYLOAD_SIZE + __mrfi_FRAME_OVERHEAD_SIZE__) +#define MRFI_RX_METRICS_SIZE __mrfi_RX_METRICS_SIZE__ +#define MRFI_RX_METRICS_RSSI_OFS __mrfi_RX_METRICS_RSSI_OFS__ +#define MRFI_RX_METRICS_CRC_LQI_OFS __mrfi_RX_METRICS_CRC_LQI_OFS__ + +/* Radio States */ +#define MRFI_RADIO_STATE_UNKNOWN 0 +#define MRFI_RADIO_STATE_OFF 1 +#define MRFI_RADIO_STATE_IDLE 2 +#define MRFI_RADIO_STATE_RX 3 + +/* Platform constant used to calculate worst-case for an application + * acknowledgment delay. Used in the NWK_REPLY_DELAY() macro. + * + + processing time on peer + | round trip + | | max number of replays + | | | number of backoff opportunities + | | | | average number of backoffs + | | | | | */ +#define PLATFORM_FACTOR_CONSTANT (2 + 2*(MAX_HOPS*(MRFI_CCA_RETRIES*(8*MRFI_BACKOFF_PERIOD_USECS)/1000))) + + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_GET_PAYLOAD_LEN(p) __mrfi_GET_PAYLOAD_LEN__(p) +#define MRFI_SET_PAYLOAD_LEN(p,x) __mrfi_SET_PAYLOAD_LEN__(p,x) + +#define MRFI_P_DST_ADDR(p) __mrfi_P_DST_ADDR__(p) +#define MRFI_P_SRC_ADDR(p) __mrfi_P_SRC_ADDR__(p) +#define MRFI_P_PAYLOAD(p) __mrfi_P_PAYLOAD__(p) + +/* ------------------------------------------------------------------------------------------------ + * Typdefs + * ------------------------------------------------------------------------------------------------ + */ +typedef struct +{ + uint8_t frame[MRFI_MAX_FRAME_SIZE]; + uint8_t rxMetrics[MRFI_RX_METRICS_SIZE]; +} mrfiPacket_t; + + +/* ------------------------------------------------------------------------------------------------ + * Prototypes + * ------------------------------------------------------------------------------------------------ + */ +void MRFI_Init(void); +uint8_t MRFI_Transmit(mrfiPacket_t *, uint8_t); +void MRFI_Receive(mrfiPacket_t *); +void MRFI_RxCompleteISR(void); /* populated by code using MRFI */ +uint8_t MRFI_GetRadioState(void); +void MRFI_RxOn(void); +void MRFI_RxIdle(void); +int8_t MRFI_Rssi(void); +void MRFI_SetLogicalChannel(uint8_t); +uint8_t MRFI_SetRxAddrFilter(uint8_t *); +void MRFI_EnableRxAddrFilter(void); +void MRFI_DisableRxAddrFilter(void); +void MRFI_Sleep(void); +void MRFI_WakeUp(void); +uint8_t MRFI_RandomByte(void); +void MRFI_DelayMs(uint16_t); +void MRFI_ReplyDelay(void); +void MRFI_PostKillSem(void); +void MRFI_SetRFPwr(uint8_t); + +/* ------------------------------------------------------------------------------------------------ + * Global Constants + * ------------------------------------------------------------------------------------------------ + */ +extern const uint8_t mrfiBroadcastAddr[]; + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/mrfi_defs.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/mrfi_defs.h new file mode 100755 index 0000000..2e1c546 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/mrfi_defs.h @@ -0,0 +1,226 @@ +/************************************************************************************************** + Revised: $Date: 2009-01-13 16:32:00 -0700 (Wed, 13 Jan 2009) $ + Revision: $Revision: 18768 $ + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Definition and abstraction for radio targets. + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ +#ifndef MRFI_DEFS_H +#define MRFI_DEFS_H + + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "bsp.h" + + +/* ------------------------------------------------------------------------------------------------ + * Common Defines + * ------------------------------------------------------------------------------------------------ + */ +#define MRFI_CCA_RETRIES 4 + +#define MRFI_ASSERT(x) BSP_ASSERT(x) +#define MRFI_FORCE_ASSERT() BSP_FORCE_ASSERT() +#define MRFI_ASSERTS_ARE_ON BSP_ASSERTS_ARE_ON + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family Assigment + * ------------------------------------------------------------------------------------------------ + */ + +/* ------ Radio Family 1 ------ */ +#if (defined MRFI_CC1100) /* Sub 1 GHz RF Transceiver */ || \ + (defined MRFI_CC1101) /* Sub 1 GHz RF Transceiver */ || \ + (defined MRFI_CC1100E_470) /* Sub 1 GHz RF Transceiver (CC1100E Asia) */ || \ + (defined MRFI_CC1100E_950) /* Sub 1 GHz RF Transceiver (CC1100E Asia) */ || \ + (defined MRFI_CC2500) /* 2.4 GHz RF Transceiver */ +#define MRFI_RADIO_FAMILY1 + +/* ------ Radio Family 2 ------ */ +#elif (defined MRFI_CC1110) /* Sub 1 GHz SoC */ || \ + (defined MRFI_CC1111) /* Sub 1 GHz SoC with USB controller */ || \ + (defined MRFI_CC2510) /* 2.4 GHz SoC */ || \ + (defined MRFI_CC2511) /* 2.4 GHz SoC with USB controller */ +#define MRFI_RADIO_FAMILY2 + +/* ------ Radio Family 3 ------ */ +#elif (defined MRFI_CC2420) /* 2.4 GHz IEEE 802.15.4 RF Transceiver */ || \ + (defined MRFI_CC2520) /* 2.4 GHz IEEE 802.15.4 RF Transceiver */ + +#define MRFI_RADIO_FAMILY3 + +/* ------ Radio Family 4 ------ */ +#elif (defined MRFI_CC2430) /* 2.4 GHz IEEE 802.15.4 SoC */ || \ + (defined MRFI_CC2431) /* 2.4 GHz IEEE 802.15.4 SoC */ +#define MRFI_RADIO_FAMILY4 + +/* ------ Radio Family 5 ------ */ +#elif (defined MRFI_CC430) /* Sub 1 GHz MSP SoC */ +#define MRFI_RADIO_FAMILY5 + +/* ------ Radio Family 6 ------ */ +#elif (defined MRFI_CC2530) /* 2.4 GHz IEEE 802.15.4 SoC */ + +#define MRFI_RADIO_FAMILY6 + +#else +#error "ERROR: Unknown or missing radio selection." +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family 1 / Radio Family 2 / Radio Family 5 + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_RADIO_FAMILY1) || (defined MRFI_RADIO_FAMILY2) || (defined MRFI_RADIO_FAMILY5) + +#define __mrfi_LENGTH_FIELD_SIZE__ 1 +#define __mrfi_ADDR_SIZE__ 4 +#define __mrfi_MAX_PAYLOAD_SIZE__ 20 + +#define __mrfi_RX_METRICS_SIZE__ 2 +#define __mrfi_RX_METRICS_RSSI_OFS__ 0 +#define __mrfi_RX_METRICS_CRC_LQI_OFS__ 1 +#define __mrfi_RX_METRICS_CRC_OK_MASK__ 0x80 +#define __mrfi_RX_METRICS_LQI_MASK__ 0x7F + +#define __mrfi_NUM_LOGICAL_CHANS__ 4 +#define __mrfi_NUM_POWER_SETTINGS__ 3 + +#define __mrfi_BACKOFF_PERIOD_USECS__ 250 + +#define __mrfi_LENGTH_FIELD_OFS__ 0 +#define __mrfi_DST_ADDR_OFS__ (__mrfi_LENGTH_FIELD_OFS__ + __mrfi_LENGTH_FIELD_SIZE__) +#define __mrfi_SRC_ADDR_OFS__ (__mrfi_DST_ADDR_OFS__ + __mrfi_ADDR_SIZE__) +#define __mrfi_PAYLOAD_OFS__ (__mrfi_SRC_ADDR_OFS__ + __mrfi_ADDR_SIZE__) + +#define __mrfi_HEADER_SIZE__ (2 * __mrfi_ADDR_SIZE__) +#define __mrfi_FRAME_OVERHEAD_SIZE__ (__mrfi_LENGTH_FIELD_SIZE__ + __mrfi_HEADER_SIZE__) + +#define __mrfi_GET_PAYLOAD_LEN__(p) ((p)->frame[__mrfi_LENGTH_FIELD_OFS__] - __mrfi_HEADER_SIZE__) +#define __mrfi_SET_PAYLOAD_LEN__(p,x) st( (p)->frame[__mrfi_LENGTH_FIELD_OFS__] = x + __mrfi_HEADER_SIZE__; ) + +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family 3 / Radio Family 4 / Radio Family 6 + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_RADIO_FAMILY3) || (defined MRFI_RADIO_FAMILY4) || (defined MRFI_RADIO_FAMILY6) + +#define __mrfi_LENGTH_FIELD_SIZE__ 1 +#define __mrfi_FCF_SIZE__ 2 +#define __mrfi_DSN_SIZE__ 1 +#define __mrfi_ADDR_SIZE__ 4 +#define __mrfi_MAX_PAYLOAD_SIZE__ 20 + +#define __mrfi_RX_METRICS_SIZE__ 2 +#define __mrfi_RX_METRICS_RSSI_OFS__ 0 +#define __mrfi_RX_METRICS_CRC_LQI_OFS__ 1 +#define __mrfi_RX_METRICS_CRC_OK_MASK__ 0x80 +#define __mrfi_RX_METRICS_LQI_MASK__ 0x7F + +#define __mrfi_NUM_LOGICAL_CHANS__ 4 +#define __mrfi_NUM_POWER_SETTINGS__ 3 + +#define __mrfi_BACKOFF_PERIOD_USECS__ 250 + +#define __mrfi_LENGTH_FIELD_OFS__ 0 +#define __mrfi_FCF_OFS__ (__mrfi_LENGTH_FIELD_OFS__ + __mrfi_LENGTH_FIELD_SIZE__) +#define __mrfi_DSN_OFS__ (__mrfi_FCF_OFS__ + __mrfi_FCF_SIZE__) +#define __mrfi_DST_ADDR_OFS__ (__mrfi_DSN_OFS__ + __mrfi_DSN_SIZE__) +#define __mrfi_SRC_ADDR_OFS__ (__mrfi_DST_ADDR_OFS__ + __mrfi_ADDR_SIZE__) +#define __mrfi_PAYLOAD_OFS__ (__mrfi_SRC_ADDR_OFS__ + __mrfi_ADDR_SIZE__) + +#define __mrfi_HEADER_SIZE__ ((2 * __mrfi_ADDR_SIZE__) + __mrfi_FCF_SIZE__ + __mrfi_DSN_SIZE__) +#define __mrfi_FRAME_OVERHEAD_SIZE__ (__mrfi_LENGTH_FIELD_SIZE__ + __mrfi_HEADER_SIZE__) + +#define __mrfi_GET_PAYLOAD_LEN__(p) ((p)->frame[__mrfi_LENGTH_FIELD_OFS__] - __mrfi_HEADER_SIZE__) +#define __mrfi_SET_PAYLOAD_LEN__(p,x) st( (p)->frame[__mrfi_LENGTH_FIELD_OFS__] = x + __mrfi_HEADER_SIZE__; ) + +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Family Commonality + * ------------------------------------------------------------------------------------------------ + */ +#define __mrfi_P_DST_ADDR__(p) (&((p)->frame[__mrfi_DST_ADDR_OFS__])) +#define __mrfi_P_SRC_ADDR__(p) (&((p)->frame[__mrfi_SRC_ADDR_OFS__])) +#define __mrfi_P_PAYLOAD__(p) (&((p)->frame[__mrfi_PAYLOAD_OFS__])) + + +/* ************************************************************************************************ + * Compile Time Integrity Checks + * ************************************************************************************************ + */ + +/* verify that only one supported radio is selected */ +#define MRFI_NUM_SUPPORTED_RADIOS_SELECTED ((defined MRFI_CC1100) + \ + (defined MRFI_CC1101) + \ + (defined MRFI_CC1110) + \ + (defined MRFI_CC1111) + \ + (defined MRFI_CC1100E_470) + \ + (defined MRFI_CC1100E_950) + \ + (defined MRFI_CC2500) + \ + (defined MRFI_CC2510) + \ + (defined MRFI_CC2511) + \ + (defined MRFI_CC2430) + \ + (defined MRFI_CC2431) + \ + (defined MRFI_CC2520) + \ + (defined MRFI_CC430) + \ + (defined MRFI_CC2530)) +#if (MRFI_NUM_SUPPORTED_RADIOS_SELECTED == 0) +#error "ERROR: A valid radio is not selected." +#elif (MRFI_NUM_SUPPORTED_RADIOS_SELECTED > 1) +#error "ERROR: More than one radio is selected." +#endif + +/* verify that a radio family is selected */ +#if (!defined MRFI_RADIO_FAMILY1) && \ + (!defined MRFI_RADIO_FAMILY2) && \ + (!defined MRFI_RADIO_FAMILY3) && \ + (!defined MRFI_RADIO_FAMILY4) && \ + (!defined MRFI_RADIO_FAMILY5) && \ + (!defined MRFI_RADIO_FAMILY6) +#error "ERROR: A radio family has not been assigned." +#endif + + +/************************************************************************************************** + */ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/radios/common/mrfi_f1f2.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/radios/common/mrfi_f1f2.c new file mode 100755 index 0000000..5c8c30e --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/radios/common/mrfi_f1f2.c @@ -0,0 +1,491 @@ +/************************************************************************************************** + Revised: $Date: 2007-07-06 11:19:00 -0700 (Fri, 06 Jul 2007) $ + Revision: $Revision: 13579 $ + + Copyright 2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS? WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/* ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + * MRFI (Minimal RF Interface) + * Shared code between Radio Family 1 & Family 2 + * ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= + */ + +/* ------------------------------------------------------------------------------------------------ + * Includes + * ------------------------------------------------------------------------------------------------ + */ +#include "mrfi.h" +#include "mrfi_defs.h" +#include "mrfi_f1f2.h" +#include "bsp.h" +#include "bsp_macros.h" + + +/* ------------------------------------------------------------------------------------------------ + * Common + * ------------------------------------------------------------------------------------------------ + */ + +/* Packet automation control - base value is power up value whick has APPEND_STATUS enabled; no CRC autoflush */ +#define PKTCTRL1_BASE_VALUE BV(2) +#define PKTCTRL1_ADDR_FILTER_OFF PKTCTRL1_BASE_VALUE +#define PKTCTRL1_ADDR_FILTER_ON (PKTCTRL1_BASE_VALUE | (BV(0)|BV(1))) + +#ifdef MRFI_ASSERTS_ARE_ON +#define RX_FILTER_ADDR_INITIAL_VALUE 0xFF +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Radio Abstraction + * ------------------------------------------------------------------------------------------------ + */ + +/* ----- Radio Family 1 ----- */ +#if (defined MRFI_RADIO_FAMILY1) +#include "../family1/mrfi_spi.h" +#define MRFI_WRITE_REGISTER(x,y) mrfiSpiWriteReg( x, y ) + +/* ----- Radio Family 2 ----- */ +#elif (defined MRFI_RADIO_FAMILY2) +#define MRFI_WRITE_REGISTER(x,y) st( x = y; ) + +/* unknown or missing radio family */ +#else +#error "ERROR: Expected radio family not specified. Most likely a project issue." +#endif + + +/* ------------------------------------------------------------------------------------------------ + * Global Constants + * ------------------------------------------------------------------------------------------------ + */ +const uint8_t mrfiBroadcastAddr[] = { 0xFF, 0xFF, 0xFF, 0xFF }; + +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(MRFI_ADDR_SIZE == ((sizeof(mrfiBroadcastAddr)/sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0]))); + + +/* ------------------------------------------------------------------------------------------------ + * Local Constants + * ------------------------------------------------------------------------------------------------ + */ + +/* + * Logical channel table - this table translates logical channel into + * actual radio channel number. Channel 0, the default channel, is + * determined by the channel exported from SmartRF Studio. The other + * table entries are derived from that default. Each derived channel is + * masked with 0xFF to prevent generation of an illegal channel number. + * + * This table is easily customized. Just replace or add entries as needed. + * If the number of entries changes, the corresponding #define must also + * be adjusted. It is located in mrfi_defs.h and is called __mrfi_NUM_LOGICAL_CHANS__. + * The static assert below ensures that there is no mismatch. + */ +#if defined( MRFI_CC2500 ) || defined( MRFI_CC2510 ) || defined( MRFI_CC2511 ) +static const uint8_t mrfiLogicalChanTable[] = +{ + SMARTRF_SETTING_CHANNR, + 103, + 202, + 212 +}; +#elif defined( MRFI_CC1100 ) || defined( MRFI_CC1101 ) || defined( MRFI_CC1110 ) || defined( MRFI_CC1111 ) +//static const uint8_t mrfiLogicalChanTable[] = +//{ +// SMARTRF_SETTING_CHANNR, +// 50, +// 80, +// 110 +//}; +// [BM] Changed channel settings to comply with local regulations +static const uint8_t mrfiLogicalChanTable[] = +{ +#ifdef ISM_EU + 0, +#else + #ifdef ISM_US + 20, + #else + #ifdef ISM_LF + 0, + #else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" + #endif + #endif +#endif + 50, + 80, + 110 +}; +#elif defined(MRFI_CC1100E_470) +static const uint8_t mrfiLogicalChanTable[] = +{ + SMARTRF_SETTING_CHANNR, + 40, + 60, + 80 +}; +#elif defined(MRFI_CC1100E_950) +static const uint8_t mrfiLogicalChanTable[] = +{ + SMARTRF_SETTING_CHANNR, + 10, + 15, + 20 +}; +#else +#error "ERROR: A valid radio is not specified." +#endif + +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(__mrfi_NUM_LOGICAL_CHANS__ == ((sizeof(mrfiLogicalChanTable)/sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0]))); + +/* + * RF Power setting table - this table translates logical power value + * to radio register setting. The logical power value is used directly + * as an index into the power setting table. The values in the table are + * from low to high. The default settings set 3 values: -20 dBm, -10 dBm, + * and 0 dBm. The default at startup is the highest value. Note that these + * are approximate depending on the radio. Information is taken from the + * data sheet. + * + * This table is easily customized. Just replace or add entries as needed. + * If the number of entries changes, the corresponding #define must also + * be adjusted. It is located in mrfi_defs.h and is called __mrfi_NUM_POWER_SETTINGS__. + * The static assert below ensures that there is no mismatch. + */ +#if defined( MRFI_CC2500 ) +static const uint8_t mrfiRFPowerTable[] = +{ + 0x46, + 0x97, + 0xFE +}; + +#elif defined( MRFI_CC2510 ) || defined( MRFI_CC2511 ) +static const uint8_t mrfiRFPowerTable[] = +{ + 0xC1, + 0xCB, + 0xFE +}; + +#elif defined( MRFI_CC1100 ) +static const uint8_t mrfiRFPowerTable[] = +{ + 0x0D, + 0x34, + 0x8E +}; + +#elif defined( MRFI_CC1101 ) +static const uint8_t mrfiRFPowerTable[] = +{ + 0x0F, + 0x27, + 0x50 +}; + +#elif defined( MRFI_CC1110 ) || defined( MRFI_CC1111 ) +//static const uint8_t mrfiRFPowerTable[] = +//{ +// 0x0E, +// 0x27, +// 0x50 +//}; +// [BM] Increase output power from -0.3dBm to +1.4dBm (433MHz) / +1.1dBm (868MHz) / +1.3dBm (915MHz) to compensate antenna loss +static const uint8_t mrfiRFPowerTable[] = +{ + 0x0E, + 0x27, +#ifdef ISM_EU + 0x8C, +#else + #ifdef ISM_US + 0x8B, + #else + #ifdef ISM_LF + 0x8D, + #else + #error "Wrong ISM band specified (valid are ISM_EU and ISM_US)" + #endif + #endif +#endif +}; +#elif defined(MRFI_CC1100E_470) +static const uint8_t mrfiRFPowerTable[] = +{ + 0x0E, + 0x34, + 0x60 +}; +#elif defined(MRFI_CC1100E_950) +static const uint8_t mrfiRFPowerTable[] = +{ + 0x0E, + 0x27, + 0x8E +}; +#endif + +/* verify number of table entries matches the corresponding #define */ +BSP_STATIC_ASSERT(__mrfi_NUM_POWER_SETTINGS__ == ((sizeof(mrfiRFPowerTable)/sizeof(mrfiRFPowerTable[0])) * sizeof(mrfiRFPowerTable[0]))); + + +/* ------------------------------------------------------------------------------------------------ + * Local Variables + * ------------------------------------------------------------------------------------------------ + */ +static uint8_t mrfiRxFilterEnabled=0; +static uint8_t mrfiRxFilterAddr[MRFI_ADDR_SIZE] = { RX_FILTER_ADDR_INITIAL_VALUE }; + + +/************************************************************************************************** + * @fn MRFI_SetLogicalChannel + * + * @brief Set logical channel. + * + * @param chan - logical channel number + * + * @return none + ************************************************************************************************** + */ +void MRFI_SetLogicalChannel(uint8_t chan) +{ + /* logical channel is not valid? */ + MRFI_ASSERT( chan < MRFI_NUM_LOGICAL_CHANS ); + + /* make sure radio is off before changing channels */ + Mrfi_RxModeOff(); + + MRFI_WRITE_REGISTER( CHANNR, mrfiLogicalChanTable[chan] ); + + /* turn radio back on if it was on before channel change */ + if(mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOn(); + } +} + +/************************************************************************************************** + * @fn MRFI_SetRFPwr + * + * @brief Set RF Output power level. + * + * @param idx - index into power table. + * + * @return none + ************************************************************************************************** + */ +void MRFI_SetRFPwr(uint8_t idx) +{ + /* is power level specified valid? */ + MRFI_ASSERT( idx < MRFI_NUM_POWER_SETTINGS ); + + /* make sure radio is off before changing power levels */ + Mrfi_RxModeOff(); + + MRFI_WRITE_REGISTER( PA_TABLE0, mrfiRFPowerTable[idx] ); + + /* turn radio back on if it was on before power level change */ + if(mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOn(); + } +} + +/************************************************************************************************** + * @fn MRFI_SetRxAddrFilter + * + * @brief Set the address used for filtering received packets. + * + * @param pAddr - pointer to address to use for filtering + * + * @return zero : successfully set filter address + * non-zero : illegal address + ************************************************************************************************** + */ +uint8_t MRFI_SetRxAddrFilter(uint8_t * pAddr) +{ + /* + * If first byte of filter address match fir byte of broadcast address, + * there is a conflict with hardware filtering. + */ + if (pAddr[0] == mrfiBroadcastAddr[0]) + { + /* unable to set filter address */ + return( 1 ); + } + + /* + * Set the hardware address register. The hardware address filtering only recognizes + * a single byte but this does provide at least some automatic hardware filtering. + */ + MRFI_WRITE_REGISTER( ADDR, pAddr[0] ); + + /* save a copy of the filter address */ + { + uint8_t i; + + for (i=0; i +#include "mrfi.h" +#include "bsp.h" +#include "bsp_macros.h" +#include "mrfi_defs.h" +#include "../common/mrfi_f1f2.h" +#include "bsp_external/mrfi_board_defs.h" + +/* ------------------------------------------------------------------------------------------------ + * Defines + * ------------------------------------------------------------------------------------------------ + */ +#if (defined MRFI_CC2510) || (defined MRFI_CC2511) + + #define MRFI_RSSI_OFFSET 71 /* for 250 kbsp. no units */ + + /* Worst case wait period in RX state before RSSI becomes valid. + * These numbers are from Design Note DN505 with added safety margin. + */ + #define MRFI_RSSI_VALID_DELAY_US 1000 + +#elif (defined MRFI_CC1110) || (defined MRFI_CC1111) + + #define MRFI_RSSI_OFFSET 73 /* for 433MHz @ 250 kbsp. no units */ + + /* Worst case wait period in RX state before RSSI becomes valid. + * These numbers are from Design Note DN505 with added safety margin. + */ + #define MRFI_RSSI_VALID_DELAY_US 1300 + +#else + #error "ERROR: RSSI Offset value not defined for this radio. +#endif + + +#define MRFI_LENGTH_FIELD_OFS __mrfi_LENGTH_FIELD_OFS__ +#define MRFI_LENGTH_FIELD_SIZE __mrfi_LENGTH_FIELD_SIZE__ +#define MRFI_HEADER_SIZE __mrfi_HEADER_SIZE__ +#define MRFI_FRAME_BODY_OFS __mrfi_DST_ADDR_OFS__ +#define MRFI_BACKOFF_PERIOD_USECS __mrfi_BACKOFF_PERIOD_USECS__ + +#define MRFI_MIN_SMPL_FRAME_SIZE (MRFI_HEADER_SIZE + NWK_HDR_SIZE) + +/* Max time we can be in a critical section within the delay function. + * This could be fine-tuned by observing the overhead is calling the bsp delay + * function. The overhead should be very small compared to this value. + * Note that the max value for this must be less than 19 usec with the + * default CLKCON.TICKSPD and CLKCON.CLOCKSPD settings and external 26 MHz + * crystal as a clock source (which we use). The CCxx11 USB uses a 48 MHz + * crystal to support USB divided down to 24 MHz for radio. This gives a + * maximum of 21 usec per chunk for these radios. + * + * Be careful of direct calls to Mrfi_DelayUsec(). + */ +#define MRFI_MAX_DELAY_US 16 /* usec */ + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Radio Definitions + * - - - - - - - - - - + */ + +#if (defined MRFI_CC1110) || (defined MRFI_CC1111) +#define MRFI_SETTING_PA_TABLE0 0x8E +#define MRFI_RADIO_PARTNUM 0x01 +#define MRFI_RADIO_MIN_VERSION 3 + +#elif (defined MRFI_CC2510) || (defined MRFI_CC2511) +#define MRFI_SETTING_PA_TABLE0 0xFE +#define MRFI_RADIO_PARTNUM 0x81 +#define MRFI_RADIO_MIN_VERSION 4 + +#else +#error "ERROR: Unspecified or unsupported radio." +#endif + +/* bit of PARTNUM register that signifies chip has USB capability */ +#define MRFI_RADIO_PARTNUM_USB_BIT 0x10 + +/* rx metrics definitions, known as appended "packet status bytes" in datasheet parlance */ +#define MRFI_RX_METRICS_CRC_OK_MASK __mrfi_RX_METRICS_CRC_OK_MASK__ +#define MRFI_RX_METRICS_LQI_MASK __mrfi_RX_METRICS_LQI_MASK__ + +/* register RFST - command strobes */ +#define SFSTXON 0x00 +#define SCAL 0x01 +#define SRX 0x02 +#define STX 0x03 +#define SIDLE 0x04 + +/* register MARCSTATE - state values */ +#define RXTX_SWITCH 0x15 +#define RX 0x0D +#define IDLE 0x01 + +/* register IEN2 - bit definitions */ +#define RFIE BV(0) + +/* register S1CON - bit definitions */ +#define RFIF_1 BV(1) +#define RFIF_0 BV(0) + +/* register DMAARM - bit definitions */ +#define ABORT BV(7) + +/* register CLKCON - bit definitions */ +#define OSC BV(6) + +/* register SLEEP - bit definitions */ +#define XOSC_STB BV(6) +#define OSC_PD BV(2) + +/* register RFIF - bit definitions */ +#define IRQ_DONE BV(4) +#define IRQ_RXOVFL BV(6) + +/* register RFIM - bit definitions */ +#define IM_DONE BV(4) + +/* register PKTSTATUS - bit definitions */ +#define MRFI_PKTSTATUS_CCA BV(4) +#define MRFI_PKTSTATUS_CS BV(6) + +/* random number generator */ +#define RCTRL_CLOCK_LFSR BV(2) + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Radio Register Settings + * - - - - - - - - - - - - - + */ + +/* Main Radio Control State Machine control configuration - Calibrate when going from IDLE to RX or TX. */ +#define MRFI_SETTING_MCSM0 0x14 + +/* Main Radio Control State Machine control configuration - Go to RX state after RX + * and go to IDLE after TX. + */ +#define MRFI_SETTING_MCSM1 0x3C + +/* + * Packet Length - Setting for maximum allowed packet length. + * The PKTLEN setting does not include the length field but maximum frame size does. + * Subtract length field size from maximum frame size to get value for PKTLEN. + */ +#define MRFI_SETTING_PKTLEN (MRFI_MAX_FRAME_SIZE - MRFI_LENGTH_FIELD_SIZE) + +/* Packet automation control - Original value except WHITE_DATA is extracted from SmartRF setting. */ +#define MRFI_SETTING_PKTCTRL0 (0x05 | (SMARTRF_SETTING_PKTCTRL0 & BV(6))) + +/* Packet automation control - base value is power up value whick has APPEND_STATUS enabled */ +#define MRFI_SETTING_PKTCTRL1_BASE BV(2) +#define MRFI_SETTING_PKTCTRL1_ADDR_FILTER_OFF MRFI_SETTING_PKTCTRL1_BASE +#define MRFI_SETTING_PKTCTRL1_ADDR_FILTER_ON (MRFI_SETTING_PKTCTRL1_BASE | (BV(1)|BV(0))) + +/* early versions of SmartRF Studio did not export this value */ +#ifndef SMARTRF_SETTING_FSCAL1 +#define SMARTRF_SETTING_FSCAL1 0x80 +#endif + +/* TEST0 Various Test Settings - the VCO_SEL_CAL_EN bit must be zero */ +#define MRFI_SETTING_TEST0 (SMARTRF_SETTING_TEST0 & ~(BV(1))) + +/* if SmartRF setting for PA_TABLE0 is supplied, use that instead of built-in default */ +#ifdef SMARTRF_SETTING_PA_TABLE0 +#undef MRFI_SETTING_PA_TABLE0 +#define MRFI_SETTING_PA_TABLE0 SMARTRF_SETTING_PA_TABLE0 +#endif + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * DMA Configuration Values + * - - - - - - - - - - - - - - + */ + +/* DMA channel number */ +#define MRFI_DMA_CHAN 0 + +/* DMA configuration data structure size */ +#define RXTX_DMA_STRUCT_SIZE 8 + +/* byte offset 4 (upper bits of LEN are never used so are always set to zero) */ +#define RXTX_DMA_VLEN_XFER_BYTES_PLUS_1 ((/* VLEN = */( 1 ))<<5) +#define RXTX_DMA_VLEN_XFER_BYTES_PLUS_3 ((/* VLEN = */( 4 ))<<5) + +/* byte offset 5 */ +#define RXTX_DMA_LEN (MRFI_MAX_FRAME_SIZE + MRFI_RX_METRICS_SIZE) + +/* byte offset 6 */ +#define RXTX_DMA_WORDSIZE (/* WORDSIZE = */( 0 ) << 7) +#define RXTX_DMA_TMODE (/* TMODE = */( 0 ) << 5) +#define RXTX_DMA_TRIG (/* TRIG = */( 19 ) << 0) + +/* byte offset 7 */ +#define RXTX_DMA_SRCINC_PLUS_1 (/* SRCINC = */( 1 ) << 6) +#define RXTX_DMA_SRCINC_NONE (/* SRCINC = */( 0 ) << 6) +#define RXTX_DMA_DESTINC_PLUS_1 (/* DESTINC = */( 1 ) << 4) +#define RXTX_DMA_DESTINC_NONE (/* DESTINC = */( 0 ) << 4) +#define RXTX_DMA_IRQMASK (/* IRQMASK = */( 0 ) << 3) +#define RXTX_DMA_M8 (/* M8 = */( 0 ) << 2) +#define RXTX_DMA_PRIORITY (/* PRIORITY = */( 1 ) << 0) + + /* The SW timer is calibrated by adjusting the call to the microsecond delay + * routine. This allows maximum calibration control with repects to the longer + * times requested by applicationsd and decouples internal from external calls + * to the microsecond routine which can be calibrated independently. + */ +#if defined(SW_TIMER) +#define APP_USEC_VALUE 100 +#else +#define APP_USEC_VALUE 500 +#endif + +/* ------------------------------------------------------------------------------------------------ + * Macros + * ------------------------------------------------------------------------------------------------ + */ +#define HIGH_BYTE_OF_WORD(x) ((uint8_t) (((uint16_t)(x)) >> 8)) +#define LOW_BYTE_OF_WORD(x) ((uint8_t) (((uint16_t)(x)) & 0xFF)) + + + +/* There is no bit in h/w to tell if RSSI in the register is valid or not. + * The hardware needs to be in RX state for a certain amount of time before + * a valid RSSI value is calculated and placed in the register. This min + * wait time is defined by MRFI_BOARD_RSSI_VALID_DELAY_US. We don't need to + * add such delay every time RSSI value is needed. If the Carier Sense signal + * is high or CCA signal is high, we know that the RSSI value must be valid. + * We use that knowledge to reduce our wait time. We break down the delay loop + * in multiple chunks and during each iteration, check for the CS and CCA + * signal. If either of these signals is high, we return immediately. Else, + * we wait for the max delay specified. + */ +#define MRFI_RSSI_VALID_WAIT() \ +{ \ + int16_t delay = MRFI_RSSI_VALID_DELAY_US; \ + do \ + { \ + if(PKTSTATUS & (MRFI_PKTSTATUS_CCA | MRFI_PKTSTATUS_CS)) \ + { \ + break; \ + } \ + Mrfi_DelayUsec(64); /* sleep */ \ + delay -= 64; \ + }while(delay > 0); \ +} \ + +#define MRFI_STROBE_IDLE_AND_WAIT() \ +{ \ + RFST = SIDLE; \ + while (MARCSTATE != IDLE) ; \ +} + +/* ------------------------------------------------------------------------------------------------ + * Local Prototypes + * ------------------------------------------------------------------------------------------------ + */ +static void Mrfi_RxModeOn(void); +static void Mrfi_RxModeOff(void); +static void Mrfi_DelayUsec(uint16_t); +static void Mrfi_RandomBackoffDelay(void); +static int8_t Mrfi_CalculateRssi(uint8_t); +static void Mrfi_DelayUsecSem(uint16_t); +// [BM] Need this prototype declaration due to strict prototyping turned on +void MRFI_RfIsr(void); + +/* ------------------------------------------------------------------------------------------------ + * Local Variables + * ------------------------------------------------------------------------------------------------ + */ +static uint8_t mrfiRadioState = MRFI_RADIO_STATE_UNKNOWN; +static mrfiPacket_t mrfiIncomingPacket; + +/* reply delay support */ +static volatile uint8_t sKillSem = 0; +static volatile uint8_t sReplyDelayContext = 0; +static uint16_t sReplyDelayScalar = 0; +static uint16_t sBackoffHelper = 0; + +#if (MRFI_DMA_CHAN == 0) +uint8_t XDATA mrfiDmaCfg[RXTX_DMA_STRUCT_SIZE]; +#define MRFI_DMA_CFG_ADDRESS &mrfiDmaCfg[0] +#endif + +// [BM] Frequency offset set during calibration +extern uint8_t frequoffset; + +/************************************************************************************************** + * @fn MRFI_Init + * + * @brief Initialize MRFI. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_Init(void) +{ + /* ------------------------------------------------------------------ + * Run-time integrity checks + * --------------------------- + */ + + memset(&mrfiIncomingPacket, 0x0, sizeof(mrfiIncomingPacket)); + /* verify the correct radio is installed */ + MRFI_ASSERT( (PARTNUM & ~MRFI_RADIO_PARTNUM_USB_BIT) == MRFI_RADIO_PARTNUM ); + MRFI_ASSERT( VERSION >= MRFI_RADIO_MIN_VERSION ); /* obsolete radio version */ + + + /* ------------------------------------------------------------------ + * Switch to high speed crystal oscillator. + * ------------------------------------------ + */ + + /* power up both oscillators - high speed crystal oscillator will power up, + * the RC oscillator will remain powered-up and selected. + */ + SLEEP &= ~OSC_PD; + + /* wait for high speed crystal to become stable */ + while(!(SLEEP & XOSC_STB)); + + /* switch from RC oscillator to high speed crystal oscillator */ + CLKCON &= ~OSC; + + /* power down the oscillator not selected, i.e. the RC oscillator */ + SLEEP |= OSC_PD; + + /* ------------------------------------------------------------------ + * Variable Initialization + * ------------------------- + */ + + + /* ------------------------------------------------------------------ + * DMA Initialization + * -------------------- + */ +#if (MRFI_DMA_CHAN == 0) + DMA0CFGH = HIGH_BYTE_OF_WORD( &mrfiDmaCfg[0] ); + DMA0CFGL = LOW_BYTE_OF_WORD ( &mrfiDmaCfg[0] ); +#endif + + + /* ------------------------------------------------------------------ + * Configure radio + * ----------------- + */ + + /* internal radio register configuration */ + MCSM1 = MRFI_SETTING_MCSM1; + MCSM0 = MRFI_SETTING_MCSM0; + PKTLEN = MRFI_SETTING_PKTLEN; + PKTCTRL0 = MRFI_SETTING_PKTCTRL0; + PA_TABLE0 = MRFI_SETTING_PA_TABLE0; + TEST0 = MRFI_SETTING_TEST0; + + /* imported SmartRF radio register configuration */ + FSCTRL1 = SMARTRF_SETTING_FSCTRL1; + //FSCTRL0 = SMARTRF_SETTING_FSCTRL0; + // [BM] Fine-tune synthesizer with global calibration value + FSCTRL0 = frequoffset; + FREQ2 = SMARTRF_SETTING_FREQ2; + FREQ1 = SMARTRF_SETTING_FREQ1; + FREQ0 = SMARTRF_SETTING_FREQ0; + MDMCFG4 = SMARTRF_SETTING_MDMCFG4; + MDMCFG3 = SMARTRF_SETTING_MDMCFG3; + MDMCFG2 = SMARTRF_SETTING_MDMCFG2; + MDMCFG1 = SMARTRF_SETTING_MDMCFG1; + MDMCFG0 = SMARTRF_SETTING_MDMCFG0; + DEVIATN = SMARTRF_SETTING_DEVIATN; + FOCCFG = SMARTRF_SETTING_FOCCFG; + BSCFG = SMARTRF_SETTING_BSCFG; + AGCCTRL2 = SMARTRF_SETTING_AGCCTRL2; + AGCCTRL1 = SMARTRF_SETTING_AGCCTRL1; + AGCCTRL0 = SMARTRF_SETTING_AGCCTRL0; + FREND1 = SMARTRF_SETTING_FREND1; + FREND0 = SMARTRF_SETTING_FREND0; + FSCAL3 = SMARTRF_SETTING_FSCAL3; + FSCAL2 = SMARTRF_SETTING_FSCAL2; + FSCAL1 = SMARTRF_SETTING_FSCAL1; + FSCAL0 = SMARTRF_SETTING_FSCAL0; + TEST2 = SMARTRF_SETTING_TEST2; + TEST1 = SMARTRF_SETTING_TEST1; + + + /* Initial radio state is IDLE state */ + mrfiRadioState = MRFI_RADIO_STATE_IDLE; + + /* set default channel */ + MRFI_SetLogicalChannel( 0 ); + + /* Seed for the Random Number Generator */ + { + uint16_t rndSeed = 0x0; + + /* Put radio in RX mode */ + RFST = SRX; + + /* Delay for valid RSSI. Otherwise same RSSI + * value could be read every time. + */ + MRFI_RSSI_VALID_WAIT(); + + { + uint8_t i; + for(i=0; i<16; i++) + { + /* use most random bit of RSSI to populate the random seed */ + rndSeed = (rndSeed << 1) | (RSSI & 0x01); + } + } + + /* Force the seed to be non-zero by setting one bit, just in case... */ + rndSeed |= 0x0080; + + /* Need to write to RNDL twice to seed it */ + RNDL = rndSeed & 0xFF; + RNDL = rndSeed >> 8; + + /* Call RxModeOff() instead of an idle strobe. + * This will clean up any flags that were set while radio was in rx state. + */ + Mrfi_RxModeOff(); + } + + + /***************************************************************************************** + * Compute reply delay scalar + * + * Formula from data sheet for all the narrow band radios is: + * + * (256 + DATAR_Mantissa) * 2^(DATAR_Exponent) + * DATA_RATE = ------------------------------------------ * f(xosc) + * 2^28 + * + * To try and keep some accuracy we change the exponent of the denominator + * to (28 - (exponent from the configuration register)) so we do a division + * by a smaller number. We find the power of 2 by shifting. + * + * The maximum delay needed depends on the MAX_APP_PAYLOAD parameter. Figure + * out how many bits that will be when overhead is included. Bits/bits-per-second + * is seconds to transmit (or receive) the maximum frame. We multiply this number + * by 1000 to find the time in milliseconds. We then additionally multiply by + * 10 so we can add 5 and divide by 10 later, thus rounding up to the number of + * milliseconds. This last won't matter for slow transmissions but for faster ones + * we want to err on the side of being conservative and making sure the radio is on + * to receive the reply. The semaphore monitor will shut it down. The delay adds in + * a platform fudge factor that includes processing time on peer plus lags in Rx and + * processing time on receiver's side. Also includes round trip delays from CCA + * retries. This portion is included in PLATFORM_FACTOR_CONSTANT defined in mrfi.h. + * + * Note: We assume a 26 MHz oscillator frequency for the non-USB target radios + * and 24 MHz for the USB-target radios. + * *************************************************************************************** + */ +#if defined(MRFI_CC2510) || defined(MRFI_CC1110) +#define MRFI_RADIO_OSC_FREQ 26000000 +#elif defined(MRFI_CC2511) || defined(MRFI_CC1111) +#define MRFI_RADIO_OSC_FREQ 24000000 +#endif + +#define PHY_PREAMBLE_SYNC_BYTES 8 + + { + uint32_t dataRate, bits; + uint16_t exponent, mantissa; + + /* mantissa is in MDMCFG3 */ + mantissa = 256 + SMARTRF_SETTING_MDMCFG3; + + /* exponent is lower nibble of MDMCFG4. */ + exponent = 28 - (SMARTRF_SETTING_MDMCFG4 & 0x0F); + + /* we can now get data rate */ + dataRate = mantissa * (MRFI_RADIO_OSC_FREQ>>exponent); + + bits = ((uint32_t)((PHY_PREAMBLE_SYNC_BYTES + MRFI_MAX_FRAME_SIZE)*8))*10000; + + /* processing on the peer + the Tx/Rx time plus more */ + sReplyDelayScalar = PLATFORM_FACTOR_CONSTANT + (((bits/dataRate)+5)/10); + + /* This helper value is used to scale the backoffs during CCA. At very + * low data rates we need to backoff longer to prevent continual sampling + * of valid frames which take longer to send at lower rates. Use the scalar + * we just calculated divided by 32. With the backoff algorithm backing + * off up to 16 periods this will result in waiting up to about 1/2 the total + * scalar value. For high data rates this does not contribute at all. Value + * is in microseconds. + */ + sBackoffHelper = MRFI_BACKOFF_PERIOD_USECS + (sReplyDelayScalar>>5)*1000; + } + + /* ------------------------------------------------------------------ + * Configure interrupts + * ---------------------- + */ + + /* enable general RF interrupts */ + IEN2 |= RFIE; + + /* enable global interrupts */ + BSP_ENABLE_INTERRUPTS(); +} + + +/************************************************************************************************** + * @fn MRFI_Transmit + * + * @brief Transmit a packet using CCA algorithm. + * + * @param pPacket - pointer to packet to transmit + * + * @return Return code indicates success or failure of transmit: + * MRFI_TX_RESULT_SUCCESS - transmit succeeded + * MRFI_TX_RESULT_FAILED - transmit failed because CCA failed + ************************************************************************************************** + */ +uint8_t MRFI_Transmit(mrfiPacket_t * pPacket, uint8_t txType) +{ + uint8_t ccaRetries; + uint8_t returnValue = MRFI_TX_RESULT_SUCCESS; + + /* radio must be awake to transmit */ + MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF ); + + /* Turn off reciever. We can ignore/drop incoming packets during transmit. */ + Mrfi_RxModeOff(); + + /* configure DMA channel for transmit */ + { + uint8_t XDATA * pCfg; + + pCfg = MRFI_DMA_CFG_ADDRESS; + *pCfg++ = /* offset 0 : */ HIGH_BYTE_OF_WORD( &(pPacket->frame[0]) ); /* SRCADDRH */ + *pCfg++ = /* offset 1 : */ LOW_BYTE_OF_WORD ( &(pPacket->frame[0]) ); /* SRCADDRL */ + *pCfg++ = /* offset 2 : */ HIGH_BYTE_OF_WORD( &X_RFD ); /* DSTADDRH */ + *pCfg++ = /* offset 3 : */ LOW_BYTE_OF_WORD ( &X_RFD ); /* DSTADDRL */ + *pCfg++ = /* offset 4 : */ RXTX_DMA_VLEN_XFER_BYTES_PLUS_1; + *pCfg++ = /* offset 5 : */ RXTX_DMA_LEN; + *pCfg++ = /* offset 6 : */ RXTX_DMA_WORDSIZE | RXTX_DMA_TMODE | RXTX_DMA_TRIG; + *pCfg = /* offset 7 : */ RXTX_DMA_SRCINC_PLUS_1 | RXTX_DMA_DESTINC_NONE | + RXTX_DMA_IRQMASK | RXTX_DMA_M8 | RXTX_DMA_PRIORITY; + } + + /* ------------------------------------------------------------------ + * Immediate transmit + * --------------------- + */ + if (txType == MRFI_TX_TYPE_FORCED) + { + /* ARM the DMA channel */ + DMAARM |= BV( MRFI_DMA_CHAN ); + + /* Strobe TX */ + RFST = STX; + + /* wait for transmit to complete */ + while (!(RFIF & IRQ_DONE)); + + /* Clear the interrupt flag */ + RFIF &= ~IRQ_DONE; + } + else + { + /* ------------------------------------------------------------------ + * CCA transmit + * --------------- + */ + + MRFI_ASSERT( txType == MRFI_TX_TYPE_CCA ); + + /* set number of CCA retries */ + ccaRetries = MRFI_CCA_RETRIES; + + /* =============================================================================== + * CCA Loop + * ============= + */ + while(1) + { + /* ARM the DMA channel */ + DMAARM |= BV( MRFI_DMA_CHAN ); + + /* strobe to enter receive mode */ + RFST = SRX; + + /* Wait for radio to enter the RX mode */ + while(MARCSTATE != RX); + + /* wait for the rssi to be valid. */ + MRFI_RSSI_VALID_WAIT(); + + /* Strobe TX-if-CCA */ + RFST = STX; + + if(MARCSTATE != RX) /* ck if exited rx state */ + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment passed. + * ---------------------------------- + */ + + /* wait for transmit to complete */ + while (!(RFIF & IRQ_DONE)); + + /* Clear the interrupt flag */ + RFIF &= ~IRQ_DONE; + + break; + } + else + { + /* ------------------------------------------------------------------ + * Clear Channel Assessment failed. + * ---------------------------------- + */ + + /* Retry ? */ + if (ccaRetries != 0) + { + /* turn off reciever to conserve power during backoff */ + Mrfi_RxModeOff(); + + /* delay for a random number of backoffs */ + Mrfi_RandomBackoffDelay(); + + /* decrement CCA retries before loop continues */ + ccaRetries--; + } + else /* No CCA retries are left, abort */ + { + /* set return value for failed transmit and break */ + returnValue = MRFI_TX_RESULT_FAILED; + break; + } + } /* CCA Failed */ + } /* CCA loop */ + }/* txType is CCA */ + + + /* Done with TX. Clean up time... */ + + /* turn radio back off to put it in a known state */ + Mrfi_RxModeOff(); + + /* If the radio was in RX state when transmit was attempted, + * put it back in RX state. + */ + if(mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOn(); + } + + return( returnValue ); +} + + +/************************************************************************************************** + * @fn MRFI_Receive + * + * @brief Copies last packet received to the location specified. + * This function is meant to be called after the ISR informs + * higher level code that there is a newly received packet. + * + * @param pPacket - pointer to location of where to copy received packet + * + * @return none + ************************************************************************************************** + */ +void MRFI_Receive(mrfiPacket_t * pPacket) +{ + *pPacket = mrfiIncomingPacket; +} + + +/************************************************************************************************** + * @fn MRFI_RfIsr + * + * @brief - + * + * @param none + * + * @return none + ************************************************************************************************** + */ +// [BM] Function is called from application RF_VECTOR ISR +//BSP_ISR_FUNCTION( MRFI_RfIsr, RF_VECTOR ) +void MRFI_RfIsr(void) +{ + uint8_t frameLen; + + /* We should receive this interrupt only in RX state + * Should never receive it if RX was turned On only for + * some internal mrfi processing like - during CCA. + * Otherwise something is terribly wrong. + */ + MRFI_ASSERT( mrfiRadioState == MRFI_RADIO_STATE_RX ); + + /* Check for overflow */ + if ((RFIF & IRQ_DONE) && (RFIF & IRQ_RXOVFL)) + { + RFIF &= ~IRQ_DONE; + RFIF &= ~IRQ_RXOVFL; + S1CON &= ~(RFIF_1 | RFIF_0); /* Clear MCU interrupt flag */ + + /* Only way out of this is to go to IDLE state */ + Mrfi_RxModeOff(); + + /* zero-out MRFI buffer to help NWK eliminate undetected rogue frames if they pass here */ + memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame)); + + /* OK to start again... */ + Mrfi_RxModeOn(); + + return; + } + + RFIF &= ~IRQ_DONE; /* Clear the interrupt at the source */ + S1CON &= ~(RFIF_1 | RFIF_0); /* Clear MCU interrupt flag */ + + /* ------------------------------------------------------------------ + * Copy RX Metrics into packet structure + * --------------------------------------- + */ + { + uint8_t offsetToRxMetrics = mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFS] + 1; + /* The metrics were DMA'd so they may reside on the frame buffer rather than the + * metrics buffer. Get them to the proper location. + */ + memmove(mrfiIncomingPacket.rxMetrics,&mrfiIncomingPacket.frame[offsetToRxMetrics], sizeof(mrfiIncomingPacket.rxMetrics)); + } + + + /* ------------------------------------------------------------------ + * CRC and frame length check + * ------------ + */ + + frameLen = mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFS]; + /* determine if CRC or length check failed */ + if (!(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & MRFI_RX_METRICS_CRC_OK_MASK) || + ((frameLen + MRFI_LENGTH_FIELD_SIZE) > MRFI_MAX_FRAME_SIZE) || + (frameLen < MRFI_MIN_SMPL_FRAME_SIZE) + ) + { + /* CRC or length check failed - do nothing, skip to end */ + } + else + { + /* CRC passed - continue processing */ + + /* ------------------------------------------------------------------ + * Filtering + * ----------- + */ + + /* if address is not filtered, receive is successful */ + if (!MRFI_RxAddrIsFiltered(MRFI_P_DST_ADDR(&mrfiIncomingPacket))) + { + { + /* ------------------------------------------------------------------ + * Receive successful + * -------------------- + */ + + /* Convert the raw RSSI value and do offset compensation for this radio */ + mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS] = + Mrfi_CalculateRssi(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS]); + + /* Remove the CRC valid bit from the LQI byte */ + mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] = + (mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & MRFI_RX_METRICS_LQI_MASK); + + + /* call external, higher level "receive complete" processing routine */ + MRFI_RxCompleteISR(); + } + } + } + + /* zero-out MRFI buffer to help NWK eliminate undetected rogue frames if they pass here */ + memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame)); + + /* arm DMA channel for next receive */ + DMAARM |= BV( MRFI_DMA_CHAN ); +} + + +/************************************************************************************************** + * @fn MRFI_Sleep + * + * @brief Request radio go to sleep. + * + * @param none + * + * @return zero : if successfully went to sleep + * non-zero : if sleep was not entered + ************************************************************************************************** + */ +void MRFI_Sleep(void) +{ + /* If radio is not asleep, put it to sleep */ + if(mrfiRadioState != MRFI_RADIO_STATE_OFF) + { + bspIState_t s; + + /* critical section necessary for watertight testing and setting of state variables */ + BSP_ENTER_CRITICAL_SECTION(s); + + /* go to idle so radio is in a known state before sleeping */ + MRFI_RxIdle(); + + /* There is no individual power control to the RF block on this radio. + * So putting it to Idle is the best we can do. + */ + + /* Our new state is OFF */ + mrfiRadioState = MRFI_RADIO_STATE_OFF; + + BSP_EXIT_CRITICAL_SECTION(s); + } +} + + +/************************************************************************************************** + * @fn MRFI_WakeUp + * + * @brief Wake up radio from sleep state. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_WakeUp(void) +{ + /* verify high speed crystal oscillator is selected, required for radio operation */ + MRFI_ASSERT( !(CLKCON & OSC) ); + + /* if radio is already awake, just ignore wakeup request */ + if(mrfiRadioState != MRFI_RADIO_STATE_OFF) + { + return; + } + + /* restore radio registers that are reset during sleep */ + FSCAL3 = SMARTRF_SETTING_FSCAL3; + FSCAL2 = SMARTRF_SETTING_FSCAL2; + FSCAL1 = SMARTRF_SETTING_FSCAL1; + + /* enter idle mode */ + mrfiRadioState = MRFI_RADIO_STATE_IDLE; + MRFI_STROBE_IDLE_AND_WAIT(); +} + +/************************************************************************************************** + * @fn MRFI_RandomByte + * + * @brief Returns a random byte + * + * @param none + * + * @return a random byte + ************************************************************************************************** + */ +uint8_t MRFI_RandomByte(void) +{ + /* clock the random generator once to get a new random value */ + ADCCON1 |= RCTRL_CLOCK_LFSR; + + return RNDL; +} + + + +/************************************************************************************************** + * @fn Mrfi_RxModeOn + * + * @brief Put radio into receive mode. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Mrfi_RxModeOn(void) +{ + uint8_t XDATA * pCfg; + + /* configure DMA channel for receive */ + pCfg = MRFI_DMA_CFG_ADDRESS; + *pCfg++ = /* offset 0 : */ HIGH_BYTE_OF_WORD( &X_RFD ); /* SRCADDRH */ + *pCfg++ = /* offset 1 : */ LOW_BYTE_OF_WORD ( &X_RFD ); /* SRCADDRL */ + *pCfg++ = /* offset 2 : */ HIGH_BYTE_OF_WORD( &(mrfiIncomingPacket.frame[0]) ); /* DSTADDRH */ + *pCfg++ = /* offset 3 : */ LOW_BYTE_OF_WORD ( &(mrfiIncomingPacket.frame[0]) ); /* DSTADDRL */ + *pCfg++ = /* offset 4 : */ RXTX_DMA_VLEN_XFER_BYTES_PLUS_3; + *pCfg++ = /* offset 5 : */ RXTX_DMA_LEN; + *pCfg++ = /* offset 6 : */ RXTX_DMA_WORDSIZE | RXTX_DMA_TMODE | RXTX_DMA_TRIG; + *pCfg = /* offset 7 : */ RXTX_DMA_SRCINC_NONE | RXTX_DMA_DESTINC_PLUS_1 | + RXTX_DMA_IRQMASK | RXTX_DMA_M8 | RXTX_DMA_PRIORITY; + + /* abort any DMA transfer that might be in progress */ + DMAARM = ABORT | BV( MRFI_DMA_CHAN ); + + /* clean out buffer to help protect against spurious frames */ + memset(mrfiIncomingPacket.frame, 0x00, sizeof(mrfiIncomingPacket.frame)); + + /* arm the dma channel for receive */ + DMAARM |= BV( MRFI_DMA_CHAN ); + + /* Clear interrupts */ + S1CON &= ~(RFIF_1 | RFIF_0); /* Clear MCU interrupt flag */ + RFIF &= ~IRQ_DONE; /* Clear the interrupt at the source */ + + /* send strobe to enter receive mode */ + RFST = SRX; + + /* enable "receive/transmit done" interrupts */ + RFIM |= IM_DONE; +} + +/************************************************************************************************** + * @fn MRFI_RxOn + * + * @brief Turn on the receiver. No harm is done if this function is called when + * receiver is already on. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_RxOn(void) +{ + /* radio must be awake before we can move it to RX state */ + MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF ); + + /* Put the radio in RX state, if not already */ + if(mrfiRadioState != MRFI_RADIO_STATE_RX) + { + mrfiRadioState = MRFI_RADIO_STATE_RX; + Mrfi_RxModeOn(); + } +} + +/************************************************************************************************** + * @fn Mrfi_RxModeOff + * + * @brief - + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Mrfi_RxModeOff(void) +{ + /*disable receive interrupts */ + RFIM &= ~IM_DONE; + + /* turn off radio */ + MRFI_STROBE_IDLE_AND_WAIT(); + + /* Abort any ongoing DMA transfer */ + DMAARM = ABORT | BV( MRFI_DMA_CHAN ); + + /* Clear any pending DMA interrupts */ + DMAIRQ &= ~BV(MRFI_DMA_CHAN); + + /* flush the receive FIFO of any residual data */ + /* no need for flush. only 1 byte deep fifo. */ + + /* clear receive interrupt */ + S1CON &= ~(RFIF_1 | RFIF_0); /* Clear MCU interrupt flag */ + RFIF &= ~IRQ_DONE; /* Clear the interrupt at the source */ +} + + +/************************************************************************************************** + * @fn MRFI_RxIdle + * + * @brief Put radio in idle mode (receiver if off). No harm is done this function is + * called when radio is already idle. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_RxIdle(void) +{ + /* radio must be awake to move it to idle mode */ + MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF ); + + /* if radio is on, turn it off */ + if(mrfiRadioState == MRFI_RADIO_STATE_RX) + { + Mrfi_RxModeOff(); + mrfiRadioState = MRFI_RADIO_STATE_IDLE; + } +} + +/**************************************************************************************************** + * @fn Mrfi_DelayUsec + * + * @brief Execute a delay loop using HW timer. The macro actually used to do the delay + * is not thread-safe. This routine makes the delay execution thread-safe by breaking + * up the requested delay into small chunks and executing each chunk as a critical + * section. The chunk size is choosen to be the smallest value used by MRFI. The delay + * is only approximate because of the overhead computations. It errs on the side of + * being too long. + * + * input parameters + * @param howLong - number of microseconds to delay + * + * @return none + **************************************************************************************************** + */ +void Mrfi_DelayUsec(uint16_t howLong) +{ + bspIState_t s; + uint16_t count = howLong/MRFI_MAX_DELAY_US; + + if (howLong) + { + do + { + BSP_ENTER_CRITICAL_SECTION(s); + BSP_DELAY_USECS(MRFI_MAX_DELAY_US); + BSP_EXIT_CRITICAL_SECTION(s); + } while (count--); + } + + return; +} + +/**************************************************************************************************** + * @fn Mrfi_DelayUsecSem + * + * @brief Execute a delay loop using a HW timer. See comments for Mrfi_DelayUsec(). + * Delay specified number of microseconds checking semaphore for + * early-out. Run in a separate thread when the reply delay is + * invoked. Cleaner then trying to make MRFI_DelayUsec() thread-safe + * and reentrant. + * + * input parameters + * @param howLong - number of microseconds to delay + * + * @return none + **************************************************************************************************** + */ +static void Mrfi_DelayUsecSem(uint16_t howLong) +{ + bspIState_t s; + uint16_t count = howLong/MRFI_MAX_DELAY_US; + + if (howLong) + { + do + { + BSP_ENTER_CRITICAL_SECTION(s); + BSP_DELAY_USECS(MRFI_MAX_DELAY_US); + BSP_EXIT_CRITICAL_SECTION(s); + if (sKillSem) + { + break; + } + } while (count--); + } + + return; +} + +/************************************************************************************************** + * @fn MRFI_DelayMs + * + * @brief Delay the specified number of milliseconds. + * + * @param milliseconds - delay time + * + * @return none + ************************************************************************************************** + */ +void MRFI_DelayMs(uint16_t milliseconds) +{ + while (milliseconds) + { + Mrfi_DelayUsec( APP_USEC_VALUE ); + milliseconds--; + } +} + +/************************************************************************************************** + * @fn MRFI_ReplyDelay + * + * @brief Delay number of milliseconds scaled by data rate. Check semaphore for + * early-out. Run in a separate thread when the reply delay is + * invoked. Cleaner then trying to make MRFI_DelayMs() thread-safe + * and reentrant. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_ReplyDelay() +{ + bspIState_t s; + uint16_t milliseconds = sReplyDelayScalar; + + BSP_ENTER_CRITICAL_SECTION(s); + sReplyDelayContext = 1; + BSP_EXIT_CRITICAL_SECTION(s); + + while (milliseconds) + { + Mrfi_DelayUsecSem( APP_USEC_VALUE ); + if (sKillSem) + { + break; + } + milliseconds--; + } + + BSP_ENTER_CRITICAL_SECTION(s); + sKillSem = 0; + sReplyDelayContext = 0; + BSP_EXIT_CRITICAL_SECTION(s); +} + +/************************************************************************************************** + * @fn MRFI_PostKillSem + * + * @brief Post to the loop-kill semaphore that will be checked by the iteration loops + * that control the delay thread. + * + * @param none + * + * @return none + ************************************************************************************************** + */ +void MRFI_PostKillSem(void) +{ + + if (sReplyDelayContext) + { + sKillSem = 1; + } + + return; +} + +/************************************************************************************************** + * @fn Mrfi_RandomBackoffDelay + * + * @brief - + * + * @param none + * + * @return none + ************************************************************************************************** + */ +static void Mrfi_RandomBackoffDelay(void) +{ + uint8_t backoffs; + uint8_t i; + + /* calculate random value for backoffs - 1 to 16 */ + backoffs = (MRFI_RandomByte() & 0x0F) + 1; + + /* delay for randomly computed number of backoff periods */ + for (i=0; i= 128) + { + rssi = (int16_t)(rawValue - 256)/2 - MRFI_RSSI_OFFSET; + } + else + { + rssi = (rawValue/2) - MRFI_RSSI_OFFSET; + } + + /* Restrict this value to least value can be held in an 8 bit signed int */ + if(rssi < -128) + { + rssi = -128; + } + + return rssi; +} + +/************************************************************************************************** + * @fn MRFI_GetRadioState + * + * @brief Returns the current radio state. + * + * @param none + * + * @return radio state - off/idle/rx + ************************************************************************************************** + */ +uint8_t MRFI_GetRadioState(void) +{ + return mrfiRadioState; +} + + +/************************************************************************************************** + * Compile Time Integrity Checks + ************************************************************************************************** + */ +#if (MRFI_DMA_CHAN != 0) +#error "ERROR: Code implementation requires use of DMA channel zero." +/* Using a channel other than zero is not difficult to implement. The hardware + * requires channels 1-4 to use a common configuration structure. For this module + * to use a channel other than zero, this data structure would need to be integrated + * with the external code. Hooks are provided to make this as easy as possible. + */ +#endif + + +#define MRFI_RADIO_TX_FIFO_SIZE 64 /* from datasheet */ + +/* verify largest possible packet fits within FIFO buffer */ +#if ((MRFI_MAX_FRAME_SIZE + MRFI_RX_METRICS_SIZE) > MRFI_RADIO_TX_FIFO_SIZE) +#error "ERROR: Maximum possible packet length exceeds FIFO buffer. Decrease value of maximum application payload." +#endif + +/* verify that the SmartRF file supplied is compatible */ +#if ((!defined SMARTRF_RADIO_CC2510) && \ + (!defined SMARTRF_RADIO_CC2511) && \ + (!defined SMARTRF_RADIO_CC1110) && \ + (!defined SMARTRF_RADIO_CC1111)) +#error "ERROR: The SmartRF export file is not compatible." +#endif + + +/************************************************************************************************** +*/ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/smartrf/CC1111/smartrf_CC1111.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/smartrf/CC1111/smartrf_CC1111.h new file mode 100755 index 0000000..310bb79 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/mrfi/smartrf/CC1111/smartrf_CC1111.h @@ -0,0 +1,126 @@ +/*************************************************************** + * SmartRF Studio(tm) Export + * + * Radio register settings specifed with C-code + * compatible #define statements. + * + ***************************************************************/ + +// [BM] Modified radio settings for 433MHz, 868MHz, 915MHz + +#ifndef SMARTRF_CC1111_H +#define SMARTRF_CC1111_H + +#define SMARTRF_RADIO_CC1111 + +// ISM_EU configuration +// +// Chipcon +// Product = CC1111 +// Chip version = D (VERSION = 0x03) +// X-tal frequency = 24 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 250.000000 kHz +// Deviation = 32 kHz +// Datarate = 76.721191 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 869.524658 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable packet length mode, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// Device address = 0 + +// ISM_US configuration +// +// Chipcon +// Product = CC1111 +// Chip version = D (VERSION = 0x03) +// X-tal frequency = 24 MHz +// RF output power = 0 dBm +// RX filterbandwidth = 250.000000 kHz +// Deviation = 32 kHz +// Datarate = 76.721191 kBaud +// Modulation = (1) GFSK +// Manchester enable = (0) Manchester disabled +// RF Frequency = 905.998901 MHz +// Channel spacing = 199.951172 kHz +// Channel number = 0 +// Optimization = - +// Sync mode = (3) 30/32 sync word bits detected +// Format of RX/TX data = (0) Normal mode +// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled +// Forward Error Correction = (0) FEC disabled +// Length configuration = (1) Variable packet length mode, packet length configured by the first received byte after sync word. +// Packetlength = 255 +// Preamble count = (2) 4 bytes +// Append status = 1 +// Address check = (0) No address check +// Device address = 0 + +#define SMARTRF_SETTING_FSCTRL1 0x09 +#define SMARTRF_SETTING_FSCTRL0 0x00 +#ifdef ISM_EU + #define SMARTRF_SETTING_FREQ2 0x24 + #define SMARTRF_SETTING_FREQ1 0x3A + #define SMARTRF_SETTING_FREQ0 0xEE +#else + #ifdef ISM_US + // 902MHz (CHANNR=20 --> 906MHz) + #define SMARTRF_SETTING_FREQ2 0x25 + #define SMARTRF_SETTING_FREQ1 0x95 + #define SMARTRF_SETTING_FREQ0 0x55 + // 912MHz (CHANNR=0) +// #define SMARTRF_SETTING_FREQ2 0x26 +// #define SMARTRF_SETTING_FREQ1 0x00 +// #define SMARTRF_SETTING_FREQ0 0x00 + #else + #ifdef ISM_LF + // 433.30MHz + #define SMARTRF_SETTING_FREQ2 0x12 + #define SMARTRF_SETTING_FREQ1 0x14 + #define SMARTRF_SETTING_FREQ0 0x7A + #else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" + #endif // ISM_LF + #endif // ISM_US +#endif // ISM_EU +#define SMARTRF_SETTING_MDMCFG4 0x6B +#define SMARTRF_SETTING_MDMCFG3 0xA3 +#define SMARTRF_SETTING_MDMCFG2 0x13 +#define SMARTRF_SETTING_MDMCFG1 0x23 +#define SMARTRF_SETTING_MDMCFG0 0x11 +#define SMARTRF_SETTING_CHANNR 0x00 +#define SMARTRF_SETTING_DEVIATN 0x43 +#define SMARTRF_SETTING_FREND1 0xB6 +#define SMARTRF_SETTING_FREND0 0x10 +#define SMARTRF_SETTING_MCSM0 0x18 +#define SMARTRF_SETTING_FOCCFG 0x1D +#define SMARTRF_SETTING_BSCFG 0x1C +#define SMARTRF_SETTING_AGCCTRL2 0xC7 +#define SMARTRF_SETTING_AGCCTRL1 0x00 +#define SMARTRF_SETTING_AGCCTRL0 0xB0 +#define SMARTRF_SETTING_FSCAL3 0xEA +#define SMARTRF_SETTING_FSCAL2 0x2A +#define SMARTRF_SETTING_FSCAL1 0x00 +#define SMARTRF_SETTING_FSCAL0 0x1F +#define SMARTRF_SETTING_TEST2 0x81 +#define SMARTRF_SETTING_TEST1 0x35 +#define SMARTRF_SETTING_TEST0 0x09 +#define SMARTRF_SETTING_PA_TABLE0 0x50 +#define SMARTRF_SETTING_PKTCTRL1 0x04 +#define SMARTRF_SETTING_PKTCTRL0 0x05 +#define SMARTRF_SETTING_ADDR 0x00 +#define SMARTRF_SETTING_PKTLEN 0xFF + +#endif // SMARTRF_CC1111_H + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk.c new file mode 100755 index 0000000..986ae46 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk.c @@ -0,0 +1,1069 @@ +/************************************************************************************************** + Filename: nwk.c + Revised: $Date: 2009-03-11 15:29:07 -0700 (Wed, 11 Mar 2009) $ + Revision: $Revision: 19382 $ + Author $Author: lfriedman $ + + Description: This file supports the SimpliciTI network layer. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "nwk_globals.h" +#include "nwk_QMgmt.h" + +/****************************************************************************** + * MACROS + */ +/************************* NETWORK MANIFEST CONSTANT SANITY CHECKS ****************************/ +#if !defined(ACCESS_POINT) && !defined(RANGE_EXTENDER) && !defined(END_DEVICE) +#error ERROR: No SimpliciTI device type defined +#endif + +#if defined(END_DEVICE) && !defined(RX_POLLS) +#define RX_USER +#endif + +#ifndef MAX_HOPS +#define MAX_HOPS 3 +#elif MAX_HOPS > 4 +#error ERROR: MAX_HOPS must be 4 or fewer +#endif + +#ifndef MAX_APP_PAYLOAD +#error ERROR: MAX_APP_PAYLOAD must be defined +#endif + +#if ( MAX_PAYLOAD < MAX_FREQ_APP_FRAME ) +#error ERROR: Application payload size too small for Frequency frame +#endif + +#if ( MAX_PAYLOAD < MAX_JOIN_APP_FRAME ) +#error ERROR: Application payload size too small for Join frame +#endif + +#if ( MAX_PAYLOAD < MAX_LINK_APP_FRAME ) +#error ERROR: Application payload size too small for Link frame +#endif + +#if ( MAX_PAYLOAD < MAX_MGMT_APP_FRAME ) +#error ERROR: Application payload size too small for Management frame +#endif + +#if ( MAX_PAYLOAD < MAX_SEC_APP_FRAME ) +#error ERROR: Application payload size too small for Security frame +#endif + +#if ( MAX_PAYLOAD < MAX_PING_APP_FRAME ) +#error ERROR: Application payload size too small for Ping frame +#endif + +#if NWK_FREQ_TBL_SIZE < 1 +#error ERROR: NWK_FREQ_TBL_SIZE must be > 0 +#endif + +/************************* END NETWORK MANIFEST CONSTANT SANITY CHECKS ************************/ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ +#define SYS_NUM_CONNECTIONS (NUM_CONNECTIONS+1) + +/* Increment this if the persistentContext_t structure is changed. It will help + * detect the upgrade context: any saved values will have a version with a + * lower number. + */ +#define CONNTABLEINFO_STRUCTURE_VERSION 1 + +#define SIZEOF_NV_OBJ sizeof(sPersistInfo) + +/****************************************************************************** + * TYPEDEFS + */ +/* This structure aggregates eveything necessary to save if we want to restore + * the connection information later. + */ +typedef struct +{ + const uint8_t structureVersion; /* to dectect upgrades... */ + uint8_t numConnections; /* count includes the UUD port/link ID */ +/* The next two are used to detect overlapping port assignments. When _sending_ a + * link frame the local port is assigned from the top down. When sending a _reply_ + * the assignment is bottom up. Overlapping assignments are rejected. That said it + * is extremely unlikely that this will ever happen. If it does the test implemented + * here is overly cautious (it will reject assignments when it needn't). But we leave + * it that way on the assumption that it will never happen anyway. + */ + uint8_t curNextLinkPort; + uint8_t curMaxReplyPort; + linkID_t nextLinkID; +#ifdef ACCESS_POINT + sfInfo_t sSandFContext; +#endif +/* Connection table entries last... */ + connInfo_t connStruct[SYS_NUM_CONNECTIONS]; +} persistentContext_t; + +/****************************************************************************** + * LOCAL VARIABLES + */ + +/* This will be overwritten if we restore the structure from NV for example. + * Note that restoring will not permit overwriting the version element as it + * is declared 'const'. + */ +static persistentContext_t sPersistInfo = {CONNTABLEINFO_STRUCTURE_VERSION}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static uint8_t map_lid2idx(linkID_t, uint8_t *); +static void initializeConnection(connInfo_t *); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_nwkInit + * + * @brief Initialize NWK conext. + * + * input parameters + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_nwkInit(uint8_t (*f)(linkID_t)) +{ + /* Truly ugly initialization because CCE won't initialize properly. Must + * skip first const element. Yuk. + */ + memset((((uint8_t *)&sPersistInfo)+1), 0x0, (sizeof(sPersistInfo)-1)); + /* OK. The zeroed elements are set. Now go back and do fixups... */ + + sPersistInfo.numConnections = SYS_NUM_CONNECTIONS; + sPersistInfo.curNextLinkPort = SMPL_PORT_USER_MAX; + sPersistInfo.curMaxReplyPort = PORT_BASE_NUMBER; + sPersistInfo.nextLinkID = 1; + + /* initialize globals */ + nwk_globalsInit(); + + /* initialize frame processing */ + nwk_frameInit(f); + + /* initialize queue manager */ + nwk_QInit(); + + /* initialize each network application. */ + nwk_freqInit(); + nwk_pingInit(); + nwk_joinInit(f); + nwk_mgmtInit(); + nwk_linkInit(); + nwk_securityInit(); + + /* set up the last connection as the broadcast port mapped to the broadcast Link ID */ + if (CONNSTATE_FREE == sPersistInfo.connStruct[NUM_CONNECTIONS].connState) + { + sPersistInfo.connStruct[NUM_CONNECTIONS].connState = CONNSTATE_CONNECTED; + sPersistInfo.connStruct[NUM_CONNECTIONS].hops2target = MAX_HOPS; + sPersistInfo.connStruct[NUM_CONNECTIONS].portRx = SMPL_PORT_USER_BCAST; + sPersistInfo.connStruct[NUM_CONNECTIONS].portTx = SMPL_PORT_USER_BCAST; + sPersistInfo.connStruct[NUM_CONNECTIONS].thisLinkID = SMPL_LINKID_USER_UUD; + /* set peer address to broadcast so it is used when Application sends to the broadcast Link ID */ + memcpy(sPersistInfo.connStruct[NUM_CONNECTIONS].peerAddr, nwk_getBCastAddress(), NET_ADDR_SIZE); + } + + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_getNextConnection + * + * @brief Return the next free connection structure if on is available. + * + * input parameters + * + * output parameters + * The returned structure has the Rx port number populated based on the + * free strucure found. This is the port queried when the app wants to + * do a receive. + * + * @return pointer to the new connInfo_t structure. NULL if there is + * no room in connection structure array. + */ +connInfo_t *nwk_getNextConnection() +{ + uint8_t i; + + for (i=0; iportTx = 0; + + pCInfo->connState = CONNSTATE_CONNECTED; + pCInfo->thisLinkID = *locLID; + + /* Generate the next Link ID. This isn't foolproof. If the count wraps + * we can end up with confusing duplicates. We can protect aginst using + * one that is already in use but we can't protect against a stale Link ID + * remembered by an application that doesn't know its connection has been + * torn down. The test for 0 will hopefully never be true (indicating a wrap). + */ + (*locLID)++; + + while (!*locLID || (*locLID == SMPL_LINKID_USER_UUD) || map_lid2idx(*locLID, &tmp)) + { + (*locLID)++; + } + + return; +} + + +/****************************************************************************** + * @fn nwk_freeConnection + * + * @brief Return the connection structure to the free pool. Currently + * this routine is only called when a link freame is sent and + * no reply is received so the freeing steps are pretty simple. + * But eventually this will be more complex so this place-holder + * is introduced. + * + * input parameters + * @param pCInfo - pointer to entry to be freed + * + * output parameters + * + * @return None. + */ +void nwk_freeConnection(connInfo_t *pCInfo) +{ +#if NUM_CONNECTIONS > 0 + pCInfo->connState = CONNSTATE_FREE; +#endif +} + +/****************************************************************************** + * @fn nwk_getConnInfo + * + * @brief Return the connection info structure to which the input Link ID maps. + * + * input parameters + * @param port - port for which mapping desired + * + * output parameters + * + * @return pointer to connInfo_t structure found. NULL if no mapping + * found or entry not valid. + */ +connInfo_t *nwk_getConnInfo(linkID_t linkID) +{ + uint8_t idx, rc; + + rc = map_lid2idx(linkID, &idx); + + return (rc && (CONNSTATE_CONNECTED == sPersistInfo.connStruct[idx].connState)) ? &sPersistInfo.connStruct[idx] : (connInfo_t *)0; +} + +/****************************************************************************** + * @fn nwk_isLinkDuplicate + * + * @brief Help determine if the link has already been established.. Defense + * against duplicate link frames. This file owns the data structure + * so the comparison is done here. + * + * input parameters + * @param addr - pointer to address of linker in question + * @param remotePort - remote port number provided by linker + * + * output parameters + * + * @return Returns pointer to connection entry if the address and remote Port + * match an existing entry, otherwise 0. + */ +connInfo_t *nwk_isLinkDuplicate(uint8_t *addr, uint8_t remotePort) +{ +#if NUM_CONNECTIONS > 0 + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + if (!(memcmp(ptr->peerAddr, addr, NET_ADDR_SIZE)) && + (ptr->portTx == remotePort)) + { + return ptr; + } + } + } +#endif + + return (connInfo_t *)NULL; +} + +/****************************************************************************** + * @fn nwk_findAddressMatch + * + * @brief Used to look for an address match in the Connection table. + * Match is based on source address in frame. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns non-zero if a match is found, otherwise 0. + */ +uint8_t nwk_findAddressMatch(mrfiPacket_t *frame) +{ +#if NUM_CONNECTIONS > 0 + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + if (!(memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + return 1; + } + } + } +#endif + + return 0; +} + +#ifdef ACCESS_POINT +/****************************************************************************** + * @fn nwk_getSFInfoPtr + * + * @brief Get pointer to store-and-forward information object kept in the + * NV object aggregate. + * + * input parameters + * + * output parameters + * + * @return Returns pointer to the store-nad-forward object. + */ +sfInfo_t *nwk_getSFInfoPtr(void) +{ + return &sPersistInfo.sSandFContext; +} + +#if defined(AP_IS_DATA_HUB) +/*************************************************************************************** + * @fn nwk_saveJoinedDevice + * + * @brief Save the address of a joining device on the Connection Table expecting + * a Link frame to follow. Only for when AP is a data hub. We want to + * use the space already allocated for a connection able entry instead + * of having redundant arrays for alread-joined devices in the data hub + * case. + * + * input parameters + * @param frame - pointer to frame containing address or joining device. + * + * output parameters + * + * @return Returns non-zero if this is a new device and it is saved. Returns + * 0 if device already there or there is no room in the Connection + * Table. + */ +uint8_t nwk_saveJoinedDevice(mrfiPacket_t *frame) +{ + uint8_t i; + connInfo_t *avail = 0; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState == CONNSTATE_CONNECTED) || (ptr->connState == CONNSTATE_JOINED)) + { + if (!memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + return 0; + } + } + else + { + avail = ptr; + } + } + + if (!avail) + { + return 0; + } + + avail->connState = CONNSTATE_JOINED; + memcpy(avail->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + return 1; +} + +/*********************************************************************************** + * @fn nwk_findAlreadyJoined + * + * @brief Used when AP is a data hub to look for an address match in the + * Connection table for a device that is already enterd in the joined + * state. This means that the Connection Table resource is already + * allocated so the link-listen doesn't have to do it again. Match is + * based on source address in frame. Thsi shoudl only be called from + * the Link-listen context during the link frame reply. + * + * If found the Connection Table entry is initialized as if it were + * found using the nwk_getNextConnection() method. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns pointer to Connection Table entry if match is found, otherwise + * 0. This call will only fail if the Connection Table was full when the + * device tried to join initially. + */ +connInfo_t *nwk_findAlreadyJoined(mrfiPacket_t *frame) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + /* Is this it? */ + if (!(memcmp(&ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + /* Yes. Initilize tabel entry and return the pointer. */ + initializeConnection(ptr); + return ptr; + } + } + } + + /* Nothing found... */ + return (connInfo_t *)NULL; +} +#endif /* AP_IS_DATA_HUB */ +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_checkConnInfo + * + * @brief Do a sanity/validity check on the connection info + * + * input parameters + * @param ptr - pointer to a valid connection info structure to validate + * @param which - Tx or Rx port checked + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_checkConnInfo(connInfo_t *ptr, uint8_t which) +{ + uint8_t port; + + /* make sure port isn't null and that the entry is active */ + port = (CHK_RX == which) ? ptr->portRx : ptr->portTx; + if (!port || (CONNSTATE_FREE == ptr->connState)) + { + return SMPL_BAD_PARAM; + } + + /* validate port number */ + if (port < PORT_BASE_NUMBER) + { + return SMPL_BAD_PARAM; + } + + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_isConnectionValid + * + * @brief Do a sanity/validity check on the frame target address by + * validating frame against connection info + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * @param lid - link ID of found connection + * + * @return 0 if connection specified in frame is not valid, otherwise non-zero. + */ +uint8_t nwk_isConnectionValid(mrfiPacket_t *frame, linkID_t *lid) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + uint8_t port = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_PORT_OS); + + for (i=0; iconnState) + { + /* check port first since we're done if the port is the user bcast port. */ + if (port == ptr->portRx) + { + /* yep...ports match. */ + if ((SMPL_PORT_USER_BCAST == port) || !(memcmp(ptr->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE))) + { + uint8_t rc = 1; + + /* we're done. */ + *lid = ptr->thisLinkID; +#ifdef APP_AUTO_ACK + /* can't ack the broadcast port... */ + if (!(SMPL_PORT_USER_BCAST == port)) + { + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_ACK_REQ)) + { + /* Ack requested. Send ack now */ + nwk_sendAckReply(frame, ptr->portTx); + } + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_ACK_RPLY)) + { + /* This is a reply. Signal that it was received by resetting the + * saved transaction ID in the connection object if they match. The + * main thread is polling this value. The setting here is in the + * Rx ISR thread. + */ + if (ptr->ackTID == GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS)) + { + ptr->ackTID = 0; + } + /* This causes the frame to be dropped. All ack frames are + * dropped. + */ + rc = 0; + } + } +#endif /* APP_AUTO_ACK */ + /* Unconditionally kill the reply delay semaphore. This used to be done + * unconditionally in the calling routine. + */ + MRFI_PostKillSem(); + return rc; + } + } + } + } + + /* no matches */ + return 0; +} + +/****************************************************************************** + * @fn nwk_allocateLocalRxPort + * + * @brief Allocate a local port on which to receive frames from a peer. + * + * Allocation differs depending on whether the allocation is for + * a link reply frame or a link frame. In the former case we + * know the address of the peer so we can ensure allocating a + * unique port number for that address. The same port number can be + * used mulitple times for distinct peers. Allocations are done from + * the bottom of the namespace upward. + * + * If allocation is for a link frame we do not yet know the peer + * address so we must ensure the port number is unique now. + * Allocations are done from the top of the namespace downward. + * + * The two allocation methods track the extreme values used in each + * case to detect overlap, i.e., exhausted namespace. This can only + * happen if the number of connections supported is greater than the + * total namespace available. + * + * input parameters + * @param which - Sending a link frame or a link reply frame + * @param newPtr - pointer to connection info structure to be populated + * + * output parameters + * @param newPtr->portRx - element is populated with port number. + * + * @return Non-zero if port number assigned. 0 if no port available. + */ +uint8_t nwk_allocateLocalRxPort(uint8_t which, connInfo_t *newPtr) +{ +#if NUM_CONNECTIONS > 0 + uint8_t num, i; + uint8_t marker[NUM_CONNECTIONS]; + connInfo_t *ptr = sPersistInfo.connStruct; + + memset(&marker, 0x0, sizeof(marker)); + + for (i=0; iconnState) && (ptr->portRx <= SMPL_PORT_USER_MAX)) + { + if (LINK_SEND == which) + { + if (ptr->portRx > sPersistInfo.curNextLinkPort) + { + marker[SMPL_PORT_USER_MAX - ptr->portRx] = 1; + } + } + else if (!memcmp(ptr->peerAddr, newPtr->peerAddr, NET_ADDR_SIZE)) + { + marker[ptr->portRx - PORT_BASE_NUMBER] = 1; + } + } + } + + num = 0; + for (i=0; i sPersistInfo.curMaxReplyPort) + { + /* remember maximum port number used */ + sPersistInfo.curMaxReplyPort = num; + } + } + else + { + /* the port number we need has already been used in the other context. It may or + * may not have been used for the same address but we don't bother to check...we + * just reject the asignment. This is the overly cautious part but is extermely + * unlikely to ever occur. + */ + num = 0; + } + } + else + { + /* if the number we have doesn't overlap the assignment of ports used + * for sending link frame replies, use it. + */ + if (num >= sPersistInfo.curMaxReplyPort) + { + if (num == sPersistInfo.curNextLinkPort) + { + sPersistInfo.curNextLinkPort--; + } + } + else + { + /* the port number we need has already been used in the other context. It may or + * may not have been used for the same address but we don't bother to check...we + * just reject the asignment. This is the overly cautious part but is extermely + * unlikely to ever occur. + */ + num = 0; + } + } + + newPtr->portRx = num; + + return num; +#else + return 0; +#endif /* NUM_CONNECTIONS > 0 */ + +} + +/******************************************************************************* + * @fn nwk_isValidReply + * + * @brief Examine a frame to see if it is a valid reply when compared with + * expected parameters. + * + * input parameters + * @param frame - pointer to frmae being examined + * @param tid - expected transaction ID in application payload + * @param infoOffset - offset to payload information containing reply hint + * @param tidOffset - offset to transaction ID in payload + * + * output parameters + * + * @return reply category: + * SMPL_NOT_REPLY: not a reply + * SMPL_MY_REPLY : a reply that matches input parameters + * SMPL_A_REPLY : a reply but does not match input parameters + */ +uint8_t nwk_isValidReply(mrfiPacket_t *frame, uint8_t tid, uint8_t infoOffset, uint8_t tidOffset) +{ + uint8_t rc = SMPL_NOT_REPLY; + + if ((*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+infoOffset) & NWK_APP_REPLY_BIT)) + { + if ((*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+tidOffset) == tid) && + !memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + rc = SMPL_MY_REPLY; + } + else + { + rc = SMPL_A_REPLY; + } + } + + return rc; +} + +/****************************************************************************** + * @fn map_lid2idx + * + * @brief Map link ID to index into connection table. + * + * input parameters + * @param lid - Link ID to be matched + * + * output parameters + * @param idx - populated with index into connection table + * + * @return Non-zero if Link ID found and output is valid else 0. + */ +static uint8_t map_lid2idx(linkID_t lid, uint8_t *idx) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) && (ptr->thisLinkID == lid)) + { + *idx = i; + return 1; + } + } + + return 0; +} + +/****************************************************************************** + * @fn nwk_findPeer + * + * @brief Find connection entry for a peer + * + * input parameters + * @param peerAddr - address of peer + * @param peerPort - port on which this device was sending to peer. + * + * output parameters + * + * @return Pointer to matching connection table entry else 0. + */ +connInfo_t *nwk_findPeer(addr_t *peerAddr, uint8_t peerPort) +{ + uint8_t i; + connInfo_t *ptr = sPersistInfo.connStruct; + + for (i=0; iconnState) + { + if (!memcmp(peerAddr, ptr->peerAddr, NET_ADDR_SIZE)) + { + if (peerPort == ptr->portTx) + { + return ptr; + } + } + } + } + + return (connInfo_t *)NULL; +} + +/****************************************************************************** + * @fn nwk_checkAppMsgTID + * + * @brief Compare received TID to last-seen TID to decide whether the + * received message is a duplicate or we missed some. + * + * input parameters + * @param lastTID - last-seen TID + * @param appMsgTID - TID from current application payload. + * + * output parameters + * + * @return Returns zero if message with supplied TID should be discarded. + * Otherwise returns non-zero. In this case the message should be + * processed. The last-seen TID should be updated with the current + * application payload TID. + * + */ +uint8_t nwk_checkAppMsgTID(appPTid_t lastTID, appPTid_t appMsgTID) +{ + uint8_t rc = 0; + + /* If the values are equal this is a duplicate. We're done. */ + if (lastTID != appMsgTID) + { + /* Is the new TID bigger? */ + if (appMsgTID > lastTID) + { + /* In this case the current payload is OK unless we've received a late + * (duplicate) message that occurred just before the TID wrapped. This is + * considered a duplicate and we should discard it. + */ + if (!(DUP_TID_AFTER_WRAP(lastTID, appMsgTID))) + { + rc = 1; + } + } + else + { + /* New TID is smaller. Accept the payload if this is the wrap case or we missed + * the specific wrap frame but are still within the range in which we assume + * we missed it. Otherwise is a genuine late frame so we should ignore it. + */ + if (CHECK_TID_WRAP(lastTID, appMsgTID)) + { + rc = 1; + } + } + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_getNumObjectFromMsg + * + * @brief Get a numeric object from a message buffer. Take care of + * alignment and endianess issues. + * + * input parameters + * @param src - pointer to object location in message buffer + * @param objSize - size of numeric object + * + * output parameters + * @param dest - pointer to numeric type variable receiving the object + * contains aligned number in correct endian order on return. + * + * @return void. There is no warning if there is no case for the supplied + * object size. A simple copy is then done. Alignment is + * guaranteed only for object size cases defined (and + * vacuously size 1). + * + */ +void nwk_getNumObjectFromMsg(void *src, void *dest, uint8_t objSize) +{ + /* Take care of alignment */ + memmove(dest, src, objSize); + + /* Take care of endianess */ + switch(objSize) + { + case 2: + *((uint16_t *)dest) = ntohs(*((uint16_t *)dest)); + break; + + case 4: + *((uint32_t *)dest) = ntohl(*((uint32_t *)dest)); + break; + } + + return; +} + +/****************************************************************************** + * @fn nwk_putNumObjectIntoMsg + * + * @brief Put a numeric object into a message buffer. Take care of + * alignment and endianess issues. + * + * input parameters + * @param src - pointer to numeric type variable providing the object + * @param objSize - size of numeric object. Fuction works for object size 1. + * + * output parameters + * @param dest - pointer to object location in message buffer where the + * correct endian order representation will be placed. + * + * @return void. There is no warning if there is no case for the supplied + * object size. A simple copy is then done. + * + */ +void nwk_putNumObjectIntoMsg(void *src, void *dest, uint8_t objSize) +{ + + uint8_t *ptr; + uint16_t u16; + uint32_t u32; + + /* Take care of endianess */ + switch(objSize) + { + case 1: + ptr = (uint8_t *)src; + break; + + case 2: + u16 = htons(*((uint16_t *)src)); + ptr = (uint8_t *)&u16; + break; + + case 4: + u32 = htonl(*((uint32_t *)src)); + ptr = (uint8_t *)&u32; + break; + + default: + ptr = (uint8_t *)src; + break; + } + + /* Take care of alignment */ + memmove(dest, ptr, objSize); + + return; +} +/****************************************************************************** + * @fn nwk_NVObj + * + * @brief GET and SET support for NV object (connection context). + * + * input parameters + * @param action - GET or SET + * @param val - (GET/SET) pointer to NV IOCTL object. + * (SET) NV length and version values to be used for sanity + * checks. + * + * output parameters + * @param val - (GET) Version number of NV object, size of NV object and + * pointer to the connection context memory. + * - (SET) Pointer to the connection context memory. + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Object version or size do not conform on a SET call + * or illegal action specified. + */ +smplStatus_t nwk_NVObj(ioctlAction_t action, ioctlNVObj_t *val) +{ +#ifdef NVOBJECT_SUPPORT + smplStatus_t rc = SMPL_SUCCESS; + + if (IOCTL_ACT_GET == action) + { + /* Populate helper objects */ + val->objLen = SIZEOF_NV_OBJ; + val->objVersion = sPersistInfo.structureVersion; + /* Set pointer to connection context if address of pointer is not null */ + if (val->objPtr) + { + *(val->objPtr) = (uint8_t *)&sPersistInfo; + } + } + else + { + rc = SMPL_BAD_PARAM; + } + + return rc; +#else /* NVOBJECT_SUPPORT */ + return SMPL_BAD_PARAM; +#endif +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk.h new file mode 100755 index 0000000..6009f38 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk.h @@ -0,0 +1,159 @@ +/************************************************************************************************** + Filename: nwk.h + Revised: $Date: 2008-12-01 11:58:33 -0800 (Mon, 01 Dec 2008) $ + Revision: $Revision: 18551 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI network layer. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_H +#define NWK_H + + +/* well known ports*/ +#define SMPL_PORT_PING 0x01 +#define SMPL_PORT_LINK 0x02 +#define SMPL_PORT_JOIN 0x03 +#define SMPL_PORT_SECURITY 0x04 +#define SMPL_PORT_FREQ 0x05 +#define SMPL_PORT_MGMT 0x06 + +#define SMPL_PORT_NWK_BCAST 0x1F +#define SMPL_PORT_USER_BCAST 0x3F + +/* Unconnected User Datagram Link ID */ +#define SMPL_LINKID_USER_UUD ((linkID_t) ~0) + +#define PORT_BASE_NUMBER 0x20 + +/* Reserve the top of the User port namespace below the broadcast + * address for static allocation. + */ +#define PORT_USER_STATIC_NUM 1 +#define SMPL_PORT_STATIC_MAX 0x3E +#define SMPL_PORT_USER_MAX (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM) + + +/* to check connection info sanity */ +#define CHK_RX 0 +#define CHK_TX 1 + +/* return types for validating a reply frame */ +#define SMPL_MY_REPLY 0 +#define SMPL_A_REPLY 1 +#define SMPL_NOT_REPLY 2 + +/* when allocating local Rx port it depends on whether the allocation + * is being done as a result of a link or a link reply + */ +#define LINK_SEND 1 +#define LINK_REPLY 2 + +#define CONNSTATE_FREE (0x00) +#define CONNSTATE_JOINED (0x01) +#define CONNSTATE_CONNECTED (0x02) + +typedef struct +{ + volatile uint8_t connState; + uint8_t hops2target; +#ifdef APP_AUTO_ACK + volatile uint8_t ackTID; +#endif + uint8_t peerAddr[NET_ADDR_SIZE]; + rxMetrics_t sigInfo; + uint8_t portRx; + uint8_t portTx; + linkID_t thisLinkID; +#ifdef SMPL_SECURE + uint32_t connTxCTR; + uint32_t connRxCTR; +#endif +} connInfo_t; + +/**************************************************************************************** + * Application Payload TID support + * + * Sometimes the receiving application uses a payload TID to determine if either it + * missed frames (received TID > (last-seen TID+1)) or is seeing a duplicate (received + * TID <= last-seen TID). Typically the TID simply increments for each successive frame. + * But when the count wraps there is a problem. The received TID should always be one + * more than the last TID. If it's equal, it's a duplicate. If it's less it's late. If + * it's one more it's the one we expect. If it's more than 1 more then we missed frames. + * Simple increments work for the wrap arithmetically. If the received TID is 0 and the last + * seen ID is the biggest number in the world -- 0xFF... depending on type we can detect + * the wrap. But if the receiver misses the 0 TID value for any reason or the biggest + * number in the world TID is missed then susbequent testing for missed or duplicate + * frames can get confused. We resolve this by allowing some leeway in the wrap testing. + * this testing is assisted by the following macros. Setting TID_VALID_WINDOW to 0 + * will enforce a no leniency policy. In this case you'd better not miss either the + * biggest number or the 0. The CHECK_TID_WRAP macro is only needed if the received + * TID is less than the last-seen TID. The DUP_TID_AFTER_WRAP macro is only needed if the + * received TID is greater than 1 more than the last-seen TID. + ***************************************************************************************/ +#define MAX_APT ((appPTid_t)~0) /* max value of application payload TID type */ +#define TID_VALID_WINDOW 2 /* window around max and 0 */ + +#define CHECK_TID_WRAP(lastTID, newTID) ((lastTID >= (MAX_APT - TID_VALID_WINDOW)) && \ + (newTID <= TID_VALID_WINDOW) \ + ) +#define DUP_TID_AFTER_WRAP(lastTID, newTID) ((newTID >= (MAX_APT - TID_VALID_WINDOW)) && \ + (lastTID <= TID_VALID_WINDOW) \ + ) + +/* prototypes */ +smplStatus_t nwk_nwkInit(uint8_t (*)(linkID_t)); +connInfo_t *nwk_getNextConnection(void); +void nwk_freeConnection(connInfo_t *); +uint8_t nwk_getNextClientPort(void); +connInfo_t *nwk_getConnInfo(linkID_t port); +connInfo_t *nwk_isLinkDuplicate(uint8_t *, uint8_t); +uint8_t nwk_findAddressMatch(mrfiPacket_t *); +smplStatus_t nwk_checkConnInfo(connInfo_t *, uint8_t); +uint8_t nwk_isConnectionValid(mrfiPacket_t *, linkID_t *); +uint8_t nwk_allocateLocalRxPort(uint8_t, connInfo_t *); +uint8_t nwk_isValidReply(mrfiPacket_t *, uint8_t, uint8_t, uint8_t); +connInfo_t *nwk_findPeer(addr_t *, uint8_t); +smplStatus_t nwk_NVObj(ioctlAction_t, ioctlNVObj_t *); + + +uint8_t nwk_checkAppMsgTID(appPTid_t, appPTid_t); +void nwk_getNumObjectFromMsg(void *, void *, uint8_t); +void nwk_putNumObjectIntoMsg(void *, void *, uint8_t); +#ifdef ACCESS_POINT +sfInfo_t *nwk_getSFInfoPtr(void); +#ifdef AP_IS_DATA_HUB +uint8_t nwk_saveJoinedDevice(mrfiPacket_t *); +connInfo_t *nwk_findAlreadyJoined(mrfiPacket_t *); +#endif +#endif + + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_QMgmt.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_QMgmt.c new file mode 100755 index 0000000..4cb34ea --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_QMgmt.c @@ -0,0 +1,417 @@ +/************************************************************************************************** + Filename: nwk_QMgmt.c + Revised: $Date: 2009-03-10 17:01:56 -0700 (Tue, 10 Mar 2009) $ + Revision: $Revision: 19372 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI input and output frame queues + + Copyright 2007-2008 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk.h" +#include "nwk_frame.h" +#include "nwk_QMgmt.h" +#include "nwk_mgmt.h" /* need offsets for poll frames */ + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +#if SIZE_INFRAME_Q > 0 +static frameInfo_t sInFrameQ[SIZE_INFRAME_Q]; +#else +static frameInfo_t *sInFrameQ = NULL; +#endif /* SIZE_INFRAME_Q > 0 */ + +static frameInfo_t sOutFrameQ[SIZE_OUTFRAME_Q]; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** +* @fn nwk_QInit +* +* @brief Initialize the input and output frame queues to hold no packets. +* +* input parameters +* +* output parameters +* +* @return void +*/ +void nwk_QInit(void) +{ +#if SIZE_INFRAME_Q > 0 + memset(sInFrameQ, 0, sizeof(sInFrameQ)); +#endif // SIZE_INFRAME_Q > 0 + memset(sOutFrameQ, 0, sizeof(sOutFrameQ)); +} + +/****************************************************************************** + * @fn nwk_QfindSlot + * + * @brief Finds a slot to use to retrieve the frame from the radio. It + * uses a LRU cast-out scheme. It is possible that this routine + * finds no slot. This can happen if the queue is of size 1 or 2 + * and the Rx interrupt occurs during a retrieval call from an + * application. There are meta-states for frames as the application + * looks for the oldest frame on the port being requested. + * + * This routine is running in interrupt context. + * + * input parameters + * @param which - INQ or OUTQ to search + * + * output parameters + * + * @return Pointer to oldest available frame in the queue + */ +frameInfo_t *nwk_QfindSlot(uint8_t which) +{ + frameInfo_t *pFI, *oldest= 0, *newFI = 0; + uint8_t i, num, newOrder = 0, orderTest; + + if (INQ == which) + { + pFI = sInFrameQ; + num = SIZE_INFRAME_Q; + } + else + { + pFI = sOutFrameQ; + num = SIZE_OUTFRAME_Q; + } + + orderTest = num + 1; + + for (i=0; ifi_usage != FI_AVAILABLE) + { + if (INQ == which) /* TODO: do cast-out for Tx as well */ + { + + /* need to know the number of occupied slots so we know the age value + * for the unoccupied slot (if there is one). + */ + newOrder++; + + /* make sure nwk_retrieveFrame() is not processing this frame */ + if (FI_INUSE_TRANSITION == pFI->fi_usage) + { + continue; + } + /* is this frame older than any we've seen? */ + if (orderTest > pFI->orderStamp) + { + /* yes. */ + oldest = pFI; + orderTest = pFI->orderStamp; + } + } + } + else + { + if (OUTQ == which) /* TODO: do cast-out for Tx as well */ + { + return pFI; + } + newFI = pFI; + } + } + + /* did we find anything? */ + if (!newFI) + { + /* queue was full. cast-out happens here...unless... */ + if (!oldest) + { + /* This can happen if the queue is only of size 1 or 2 and all + * the frames are in transition when the Rx interrupt occurs. + */ + return (frameInfo_t *)0; + } + newFI = oldest; + nwk_QadjustOrder(which, newFI->orderStamp); + newFI->orderStamp = i; + } + else + { + /* mark the available slot. */ + newFI->orderStamp = ++newOrder; + } + + return newFI; +} + +/****************************************************************************** + * @fn nwk_QadjustOrder + * + * @brief Adjusts the age of everyone in the queue newer than the frame + * being removed. + * + * input parameters + * @param which - INQ or OUTQ to adjust + * @param stamp - value of frame being removed + * + * output parameters + * + * @return void + */ +void nwk_QadjustOrder(uint8_t which, uint8_t stamp) +{ + frameInfo_t *pFI; + uint8_t i, num; + bspIState_t intState; + + if (INQ == which) + { + pFI = sInFrameQ; + num = SIZE_INFRAME_Q; + } + else + { +/* pFI = sOutFrameQ; */ +/* num = SIZE_OUTFRAME_Q; */ + return; + } + + BSP_ENTER_CRITICAL_SECTION(intState); + + for (i=0; ifi_usage != FI_AVAILABLE) && (pFI->orderStamp > stamp)) + { + pFI->orderStamp--; + } + } + + BSP_EXIT_CRITICAL_SECTION(intState); + + return; +} + +/****************************************************************************** + * @fn nwk_QfindOldest + * + * @brief Look through frame queue and find the oldest available frame + * in the context in question. Supports connection-based (user), + * non-connection based (NWK applications), and the special case + * of store-and-forward. + * + * input parameters + * @param which - INQ or OUTQ to adjust + * @param rcvContext - context information for finding the oldest + * @param usage - normal usage or store-and-forward usage + * + * output parameters + * + * @return Pointer to frame that is the oldsest on the requested port, or + * 0 if there are none. + */ +frameInfo_t *nwk_QfindOldest(uint8_t which, rcvContext_t *rcv, uint8_t fi_usage) +{ + uint8_t i, oldest, num, port; + uint8_t uType, addr12Compare; + bspIState_t intState; + frameInfo_t *fPtr = 0, *wPtr; + connInfo_t *pCInfo = 0; + uint8_t *pAddr1, *pAddr2, *pAddr3 = 0; + + if (INQ == which) + { + wPtr = sInFrameQ; + num = SIZE_INFRAME_Q; + oldest = SIZE_INFRAME_Q+1; + } + else + { +/* pFI = sOutFrameQ; */ +/* num = SIZE_OUTFRAME_Q; */ + return 0; + } + + if (RCV_APP_LID == rcv->type) + { + pCInfo = nwk_getConnInfo(rcv->t.lid); + if (!pCInfo) + { + return (frameInfo_t *)0; + } + port = pCInfo->portRx; + pAddr2 = pCInfo->peerAddr; + } + else if (RCV_NWK_PORT == rcv->type) + { + port = rcv->t.port; + } +#ifdef ACCESS_POINT + else if (RCV_RAW_POLL_FRAME == rcv->type) + { + port = *(MRFI_P_PAYLOAD(rcv->t.pkt)+F_APP_PAYLOAD_OS+M_POLL_PORT_OS); + pAddr2 = MRFI_P_SRC_ADDR(rcv->t.pkt); + pAddr3 = MRFI_P_PAYLOAD(rcv->t.pkt)+F_APP_PAYLOAD_OS+M_POLL_ADDR_OS; + } +#endif + else + { + return (frameInfo_t *)0; + } + + uType = (USAGE_NORMAL == fi_usage) ? FI_INUSE_UNTIL_DEL : FI_INUSE_UNTIL_FWD; + + for (i=0; ifi_usage) + { + wPtr->fi_usage = FI_INUSE_TRANSITION; + + BSP_EXIT_CRITICAL_SECTION(intState); /* release hold */ + /* message sent to this device? */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&wPtr->mrfiPkt), F_PORT_OS) == port) + { + /* Port matches. If the port of interest is a NWK applicaiton we're a + * match...the NWK applications are not connection-based. If it is a + * NWK application we need to check the source address for disambiguation. + * Also need to check source address if it's a raw frame lookup (S&F frame) + */ + if (RCV_APP_LID == rcv->type) + { + if (SMPL_PORT_USER_BCAST == port) + { + /* guarantee a match... */ + pAddr1 = pCInfo->peerAddr; + } + else + { + pAddr1 = MRFI_P_SRC_ADDR(&wPtr->mrfiPkt); + } + } +#ifdef ACCESS_POINT + else if (RCV_RAW_POLL_FRAME == rcv->type) + { + pAddr1 = MRFI_P_DST_ADDR(&wPtr->mrfiPkt); + } +#endif + + addr12Compare = memcmp(pAddr1, pAddr2, NET_ADDR_SIZE); + if ( (RCV_NWK_PORT == rcv->type) || + (!pAddr3 && !addr12Compare) || + (pAddr3 && !memcmp(pAddr3, MRFI_P_SRC_ADDR(&wPtr->mrfiPkt), NET_ADDR_SIZE)) + ) + { + if (wPtr->orderStamp < oldest) + { + if (fPtr) + { + /* restore previous oldest one */ + fPtr->fi_usage = uType; + } + oldest = wPtr->orderStamp; + fPtr = wPtr; + continue; + } + else + { + /* not oldest. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + /* not a match. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + /* wrong port. restore state */ + wPtr->fi_usage = uType; + } + } + else + { + BSP_EXIT_CRITICAL_SECTION(intState); + } + } + + return fPtr; +} + +/****************************************************************************** + * @fn nwk_getQ + * + * @brief Get location of teh specified frame queue. + * + * input parameters + * @param which - INQ or OUTQ to get + * + * output parameters + * + * @return Pointer to frame queue + */ +frameInfo_t *nwk_getQ(uint8_t which) +{ + return (INQ == which) ? sInFrameQ : sOutFrameQ; +} + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_QMgmt.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_QMgmt.h new file mode 100755 index 0000000..aa5535b --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_QMgmt.h @@ -0,0 +1,53 @@ +/************************************************************************************************** + Filename: nwk_QMgmt.h + Revised: $Date: 2009-01-17 15:14:16 -0800 (Sat, 17 Jan 2009) $ + Revision: $Revision: 18788 $ + Author: $Author: rlord $ + + Description: This header file supports the SimpliciTI input and output frame queues. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_QMGMT_H +#define NWK_QMGMT_H + + +#define INQ 1 +#define OUTQ 2 + +#define USAGE_NORMAL 1 +#define USAGE_FWD 2 + +/* prototypes */ +void nwk_QInit(void); +frameInfo_t *nwk_QfindSlot(uint8_t); +void nwk_QadjustOrder(uint8_t, uint8_t); +frameInfo_t *nwk_QfindOldest(uint8_t, rcvContext_t *, uint8_t); +frameInfo_t *nwk_getQ(uint8_t); + +#endif /* NWK_QMGMT_H */ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_api.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_api.c new file mode 100755 index 0000000..2139b2c --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_api.c @@ -0,0 +1,858 @@ +/************************************************************************************************** + Filename: nwk_api.c + Revised: $Date: 2009-01-28 18:27:38 -0800 (Wed, 28 Jan 2009) $ + Revision: $Revision: 18875 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI appliction layer API. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "mrfi.h" +#include "nwk_globals.h" +#include "nwk_freq.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/* These defines are in support an application listening for a link frame to + * terminate after some amount of time. The intention is that this guard be + * the exception. The intention of the SimpliciTI design is that the + * temporal contiguity between the listen and the reception of the link frame + * from the peer be very tight. The SMPL_LinkListen() should be termninated + * by the reception of the link frame. But in case it does not receive the frame + * the support below allows intervention by the application. + */ + +/* The intention is for user to modify just the following single value */ +#define LINKLISTEN_MILLISECONDS_2_WAIT (5000) + +#define LINKLISTEN_POLL_PERIOD_MS (10) +#define LINKLISTEN_POLL_COUNT ( (LINKLISTEN_MILLISECONDS_2_WAIT) / (LINKLISTEN_POLL_PERIOD_MS) ) + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +// [BM] Workaround to enable stack restarting +//static uint8_t sInit_done = 0; +uint8_t sInit_done = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static uint8_t ioctlPreInitAccessIsOK(ioctlObject_t); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/*********************************************************************************** + * @fn SMPL_Init + * + * @brief Initialize the SimpliciTI stack. + * + * input parameters + * @param f - Pointer to call back function. Function called by NWK when + * user application frame received. The callback is done in the + * ISR thread. Argument is Link ID associated with frame. Function + * returns 0 if frame is to be kept by NWK, otherwise 1. Frame + * should be kept if application will do a SMPL_Receive() in the + * user thread (recommended). Pointer may be NULL. + * + * output parameters + * + * @return Status of operation: + * SMPL_SUCCESS + * SMPL_NO_JOIN No Join reply. AP possibly not yet up. + * SMPL_NO_CHANNEL Only if Frequency Agility enabled. Channel scan + * failed. AP possibly not yet up. + */ +smplStatus_t SMPL_Init(uint8_t (*f)(linkID_t)) +{ + smplStatus_t rc; + + if (!sInit_done) + { + /* set up radio. */ + MRFI_Init(); + + /* initialize network */ + if ((rc=nwk_nwkInit(f)) != SMPL_SUCCESS) + { + return rc; + } + + MRFI_WakeUp(); +#if defined( FREQUENCY_AGILITY ) + { + freqEntry_t chan; + + chan.logicalChan = 0; + /* ok to set default channel explicitly now that MRFI initialized. */ + nwk_setChannel(&chan); + } +#endif + /* don't turn Rx on if we're an end device that isn't always on. */ +#if !defined( END_DEVICE ) + MRFI_RxOn(); +#endif + +#if defined( END_DEVICE ) + /* All except End Devices are in promiscuous mode */ + MRFI_SetRxAddrFilter((uint8_t *)nwk_getMyAddress()); + MRFI_EnableRxAddrFilter(); +#endif + } + sInit_done = 1; + + /* Join. if no AP or Join fails that status is returned. */ + rc = nwk_join(); + + return rc; +} + +/****************************************************************************** + * @fn SMPL_LinkListen + * + * @brief Listen for a link frame from a 'client' device. + * + * input parameters + * + * output parameters + * @param linkID - pointer to Link ID to be used by application to + * read and write to the linked peer. + * + * @return status of operation. + * SMPL_SUCCESS + * SMPL_TIMEOUT No link frame received during listen interval. +* Interval set in #defines above. linkID not valid. + * + */ + +smplStatus_t SMPL_LinkListen(linkID_t *linkID) +{ + uint8_t radioState = MRFI_GetRadioState(); + uint16_t i; + linkID_t locLinkID; + + /* Set the context. We want to reject any link frames received if + * we're not listening. For example if we're an AP we are in + * promiscuous mode and we'll see any broadcast link frames. + */ + nwk_setListenContext(LINK_LISTEN_ON); + + NWK_CHECK_FOR_SETRX(radioState); + + for (i=0; i MAX_APP_PAYLOAD)) + { + return rc; + } + + /* Build an outgoing message frame destined for the port from the + * connection info using the destination address also from the + * connection info. + */ + if (SMPL_TXOPTION_NONE == options) + { + pFrameInfo = nwk_buildFrame(pCInfo->portTx, msg, len, pCInfo->hops2target); + } +#if defined(APP_AUTO_ACK) + else if (options & SMPL_TXOPTION_ACKREQ) + { + if (SMPL_LINKID_USER_UUD != lid) + { + pFrameInfo = nwk_buildAckReqFrame(pCInfo->portTx, msg, len, pCInfo->hops2target, &pCInfo->ackTID); + ackreq = 1; + } + else + { + /* can't request an ack on the UUD link ID */ + return SMPL_BAD_PARAM; + } + } +#endif /* APP_AUTO_ACK */ + else + { + return SMPL_BAD_PARAM; + } + + if (!pFrameInfo) + { + return SMPL_NOMEM; + } + memcpy(MRFI_P_DST_ADDR(&pFrameInfo->mrfiPkt), pCInfo->peerAddr, NET_ADDR_SIZE); + +#if defined(SMPL_SECURE) + { + uint32_t *pUL = 0; + + if (pCInfo->thisLinkID != SMPL_LINKID_USER_UUD) + { + pUL = &pCInfo->connTxCTR; + } + nwk_setSecureFrame(&pFrameInfo->mrfiPkt, len, pUL); + } +#endif /* SMPL_SECURE */ + +#if defined(ACCESS_POINT) + /* If we are an AP trying to send to a polling device, don't do it. + * See if the target is a store-and-forward client. + */ + if (nwk_isSandFClient(MRFI_P_DST_ADDR(&pFrameInfo->mrfiPkt), &loc)) + { + pFrameInfo->fi_usage = FI_INUSE_UNTIL_FWD; + return SMPL_SUCCESS; + } + else +#endif /* ACCESS_POINT */ + { + rc = nwk_sendFrame(pFrameInfo, MRFI_TX_TYPE_CCA); + } + +#if !defined(APP_AUTO_ACK) + /* save a little code space with this #if */ + (void) ackreq; /* keep compiler happy */ + return rc; +#else + /* we're done if the send failed or no ack requested. */ + if (SMPL_SUCCESS != rc || !ackreq) + { + return rc; + } + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + { + bspIState_t intState; + + /* If the saved TID hasn't been reset then we never got the ack. */ + BSP_ENTER_CRITICAL_SECTION(intState); + if (pCInfo->ackTID) + { + pCInfo->ackTID = 0; + rc = SMPL_NO_ACK; + } + BSP_EXIT_CRITICAL_SECTION(intState); + } + + return rc; +#endif /* APP_AUTO_ACK */ +} + +/************************************************************************************** + * @fn SMPL_Receive + * + * @brief Receive a message from a peer application. + * + * input parameters + * @param lid - Link ID (port) from application + * + * + * output parameters + * @param msg - pointer to where received message should be copied. + * buffer should be of size == MAX_APP_PAYLOAD + * @param len - pointer to receive length of received message + * + * @return Status of operation. + * Caller should not use the value returned in 'len' to decide + * whether there is a frame or not. It could be useful to the + * Caller to distinguish between no frame and a frame with no data. + * For example, in the polling case a frame with no application payload + * is the way the AP conveys that there are no frames waiting. + * + * SMPL_SUCCESS + * + * SMPL_BAD_PARAM No valid Connection Table entry for Link ID + * Data in Connection Table entry bad + * SMPL_NO_FRAME No frame received. + * SMPL_NO_PAYLOAD Frame received with no payload (not necessarily + * an error and could be deduced by application + * because the returned length will be 0) + * + * Polling device only: + * + * SMPL_TIMEOUT No response from Access Point + * SMPL_NO_AP_ADDRESS Access Point address unknown + * SMPL_TX_CCA_FAIL Could not send poll frame + * SMPL_NOMEM No memory in output frame queue + * SMPL_NO_CHANNEL Frequency Agility enabled and could not find channel + */ +smplStatus_t SMPL_Receive(linkID_t lid, uint8_t *msg, uint8_t *len) +{ + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + rcvContext_t rcv; + + if (!pCInfo || ((rc=nwk_checkConnInfo(pCInfo, CHK_RX)) != SMPL_SUCCESS)) + { + return rc; + } + + rcv.type = RCV_APP_LID; + rcv.t.lid = lid; + +#if defined(RX_POLLS) + { + uint8_t numChans = 1; +#if defined(FREQUENCY_AGILITY) + freqEntry_t chans[NWK_FREQ_TBL_SIZE]; + uint8_t scannedB4 = 0; +#endif + + do + { + uint8_t radioState = MRFI_GetRadioState(); + + /* I'm polling. Do the poll to stimulate the sending of a frame. If the + * frame has application length of 0 it means there were no frames. If + * no reply is received infer that the channel is changed. We then need + * to scan and then retry the poll on each channel returned. + */ + if (SMPL_SUCCESS != (rc=nwk_poll(pCInfo->portRx, pCInfo->peerAddr))) + { + /* for some reason couldn't send the poll out. */ + return rc; + } + + /* do this before code block below which may reset it. */ + numChans--; + + /* Wait until there's a frame. if the len is 0 then return SMPL_NO_FRAME + * to the caller. In the poll case the AP always sends something. + */ + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + /* TODO: deal with pending */ + rc = nwk_retrieveFrame(&rcv, msg, len, 0, 0); + +#if defined(FREQUENCY_AGILITY) + if (SMPL_SUCCESS == rc) + { + /* we received something... */ + return (*len) ? SMPL_SUCCESS : SMPL_NO_PAYLOAD; + } + + /* No reply. scan for other channel(s) if we haven't already. Then set + * one and try again. + */ + if (!scannedB4) + { + numChans = nwk_scanForChannels(chans); + scannedB4 = 1; + } + if (numChans) + { + nwk_setChannel(&chans[numChans-1]); + } +#else /* FREQUENCY_AGILITY */ + return (*len) ? rc : ((SMPL_SUCCESS == rc) ? SMPL_NO_PAYLOAD : SMPL_TIMEOUT); +#endif + } while (numChans); + } + +#if defined(FREQUENCY_AGILITY) + return SMPL_NO_CHANNEL; +#endif + +#else /* RX_POLLS */ + return nwk_retrieveFrame(&rcv, msg, len, 0, 0); +#endif /* RX_POLLS */ +} + + +/****************************************************************************** + * @fn SMPL_Link + * + * @brief Link to a peer. + * + * input parameters + * + * output parameters + * @param lid - pointer to where we should write the link ID to which the + * application will read and write. + * + * @return Status of operation. + * SMPL_SUCCESS + * SMPL_NOMEM No room to allocate local Rx port, no more + * room in Connection Table, or no room in + * output frame queue. + * SMPL_NO_LINK No reply frame during wait window. + * SMPL_TX_CCA_FAIL Could not send Link frame. + */ +smplStatus_t SMPL_Link(linkID_t *lid) +{ + return nwk_link(lid); +} + +#if defined(EXTENDED_API) +/************************************************************************************** + * @fn SMPL_Unlink + * + * @brief Tear down connection to a peer. + * + * input parameters + * @param lid - Link ID whose connection is to be terminated. + * + * output parameters + * + * @return Status of operation. The Connection Table entry for the Link ID + * is always freed successfuly. The returned status value is the + * status of the _peer's_ connection tear-down as a result of the + * message sent here. + * SMPL_SUCCESS Local and remote connection destroyed. + * SMPL_BAD_PARAM No local connection table entry for this Link ID + * SMPL_TIMEOUT No reply from peer. + * SMPL_NO_PEER_UNLINK Peer did not have a Connection Table entry for me. + */ +smplStatus_t SMPL_Unlink(linkID_t lid) +{ + return nwk_unlink(lid); +} + +/************************************************************************************** + * @fn SMPL_Ping + * + * @brief Ping a peer. Synchronous call. Although a link ID is used it is the + * NWK Ping application that is pinged, not the peer of this Link ID. The + * peer is not expected to be the responder to the frame sent from here. + * This API is a proxy for a real ping since the application doesn't + * have direct access to SimpliciTI device addresses. Kind of hokey but a + * useful keep-alive mechanism without having to support it with + * user application service. + * + * input parameters + * @param lid - The link ID whose peer device address is used to direct the NWK Ping + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t SMPL_Ping(linkID_t lid) +{ + return nwk_ping(lid); +} + +/************************************************************************************** + * @fn SMPL_Commission + * + * @brief Commission a connection. + * + * input parameters + * @param peerAddr - Pointer to address of the peer for this connection + * @param locPort - Port on which to listen for messages from the peer + * @param rmtPort - Port on which to send messages to the peer. + * @param lid - Pointer to Link ID object. If content of location is + * non-zero on input the value is placed in the Connection + * object. + * + * output parameters + * @param lid - Pointer to Link ID object. If content of location is zero + * on input the value in the Connection object is stored there. + * + * @return SMPL_SUCCESS + * SMPL_NOMEM - No room left in Connection table. + * SMPL_BAD_PARAM - A pointer to a Link object was not supplied. + */ +smplStatus_t SMPL_Commission(addr_t *peerAddr, uint8_t locPort, uint8_t rmtPort, linkID_t *lid) +{ + connInfo_t *pCInfo = nwk_getNextConnection(); + smplStatus_t rc = SMPL_BAD_PARAM; + + do { + if (pCInfo) + { + /* sanity checks... */ + + /* Check port info. */ + if ((locPort > SMPL_PORT_STATIC_MAX) || (locPort < (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM + 1))) + { + continue; + } + + if ((rmtPort > SMPL_PORT_STATIC_MAX) || (rmtPort < (SMPL_PORT_STATIC_MAX - PORT_USER_STATIC_NUM + 1))) + { + continue; + } + + /* Must supply a pointer to the Link ID object */ + if (!lid) + { + /* No Link ID pointer supplied */ + continue; + } + + /* we're sane */ + + /* Use the value generated at connection object assign time. */ + *lid = pCInfo->thisLinkID; + + /* store peer's address */ + memcpy(pCInfo->peerAddr, peerAddr, NET_ADDR_SIZE); + + /* store port info */ + pCInfo->portRx = locPort; + pCInfo->portTx = rmtPort; + + pCInfo->hops2target = MAX_HOPS; + + rc = SMPL_SUCCESS; + } + else + { + /* No room in Connection table */ + rc = SMPL_NOMEM; + } + } while (0); + + if ((SMPL_SUCCESS != rc) && pCInfo) + { + nwk_freeConnection(pCInfo); + } + + return rc; +} +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn SMPL_Ioctl + * + * @brief This routine supplies the SimpliciTI IOCTL support. + * + * input parameters + * @param object - The IOCTL target object + * @param action - The IOCTL target action on the object + * @param val - pointer to value. exact forn depends on object type. + * + * output parameters + * + * @return Status of action. Value depends on object, action, and result. + * + * SMPL_BAD_PARAM is returned if this API is called before + * initialization and the object is not one of + * the valid exceptions. + */ +smplStatus_t SMPL_Ioctl(ioctlObject_t object, ioctlAction_t action, void *val) +{ + smplStatus_t rc; + + /* if init hasn't occurred see if access is still valid */ + if (!sInit_done && !ioctlPreInitAccessIsOK(object)) + { + return SMPL_BAD_PARAM; + } + + switch (object) + { +#if defined(EXTENDED_API) + case IOCTL_OBJ_TOKEN: + { + ioctlToken_t *t = (ioctlToken_t *)val; + + rc = SMPL_SUCCESS; + if (TT_LINK == t->tokenType) + { + if (IOCTL_ACT_SET == action) + { + nwk_setLinkToken(t->token.linkToken); + } + else if (IOCTL_ACT_GET == action) + { + nwk_getLinkToken(&t->token.linkToken); + } + else + { + rc = SMPL_BAD_PARAM; + } + } + else if (TT_JOIN == t->tokenType) + { + if (IOCTL_ACT_SET == action) + { + nwk_setJoinToken(t->token.joinToken); + } + else if (IOCTL_ACT_GET == action) + { + nwk_getJoinToken(&t->token.joinToken); + } + else + { + rc = SMPL_BAD_PARAM; + } + } + else + { + rc = SMPL_BAD_PARAM; + } + } + break; + + case IOCTL_OBJ_NVOBJ: + rc = nwk_NVObj(action, (ioctlNVObj_t *)val); + break; +#endif /* EXTENDED_API */ + + case IOCTL_OBJ_CONNOBJ: + rc = nwk_connectionControl(action, val); + break; + + case IOCTL_OBJ_ADDR: + if ((IOCTL_ACT_GET == action) || (IOCTL_ACT_SET == action)) + { + rc = nwk_deviceAddress(action, (addr_t *)val); + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_RAW_IO: + if (IOCTL_ACT_WRITE == action) + { + rc = nwk_rawSend((ioctlRawSend_t *)val); + } + else if (IOCTL_ACT_READ == action) + { + rc = nwk_rawReceive((ioctlRawReceive_t *)val); + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_RADIO: + rc = nwk_radioControl(action, val); + break; + +#if defined(ACCESS_POINT) + case IOCTL_OBJ_AP_JOIN: + rc = nwk_joinContext(action); + break; +#endif +#if defined(FREQUENCY_AGILITY) + case IOCTL_OBJ_FREQ: + rc = nwk_freqControl(action, val); + break; +#endif + case IOCTL_OBJ_FWVER: + if (IOCTL_ACT_GET == action) + { + memcpy(val, nwk_getFWVersion(), SMPL_FWVERSION_SIZE); + rc = SMPL_SUCCESS; + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + case IOCTL_OBJ_PROTOVER: + if (IOCTL_ACT_GET == action) + { + *((uint8_t *)val) = nwk_getProtocolVersion(); + rc = SMPL_SUCCESS; + } + else + { + rc = SMPL_BAD_PARAM; + } + break; + + default: + rc = SMPL_BAD_PARAM; + break; + } + + return rc; +} + +/****************************************************************************** + * @fn ioctlPreInitAccessIsOK + * + * @brief Is the request legal yet? Most requests are not legal before + * SMPL_Init(). + * + * input parameters + * @param object - The IOCTL target object + * + * output parameters + * + * @return Returns non-zero if request should be honored for further + * processing, otherwise returns 0. This function does not + * determine of the object-action pair are valid. It only knows + * about exceptions, i.e., those that are valid before the + * SMPL_Init() call. + * + */ +static uint8_t ioctlPreInitAccessIsOK(ioctlObject_t object) +{ + uint8_t rc; + + /* Currently the only legal pre-init accesses are the address and + * the token objects. + */ + switch (object) + { + case IOCTL_OBJ_ADDR: + case IOCTL_OBJ_TOKEN: + rc = 1; /* legal */ + break; + + default: + rc = 0; /* not legal when init not done */ + break; + } + + return rc; +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_api.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_api.h new file mode 100755 index 0000000..07ccf85 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_api.h @@ -0,0 +1,56 @@ +/************************************************************************************************** + Filename: nwk_api.h + Revised: $Date: 2008-11-24 12:09:31 -0800 (Mon, 24 Nov 2008) $ + Revision: $Revision: 18508 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI appliction layer API. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_API_H +#define NWK_API_H + +/* Tx options (bit map) */ +#define SMPL_TXOPTION_NONE ((txOpt_t)0x00) +#define SMPL_TXOPTION_ACKREQ ((txOpt_t)0x01) + +smplStatus_t SMPL_Init(uint8_t (*)(linkID_t)); +smplStatus_t SMPL_Link(linkID_t *); +smplStatus_t SMPL_LinkListen(linkID_t *); +smplStatus_t SMPL_Send(linkID_t lid, uint8_t *msg, uint8_t len); +smplStatus_t SMPL_SendOpt(linkID_t lid, uint8_t *msg, uint8_t len, txOpt_t); +smplStatus_t SMPL_Receive(linkID_t lid, uint8_t *msg, uint8_t *len); +smplStatus_t SMPL_Ioctl(ioctlObject_t, ioctlAction_t, void *); +#ifdef EXTENDED_API +smplStatus_t SMPL_Ping(linkID_t); +smplStatus_t SMPL_Unlink(linkID_t); +smplStatus_t SMPL_Commission(addr_t *, uint8_t, uint8_t, linkID_t *); +#endif /* EXTENDED_API */ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_app.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_app.h new file mode 100755 index 0000000..45883b4 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_app.h @@ -0,0 +1,53 @@ + +/************************************************************************************************** + Filename: nwk_app.h + Revised: $Date: 2007-07-10 11:21:35 -0700 (Tue, 10 Jul 2007) $ + Revision: $Revision: 14865 $ + Author: $Author: lfriedman $ + + Description: This header file is for convenience and includes the headers for all the + network applications. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + + + +#ifndef NWK_APP_H +#define NWK_APP_H + +#include "nwk_freq.h" +#include "nwk_ping.h" +#include "nwk_link.h" +#include "nwk_mgmt.h" +#include "nwk_join.h" +#include "nwk_security.h" +#include "nwk_ioctl.h" + +#endif + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_frame.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_frame.c new file mode 100755 index 0000000..4279b25 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_frame.c @@ -0,0 +1,948 @@ +/************************************************************************************************** + Filename: nwk_frame.c + Revised: $Date: 2009-03-10 16:21:40 -0700 (Tue, 10 Mar 2009) $ + Revision: $Revision: 19368 $ + Author $Author: lfriedman $ + + Description: This file supports the SimpliciTI frame handling functions. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_app.h" +#include "nwk_QMgmt.h" +#include "nwk_globals.h" +#include "nwk_mgmt.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +#if SIZE_INFRAME_Q > 0 +/* array of function pointers to handle NWK application frames */ +static fhStatus_t (* const func[])(mrfiPacket_t *) = { nwk_processPing, + nwk_processLink, + nwk_processJoin, + nwk_processSecurity, + nwk_processFreq, + nwk_processMgmt + }; +#endif /* SIZE_INFRAME_Q > 0 */ + +static uint8_t sTRACTID = 0; + +static addr_t const *sMyAddr = NULL; + +static uint8_t sMyRxType = 0, sMyTxType = 0; + +#if !defined(RX_POLLS) +static uint8_t (*spCallback)(linkID_t) = NULL; +#endif + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +#if SIZE_INFRAME_Q > 0 +/* local helper functions for Rx devices */ +static void dispatchFrame(frameInfo_t *); +#if !defined(END_DEVICE) +#if defined(ACCESS_POINT) +/* only Access Points need to worry about duplicate S&F frames */ +uint8_t isDupSandFFrame(mrfiPacket_t *); +#endif /* ACCESS_POINT */ +#endif /* !END_DEVICE */ +#endif /* SIZE_INFRAME_Q > 0 */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_frameInit + * + * @brief Initialize network context. + * + * input parameters + * pF - Pointer to callback function. If none intended should be NULL. + * + * output parameters + * + * @return void + */ + +void nwk_frameInit(uint8_t (*pF)(linkID_t)) +{ + +/****** Fill static values for the DEVICEINFO byte that will go in each frame ******/ + /* Rx type when frame originates from this device. Set in nwk_buildFrame() */ + /* Tx type when frame sent from this device. Set in nwk_sendframe() */ +#if !defined(END_DEVICE) + sMyRxType = F_RX_TYPE_USER_CTL; + #if defined(ACCESS_POINT) + sMyTxType = F_TX_DEVICE_AP; + #else + sMyTxType = F_TX_DEVICE_RE; + #endif +#else + sMyTxType = F_TX_DEVICE_ED; + #if defined(RX_POLLS) + sMyRxType = F_RX_TYPE_POLLS; + #endif + #if defined(RX_USER) + sMyRxType = F_RX_TYPE_USER_CTL; + #endif +#endif +/****** DONE fill static values for the DEVICEINFO byte that will go in each frame ******/ + +#if !defined(RX_POLLS) + spCallback = pF; +#else + (void) pF; +#endif + + sMyAddr = nwk_getMyAddress(); + + while (!(sTRACTID=MRFI_RandomByte())) ; + + return; +} + +/****************************************************************************** + * @fn nwk_buildFrame + * + * @brief Builds an output frame for the port and message enclosed. + * This routine prepends the frame header and populates the + * frame in the output queue. + * + * input parameters + * @param port - port from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param hops - number of hops allowed. this is less than MAX_HOPS + * whenever the frame is being sent to the AP. this is to + * help mitigate the (short) broadcast storms + * + * output parameters + * + * @return pointer to frameInfo_t structure created. NULL if there is + * no room in output queue. + */ +frameInfo_t *nwk_buildFrame(uint8_t port, uint8_t *msg, uint8_t len, uint8_t hops) +{ + frameInfo_t *fInfoPtr; + + if (!(fInfoPtr=nwk_QfindSlot(OUTQ))) + { + return (frameInfo_t *)NULL; + } + + MRFI_SET_PAYLOAD_LEN(&fInfoPtr->mrfiPkt, len+F_APP_PAYLOAD_OS); + + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ENCRYPT_OS, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_PORT_OS, port); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_TRACTID_OS, sTRACTID); + while (!(++sTRACTID)) ; /* transaction ID can't be 0 */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_RX_TYPE, sMyRxType); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_HOP_COUNT, hops); + + /* reset ack-relevant bits */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_REQ, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_RPLY, 0); + + /* reset forwarding bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_FWD_FRAME, 0); + + memcpy(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt)+F_APP_PAYLOAD_OS, msg, len); + memcpy(MRFI_P_SRC_ADDR(&fInfoPtr->mrfiPkt), sMyAddr, NET_ADDR_SIZE); + + return fInfoPtr; +} + +#if defined(APP_AUTO_ACK) +/****************************************************************************** + * @fn nwk_buildAckReqFrame + * + * @brief Builds an output frame for the port and message enclosed. + * This routine prepends the frame header and populates the + * frame in the output queue. The frame is set to request that + * an ack frame be sent by the peer. + * + * input parameters + * @param port - port from application + * @param msg - pointer to message from app to be sent + * @param len - length of enclosed message + * @param hops - number of hops allowed. this is less than MAX_HOPS + * whenever the frame is being sent to the AP. this is to + * help mitigate the (short) broadcast storms + * @param tid - Transaction ID to insert in NWK header used to match + * the ack reply. + * + * output parameters + * + * @return pointer to frameInfo_t structure created. NULL if there is + * no room in output queue. + */ +frameInfo_t *nwk_buildAckReqFrame(uint8_t port, uint8_t *msg, uint8_t len, uint8_t hops, volatile uint8_t *tid) +{ + frameInfo_t *fInfoPtr; + + /* Build a normal frame first. */ + if (!(fInfoPtr=nwk_buildFrame(port, msg, len, hops))) + { + return (frameInfo_t *)NULL; + } + + /* save TID */ + *tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_TRACTID_OS); + /* Set REQ_ACK bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_REQ, F_ACK_REQ_TYPE); + + return fInfoPtr; +} +#endif /* APP_AUTO_ACK */ + +#if SIZE_INFRAME_Q > 0 +/****************************************************************************** + * @fn MRFI_RxCompleteISR + * + * @brief Here on Rx interrupt from radio. Process received frame from the + * radio Rx FIFO. + * + * input parameters + * + * output parameters + * + * @return void + */ +void MRFI_RxCompleteISR() +{ + frameInfo_t *fInfoPtr; + + /* room for more? */ + if (fInfoPtr=nwk_QfindSlot(INQ)) + { + MRFI_Receive(&fInfoPtr->mrfiPkt); + + dispatchFrame(fInfoPtr); + } + + return; +} + +/****************************************************************************** + * @fn nwk_retrieveFrame + * + * @brief Retrieve frame from Rx frame queue. Invoked by application-level + * code either app through SMPL_Receive() or IOCTL through raw Rx. This + * should run in a user thread, not an ISR thread. + * + * input parameters + * @param port - port on which to get a frame + * + * output parameters + * @param msg - pointer to where app payload should be copied. Buffer + * allocated should be == MAX_APP_PAYLOAD. + * + * @param len - pointer to where payload length should be stored. Caller + * can check for non-zero when polling the port. initialized + * to 0 even if no frame is retrieved. + * @param srcAddr - if non-NULL, a pointer to where to copy the source address + * of the retrieved message. + * @param hopCount - if non-NULL, a pointer to where to copy the hop count + of the retrieved message. + * + * @return SMPL_SUCCESS + * SMPL_NO_FRAME - no frame found for specified destination + * SMPL_BAD_PARAM - no valid connection info for the Link ID + * + */ +smplStatus_t nwk_retrieveFrame(rcvContext_t *rcv, uint8_t *msg, uint8_t *len, addr_t *srcAddr, uint8_t *hopCount) +{ + frameInfo_t *fPtr; + uint8_t done; + + do { + /* look for a frame on requested port. */ + *len = 0; + done = 1; + + fPtr = nwk_QfindOldest(INQ, rcv, USAGE_NORMAL); + if (fPtr) + { + connInfo_t *pCInfo = 0; + + if (RCV_APP_LID == rcv->type) + { + pCInfo = nwk_getConnInfo(rcv->t.lid); + if (!pCInfo) + { + return SMPL_BAD_PARAM; + } +#if defined(SMPL_SECURE) + /* decrypt here...we have all the context we need. */ + { + uint32_t ctr = pCInfo->connRxCTR; + uint32_t *pctr = &ctr; + uint8_t len = MRFI_GET_PAYLOAD_LEN(&fPtr->mrfiPkt) - F_SEC_CTR_OS; + + if (pCInfo->thisLinkID == SMPL_LINKID_USER_UUD) + { + pctr = NULL; + } +#if defined(RX_POLLS) + else if ((F_APP_PAYLOAD_OS - F_SEC_CTR_OS) == len) + { + /* This was an empty poll reply frame generated by the AP. + * It uses the single-byte CTR value like network applications. + * We do not want to use the application layer counter in this case. + */ + pctr = NULL; + } +#endif + if (nwk_getSecureFrame(&fPtr->mrfiPkt, len, pctr)) + { + if (pctr) + { + /* Update connection's counter. */ + pCInfo->connRxCTR = ctr; + } + } + else + { + /* Frame bogus. Check for another frame. */ + done = 0; + continue; + } + } +#endif /* SMPL_SECURE */ + } + + /* it's on the requested port. */ + *len = MRFI_GET_PAYLOAD_LEN(&fPtr->mrfiPkt) - F_APP_PAYLOAD_OS; + memcpy(msg, MRFI_P_PAYLOAD(&fPtr->mrfiPkt)+F_APP_PAYLOAD_OS, *len); + /* save signal info */ + if (pCInfo) + { + /* Save Rx metrics... */ + pCInfo->sigInfo.rssi = fPtr->mrfiPkt.rxMetrics[MRFI_RX_METRICS_RSSI_OFS]; + pCInfo->sigInfo.lqi = fPtr->mrfiPkt.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS]; + } + if (srcAddr) + { + /* copy source address if requested */ + memcpy(srcAddr, MRFI_P_SRC_ADDR(&fPtr->mrfiPkt), NET_ADDR_SIZE); + } + if (hopCount) + { + /* copy hop count if requested */ + *hopCount = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fPtr->mrfiPkt), F_HOP_COUNT); + } + /* input frame no longer needed. free it. */ + nwk_QadjustOrder(INQ, fPtr->orderStamp); + + fPtr->fi_usage = FI_AVAILABLE; + return SMPL_SUCCESS; + } + } while (!done); + + return SMPL_NO_FRAME; +} + +/****************************************************************************** + * @fn dispatchFrame + * + * @brief Received frame looks OK so far. Dispatch to either NWK app by + * invoking the handler or the user's app by simply leaving the + * frame in the queue and letting the app poll the port. + * + * input parameters + * @param fiPtr - frameInfo_t pointer to received frame + * + * output parameters + * + * @return void + */ +static void dispatchFrame(frameInfo_t *fiPtr) +{ + uint8_t port = GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_PORT_OS); + uint8_t nwkAppSize = sizeof(func)/sizeof(func[0]); + fhStatus_t rc; + linkID_t lid; +#if defined(ACCESS_POINT) + uint8_t loc; +#endif +#if !defined(END_DEVICE) + uint8_t isForMe; +#endif + + /* be sure it's not an echo... */ + if (!memcmp(MRFI_P_SRC_ADDR(&fiPtr->mrfiPkt), sMyAddr, NET_ADDR_SIZE)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + + /* Make sure encyrption bit conforms to our security support context. */ +#if defined(SMPL_SECURE) + if (!(GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ENCRYPT_OS))) + { + /* Encyrption bit is not on when when it should be */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +#else + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ENCRYPT_OS)) + { + /* Encyrption bit is on when when it should not be */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +#endif /* SMPL_SECURE */ + + /* If it's a network application port dispatch to service routine. Dispose + * of frame depending on return code. + */ + if (port && (port <= nwkAppSize)) + { +#if defined(SMPL_SECURE) + /* Non-connection-based frame. We can decode here if it was encrypted */ + if (!nwk_getSecureFrame(&fiPtr->mrfiPkt, MRFI_GET_PAYLOAD_LEN(&fiPtr->mrfiPkt) - F_SEC_CTR_OS, 0)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } +#endif + rc = func[port-1](&fiPtr->mrfiPkt); + if (FHS_KEEP == rc) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + } +#if !defined(END_DEVICE) + else if (FHS_REPLAY == rc) + { + /* an AP or an RE could be relaying a NWK application frame... */ + nwk_replayFrame(fiPtr); + } +#endif + else /* rc == FHS_RELEASE (default...) */ + { + fiPtr->fi_usage = FI_AVAILABLE; + } + return; + } + /* sanity check */ + else if ((port != SMPL_PORT_USER_BCAST) && ((port < PORT_BASE_NUMBER) || (port > SMPL_PORT_STATIC_MAX))) + { + /* bogus port. drop frame */ + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + + /* At this point we know the target is a user app. If this is an end device + * and we got this far save the frame and we're done. If we're an AP there + * are 3 cases: it's for us, it's for s store-and-forward client, or we need + * to replay the frame. If we're and RE and the frame didn't come from an RE + * and it's not for us, replay the frame. + */ + +#if defined(END_DEVICE) + /* If we're s polling end device we only accept application frames from + * the AP. This prevents duplicate reception if we happen to be on when + * a linked peer sends. + */ +#if defined(RX_POLLS) + if (F_TX_DEVICE_ED != GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE)) + { + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } +#else + /* it's destined for a user app. */ + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + if (spCallback && spCallback(lid)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } +#endif /* RX_POLLS */ + +#else /* END_DEVICE */ + + /* We have an issue if the frame is broadcast to the UUD port. The AP (or RE) must + * handle this frame as if it were the target in case there is an application + * running that is listening on that port. But if it's a broadcast it must also be + * replayed. It isn't enough just to test for the UUD port because it could be a + * directed frame to another device. We must check explicitly for broadcast + * destination address. + */ + isForMe = !memcmp(sMyAddr, MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), NET_ADDR_SIZE); + if (isForMe || ((port == SMPL_PORT_USER_BCAST) && !memcmp(nwk_getBCastAddress(), MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), NET_ADDR_SIZE))) + { + /* The folllowing test will succeed for the UUD port regardless of the + * source address. + */ + if (nwk_isConnectionValid(&fiPtr->mrfiPkt, &lid)) + { + /* If this is for the UUD port and we are here then the device is either + * an AP or an RE. In either case it must replay the UUD port frame if the + * frame is not "for me". But it also must handle it since it could have a + * UUD-listening application. Do the reply first and let the subsequent code + * correctly set the frame usage state. Note that the routine return can be + * from this code block. If not it will drop through to the bottom without + * doing a replay. + */ + /* Do I need to replay it? */ + if (!isForMe) + { + /* must be a broadcast for the UUD port */ + nwk_replayFrame(fiPtr); + } + /* OK. Now I handle it... */ + fiPtr->fi_usage = FI_INUSE_UNTIL_DEL; + if (spCallback && spCallback(lid)) + { + fiPtr->fi_usage = FI_AVAILABLE; + return; + } + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } +#if defined( ACCESS_POINT ) + /* Check to see if we need to save this for a S and F client. Otherwise, + * if it's not for us, get rid of it. + */ + else if (nwk_isSandFClient(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), &loc)) + { + /* Don't bother if it is a duplicate frame or if it's a forwarded frame + * echoed back from an RE. + */ + if (!isDupSandFFrame(&fiPtr->mrfiPkt) && + !(GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_FWD_FRAME)) + ) + { +#if defined(APP_AUTO_ACK) + /* Make sure ack request bit is off. Sender will have gone away. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_ACK_REQ, 0); +#endif + fiPtr->fi_usage = FI_INUSE_UNTIL_FWD; + } + else + { + fiPtr->fi_usage = FI_AVAILABLE; + } + } + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE) == F_TX_DEVICE_AP) + { + /* I'm an AP and this frame came from an AP. Don't replay. */ + fiPtr->fi_usage = FI_AVAILABLE; + } +#elif defined( RANGE_EXTENDER ) + else if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_TX_DEVICE) == F_TX_DEVICE_RE) + { + /* I'm an RE and this frame came from an RE. Don't replay. */ + fiPtr->fi_usage = FI_AVAILABLE; + } +#endif + else + { + /* It's not for me and I'm either an AP or I'm an RE and the frame + * didn't come from an RE. Replay the frame. + */ + nwk_replayFrame(fiPtr); + } +#endif /* !END_DEVICE */ + return; +} +#endif /* SIZE_INFRAME_Q > 0 */ + +/****************************************************************************** + * @fn nwk_sendFrame + * + * @brief Send a frame by copying it to the radio Tx FIFO. + * + * input parameters + * @param pFrameInfo - pointer to frame to be sent + * @param txOption - do CCA or force frame out. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_TX_CCA_FAIL Tx failed because of CCA failure. + * Tx FIFO flushed in this case. + */ +smplStatus_t nwk_sendFrame(frameInfo_t *pFrameInfo, uint8_t txOption) +{ + smplStatus_t rc; + + /* set the type of device sending the frame in the header */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_TX_DEVICE, sMyTxType); + + if (MRFI_TX_RESULT_SUCCESS == MRFI_Transmit(&pFrameInfo->mrfiPkt, txOption)) + { + rc = SMPL_SUCCESS; + } + else + { + /* Tx failed -- probably CCA. free up frame buffer. We do not have NWK + * level retries. Let application do it. + */ + rc = SMPL_TX_CCA_FAIL; + } + + /* TX is done. free up the frame buffer */ + pFrameInfo->fi_usage = FI_AVAILABLE; + + return rc; +} + + +/****************************************************************************** + * @fn nwk_getMyRxType + * + * @brief Get my Rx type. Used to help populate the hops count in the + * frame header to try and limit the broadcast storm. Info is + * exchanged when linking. + * + * input parameters + * + * output parameters + * + * @return The address LSB. + */ +uint8_t nwk_getMyRxType(void) +{ + return sMyRxType; +} + +#if defined(APP_AUTO_ACK) +/****************************************************************************** + * @fn nwk_sendAckReply + * + * @brief Send an acknowledgement reply frame. + * + * input parameters + * @param frame - pointer to frame with ack request. + * @param port - port on whcih reply expected. + * + * output parameters + * + * @return void + */ +void nwk_sendAckReply(mrfiPacket_t *frame, uint8_t port) +{ + mrfiPacket_t dFrame; + uint8_t tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS); + + /* set the type of device sending the frame in the header */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, sMyTxType); + + /* set the listen type of device sending the frame in the header. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); + + /* destination address from received frame */ + memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + /* source address */ + memcpy(MRFI_P_SRC_ADDR(&dFrame), sMyAddr, NET_ADDR_SIZE); + + /* port is the source the Tx port from the connection object */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); + + /* frame length... */ + MRFI_SET_PAYLOAD_LEN(&dFrame,F_APP_PAYLOAD_OS); + + /* transaction ID taken from source frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, tid); + + /* hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS); + + /* set ACK field */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, F_ACK_RPLY_TYPE); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); + + /* This is not a forwarded frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, 0); + + /* Encryption state */ +#if !defined(SMPL_SECURE) + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); +#else + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + nwk_setSecureFrame(&dFrame, 0, 0); +#endif + + MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); + + return; +} +#endif /* APP_AUTO_ACK */ + +#if !defined(END_DEVICE) +/****************************************************************************** + * @fn nwk_replayFrame + * + * @brief Deal with hop count on a Range Extender or Access Point replay. + * Queue entry usage always left as available when done. + * + * input parameters + * @param pFrameInfo - pointer to frame information structure + * + * output parameters + * + * @return void + */ +void nwk_replayFrame(frameInfo_t *pFrameInfo) +{ + uint8_t hops = GET_FROM_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_HOP_COUNT); + + /* if hops are zero, drop frame. othewise send it. */ + if (hops--) + { + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt),F_HOP_COUNT,hops); + /* Don't care if the Tx fails because of TO. Either someone else + * will retransmit or the application itself will recover. + */ +#if defined(SMPL_SECURE) + /* If the frame was targeted to a NWK port it was decrypted on spec in + * the 'dispatchFrame()' method. It must be re-encypted in this case. + */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_PORT_OS) <= SMPL_PORT_NWK_BCAST) + { + nwk_setSecureFrame(&pFrameInfo->mrfiPkt, MRFI_GET_PAYLOAD_LEN(&pFrameInfo->mrfiPkt)-F_APP_PAYLOAD_OS, 0); + } +#endif + MRFI_DelayMs(1); + nwk_sendFrame(pFrameInfo, MRFI_TX_TYPE_CCA); + } + else + { + pFrameInfo->fi_usage = FI_AVAILABLE; + } + return; +} + +#if defined(ACCESS_POINT) +/****************************************************************************** + * @fn nwk_getSandFFrame + * + * @brief Get any frame waiting for the client on the port supplied in + * the frame payload. + * TODO: support returning NWK application frames always. the + * port requested in the call should be an user application port. + * NWK app ports will never be in the called frame. + * TODO: deal with broadcast NWK frames from AP. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return pointer to frame if there is one, otherwise 0. + */ +frameInfo_t *nwk_getSandFFrame(mrfiPacket_t *frame, uint8_t osPort) +{ + uint8_t i, port = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+osPort); + frameInfo_t *fiPtr; + rcvContext_t rcv; + + rcv.type = RCV_RAW_POLL_FRAME; + rcv.t.pkt = frame; + /* check the input queue for messages sent by others. */ + if (fiPtr=nwk_QfindOldest(INQ, &rcv, USAGE_FWD)) + { + return fiPtr; + } + + /* Check the output queue to see if we ourselves need to send anything. + * TODO: use the cast-out scheme for output queue so this routine finds + * the oldest in either queue. + */ + fiPtr = nwk_getQ(OUTQ); + for (i=0; ifi_usage) + { + if (!memcmp(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), F_PORT_OS) == port) + { + return fiPtr; + } + } + } + } + return 0; +} + +/****************************************************************************** + * @fn nwk_SendEmptyPollRspFrame + * + * @brief There are no frames waiting for the requester on the specified + * port. Send a frame back to that port with no payload. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return void + */ +void nwk_SendEmptyPollRspFrame(mrfiPacket_t *frame) +{ + mrfiPacket_t dFrame; + uint8_t port = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+M_POLL_PORT_OS); + + /* set the type of device sending the frame in the header. we know it's an AP */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, F_TX_DEVICE_AP); + /* set the listen type of device sending the frame in the header. we know it's + * an AP is is probably always on...but use the static variable anyway. + */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); + /* destination address from received frame (polling device) */ + memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + /* source address */ + memcpy(MRFI_P_SRC_ADDR(&dFrame), MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+M_POLL_ADDR_OS, NET_ADDR_SIZE); + /* port is the port requested */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); + /* frame length... */ + MRFI_SET_PAYLOAD_LEN(&dFrame,F_APP_PAYLOAD_OS); + /* transaction ID... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, sTRACTID); + sTRACTID++; + /* hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS_FROM_AP); + + /* Ack fields */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, 0); + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); + + /* This is logically a forwarded frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, F_FRAME_FWD_TYPE); + + /* Encryption state */ +#if !defined(SMPL_SECURE) + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); +#else + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + nwk_setSecureFrame(&dFrame, 0, 0); +#endif + + MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +/****************************************************************************** + * @fn isDupSandFFrame + * + * @brief Have we already stored this frame on behalf of a client? + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Returns 1 if the frame is a duplicate, otherwise 0. + */ +uint8_t isDupSandFFrame(mrfiPacket_t *frame) +{ + uint8_t i, plLen = MRFI_GET_PAYLOAD_LEN(frame); + frameInfo_t *fiPtr; + + /* check the input queue for duplicate S&F frame. */ + fiPtr = nwk_getQ(INQ); + for (i=0; ifi_usage) + { + /* compare everything except the DEVICE INFO byte. */ + if (MRFI_GET_PAYLOAD_LEN(&fiPtr->mrfiPkt) == plLen && + !memcmp(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), MRFI_P_DST_ADDR(frame), NET_ADDR_SIZE) && + !memcmp(MRFI_P_SRC_ADDR(&fiPtr->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE) && + !memcmp(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt), MRFI_P_PAYLOAD(frame), 1) && + !memcmp(MRFI_P_PAYLOAD(&fiPtr->mrfiPkt)+F_TRACTID_OS, MRFI_P_PAYLOAD(frame)+F_TRACTID_OS, plLen-F_TRACTID_OS) + ) + { + return 1; + } + } + } + return 0; +} +#endif /* ACCESS_POINT */ + +#endif /* !END_DEVICE */ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_frame.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_frame.h new file mode 100755 index 0000000..6c616f8 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_frame.h @@ -0,0 +1,151 @@ +/************************************************************************************************** + Filename: nwk_frame.h + Revised: $Date: 2008-12-23 13:49:41 -0800 (Tue, 23 Dec 2008) $ + Revision: $Revision: 18651 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI frame handling functions. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_FRAME_H +#define NWK_FRAME_H + +/* Frame field defines and masks. Mask name must be field name with '_MSK' appended + * so the GET and PUT macros work correctly -- they use token pasting. Offset values + * are with respect to the MRFI payload and not the entire frame. + */ +#define F_PORT_OS 0 +#define F_PORT_OS_MSK (0x3F) +#define F_ENCRYPT_OS 0 +#define F_ENCRYPT_OS_MSK (0x40) +#define F_FWD_FRAME 0 +#define F_FWD_FRAME_MSK (0x80) +#define F_RX_TYPE 1 +#define F_RX_TYPE_MSK (0x40) +#define F_ACK_REQ 1 +#define F_ACK_REQ_MSK (0x80) +#define F_ACK_RPLY 1 +#define F_ACK_RPLY_MSK (0x08) +#define F_TX_DEVICE 1 +#define F_TX_DEVICE_MSK (0x30) +#define F_HOP_COUNT 1 +#define F_HOP_COUNT_MSK (0x07) +#define F_TRACTID_OS 2 +#define F_TRACTID_OS_MSK (0xFF) +#define SMPL_NWK_HDR_SIZE 3 + +#ifdef SMPL_SECURE + +#define F_SECURE_OS 3 + +#define F_SEC_CTR_OS 3 /* counter hint */ +#define F_SEC_CTR_OS_MSK (0xFF) +#define F_SEC_ICHK_OS 4 /* Message integrity check */ +#define F_SEC_ICHK_OS_MSK (0xFF) +#define F_SEC_MAC_OS 5 /* Message authentication code */ +#define F_SEC_MAC_OS_MSK (0xFF) + +#else + +#define F_SECURE_OS 0 + +#endif /* SMPL_SECURE */ + +#define F_APP_PAYLOAD_OS (SMPL_NWK_HDR_SIZE+F_SECURE_OS) + +/* sub field details. they are in the correct bit locations (already shifted) */ +#define F_RX_TYPE_USER_CTL 0x00 /* does not poll... */ +#define F_RX_TYPE_POLLS 0x40 /* polls for held messages */ + +#define F_ACK_REQ_TYPE 0x80 +#define F_ACK_RPLY_TYPE 0x08 +#define F_FRAME_FWD_TYPE 0x80 +#define F_FRAME_ENCRYPT_TYPE 0x40 + +/* device type fields */ +#define F_TX_DEVICE_ED 0x00 /* End Device */ +#define F_TX_DEVICE_RE 0x10 /* Range Extender */ +#define F_TX_DEVICE_AP 0x20 /* Access Point */ + +/* macro to get a field from a frame buffer */ +#define GET_FROM_FRAME(b,f) ((b)[f] & (f##_MSK)) + +/* Macro to put a value 'v' into a frame buffer 'b'. 'v' value must already be shifted + * if necessary. 'b' is a byte array + */ +#define PUT_INTO_FRAME(b,f,v) do {(b)[f] = ((b)[f] & ~(f##_MSK)) | (v); } while(0) + + +/* **** frame information objects + * info kept on each frame object + */ +#define FI_AVAILABLE 0 /* entry available for use */ +#define FI_INUSE_UNTIL_DEL 1 /* in use. will be explicitly reclaimed */ +#define FI_INUSE_UNTIL_TX 2 /* in use. will be reclaimed after Tx */ +#define FI_INUSE_UNTIL_FWD 3 /* in use until forwarded by AP */ +#define FI_INUSE_TRANSITION 4 /* being retrieved. do not delete in Rx ISR thread. */ + +typedef struct +{ + uint8_t rssi; + uint8_t lqi; +} sigInfo_t; + +typedef struct +{ + volatile uint8_t fi_usage; + uint8_t orderStamp; + mrfiPacket_t mrfiPkt; +} frameInfo_t; + + +/* prototypes */ +frameInfo_t *nwk_buildFrame(uint8_t, uint8_t *msg, uint8_t len, uint8_t hops); +#ifdef APP_AUTO_ACK +frameInfo_t *nwk_buildAckReqFrame(uint8_t, uint8_t *, uint8_t, uint8_t, volatile uint8_t *); +#endif +void nwk_receiveFrame(void); +void nwk_frameInit(uint8_t (*)(linkID_t)); +smplStatus_t nwk_retrieveFrame(rcvContext_t *, uint8_t *, uint8_t *, addr_t *, uint8_t *); +smplStatus_t nwk_sendFrame(frameInfo_t *, uint8_t txOption); +frameInfo_t *nwk_getSandFFrame(mrfiPacket_t *, uint8_t); +uint8_t nwk_getMyRxType(void); +void nwk_SendEmptyPollRspFrame(mrfiPacket_t *); +#ifdef APP_AUTO_ACK +void nwk_sendAckReply(mrfiPacket_t *, uint8_t); +#endif + +#ifndef END_DEVICE +/* only APs and REs repeat frames */ +void nwk_replayFrame(frameInfo_t *); +#endif + + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_globals.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_globals.c new file mode 100755 index 0000000..121b5e3 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_globals.c @@ -0,0 +1,258 @@ +/************************************************************************************************** + Filename: nwk_globals.c + Revised: $Date: 2009-10-27 20:48:11 -0700 (Tue, 27 Oct 2009) $ + Revision: $Revision: 20995 $ + + Description: This file manages global NWK data. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_globals.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static const addr_t sMyROMAddress = THIS_DEVICE_ADDRESS; +static addr_t sAPAddress; +static addr_t sMyRAMAddress; +static uint8_t sRAMAddressIsSet = 0; + +/* Version number set as a 4 byte quantity. Each byte is a revision number + * in the form w.x.y.z. The subfields are each limited to values 0x0-0xFF. + */ +static const smplVersionInfo_t sVersionInfo = { + 0x02, /* protocol version */ + 0x01, /* major revision number */ + 0x01, /* minor revision number */ + 0x01, /* maintenance release number */ + 0x00 /* special release */ + }; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_globalsInit + * + * @brief Initialization of global symbols + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_globalsInit(void) +{ + + memset(&sAPAddress, 0x00, sizeof(addr_t)); + + /* populate RAM address from ROM default if it hasn't laready been set + * using the IOCTL interface. + */ + if (!sRAMAddressIsSet) + { + memcpy(&sMyRAMAddress, &sMyROMAddress, sizeof(addr_t)); + sRAMAddressIsSet = 1; /* RAM address is now valid */ + } + + return; +} + +/****************************************************************************** + * @fn nwk_getMyAddress + * + * @brief Return a pointer to my address. It comes either from ROM as + * set in the configuration file or it was set using the IOCTL + * interface -- probably from random bytes. + * + * input parameters + * + * output parameters + * + * @return pointer to a constant address type object. + */ +addr_t const *nwk_getMyAddress(void) +{ + /* This call supports returning a valid pointer before either the + * initialization or external setting of the address. But caller needs + * to be careful -- if this routine is called immediately it will return + * the ROM address. If the application then sets the address using the + * IOCTL before doing the SMPL_Init() the original pointer is no longer + * valid as it points to the wrong address. + */ + return sRAMAddressIsSet ? &sMyRAMAddress : &sMyROMAddress; +} + +/****************************************************************************** + * @fn nwk_getFWVersion + * + * @brief Return a pointer to the current firmware version string. + * + * input parameters + * + * output parameters + * + * @return pointer to a constant uint16_t object. + */ +uint8_t const *nwk_getFWVersion() +{ + return sVersionInfo.fwVerString; +} + +/****************************************************************************** + * @fn nwk_getProtocolVersion + * + * @brief Return the current protocol version. + * + * input parameters + * + * output parameters + * + * @return Protocol version. + */ +uint8_t nwk_getProtocolVersion(void) +{ + return sVersionInfo.protocolVersion; +} + +/****************************************************************************** + * @fn nwk_setMyAddress + * + * @brief Set my address object if it hasn't already been set. This call + * is referenced by the IOCTL support used to change the device + * address. It is effective only if the address has not already + * been set. + * + * input parameters + * + * @param addr - pointer to the address object to be used to set my address. + * + * output parameters + * + * @return Returns non-zero if request is respected, otherwise returns 0. + */ +uint8_t nwk_setMyAddress(addr_t *addr) +{ + uint8_t rc = 0; + + if (!sRAMAddressIsSet) + { + memcpy(&sMyRAMAddress, addr, sizeof(addr_t)); + sRAMAddressIsSet = 1; /* RAM address is now valid */ + rc = 1; + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_setAPAddress + * + * @brief Set the AP's address. Called after the AP address is gleaned + * from the Join reply. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_setAPAddress(addr_t *addr) +{ + + memcpy((void *)&sAPAddress, (void *)addr, NET_ADDR_SIZE); + + return; +} + +/****************************************************************************** + * @fn nwk_getAPAddress + * + * @brief Get the AP's address. + * + * input parameters + * + * output parameters + * + * @return Pointer to a constant address object or null if the address has not + * yet been set. + */ +addr_t const *nwk_getAPAddress(void) +{ + addr_t addr; + + memset(&addr, 0x0, sizeof(addr)); + + return !memcmp(&sAPAddress, &addr, NET_ADDR_SIZE) ? 0 : &sAPAddress; +} + +/****************************************************************************** + * @fn nwk_getBCastAddress + * + * @brief Get the network broadcast address. + * + * input parameters + * + * output parameters + * + * @return Pointer to a constant address object. + */ +addr_t const *nwk_getBCastAddress(void) +{ + return (addr_t const *)mrfiBroadcastAddr; +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_globals.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_globals.h new file mode 100755 index 0000000..728c2ab --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_globals.h @@ -0,0 +1,51 @@ +/************************************************************************************************** + Filename: nwk_globals.h + Revised: $Date: 2008-07-30 11:22:21 -0700 (Wed, 30 Jul 2008) $ + Revision: $Revision: 17655 $ + Author: $Author: lfriedman $ + + Description: This header file supports the management of NWK global symbols. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_GLOBALS_H +#define NWK_GLOBALS_H + + +/* Prototypes */ +void nwk_globalsInit(void); +addr_t const *nwk_getMyAddress(void); +uint8_t nwk_setMyAddress(addr_t *addr); +void nwk_setAPAddress(addr_t *addr); +addr_t const *nwk_getAPAddress(void); +addr_t const *nwk_getBCastAddress(void); +uint8_t const *nwk_getFWVersion(void); +uint8_t nwk_getProtocolVersion(void); + + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_types.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_types.h new file mode 100755 index 0000000..bb277ba --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk/nwk_types.h @@ -0,0 +1,344 @@ +/************************************************************************************************** + Filename: nwk_types.h + Revised: $Date: 2009-01-13 11:31:14 -0800 (Tue, 13 Jan 2009) $ + Revision: $Revision: 18744 $ + Author: $Author: lfriedman $ + + Description: This header file defines the SimpliciTI typedefs. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_TYPES_H +#define NWK_TYPES_H + +#define NWK_TX_RETRY_COUNT 10 +#define NWK_RX_RETRY_COUNT 10 + +#define NWK_APP_REPLY_BIT (0x80) + +#define NET_ADDR_SIZE MRFI_ADDR_SIZE /* size of address in bytes */ + +#ifdef FREQUENCY_AGILITY +#define NWK_FREQ_TBL_SIZE MRFI_NUM_LOGICAL_CHANS +#else +#define NWK_FREQ_TBL_SIZE 1 +#endif + +typedef struct +{ + uint8_t addr[NET_ADDR_SIZE]; +} addr_t; + +typedef uint8_t linkID_t; +typedef uint8_t ccRadioStatus_t; + + +/* *********************************************** + * Begin IOCTL Support + * *********************************************** + */ +enum ioctlObject { + IOCTL_OBJ_FREQ, + IOCTL_OBJ_CRYPTKEY, + IOCTL_OBJ_RAW_IO, + IOCTL_OBJ_RADIO, + IOCTL_OBJ_AP_JOIN, + IOCTL_OBJ_ADDR, + IOCTL_OBJ_CONNOBJ, + IOCTL_OBJ_FWVER, + IOCTL_OBJ_PROTOVER, + IOCTL_OBJ_NVOBJ, + IOCTL_OBJ_TOKEN +}; + +enum ioctlAction { + IOCTL_ACT_SET, + IOCTL_ACT_GET, + IOCTL_ACT_READ, + IOCTL_ACT_WRITE, + IOCTL_ACT_RADIO_SLEEP, + IOCTL_ACT_RADIO_AWAKE, + IOCTL_ACT_RADIO_SIGINFO, + IOCTL_ACT_RADIO_RSSI, + IOCTL_ACT_RADIO_RXON, + IOCTL_ACT_RADIO_RXIDLE, + IOCTL_ACT_RADIO_SETPWR, + IOCTL_ACT_ON, + IOCTL_ACT_OFF, + IOCTL_ACT_SCAN, + IOCTL_ACT_DELETE +}; + +typedef enum ioctlObject ioctlObject_t; +typedef enum ioctlAction ioctlAction_t; + +enum ioctlLevel +{ + IOCTL_LEVEL_0, + IOCTL_LEVEL_1, + IOCTL_LEVEL_2 +}; + +typedef enum ioctlLevel ioctlLevel_t; + +typedef struct +{ + addr_t *addr; + uint8_t *msg; + uint8_t len; + uint8_t port; +} ioctlRawSend_t; + +typedef struct +{ + addr_t *addr; + uint8_t *msg; + uint8_t len; + uint8_t port; + uint8_t hopCount; +} ioctlRawReceive_t; + +/* + * Signal information support + */ +typedef int8_t rssi_t; + +typedef struct +{ + rssi_t rssi; + uint8_t lqi; +} rxMetrics_t; + +typedef struct +{ + linkID_t lid; /* input: Link ID for which signal info desired */ + rxMetrics_t sigInfo; +} ioctlRadioSiginfo_t; + + +/* *** Begin SET/GET token support *** */ +enum tokenType +{ + TT_LINK, /* Token Type is Link */ + TT_JOIN /* Token Type is Join */ +}; + +typedef enum tokenType tokenType_t; + +/* Create a union. If either token ever changes type it will make things easier. */ +typedef union +{ + uint32_t linkToken; + uint32_t joinToken; +} token_t; + +typedef struct +{ + tokenType_t tokenType; + token_t token; +} ioctlToken_t; +/* *** End SET/GET token support *** */ + + +/* + * Frequency Agility support + */ +typedef struct +{ + uint8_t logicalChan; +} freqEntry_t; + +typedef struct +{ + uint8_t numChan; + freqEntry_t *freq; +} ioctlScanChan_t; + +/* Security typedefs to make things easier if they change types */ +typedef uint8_t secMAC_t; +typedef uint8_t secFCS_t; + +/*************************************************************************************** + * ** NV Object support ** + * + * The following object supports saving and restoring the information + * necessary to save and restore a device connection context. + * + * On a GET interface populates the IOCTL object with the version and length (in bytes) + * of the current static connection iformation area. In addition it populates the address + * pointed to by 'objPtr' with the base address of the connection context. At this point + * the caller can either copy to or from the address. Note that this is a dangerous + * interface, as the caller is provided with direct access to the connection context. + * + * When restoring the connection context some sanity checks are possible. If the + * version or length elements of the saved context do not match those of the current + * static object the static object should not be populated. If this sanity fails the + * caller is not provided with the pointer to the conneciton ocntext. + * + * This interface is fairly simple and it is possible to get the address of the + * connection context to do a restore by simply doing a GET call. This avoids the + * sanity checks. However, this is not recommended because there may be other side + * effects of doing a SET that are necessary when restoring a context and are done + * only when the proper option is used to restore the connection context. + * + *************************************************************************************/ +typedef struct +{ + uint8_t objVersion; + uint16_t objLen; + uint8_t **objPtr; +} ioctlNVObj_t; + +/* *********************************************** + * End IOCTL Support + * *********************************************** + */ + +enum smplStatus { + SMPL_SUCCESS, + SMPL_TIMEOUT, + SMPL_BAD_PARAM, + SMPL_NOMEM, + SMPL_NO_FRAME, + SMPL_NO_LINK, + SMPL_NO_JOIN, + SMPL_NO_CHANNEL, + SMPL_NO_PEER_UNLINK, + SMPL_TX_CCA_FAIL, + SMPL_NO_PAYLOAD, + SMPL_NO_AP_ADDRESS, + SMPL_NO_ACK +}; + +typedef enum smplStatus smplStatus_t; + +/* NWK application frame handling status codes */ +enum fhStatus +{ + FHS_RELEASE, /* handled in interrupt thread */ + FHS_KEEP, /* handled by background application */ + FHS_REPLAY /* non-ED case: NWK frame not for me that should be replayed */ +}; + +typedef enum fhStatus fhStatus_t; + +/******** BEGIN: Object support for parameter context in queue management *********/ +enum rcvType +{ + RCV_NWK_PORT, + RCV_APP_LID, + RCV_RAW_POLL_FRAME +}; + +typedef enum rcvType rcvType_t; + +/* Tx options type */ +typedef uint16_t txOpt_t; + +typedef struct +{ + rcvType_t type; + union + { + linkID_t lid; + uint8_t port; + mrfiPacket_t *pkt; + } t; +} rcvContext_t; +/******** END: Object support for parameter context in queue management *********/ + +#define SMPL_FWVERSION_SIZE 4 + +typedef struct +{ + uint8_t protocolVersion; + uint8_t fwVerString[SMPL_FWVERSION_SIZE]; +} smplVersionInfo_t; + +/* The following typedef is used to standardize the application Transaction ID field. + * This field can be used for detection of out-of-order application payloads if this + * is an issue. There is no real reason to use more than a byte for this support. But + * if this typedef is anything other than uint8_t be sure to attend to alignment and + * endian issues. + */ +typedef uint8_t appPTid_t; + +#ifdef ACCESS_POINT +/* Store-and-forward client info object */ +typedef struct +{ + addr_t clientAddr; + appPTid_t lastTID; +} sfClientInfo_t; + +typedef struct +{ + uint8_t curNumSFClients; + sfClientInfo_t sfClients[NUM_STORE_AND_FWD_CLIENTS]; +} sfInfo_t; +#endif + +/**************************************************************************************** + * SOME USEFUL MACROS + ****************************************************************************************/ + +/* Delay loop support. Requires mrfi.h */ +#define NWK_DELAY(spin) MRFI_DelayMs(spin) +#define NWK_REPLY_DELAY() MRFI_ReplyDelay(); + +/* Network applications may need to remember radio state because the user + * application may choose to turn Rx off. These macros help get and restore + * the radio Rx state. The macros should be in the same code block at the same level. + * The argument 's' is the 'current' radio state and should be set in the code block + * with a call to MRFI_GetRadioState() _before_ using the macros. + * + * Used extensively by NWK but user applications may use them as well. But it is + * much more liekly that an application will know the radio state since it likely + * will have set it with IOCTL calls. Requires mrfi.h. + */ +#define NWK_CHECK_FOR_SETRX(s) if (MRFI_RADIO_STATE_RX != s) \ + { \ + if (MRFI_RADIO_STATE_OFF == s) \ + { \ + MRFI_WakeUp(); \ + } \ + MRFI_RxOn(); \ + } + +#define NWK_CHECK_FOR_RESTORE_STATE(s) if (MRFI_RADIO_STATE_RX != s) \ + { \ + if (MRFI_RADIO_STATE_OFF == s) \ + { \ + MRFI_Sleep(); \ + } \ + else \ + { \ + MRFI_RxIdle(); \ + } \ + } +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_freq.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_freq.c new file mode 100755 index 0000000..2a93c39 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_freq.c @@ -0,0 +1,619 @@ +/************************************************************************************************** + Filename: nwk_freq.c + Revised: $Date: 2008-12-10 13:50:46 -0800 (Wed, 10 Dec 2008) $ + Revision: $Revision: 18594 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Freq network application. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ +/****************************************************************************** + * INCLUDES + */ + +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk.h" +#include "nwk_frame.h" +#include "nwk_freq.h" +#include "nwk_globals.h" +#include "nwk_api.h" +#include "nwk_security.h" + +#if defined( FREQUENCY_AGILITY ) +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static freqEntry_t sCurLogicalChan; +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +static fhStatus_t handle_freq_cmd(mrfiPacket_t *); +static fhStatus_t send_ping_reply(mrfiPacket_t *); +#ifndef ACCESS_POINT +static uint8_t change_channel_cmd_is_valid(mrfiPacket_t *); +#endif +#ifdef RANGE_EXTENDER +/* REs must replay frame before changing channels */ +static void replayFirst(mrfiPacket_t *); +#endif +#ifdef ACCESS_POINT +/* only the AP can broadcast this command */ +static void broadcast_channel_change(uint8_t); +#else +/* APs do not process this frame */ +static void change_channel_cmd(mrfiPacket_t *); +#endif + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_freqInit + * + * @brief Initialize NWK Frequency application. + * + * @return none. + */ +void nwk_freqInit(void) +{ + + memset(&sCurLogicalChan, 0x0, sizeof(sCurLogicalChan)); + + /* pick a random value to start the transaction ID for this app. */ + sTid = MRFI_RandomByte(); + + return; +} + +/*************************************************************************** + * @fn nwk_setChannel + * + * @brief Set requested logical channel. Accessed by application + * through IOCTL interface + * + * input parameters + * @param chan - pointer to channel object of requested channel + * + * @return status of operation: + * SMPL_SUCCESS if channel set + * SMPL_BAD_PARAM if requested channel is out of range + */ +smplStatus_t nwk_setChannel(freqEntry_t *chan) +{ + smplStatus_t rc = SMPL_BAD_PARAM; + + if (chan->logicalChan < NWK_FREQ_TBL_SIZE) + { + MRFI_SetLogicalChannel(chan->logicalChan); + sCurLogicalChan = *chan; + rc = SMPL_SUCCESS; + } + return rc; +} + +/****************************************************************************** + * @fn nwk_getChannel + * + * @brief Get current logical channel. Accessed by application through + * IOCTL interface + * + * input parameters + * @param chan - pointer to channel object of requested channel + * + * output parameters + * @param chan - populated channel object + * + * @return none. + */ +void nwk_getChannel(freqEntry_t *chan) +{ + *chan = sCurLogicalChan; + + return; +} + +/****************************************************************************** + * @fn handle_freq_cmd + * + * @brief Handle a Frequency application command. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return Return FHS_RELEASE if caller should release frame otherwise + * return FHS_REPLAY. + */ +static fhStatus_t handle_freq_cmd(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS)) + { + case FREQ_REQ_PING: + rc = send_ping_reply(frame); + break; + +#ifndef ACCESS_POINT + case FREQ_REQ_MOVE: +#ifdef RANGE_EXTENDER + replayFirst(frame); +#endif + /* Make sure the change channel Freq command came from + * a valid source before obeying. + */ + if (change_channel_cmd_is_valid(frame)) + { + change_channel_cmd(frame); + } + break; +#endif + +#ifdef ACCESS_POINT + case FREQ_REQ_REQ_MOVE: + break; +#endif + default: + break; + } + + return rc; +} + +#ifndef ACCESS_POINT +/****************************************************************************** + * @fn change_channel_cmd_is_valid + * + * @brief Check validity of a change channel command frame. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return Returns non-zero if command is valid, otherwise returns 0. + * Command is valid if either: + * - frame is directed + * - frame is from an AP and we know about that AP + * + * It is possible that either we don't know about an AP or that + * we do but this frame comes from another AP in range. + */ +static uint8_t change_channel_cmd_is_valid(mrfiPacket_t *frame) +{ + uint8_t rc = 0; + addr_t const *apAddr; + + /* If this was a directed frame obey the command. */ + if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + rc = 1; + } + else + { + /* Do we know about an AP? If not assume frame bogus. */ + apAddr = nwk_getAPAddress(); + if (apAddr) + { + /* Yes, we know about an AP. Is that who sent it? */ + if (!memcmp(apAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE)) + { + /* OK. We obey. */ + rc = 1; + } + } + } + + return rc; +} +#endif /* !ACCESS_POINT */ + +#ifdef RANGE_EXTENDER +/****************************************************************************** + * @fn replayFirst + * + * @brief Range Extenders must replay the change-channel boradcast + * frame before actually changing its own channel. + * + * input parameters + * @param frame - pointer to frame with command context + * + * @return void + */ + +/* This routine takes care of some awkwardness. From the dispatch thread all + * we have is a pointer to the mrfiPacket_t element in the frame buffer into + * which the frame was retrieved. But to call the replay routine we need the + * entire frame information structure frameInfo_t. This routine regenerates + * the frame information structure pointer and then calls the replay routine. + * + * This approach requires that the disptach thread guarantee that it will + * always pass a pointer to the mrfiPacket_t structure in the frame + * information structure and not a copy of the mrfipacket_t element. It is + * either the approach here or change all the NWK application dispatch routine + * argument types. This latter has the downside of interfering with any + * user-implemented NWK applications. It also needlessly complicates the argument + * handling: except for this instance all any routine needs is the mrfiPacket_t + * pointer. + */ +static void replayFirst(mrfiPacket_t *frame) +{ + frameInfo_t *fiptr; + uint16_t offset = (uint16_t)&(((frameInfo_t *)0)->mrfiPkt); + + fiptr = (frameInfo_t *)(((uint8_t *)frame) - ((uint8_t *)offset)); + + nwk_replayFrame(fiptr); + + return; +} +#endif /* RANGE_EXTENDER */ + +#ifndef ACCESS_POINT +/******************************************************************************** + * @fn change_channel_cmd + * + * @brief Change to channel specified in received frame. Polling devices + * might be awake when the broadcast occurs but we want the channel + * change recovery to occur in a disciplined manner using the + * polling code. Also, with certain Test sceanrios in which a + * sleeping device is emulated we want to emulate 'missing' the + * broadcast change-channel command. + * + * input parameters + * @param frame - pointer to frame containing target logical channel. + * + * @return none. + */ +static void change_channel_cmd(mrfiPacket_t *frame) +{ +#if !defined( RX_POLLS ) + freqEntry_t chan; + + chan.logicalChan = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+F_CHAN_OS); + + nwk_setChannel(&chan); +#endif + return; +} +#endif /* !ACCESS_POINT */ + +/****************************************************************************** + * @fn send_ping_reply + * + * @brief Send Frequency application ping reply. + * + * input parameters + * @param frame - pointer to frame from pinger. + * + * @return FHS_RELEASE unless this isn't an Access Point. In this case for + * flow to et this far it is a Range Extender, so replay the frame + * by returning FHW_REPLAY + */ +static fhStatus_t send_ping_reply(mrfiPacket_t *frame) +{ +#ifdef ACCESS_POINT + uint8_t msg[FREQ_REQ_PING_FRAME_SIZE]; + frameInfo_t *pOutFrame; + + /* original request with reply bit on */ + msg[FB_APP_INFO_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS) | NWK_APP_REPLY_BIT; + msg[FB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+FB_TID_OS); + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_FREQ, msg, sizeof(msg), MAX_HOPS_FROM_AP)) + { + /* destination address is the source address of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + /* must use transaction ID of source frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_TRACTID_OS, (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS))); +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + + return FHS_RELEASE; +#else + return FHS_REPLAY; +#endif /* ACCESS_POINT */ +} + +/**************************************************************************************** + * @fn nwk_processFreq + * + * @brief Process a Frequency application frame. + * + * input parameters + * @param frame - pointer to frame + * + * @return Disposition for frame: either release (FHS_RELEASE) or replay (FHS_REPLAY). + */ +fhStatus_t nwk_processFreq(mrfiPacket_t *frame) +{ + fhStatus_t rc = FHS_RELEASE; + uint8_t replyType; + + /* Make sure this is a reply and see if we sent this. Validate the + * packet for reception by client app. + */ + if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, FB_APP_INFO_OS, FB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else if (SMPL_NOT_REPLY == replyType) + { + rc = handle_freq_cmd(frame); + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_scanForChannels + * + * @brief Scan for channels by sending a ping frame on each channel in the + * channel table and listen for a reply. + * + * input parameters + * @param channels - pointer to area to receive list of channels from which + * ping replies were received. + * + * output parameters + * @param channels - populated list of channels. + * + * @return statuis of operation.. + */ +uint8_t nwk_scanForChannels(freqEntry_t *channels) +{ + uint8_t msg[FREQ_REQ_PING_FRAME_SIZE], i, num=0, notBcast = 1; + addr_t *apAddr, retAddr; + uint8_t radioState = MRFI_GetRadioState(); + freqEntry_t chan; + freqEntry_t curChan; + + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + nwk_getChannel(&curChan); + + /* send to AP. If we don't know AP address, broadcast. */ + apAddr = (addr_t *)nwk_getAPAddress(); + if (!apAddr) + { + apAddr = (addr_t *)nwk_getBCastAddress(); + notBcast = 0; + } + + for (i=0; ilogicalChan); +#endif /* ACCESS_POINT */ + rc = nwk_setChannel((freqEntry_t *)val); + break; + + case IOCTL_ACT_GET: + nwk_getChannel((freqEntry_t *)val); + rc = SMPL_SUCCESS; + break; + + case IOCTL_ACT_SCAN: + { + ioctlScanChan_t *sc = (ioctlScanChan_t *)val; + + sc->numChan = nwk_scanForChannels(sc->freq); + rc = SMPL_SUCCESS; + } + break; + + default: + rc = SMPL_BAD_PARAM; + break; + } + + return rc; +} + +/****************************************************************************** + * @fn broadcast_channel_change + * +* @brief For Access Point only: broadcast a channel change frame. + * + * input parameters + * @param idx - index into channel table of new (logical) channel + * + * @return none. + */ +#ifdef ACCESS_POINT +#define CC_REDUNDANCY 1 /* Change-channel redundancy count */ +static void broadcast_channel_change(uint8_t idx) +{ + ioctlRawSend_t send; + uint8_t msg[FREQ_REQ_MOVE_FRAME_SIZE]; + uint8_t repeat = CC_REDUNDANCY; + + if (idx >= NWK_FREQ_TBL_SIZE) + { + return; + } + + msg[FB_APP_INFO_OS] = FREQ_REQ_MOVE; + msg[F_CHAN_OS] = idx; + + send.addr = (addr_t *)nwk_getBCastAddress(); + send.msg = msg; + send.len = sizeof(msg); + send.port = SMPL_PORT_FREQ; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); + /* Redundancy addresses the fact that an RE (or any always-listening + * device) might miss the command + */ + while (repeat--) + { + NWK_DELAY(250); + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); + } +} +#endif /* ACCESS_POINT */ + +#else /* FREQUENCY_AGILITY */ + +/********************************************************************************** + * @fn nwk_freqInit + * + * @brief Initialize NWK Frequency application. Stub when Frequency Agility + * not supported. + * + * @return none. + */ +void nwk_freqInit(void) +{ + return; +} + +/**************************************************************************************** + * @fn nwk_processFreq + * + * @brief Process a Frequency application frame. Stub when Frequency Agility + * not supported. + * + * input parameters + * @param frame - pointer to frame + * + * @return Disposition for frame: either release (FHS_RELEASE) or replay (FHS_REPLAY). + */ +fhStatus_t nwk_processFreq(mrfiPacket_t *frame) +{ + return FHS_RELEASE; +} + +#endif /* FREQUENCY_AGILITY */ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_freq.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_freq.h new file mode 100755 index 0000000..4cc5f11 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_freq.h @@ -0,0 +1,72 @@ +/************************************************************************************************** + Filename: nwk_freq.h + Revised: $Date: 2008-05-06 16:48:33 -0700 (Tue, 06 May 2008) $ + Revision: $Revision: 17025 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI Freq network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +#ifndef NWK_FREQ_H +#define NWK_FREQ_H + +/* application payload offsets */ +/* both */ +#define FB_APP_INFO_OS 0 +#define FB_TID_OS 1 + +/* Logical channel number for MOVE request. Frame brodcast so no TID + * is used. Channel number can occupy the TID location. Same offset + * used for channel change request. No reply to that frame. + */ +#define F_CHAN_OS 1 + +/* MGMT frame application requests */ +#define FREQ_REQ_MOVE 0x01 +#define FREQ_REQ_PING 0x02 +#define FREQ_REQ_REQ_MOVE 0x03 + +/* change the following as protocol developed */ +#define MAX_FREQ_APP_FRAME 2 + +/* set the out frame sizes */ +#define FREQ_REQ_MOVE_FRAME_SIZE 2 +#define FREQ_REQ_PING_FRAME_SIZE 2 + +/* prototypes */ +void nwk_freqInit(void); +fhStatus_t nwk_processFreq(mrfiPacket_t *); +#if defined( FREQUENCY_AGILITY ) +smplStatus_t nwk_setChannel(freqEntry_t *); +void nwk_getChannel(freqEntry_t *); +uint8_t nwk_scanForChannels(freqEntry_t *); +smplStatus_t nwk_freqControl(ioctlAction_t, void *); +#endif + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ioctl.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ioctl.c new file mode 100755 index 0000000..0dcd14a --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ioctl.c @@ -0,0 +1,349 @@ + +/************************************************************************************************** + Filename: nwk_ioctl.c + Revised: $Date: 2009-01-13 11:31:14 -0800 (Tue, 13 Jan 2009) $ + Revision: $Revision: 18744 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI IOCTL implmentation. This interface + gives applications access to the "driver" network level functions + when necessary. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_ioctl.h" +#include "nwk_globals.h" +#include "nwk_security.h" +#ifdef ACCESS_POINT +#include "nwk_join.h" +#endif + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + + +/****************************************************************************** + * @fn nwk_rawSend + * + * @brief Builds an outut frame based on information provided by the + * caller. This function allows a raw transmission to the target + * if the network address is known. this function is used a lot + * to support NWK applications. + * + * input parameters + * @param info - pointer to strcuture containing info on how to build + * the outgoing frame. + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_NOMEM - no room in output frame queue + * SMPL_TX_CCA_FAIL - CCA failure + */ +smplStatus_t nwk_rawSend(ioctlRawSend_t *info) +{ + frameInfo_t *pOutFrame; + uint8_t hops; + + /* If we know frame is going to or from the AP then we can reduce the hop + * count. + */ + switch (info->port) + { + case SMPL_PORT_JOIN: + case SMPL_PORT_FREQ: + case SMPL_PORT_MGMT: + hops = MAX_HOPS_FROM_AP; + break; + + default: + hops = MAX_HOPS; + break; + } + + if (pOutFrame = nwk_buildFrame(info->port, info->msg, info->len, hops)) + { + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), info->addr, NET_ADDR_SIZE); +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, info->len, 0); +#endif /* SMPL_SECURE */ + return nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_CCA); + } + return SMPL_NOMEM; +} + +/****************************************************************************** + * @fn nwk_rawReceive + * + * @brief Retriievs specified from from the input frame queue. Additional + * information such as source address and hop count may also be + * retrieved + * + * input parameters + * @param info - pointer to structure containing info on what to retrieve + * + * output parameters - actually populated by nwk_retrieveFrame() + * info->msg - application payload copied here + * info->len - length of received application payload + * info->addr - if non-NULL points to memory to be populated with + * source address of retrieved frame. + * info->hopCount - if non-NULL points to memory to be populated with + * hop count of retrieved frame. + * + * @return Status of operation. + */ +smplStatus_t nwk_rawReceive(ioctlRawReceive_t *info) +{ + rcvContext_t rcv; + + rcv.type = RCV_NWK_PORT; + rcv.t.port = info->port; + + return nwk_retrieveFrame(&rcv, info->msg, &info->len, info->addr, &info->hopCount); +} + +/****************************************************************************** + * @fn nwk_radioControl + * + * @brief Handle radio control functions. + * + * input parameters + * @param action - radio operation to perform. currently suppoerted: + * sleep/unsleep + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_radioControl(ioctlAction_t action, void *val) +{ + smplStatus_t rc = SMPL_SUCCESS; + + if (IOCTL_ACT_RADIO_SLEEP == action) + { + /* go to sleep mode. */ + MRFI_RxIdle(); + MRFI_Sleep(); + } + else if (IOCTL_ACT_RADIO_AWAKE == action) + { + MRFI_WakeUp(); + +#if !defined( END_DEVICE ) + MRFI_RxOn(); +#endif + + } + else if (IOCTL_ACT_RADIO_SIGINFO == action) + { + ioctlRadioSiginfo_t *pSigInfo = (ioctlRadioSiginfo_t *)val; + connInfo_t *pCInfo = nwk_getConnInfo(pSigInfo->lid); + + if (!pCInfo) + { + return SMPL_BAD_PARAM; + } + memcpy(&pSigInfo->sigInfo, &pCInfo->sigInfo, sizeof(pCInfo->sigInfo)); + } + else if (IOCTL_ACT_RADIO_RSSI == action) + { + *((rssi_t *)val) = MRFI_Rssi(); + } + else if (IOCTL_ACT_RADIO_RXON == action) + { + MRFI_RxOn(); + } + else if (IOCTL_ACT_RADIO_RXIDLE == action) + { + MRFI_RxIdle(); + } +#ifdef EXTENDED_API + else if (IOCTL_ACT_RADIO_SETPWR == action) + { + uint8_t idx; + + switch (*(ioctlLevel_t *)val) + { + case IOCTL_LEVEL_2: + idx = 2; + break; + + case IOCTL_LEVEL_1: + idx = 1; + break; + + case IOCTL_LEVEL_0: + idx = 0; + break; + + default: + return SMPL_BAD_PARAM; + } + MRFI_SetRFPwr(idx); + return SMPL_SUCCESS; + } +#endif /* EXTENDED_API */ + else + { + rc = SMPL_BAD_PARAM; + } + return rc; +} + +/****************************************************************************** + * @fn nwk_joinContext + * + * @brief For Access Points we need a way to support changing the Join + * context. This will allow arbitration bewteen potentially nearby + * Access Points when a new device is joining. + * + * input parameters + * @param action - Join context is either on or off. + * + * output parameters + * + * @return Status of operation. Currently always succeeds. + */ +#ifdef ACCESS_POINT +smplStatus_t nwk_joinContext(ioctlAction_t action) +{ + nwk_setJoinContext((IOCTL_ACT_ON == action) ? JOIN_CONTEXT_ON : JOIN_CONTEXT_OFF); + + return SMPL_SUCCESS; +} +#endif + +/****************************************************************************** + * @fn nwk_deviceAddress + * + * @brief Set or Get this device address. The Set must be done before + * SMPL_Init() for it to take effect. The Get is always legal but + * the value could be invalid if it is called before a valid set + * call is made. + * + * input parameters + * @param action - Gte or Set + * @param addr - pointer to address object containing value on Set + * + * output parameters + * @param addr - pointer to address object to receive value on Get. + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Action request illegal or a Set request + * was not respected. + */ +smplStatus_t nwk_deviceAddress(ioctlAction_t action, addr_t *addr) +{ + smplStatus_t rc = SMPL_BAD_PARAM; + + if (IOCTL_ACT_GET == action) + { + memcpy(addr, nwk_getMyAddress(), sizeof(addr_t)); + rc = SMPL_SUCCESS; + } + else if (IOCTL_ACT_SET == action) + { + if (nwk_setMyAddress(addr)) + { + rc = SMPL_SUCCESS; + } + } + + return rc; +} + +/****************************************************************************** + * @fn nwk_connectionControl + * + * @brief Access to connection table. Currently supports only deleting + * a connection from the table. + * + * input parameters + * @param action - Connection control action (only delete is curently valid). + * @param val - pointer to Link ID of connection on which to operate. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_BAD_PARAM Action is not delete + * Link ID is the UUD Link ID + * No connection table info for Link ID + */ +smplStatus_t nwk_connectionControl(ioctlAction_t action, void *val) +{ + connInfo_t *pCInfo; + linkID_t lid = *((linkID_t *)val); + + if (IOCTL_ACT_DELETE != action) + { + return SMPL_BAD_PARAM; + } + + if ((SMPL_LINKID_USER_UUD == lid) || + (!(pCInfo=nwk_getConnInfo(lid)))) + { + return SMPL_BAD_PARAM; + } + + nwk_freeConnection(pCInfo); + + return SMPL_SUCCESS; +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ioctl.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ioctl.h new file mode 100755 index 0000000..fa5b961 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ioctl.h @@ -0,0 +1,53 @@ +/************************************************************************************************** + Filename: nwk_ioctl.h + Revised: $Date: 2008-04-29 15:47:05 -0700 (Tue, 29 Apr 2008) $ + Revision: $Revision: 16972 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI IOCTL implmentation. This interface + gives applications access to the "driver" network level functions + when necessary. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + + +#ifndef NWK_IOCTL_H +#define NWK_IOCTL_H + +/* prototypes */ +smplStatus_t nwk_rawSend(ioctlRawSend_t *); +smplStatus_t nwk_rawReceive(ioctlRawReceive_t *); +smplStatus_t nwk_radioControl(ioctlAction_t, void *); +smplStatus_t nwk_deviceAddress(ioctlAction_t, addr_t *); +smplStatus_t nwk_connectionControl(ioctlAction_t, void *); +#ifdef ACCESS_POINT +smplStatus_t nwk_joinContext(ioctlAction_t); +#endif + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_join.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_join.c new file mode 100755 index 0000000..b96325f --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_join.c @@ -0,0 +1,583 @@ +/************************************************************************************************** + Filename: nwk_join.c + Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ + Revision: $Revision: 18697 $ + + Description: This file supports the SimpliciTI Join network application. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_link.h" +#include "nwk_join.h" +#include "nwk_globals.h" +#include "nwk_freq.h" +#include "nwk_security.h" +#include "nwk_mgmt.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +static uint32_t sJoinToken = 0; +static uint8_t (*spCallback)(linkID_t) = NULL; +static volatile uint8_t sTid = 0; + +#ifdef ACCESS_POINT +static sfInfo_t *spSandFContext = NULL; +static uint8_t sJoinOK = 0; +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +#ifdef ACCESS_POINT +static void smpl_send_join_reply(mrfiPacket_t *frame); +static uint32_t generateLinkToken(void); +static void handleJoinRequest(mrfiPacket_t *); +#endif /* ACCESS_POINT */ + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_joinInit + * + * @brief Initialize Join application. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_joinInit(uint8_t (*pf)(linkID_t)) +{ + if (!sJoinToken) + { + sJoinToken = DEFAULT_JOIN_TOKEN; + } + + spCallback = pf; + (void) spCallback; /* keep compiler happy if we don't use this */ + + sTid = MRFI_RandomByte() ; + +#ifdef ACCESS_POINT + /* set link token to something other than deafult if desired */ + nwk_setLinkToken(generateLinkToken()); +#if defined(STARTUP_JOINCONTEXT_ON) + sJoinOK = 1; +#elif defined(STARTUP_JOINCONTEXT_OFF) + sJoinOK = 0; +#else +#error ERROR: Must define either STARTUP_JOINCONTEXT_ON or STARTUP_JOINCONTEXT_OFF +#endif + spSandFContext = nwk_getSFInfoPtr(); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_setJoinToken + * + * @brief Sets the join token. + * + * input parameters + * @param token - join token to be used on this network. + * + * output parameters + * no room in output queue. + * + * @return void + */ +void nwk_setJoinToken(uint32_t token) +{ + /* only set if the supplied token is non-zero. */ + if (token) + { + sJoinToken = token; + } + + return; +} + +/****************************************************************************** + * @fn nwk_getJoinToken + * + * @brief Gets the current join token. + * + * input parameters + * + * output parameters + * @param pToken - pointer to the returned value. + * + * @return Current link token + */ +void nwk_getJoinToken(uint32_t *pToken) +{ + /* only set if the supplied token is non-zero. */ + if (pToken) + { + *pToken = sJoinToken; + } + + return; +} + +/****************************************************************************** + * @fn generateLinkToken + * + * @brief Generate the link token to be used for the network controlled + * by this Access Point. + * + * input parameters + * + * output parameters + * + * @return void + */ +#ifdef ACCESS_POINT +static uint32_t generateLinkToken(void) +{ + return 0xDEADBEEF; +} + +/****************************************************************************** + * @fn smpl_send_join_reply + * + * @brief Send the Join reply. Include the Link token. If the device is + * a polling sleeper put it into the list of store-and-forward + * clients. + * + * input parameters + * @param frame - join frame for which a reply is needed...maybe + * + * output parameters + * + * @return void + */ +static void smpl_send_join_reply(mrfiPacket_t *frame) +{ + frameInfo_t *pOutFrame; + uint8_t msg[JOIN_REPLY_FRAME_SIZE]; + + /* Is this a legacy frame? If so continue. Otherwise check verion.*/ + if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > JOIN_LEGACY_MSG_LENGTH) + { + /* see if protocol version is correct... */ + if (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_PROTOCOL_VERSION_OS) != nwk_getProtocolVersion()) + { + /* Accommodation of protocol version differences can be noted or accomplished here. + * Otherwise, no match and the board goes back + */ + return; + } + } + + + /* see if join token is correct */ + { + uint32_t jt; + + nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_JOIN_TOKEN_OS, &jt, sizeof(jt)); + if (jt != sJoinToken) + { + return; + } + } + + /* send reply with tid, the link token, and the encryption context */ + { + uint32_t linkToken; + + nwk_getLinkToken(&linkToken); + nwk_putNumObjectIntoMsg((void *)&linkToken, msg+JR_LINK_TOKEN_OS, sizeof(linkToken)); + } + msg[JR_CRYPTKEY_SIZE_OS] = SEC_CRYPT_KEY_SIZE; + msg[JB_REQ_OS] = JOIN_REQ_JOIN | NWK_APP_REPLY_BIT; + /* sender's tid... */ + msg[JB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+JB_TID_OS); + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_JOIN, msg, sizeof(msg), MAX_HOPS_FROM_AP)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + +#ifdef AP_IS_DATA_HUB + /* if source device supports ED objects save source address to detect duplicate joins */ + if (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+J_NUMCONN_OS)) + { + if (nwk_saveJoinedDevice(frame) && spCallback) + { + spCallback(0); + } + } +#endif + } + else + { + /* oops -- no room left for Tx frame. Don't send reply. */ + return; + } + + /* If this device polls we need to provide store-and-forward support */ + if (GET_FROM_FRAME(MRFI_P_PAYLOAD(frame),F_RX_TYPE) == F_RX_TYPE_POLLS) + { + uint8_t loc; + + /* Check duplicate status */ + if (!nwk_isSandFClient(MRFI_P_SRC_ADDR(frame), &loc)) + { + uint8_t *pNumc = &spSandFContext->curNumSFClients; + sfClientInfo_t *pClient = &spSandFContext->sfClients[*pNumc]; + + /* It's not a duplicate. Save it if there's room */ + if (*pNumc < NUM_STORE_AND_FWD_CLIENTS) + { + memcpy(pClient->clientAddr.addr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + *pNumc = *pNumc + 1; + } + else + { + /* No room left. Just return and don't send reply. */ + return; + } + } + else + { + /* We get here if it's a duplicate. We drop through and send reply. + * Reset the S&F marker in the Management application -- we should + * assume that the Client reset so the TID will be random. If this is + * simply a duplicate frame it causes no harm. + */ + nwk_resetSFMarker(loc); + } + } + +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + + /* It's not S&F or it is but we're OK to send reply. */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + + return; +} + +/****************************************************************************** + * @fn nwk_join + * + * @brief Stub Join function for Access Points. + * + * input parameters + * + * output parameters + * + * @return Always returns SMPL_SUCCESS. + */ +smplStatus_t nwk_join(void) +{ + return SMPL_SUCCESS; +} + +/****************************************************************************** + * @fn nwk_isSandFClient + * + * @brief Helper function to see if the destination of a frame we have is + * one of AP's store-and-forward clients. + * + * input parameters + * @param fPtr - pointer to address in frame in question + * + * output parameters + * @param entLoc - pointer to receive entry location in array of clients. + * + * @return Returns client info structure pointer if the destination is a + * store-and-forward client, else 0. + */ +sfClientInfo_t *nwk_isSandFClient(uint8_t *pAddr, uint8_t *entLoc) +{ + uint8_t i; + sfClientInfo_t *pSFClient = spSandFContext->sfClients; + + for (i=0; icurNumSFClients; ++i, ++pSFClient) + { + if (!memcmp(&pSFClient->clientAddr.addr, pAddr, NET_ADDR_SIZE)) + { + *entLoc = i; + return pSFClient; + } + } + + return 0; +} + +/****************************************************************************** + * @fn nwk_setJoinContext + * + * @brief Helper function to set Join context for Access Point. This will + * allow arbitration bewteen potentially nearby Access Points when + * a new device is joining. + * + * input parameters + * @param which - Join context is either off or on + * + * output parameters + * + * @return void + */ +void nwk_setJoinContext(uint8_t which) +{ + sJoinOK = (JOIN_CONTEXT_ON == which) ? 1 : 0; + + return; +} + +/****************************************************************************** + * @fn handleJoinRequest + * + * @brief Dispatches handler for specfic join request + * + * input parameters + * + * @param frame - Join frame received + * + * output parameters + * + * @return void + */ +static void handleJoinRequest(mrfiPacket_t *frame) +{ + if (JOIN_LEGACY_MSG_LENGTH == (MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS)) + { + /* Legacy frame. Spoof a join request */ + *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS) = JOIN_REQ_JOIN; + } + + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS)) + { + case JOIN_REQ_JOIN: + smpl_send_join_reply(frame); + break; + + default: + break; + } + + return; +} + +#else /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_join + * + * @brief Join functioanlity for non-AP devices. Send the Join token + * and wait for the reply. + * + * input parameters + * + * output parameters + * + * @return Status of operation. + */ +smplStatus_t nwk_join(void) +{ + uint8_t msg[JOIN_FRAME_SIZE]; + uint32_t linkToken; + addr_t apAddr; + uint8_t radioState = MRFI_GetRadioState(); + smplStatus_t rc = SMPL_NO_JOIN; + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + +#if defined( FREQUENCY_AGILITY ) + uint8_t i, numChan; + freqEntry_t channels[NWK_FREQ_TBL_SIZE]; + + if (!(numChan=nwk_scanForChannels(channels))) + { + return SMPL_NO_CHANNEL; + } + + for (i=0; i +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_link.h" +#include "nwk_globals.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +static uint32_t sLinkToken = 0; +static volatile uint8_t sListenActive = 0; +#if NUM_CONNECTIONS > 0 +static volatile linkID_t sServiceLinkID[NUM_CONNECTIONS]; +#endif +static volatile uint8_t sNumLinkers = 0; +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ + +#define SENT_REPLY 1 +#define SENT_NO_REPLY 2 +static uint8_t smpl_send_link_reply(mrfiPacket_t *); +static fhStatus_t handleLinkRequest(mrfiPacket_t *); +#if defined(EXTENDED_API) +static void smpl_send_unlink_reply(mrfiPacket_t *); +#endif + + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_linkInit + * + * @brief Initialize link app. Set link token to the default. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_linkInit(void) +{ + if (!sLinkToken) + { + /* if the link token has not been set externally by the time we get here + * (such as by the ioctl token-setting interface) assign the default + */ + sLinkToken = DEFAULT_LINK_TOKEN; + } + + /* set a non-zero TID. */ + while (!(sTid = MRFI_RandomByte())) ; + +#if NUM_CONNECTIONS > 0 + memset((void *)&sServiceLinkID, 0x0, sizeof(sServiceLinkID)); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_setLinkToken + * + * @brief Sets the link token received in a Join reply. + * + * input parameters + * @param token - Link token to be used on this network to link to any peer. + * + * output parameters + * + * @return void + */ +void nwk_setLinkToken(uint32_t token) +{ + /* only set if the supplied token is non-zero. */ + if (token) + { + sLinkToken = token; + } + + return; +} + +/****************************************************************************** + * @fn nwk_getLinkToken + * + * @brief Gets the current link token. + * + * input parameters + * + * output parameters + * @param pToken - pointer to the returned value. + * + * @return Current link token + */ +void nwk_getLinkToken(uint32_t *pToken) +{ + /* only set if the supplied token is non-zero. */ + if (pToken) + { + *pToken = sLinkToken; + } + + return; +} + +#if defined(EXTENDED_API) +/****************************************************************************** + * @fn nwk_unlink + * + * @brief Called from the application level to tear down a link. + * + * input parameters + * + * output parameters + * @param lid - Link ID assigned for this link + * + * @return Status of the operation. + * SMPL_SUCCESS + * SMPL_BAD_PARAM No connection table entry for this Link ID; + * SMPL_LINKID_USER_UUD not valid since it is not + * connection-based. + * SMPL_TIMEOUT No reply from peer. + * SMPL_NO_PEER_UNLINK Peer did not have a Connection Table entry for me. + */ +smplStatus_t nwk_unlink(linkID_t lid) +{ + uint8_t msg[UNLINK_FRAME_SIZE]; + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_SUCCESS; + addr_t addr; + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + /* is there connection info? */ + if (!pCInfo || (lid == SMPL_LINKID_USER_UUD)) + { + return SMPL_BAD_PARAM; + } + + /* set request byte */ + msg[LB_REQ_OS] = LINK_REQ_UNLINK; + + /* set the transaction ID. this allows target to figure out duplicates */ + msg[LB_TID_OS] = sTid; + + /* remote port to be sent in message to help match connection */ + msg[UL_RMT_PORT_OS] = pCInfo->portRx; + + /* setup for ioctl raw I/O */ + memcpy(addr.addr, pCInfo->peerAddr, NET_ADDR_SIZE); + ioctl_info.send.addr = &addr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_LINK; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + { + uint8_t spin = NWK_RX_RETRY_COUNT; + uint8_t radioState = MRFI_GetRadioState(); + + ioctl_info.recv.port = SMPL_PORT_LINK; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = (addr_t *)0; + + do + { + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + if ((msg[LB_REQ_OS] & (~NWK_APP_REPLY_BIT)) == LINK_REQ_UNLINK) + { + rc = (smplStatus_t)msg[ULR_RESULT_OS]; + break; + } + } + if (!spin) + { + rc = SMPL_TIMEOUT; + break; + } + --spin; + } while (1); + + /* it's ok to unconditionally invalidate connection object */ + nwk_freeConnection(pCInfo); + } + return rc; +} +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn nwk_link + * + * @brief Called from the application level to accomplish the link + * + * input parameters + * + * output parameters + * @param lid - pointer to Link ID (port) assigned for this link + * + * @return Status of the operation. + */ +smplStatus_t nwk_link(linkID_t *lid) +{ + uint8_t msg[LINK_FRAME_SIZE]; + connInfo_t *pCInfo = nwk_getNextConnection(); + smplStatus_t rc; + + if (pCInfo) + { + addr_t addr; + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + if (!nwk_allocateLocalRxPort(LINK_SEND, pCInfo)) + { + nwk_freeConnection(pCInfo); + return SMPL_NOMEM; + } + + memcpy(addr.addr, nwk_getBCastAddress(), NET_ADDR_SIZE); + ioctl_info.send.addr = &addr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_LINK; + + /* Put link token in */ + nwk_putNumObjectIntoMsg((void *)&sLinkToken, msg+L_LINK_TOKEN_OS, sizeof(sLinkToken)); + + /* set port to which the remote device should send */ + msg[L_RMT_PORT_OS] = pCInfo->portRx; + + /* set the transaction ID. this allows target to figure out duplicates */ + msg[LB_TID_OS] = sTid; + + /* set my Rx type */ + msg[L_MY_RXTYPE_OS] = nwk_getMyRxType(); + + /* set request byte */ + msg[LB_REQ_OS] = LINK_REQ_LINK; + + /* protocol version number */ + msg[L_PROTOCOL_VERSION_OS] = nwk_getProtocolVersion(); + +#if defined(SMPL_SECURE) + pCInfo->connTxCTR = MRFI_RandomByte() | \ + ((uint32_t)(MRFI_RandomByte())<<8) | \ + ((uint32_t)(MRFI_RandomByte())<<16) | \ + ((uint32_t)(MRFI_RandomByte())<<24); + + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[L_CTR_OS], 4); +#endif + + + if (SMPL_SUCCESS != (rc=SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send))) + { + return rc; + } + + { + uint8_t radioState = MRFI_GetRadioState(); + + ioctl_info.recv.port = SMPL_PORT_LINK; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = (addr_t *)pCInfo->peerAddr; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + uint8_t firstByte = msg[LB_REQ_OS] & (~NWK_APP_REPLY_BIT); + + /* Sanity check for correct reply frame. Older version + * has the length instead of the request as the first byte. + */ + if ((firstByte != LINK_REQ_LINK) && + (firstByte != LINK_REPLY_LEGACY_MSG_LENGTH) + ) + { + /* invalidate connection object */ + nwk_freeConnection(pCInfo); + return SMPL_NO_LINK; + + } + } + else + { + /* no successful receive */ + nwk_freeConnection(pCInfo); + return SMPL_TIMEOUT; + } + + pCInfo->connState = CONNSTATE_CONNECTED; + pCInfo->portTx = msg[LR_RMT_PORT_OS]; /* link reply returns remote port */ + *lid = pCInfo->thisLinkID; /* return our local port number */ + + /* Set hop count. If it's a polling device set the count to the + * distance to the AP. Otherwise, set it to the max less the remaining + * which will be the path taken for this frame. It will be no worse + * then tha max and probably will be better. + */ + if (F_RX_TYPE_POLLS == msg[LR_MY_RXTYPE_OS]) + { + pCInfo->hops2target = MAX_HOPS_FROM_AP; + } + else + { + /* Can't really use this trick because the device could move. If the + * devices are all static this may work unless the initial reception + * was marginal. + */ +#if defined(DEVICE_DOES_NOT_MOVE) + pCInfo->hops2target = MAX_HOPS - ioctl_info.recv.hopCount; +#else + pCInfo->hops2target = MAX_HOPS; +#endif + } + +#if defined(SMPL_SECURE) + nwk_getNumObjectFromMsg((void *)&msg[LR_CTR_OS], (void *)&pCInfo->connRxCTR, 4); +#endif + } + + /* guard against duplicates... */ + ++sTid; + if (!sTid) + { + sTid = 1; + } + return SMPL_SUCCESS; + } + + return SMPL_NOMEM; +} + +#if defined(EXTENDED_API) +/****************************************************************************** + * @fn smpl_send_unlink_reply + * + * @brief Send the unlink reply to the device trying to unlink + * + * input parameters + * @param frame - frame received from linker + * + * output parameters + * + * @return void + */ +static void smpl_send_unlink_reply(mrfiPacket_t *frame) +{ + connInfo_t *pCInfo; + frameInfo_t *pOutFrame; + uint8_t msg[UNLINK_REPLY_FRAME_SIZE]; + smplStatus_t rc = SMPL_NO_PEER_UNLINK; + + /* match the remote port and source address with a connection table entry */ + if (pCInfo = nwk_findPeer((addr_t *)MRFI_P_SRC_ADDR(frame), *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+UL_RMT_PORT_OS))) + { + /* Note we unconditionally free the connection resources */ + nwk_freeConnection(pCInfo); + rc = SMPL_SUCCESS; + } + + /* set reply bit */ + msg[LB_REQ_OS] = LINK_REQ_UNLINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+LB_TID_OS); + + /* result of freeing local connection */ + msg[ULR_RESULT_OS] = rc; + + if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +#if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } +} +#endif /* EXTENDED_API */ + +/****************************************************************************** + * @fn smpl_send_link_reply + * + * @brief Send the link reply to the device trying to link. This routine + * will handle duplicates. + * + * input parameters + * @param frame - frame received from linker + * + * output parameters + * + * @return Returns SENT_REPLY if reply sent, else SENT_NO_REPLY. + * The return value is used as this routine unwinds to know + * whether to replay the frame. An RE or AP can host an ED + * object in which case it might send a reply (possibly from + * a duplicate frame). If we do reply we do not want to replay. + */ +static uint8_t smpl_send_link_reply(mrfiPacket_t *frame) +{ +#if NUM_CONNECTIONS > 0 + frameInfo_t *pOutFrame; + connInfo_t *pCInfo; + uint8_t remotePort; + uint8_t msg[LINK_REPLY_FRAME_SIZE]; + + /* Is this a legacy frame? If so continue. Otherwise check version.*/ + if ((MRFI_GET_PAYLOAD_LEN(frame) - F_APP_PAYLOAD_OS) > LINK_LEGACY_MSG_LENGTH) + { + /* see if protocol version is correct... */ + if (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_PROTOCOL_VERSION_OS) != nwk_getProtocolVersion()) + { + /* Accommodation of protocol version differences can be noted or accomplished here. + * This field was also checked in the join transaction but it is checked again here + * because that check may not have occurred if thre is no AP in this topology. + * Otherwise, no match and the board goes back + */ + return SENT_NO_REPLY; + } + } + + /* see if token is correct */ + { + uint32_t lt; + + nwk_getNumObjectFromMsg(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_LINK_TOKEN_OS, <, sizeof(lt)); + if (lt != sLinkToken) + { + return SENT_NO_REPLY; + } + } + + /* if we get here the token matched. */ + + /* is this a duplicate request? */ + remotePort = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_RMT_PORT_OS); + if (pCInfo=nwk_isLinkDuplicate(MRFI_P_SRC_ADDR(frame), remotePort)) + { + /* resend reply */ + msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+LB_TID_OS); + + /* Send reply with the local port number so the remote device knows where to + * send packets. + */ + msg[LR_RMT_PORT_OS] = pCInfo->portRx; + + /* put my Rx type in there. used to know how to set hops when sending back. */ + msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); +#if defined(SMPL_SECURE) + /* Set the Tx counter value for peer's Rx counter object */ + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); + /* We also need to save the newly generated Rx counter value. */ + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_CTR_OS), (void *)&pCInfo->connRxCTR, 4); +#endif + if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS-(GET_FROM_FRAME(MRFI_P_PAYLOAD(frame),F_HOP_COUNT)))) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +#if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + return SENT_REPLY; + } + + if (!sListenActive) + { + /* We've checked for duplicate and resent reply. In that case we weren't listening + * so just go back`. + */ + return SENT_NO_REPLY; + } + + /* room to link? */ +#if defined(AP_IS_DATA_HUB) + pCInfo = nwk_findAlreadyJoined(frame); + + if (!pCInfo) +#endif + { + pCInfo = nwk_getNextConnection(); + } + + if (pCInfo) + { + /* yes there's room and it's not a dup. address. */ + memcpy(&pCInfo->peerAddr, MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + if (!nwk_allocateLocalRxPort(LINK_REPLY, pCInfo)) + { + nwk_freeConnection(pCInfo); + /* we're done with the packet */ + return SENT_REPLY; + } + + /* The local Rx port is the one returned in the connection structure. The + * caller is waiting on this to be set. The code here is running in an ISR + * thread so the caller will see this change after RETI. + */ + if (NUM_CONNECTIONS == sNumLinkers) + { + /* Something is wrong -- no room to stack Link request */ + nwk_freeConnection(pCInfo); + /* we're done with the packet */ + return SENT_REPLY; + } + sServiceLinkID[sNumLinkers++] = pCInfo->thisLinkID; + + /* save the remote Tx port */ + pCInfo->portTx = remotePort; + + /* connection is valid... */ + pCInfo->connState = CONNSTATE_CONNECTED; + + /* Set hop count. If it's a polling device set the count to the + * distance to the AP. otherwise, set it to the max less the remaining + * which will be the path taken for this frame. It will be no worse + * then tha max and probably will be better. + */ + if (F_RX_TYPE_POLLS == *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_MY_RXTYPE_OS)) + { + /* It polls. so. we'll be sending to the AP which will store the + * frame. The AP is only MAX_HOPS_FROM_AP hops away from us. + */ + pCInfo->hops2target = MAX_HOPS_FROM_AP; + } + else + { + /* Can't really use this trick because the device could move. If the + * devices are all static this may work unless the initial reception + * was marginal. + */ +#if defined(DEVICE_DOES_NOT_MOVE) + pCInfo->hops2target = MAX_HOPS - GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_HOP_COUNT); +#else + pCInfo->hops2target = MAX_HOPS; +#endif + } + /* Send reply with the local port number so the remote device knows where to + * send packets. + */ + msg[LR_RMT_PORT_OS] = pCInfo->portRx; + + /* put my Rx type in there. used to know how to set hops when sending back. */ + msg[LR_MY_RXTYPE_OS] = nwk_getMyRxType(); + + msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT; + + /* sender's TID */ + msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+LB_TID_OS); +#if defined(SMPL_SECURE) + nwk_getNumObjectFromMsg((void *)(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_CTR_OS), (void *)&pCInfo->connRxCTR, 4); + pCInfo->connTxCTR = MRFI_RandomByte() | \ + ((uint32_t)(MRFI_RandomByte())<<8) | \ + ((uint32_t)(MRFI_RandomByte())<<16) | \ + ((uint32_t)(MRFI_RandomByte())<<24); + + nwk_putNumObjectIntoMsg((void *)&pCInfo->connTxCTR, (void *)&msg[LR_CTR_OS], 4); +#endif + if (pOutFrame = nwk_buildFrame(SMPL_PORT_LINK, msg, sizeof(msg), MAX_HOPS-(GET_FROM_FRAME(MRFI_P_PAYLOAD(frame),F_HOP_COUNT)))) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); +#if defined(SMPL_SECURE) + nwk_setSecureFrame(&pOutFrame->mrfiPkt, sizeof(msg), 0); +#endif + if (SMPL_SUCCESS != nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED)) + { + /* better release the connection structure */ + nwk_freeConnection(pCInfo); + } + } + else + { + /* better release the connection structure */ + nwk_freeConnection(pCInfo); + } + } + /* we're done with the packet */ + return SENT_REPLY; +#else + return SENT_NO_REPLY; +#endif /* NUM_CONNECTIONS */ +} + +/****************************************************************************** + * @fn nwk_processLink + * + * @brief Process Link frame. Just save the frame for the Link app if it + * a reply. If it isn't a reply, send the reply in this thread. + * + * input parameters + * @param frame - pointer to frame to be processed + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame.. + */ +fhStatus_t nwk_processLink(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. send the reply. + */ + if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, LB_REQ_OS, LB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* No, we didn't send it. Process request assuming it's + * intended for us. + */ + rc = handleLinkRequest(frame); + } + + (void) replyType; /* keep compiler happy when ED built... */ + + return rc; +} + +/****************************************************************************** + * @fn nwk_getLocalLinkID + * + * @brief This routine checks to see if a service port has been assigned + * as a result of a link reply frame being received. It is the means + * by which the user thread knows that the waiting is over for the + * link listen. the value is set in an interrupt thread. + * + * input parameters + * + * output parameters + * + * @return Local port assigned when the link reply was received. + */ +linkID_t nwk_getLocalLinkID(void) +{ + linkID_t lid = 0; +#if NUM_CONNECTIONS > 0 + uint8_t i; + bspIState_t intState; + + + BSP_ENTER_CRITICAL_SECTION(intState); + if (sNumLinkers) + { + sNumLinkers--; + BSP_EXIT_CRITICAL_SECTION(intState); + + nwk_setListenContext(LINK_LISTEN_OFF); + lid = sServiceLinkID[0]; + /* If more than one Link frame has been processed without an intervening + * Listen assume that there will be another Link Listen call that will + * poll for completion which has already occurred. Age any existing entries. + * This code was added to deal with the possibility of mulitple EDs being + * activated simultaneously in the AP-as-data-hub example. This opens a + * window of opportunity for a "typical" scenario to get hosed. But for + * a "typical" scenario to get hosed a number of improbable events have to + * occur. These are deemed far less likely than the multiple-ED-activation + * scenario in the AP-as-dat-hub case. + */ + for (i=0; i +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_api.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_mgmt.h" +#include "nwk_join.h" +#include "nwk_globals.h" +#include "nwk_QMgmt.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ +#ifndef ACCESS_POINT +static addr_t const *sAPAddr = NULL; +#else +static uint8_t sSFMarker[NUM_STORE_AND_FWD_CLIENTS] = {0}; +#endif + +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static void smpl_send_mgmt_reply(mrfiPacket_t *); +#ifdef ACCESS_POINT +static void send_poll_reply(mrfiPacket_t *); +#endif + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_mgmtInit + * + * @brief Initialize Management functions. + * + * input parameters + * + * output parameters + * + * @return void + */ + +void nwk_mgmtInit(void) +{ + sTid = MRFI_RandomByte(); + +#ifdef ACCESS_POINT + memset(&sSFMarker, 0x0, sizeof(sSFMarker)); +#endif + + return; +} + +/****************************************************************************** + * @fn nwk_processMgmt + * + * @brief Process Management frame. Just save the frame for the Management + * app it it is a reply. If it isn't a reply, send the reply in this + * thread. + * + * input parameters + * @param frame - pointer to frame to be processed + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ +fhStatus_t nwk_processMgmt(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. send the reply. + */ + if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, MB_APP_INFO_OS, MB_TID_OS))) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. if i'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* no, we didn't send it. send reply if it's intended for us */ + if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) + { + smpl_send_mgmt_reply(frame); + + /* we're done with the frame. */ + rc = FHS_RELEASE; + } + else + { + rc = FHS_REPLAY; + } + } + + (void) replyType; /* keep compiler happy */ + + return rc; +} + +/****************************************************************************** + * @fn smpl_send_mgmt_reply + * + * @brief Send appropriate reply to Management frame. + * + * input parameters + * @param frame - Pointer to frame for which reply required. + * + * output parameters + * + * @return void + */ +static void smpl_send_mgmt_reply(mrfiPacket_t *frame) +{ +#ifdef ACCESS_POINT + /* what kind of management frame is this? */ + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+MB_APP_INFO_OS)) + { + case MGMT_REQ_POLL: + send_poll_reply(frame); + break; + + default: + break; + } +#endif /* ACCESS_POINT */ + return; +} + + +#ifdef ACCESS_POINT +/****************************************************************************** + * @fn send_poll_reply + * + * @brief Send reply to polling frame. + * + * input parameters + * @param frame - Pointer to frame for which reply required. + * + * output parameters + * + * @return void + */ +static void send_poll_reply(mrfiPacket_t *frame) +{ + uint8_t msgtid = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+MB_TID_OS); + frameInfo_t *pOutFrame; + sfClientInfo_t *pClientInfo; + uint8_t loc; + + /* Make sure this guy is really a client. We can tell from the source address. */ + if (!(pClientInfo=nwk_isSandFClient(MRFI_P_SRC_ADDR(frame), &loc))) + { + /* TODO: maybe send an error frame? */ + return; + } + + /* If we have to resync the TID then do it based on the first + * poll frame we see + */ + if (!sSFMarker[loc]) + { + /* If the marker flag is null then it has been initialized, i.e., + * there has been a reset. In this case infer that we need to update + * a (probably) stale last TID. The test will always be true the first + * time through after a client is established even when an NV restore + * did not take place but this does no harm. + */ + pClientInfo->lastTID = msgtid; + sSFMarker[loc] = 1; + } + /* If we've seen this poll frame before ignore it. Otherwise we + * may send a stored frame when we shouldn't. + */ + else if (nwk_checkAppMsgTID(pClientInfo->lastTID, msgtid)) + { + pClientInfo->lastTID = msgtid; + } + else + { + return; + } + + if (pOutFrame = nwk_getSandFFrame(frame, M_POLL_PORT_OS)) + { + /* We need to adjust the order in the queue in this case. Currently + * we know it is in the input queue and that this adjustment is safe + * because we're in an ISR thread. This is a fragile fix, though, and + * should be revisited when time permits. + */ + nwk_QadjustOrder(INQ, pOutFrame->orderStamp); + + /* reset hop count... */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_HOP_COUNT, MAX_HOPS_FROM_AP); + /* It's gonna be a forwarded frame. */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt), F_FWD_FRAME, 0x80); + + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } + else + { + nwk_SendEmptyPollRspFrame(frame); + } + + return; +} + +/****************************************************************************** + * @fn nwk_resetSFMarker + * + * @brief Reset S&F cklient marker so the TIDs resync. + * + * input parameters + * @param idx - index of the client that should be reset. + * + * output parameters + * + * @return void + */ +void nwk_resetSFMarker(uint8_t idx) +{ + sSFMarker[idx] = 0; + + return; +} + +#else /* ACCESS_POINT */ + +/****************************************************************************** + * @fn nwk_poll + * + * @brief Poll S&F server for any waiting frames. + * + * input parameters + * @param port - Port on peer. + * @param addr - SimpliciTI address of peer. + * + * output parameters + * + * @return SMPL_SUCCESS + * SMPL_NO_AP_ADDRESS - We don't know Access Point's address + * SMPL_NOMEM - no room in output frame queue + * SMPL_TX_CCA_FAIL - CCA failure + */ +smplStatus_t nwk_poll(uint8_t port, uint8_t *addr) +{ + uint8_t msg[MGMT_POLL_FRAME_SIZE]; + ioctlRawSend_t send; + + msg[MB_APP_INFO_OS] = MGMT_REQ_POLL; + msg[MB_TID_OS] = sTid; + msg[M_POLL_PORT_OS] = port; + memcpy(msg+M_POLL_ADDR_OS, addr, NET_ADDR_SIZE); + + /* it's OK to increment the TID here because the reply will not be + * matched based on this number. The reply to the poll comes back + * to the client port, not the Management port. + */ + sTid++; + + if (!sAPAddr) + { + sAPAddr = nwk_getAPAddress(); + if (!sAPAddr) + { + return SMPL_NO_AP_ADDRESS; + } + } + send.addr = (addr_t *)sAPAddr; + send.msg = msg; + send.len = sizeof(msg); + send.port = SMPL_PORT_MGMT; + + return SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &send); +} + +#endif /* ACCESS_POINT */ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_mgmt.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_mgmt.h new file mode 100755 index 0000000..d913abb --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_mgmt.h @@ -0,0 +1,67 @@ +/************************************************************************************************** + Filename: nwk_mgmt.h + Revised: $Date: 2009-01-06 15:45:54 -0800 (Tue, 06 Jan 2009) $ + Revision: $Revision: 18697 $ + Author: $Author: lfriedman $ + + Description: This header file supports the SimpliciTI Mgmt network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_MGMT_H +#define NWK_MGMT_H + +/* MGMT frame application requests */ +#define MGMT_REQ_POLL 0x01 + +/* change the following as protocol developed */ +#define MAX_MGMT_APP_FRAME 7 + +/* application payload offsets */ +/* both */ +#define MB_APP_INFO_OS 0 +#define MB_TID_OS 1 + +/* Poll frame */ +#define M_POLL_PORT_OS 2 +#define M_POLL_ADDR_OS 3 + +/* change the following as protocol developed */ +#define MAX_MGMT_APP_FRAME 7 + +/* frame sizes */ +#define MGMT_POLL_FRAME_SIZE 7 + +/* prototypes */ +void nwk_mgmtInit(void); +fhStatus_t nwk_processMgmt(mrfiPacket_t *); +smplStatus_t nwk_poll(uint8_t, uint8_t *); +void nwk_resetSFMarker(uint8_t); + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ping.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ping.c new file mode 100755 index 0000000..2e55a48 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ping.c @@ -0,0 +1,314 @@ +/************************************************************************************************** + Filename: nwk_ping.c + Revised: $Date: 2009-01-18 16:01:08 -0800 (Sun, 18 Jan 2009) $ + Revision: $Revision: 18796 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Ping network application. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/****************************************************************************** + * INCLUDES + */ +#include +#include "bsp.h" +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_frame.h" +#include "nwk.h" +#include "nwk_ping.h" +#include "nwk_globals.h" +#include "nwk_api.h" +#include "nwk_freq.h" +#include "nwk_security.h" + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/****************************************************************************** + * TYPEDEFS + */ + +/****************************************************************************** + * LOCAL VARIABLES + */ + +static volatile uint8_t sTid = 0; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static void smpl_send_ping_reply(mrfiPacket_t *); +static void handlePingRequest(mrfiPacket_t *); + +/****************************************************************************** + * GLOBAL VARIABLES + */ + +/****************************************************************************** + * GLOBAL FUNCTIONS + */ + +/****************************************************************************** + * @fn nwk_pingInit + * + * @brief Initialize Ping application. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_pingInit(void) +{ + sTid = MRFI_RandomByte(); + + return; +} + +/****************************************************************************** + * @fn nwk_ping + * + * @brief Called from the application level to ping a peer. A small + * payload is sent that includes a tid to detect correct reply. + * Caller does not supply payload. + * + * input parameters + * @param lid - Link ID representing peer to ping + * + * output parameters + * + * @return SMPL_SUCCESS valid reply received + * SMPL_TIMEOUT no valid reply received + * SMPL_NO_CHANNEL no channels returned on a scan + */ +smplStatus_t nwk_ping(linkID_t lid) +{ + connInfo_t *pCInfo = nwk_getConnInfo(lid); + smplStatus_t rc = SMPL_BAD_PARAM; + uint8_t done = 0; + uint8_t repeatIt = 2; + uint8_t msg[MAX_PING_APP_FRAME]; + uint8_t radioState = MRFI_GetRadioState(); + union + { + ioctlRawSend_t send; + ioctlRawReceive_t recv; + } ioctl_info; + + if (!pCInfo || (SMPL_LINKID_USER_UUD == lid)) + { + /* either link ID bogus or tried to ping the unconnected user datagram link ID. */ + return rc; + } + + do + { +#if defined(FREQUENCY_AGILITY) && !defined(ACCESS_POINT) + uint8_t i, numChan; + freqEntry_t channels[NWK_FREQ_TBL_SIZE]; + + if (repeatIt == 2) + { + /* If FA enabled, first time through set up so that the 'for' + * loop checks the current channel. This saves time (no scan) + * and is very likely to succeed. Populate the proper strucure. + */ + SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_GET, channels); + numChan = 1; + } + else + { + /* If we get here we must scan for the channel we're now on */ + if (!(numChan=nwk_scanForChannels(channels))) + { + return SMPL_NO_CHANNEL; + } + } + /* Either we scan next time through or we're done */ + repeatIt--; + + /* this loop Pings on each channel (probably only 1) looking + * for peer. + */ + for (i=0; ipeerAddr; + ioctl_info.send.msg = msg; + ioctl_info.send.len = sizeof(msg); + ioctl_info.send.port = SMPL_PORT_PING; + + /* fill in msg */ + msg[PB_REQ_OS] = PING_REQ_PING; + msg[PB_TID_OS] = sTid; + + SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); + + ioctl_info.recv.port = SMPL_PORT_PING; + ioctl_info.recv.msg = msg; + ioctl_info.recv.addr = 0; + + NWK_CHECK_FOR_SETRX(radioState); + NWK_REPLY_DELAY(); + NWK_CHECK_FOR_RESTORE_STATE(radioState); + + if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) + { + repeatIt = 0; + done = 1; + sTid++; /* guard against duplicates */ + } + } + } while (repeatIt); + + return done ? SMPL_SUCCESS : SMPL_TIMEOUT; + +} + +/****************************************************************************** + * @fn smpl_send_ping_reply + * + * @brief Send a reply to a ping request. + * + * input parameters + * @param frame - pointer to frame containing request + * + * output parameters + * + * @return void + */ +static void smpl_send_ping_reply(mrfiPacket_t *frame) +{ + frameInfo_t *pOutFrame; + + /* Build the reply frame. The application payload is the one included in the + * received frame payload. + */ + if (pOutFrame = nwk_buildFrame(SMPL_PORT_PING, MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS, MRFI_GET_PAYLOAD_LEN(frame)-F_APP_PAYLOAD_OS, MAX_HOPS)) + { + /* destination address is the source adddress of the received frame. */ + memcpy(MRFI_P_DST_ADDR(&pOutFrame->mrfiPkt), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); + + /* turn on the reply bit in the application payload */ + *(MRFI_P_PAYLOAD(&pOutFrame->mrfiPkt)+F_APP_PAYLOAD_OS+PB_REQ_OS) |= NWK_APP_REPLY_BIT; +#ifdef SMPL_SECURE + nwk_setSecureFrame(&pOutFrame->mrfiPkt, MRFI_GET_PAYLOAD_LEN(frame)-F_APP_PAYLOAD_OS, 0); +#endif /* SMPL_SECURE */ + nwk_sendFrame(pOutFrame, MRFI_TX_TYPE_FORCED); + } +} + +/****************************************************************************** + * @fn nwk_processPing + * + * @brief Ping network application frame handler. + * + * input parameters + * @param frame - pointer to frame in question + * + * output parameters + * + * @return Keep frame for application, release frame, or replay frame. + */ +fhStatus_t nwk_processPing(mrfiPacket_t *frame) +{ + fhStatus_t rc; + uint8_t replyType; + + /* If we sent this then this is the reply. Validate the + * packet for reception by client app. If we didn't send + * it then we are the target. Send the reply. + */ + replyType = nwk_isValidReply(frame, sTid, PB_REQ_OS, PB_TID_OS); + if (SMPL_MY_REPLY == replyType) + { + /* It's a match and it's a reply. Validate the received packet by + * returning a 1 so it can be received by the client app. + */ + MRFI_PostKillSem(); + rc = FHS_KEEP; + } +#if !defined( END_DEVICE ) + else if (SMPL_A_REPLY == replyType) + { + /* no match. If I'm not an ED this is a reply that should be passed on. */ + rc = FHS_REPLAY; + } +#endif /* !END_DEVICE */ + else + { + /* No, we didn't send it. Send reply assuming it's a Ping intended for us. */ + handlePingRequest(frame); + + rc = FHS_RELEASE; + } + + return rc; +} + +/****************************************************************************** + * @fn handlePingRequest + * + * @brief Dispatches handler for specfic Ping request + * + * input parameters + * + * @param frame - Ping frame received + * + * output parameters + * + * @return void + */ +static void handlePingRequest(mrfiPacket_t *frame) +{ + switch (*(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS)) + { + case PING_REQ_PING: + smpl_send_ping_reply(frame); + break; + + default: + break; + } + + return; +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ping.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ping.h new file mode 100755 index 0000000..c7dd3be --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_ping.h @@ -0,0 +1,58 @@ +/************************************************************************************************** + Filename: nwk_ping.h + Revised: $Date: 2008-05-14 14:22:31 -0700 (Wed, 14 May 2008) $ + Revision: $Revision: 17075 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Ping network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_PING_H +#define NWK_PING_H + +/* change the following as protocol developed */ +#define MAX_PING_APP_FRAME 2 + +/* application payload offsets */ +/* both */ +#define PB_REQ_OS 0 +#define PB_TID_OS 1 + + +/* ping requests */ +#define PING_REQ_PING 1 + +/* prototypes */ +fhStatus_t nwk_processPing(mrfiPacket_t *); +void nwk_pingInit(void); +smplStatus_t nwk_ping(linkID_t); + + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_security.c b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_security.c new file mode 100755 index 0000000..5ee4acc --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_security.c @@ -0,0 +1,549 @@ +/************************************************************************************************** + Filename: nwk_security.c + Revised: $Date: 2009-01-20 14:05:46 -0800 (Tue, 20 Jan 2009) $ + Revision: $Revision: 18816 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Security network application. + + Copyright 2008-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ + +#include /* needed for NULL */ +#include "mrfi.h" +#include "nwk_types.h" +#include "nwk_security.h" +#include "nwk_frame.h" +#include "nwk.h" + +#ifdef SMPL_SECURE + +/* *** GENERAL SECURITY OUTLINE *** + * + * We are using XTEA (eXtended Tiny Encryption Algorithm) with a fixed + * number of rounds (32). We have removed the parameters from the API + * we harvested from the public domain. + * + * We are using a CTR-like mode. We use the 64-bit block cipher function of the + * XTEA code to encipher a concatenation of the 32-bit initialization vector and + * a 32-bit counter that increments each block. We encrypt using a fixed 128-bit + * key. The resulting 64-bit output is XOR'ed with the message. If the message is + * longer than 64 bits we encipher the next block (incrementing the counter) and + * continue until the message is exhausted. If the last cipher block is longer + * than the message we simply discard the remaining cipher block. + */ + + +/****************************************************************************** + * MACROS + */ + +/****************************************************************************** + * CONSTANTS AND DEFINES + */ + +/* The counter can be off by quite a bit because the number of cipher + * blocks can easily be more than 1 per frame. Value limited to a + * maximum of 255. + */ +#define CTR_WINDOW 255 + +#if (CTR_WINDOW > 255) || (CTR_WINDOW < 0) +#error ERROR: 0 <= CTR_WINDOW < 256 +#endif + +/* Number of rounds for XTEA algorithm. A parameter in the public domain code + * but we fix it here at 32. + */ +#define NUM_ROUNDS 32 + +/* Key and cipher block size constants */ +#define SMPL_KEYSIZE_BYTES 16 +#define SMPL_KEYSIZE_LONGS 4 + +/****************************************************************************** + * TYPEDEFS + */ +/* Union used to access key as both a string and as unsigned longs */ +typedef union +{ + uint8_t keyS[SMPL_KEYSIZE_BYTES]; + uint32_t keyL[SMPL_KEYSIZE_LONGS]; +} key_t; + + +/****************************************************************************** + * LOCAL VARIABLES + */ +/* 32-bit Initialization vector */ +static uint32_t const sIV = 0x87654321; + +/* 128-bit (16 byte) key. Initialized as string but fetched and used in XTEA + * encryption as 4 unsigned longs. Endianess could count if the peers are on + * two different MCUs. Endianess is rectified in initialization code. + * + * Initialization _MUST_ be done as a string (or character array). Though it + * won't matter how the initialization is done if both peers are the same + * endianness, good prectice will initialize these as a string (or character + * array) so that the endianess reconciliation works properly for all cases. + */ +static key_t sKey = {"SimpliciTI's Key"}; + +/* Constant set as an authentication code. Note that since it is a + * fixed value as opposed to a hash of the message it does not provide + * an integrity check. It will only differentiate two message encryptions + * with the same LSB but different MSB components. Thus it helps guard + * against replays. + */ +static secMAC_t const sMAC = 0xA5; + +/* This is the 64-bit cipher block target. It is this 64-bit block that + * is XOR'ed with the actual message to be encrypted. + */ +static uint32_t sMsg[2] = {0, 0}; + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +static secFCS_t calcFCS(uint8_t *, uint8_t); +static void msg_encipher(uint8_t *, uint8_t, uint32_t *); +static void msg_decipher(uint8_t *, uint8_t, uint32_t *); +static void xtea_encipher(void); + +#endif /* SMPL_SECURE */ + +/****************************************************************************** + * @fn nwk_securityInit + * + * @brief Initialize Security network application. + * + * input parameters + * + * output parameters + * + * @return void + */ +void nwk_securityInit(void) +{ +#ifdef SMPL_SECURE + uint8_t i; + + /* The key is set as a string. But the XTEA routines operate on 32-bit + * unsigned longs. Endianess should be taken into account and we do that + * here by treating the key as being an array of unsigned longs in + * network order. + */ + for (i=0; i= len) + { + /* we're done */ + done = 1; + } + } while (!done); + + /* return counter value start for next time */ + *cntStart = ctr; + + return; +} + +/****************************************************************************** + * @fn msg_decipher + * + * @brief Decipher a message using the XTEA algorithm and the modified + * CTR mode method. + * + * input parameters + * @param msg - pointer to message to decipher + * @param len - length of message + * @param cntStart - pointer to the counter used in the cipher block. + * + * output parameters + * @param cntStart - counter is updated during decryption. + * + * @return void + */ +static void msg_decipher(uint8_t *msg, uint8_t len, uint32_t *cntStart) +{ + msg_encipher(msg, len, cntStart); + + return; +} + +/****************************************************************************** + * @fn xtea_encipher + * + * @brief XTEA encipher algorithm. Calling arguments removed from public + * domain code and static-scope values used instead. + * + * input parameters + * + * output parameters + * + * @return void + */ +void xtea_encipher(void) +{ + uint32_t v0=sMsg[0], v1=sMsg[1]; + uint16_t i; + uint32_t sum=0, delta=0x9E3779B9; + + for(i=0; i> 5)) + v1) ^ (sum + sKey.keyL[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + sKey.keyL[(sum>>11) & 3]); + } + + sMsg[0]=v0; + sMsg[1]=v1; +} + +/****************************************************************************** + * @fn nwk_setSecureFrame + * + * @brief Called from NWK to secure a frame. + * + * input parameters + * @param frame - pointer to frame to secure + * @param msglen - length of message + * @param ctr - pointer to the counter used in the cipher block. This will + * be NULL if a network application is sending a frame. Since + * these are not connection-based there is no counter sync + * issue but we still need a counter value. A random value + * is used. + * + * output parameters + * @param cntStart - counter is updated during encryption. + * + * @return void + */ +void nwk_setSecureFrame(mrfiPacket_t *frame, uint8_t msglen, uint32_t *ctr) +{ + uint32_t locCnt; + + /* If an encrypted frame is to be sent to a non-connection based port use a + * random number as the lsb counter value. In this case only the lsb is used + * for a counter value during decryption. Not as secure but there are still + * the 32 bits in the IV. + */ + locCnt = ctr ? *ctr : MRFI_RandomByte(); + + /* place counter value into frame */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(frame), F_SEC_CTR_OS, (uint8_t)(locCnt & 0xFF)); + + /* Put MAC value in */ + nwk_putNumObjectIntoMsg((void *)&sMAC, (void *)(MRFI_P_PAYLOAD(frame)+F_SEC_MAC_OS), sizeof(secMAC_t)); + + /* Put FCS value in */ + { + secFCS_t fcs = calcFCS(MRFI_P_PAYLOAD(frame)+F_SEC_MAC_OS, msglen+sizeof(secMAC_t)); + + nwk_putNumObjectIntoMsg((void *)&fcs, (void *)(MRFI_P_PAYLOAD(frame)+F_SEC_ICHK_OS), sizeof(secFCS_t)); + } + + /* Encrypt frame */ + msg_encipher(MRFI_P_PAYLOAD(frame)+F_SEC_ICHK_OS, msglen+sizeof(secMAC_t)+sizeof(secFCS_t), &locCnt); + + /* Set the Encryption bit */ + PUT_INTO_FRAME(MRFI_P_PAYLOAD(frame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); + + /* Update the counter if it was a "real" counter. */ + if (ctr) + { + *ctr = locCnt; + } + + return; +} + +/****************************************************************************** + * @fn calcFCS + * + * @brief Calculate the frame check sequence. Currently it's just a + * cumulative XOR of each byte starting with the MAC byte. The + * FCS is placed in front of the MAC after the counter hint and is + * included in the encryption. + * + * input parameters + * @param msg - pointer to message + * @param len - length of message + * + * output parameters + * + * @return Returns the FCS using the typedef. + */ +static secFCS_t calcFCS(uint8_t *msg, uint8_t len) +{ + uint8_t i; + secFCS_t result = 0; + + for (i=0; i locCnt) + { + /* frameCnt is bigger. Second part of test below takes care of + * the unlikely case of a complete counter wrap (msb's all 0) in + * which case the test will incorrectly fail when the count is + * actually within the (wrapped) window. #ifdef'ed to avoid compiler + * warning in case user sets CNT_WINDOW to 0 (pointless comparison of + * unsigned value). + */ + if (((frameCnt-CTR_WINDOW) <= locCnt) +#if CTR_WINDOW > 0 + || (frameCnt < CTR_WINDOW) +#endif + ) + { + /* Value within window. We probably missed something. Adjust and decipher. + * If locCnt is less because it wrapped and frameCnt didn't it means that + * it's a duplicate or late frame. In that case the following will lead to + * a decryption that fails sanity checks which is OK because the frame will + * be correctly rejected. + */ + locCnt = frameCnt; + } + else + { + /* It's either a rogue or a really old duplicate packet. In either case + * we dismiss the frame. + */ + rc = 0; + done = 1; + } + } + else + { + /* locCnt is bigger. The only way the frame can be valid is if the + * counter wrapped causing frameCnt to appear to be smaller. Wrap the + * counter and decrypt. If the frame isn't valid, i.e., it's late, + * a duplicate, or a rogue, the decryption will fail sanity checks and + * the frame will be correctly rejected. The following arithmetic works + * correctly without a special test for the complete counter wrap case. + */ + frameCnt += 0x100; /* wrap the hint-based counter */ + if (((frameCnt-CTR_WINDOW) <= locCnt)) + { + /* An lsb wrap but still within window. We probably missed something. + * Adjust (with wrap) and decrypt. + */ + locCnt = frameCnt; + } + else + { + /* rogue frame */ + rc = 0; + done = 1; + } + } + } + } while (!done); + + if (ctr && rc) + { + /* Only update the counter if the count was a "real" one and the + * decryption succeeded. + */ + *ctr = locCnt; + } + + return rc; +} + +#endif /* SMPL_SECURE */ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_security.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_security.h new file mode 100755 index 0000000..212ce8f --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Components/nwk_applications/nwk_security.h @@ -0,0 +1,48 @@ +/************************************************************************************************** + Filename: nwk_security.h + Revised: $Date: 2009-01-09 15:02:17 -0800 (Fri, 09 Jan 2009) $ + Revision: $Revision: 18728 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Security network application. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +#ifndef NWK_SECURITY_H +#define NWK_SECURITY_H + +/* change the following as Security application is developed */ +#define MAX_SEC_APP_FRAME 0 + +/* prototypes */ +void nwk_securityInit(void); +fhStatus_t nwk_processSecurity(mrfiPacket_t *); +void nwk_setSecureFrame(mrfiPacket_t *, uint8_t, uint32_t *); +uint8_t nwk_getSecureFrame(mrfiPacket_t *, uint8_t, uint32_t *); +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Configuration/Access Point/smpl_config.dat b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Configuration/Access Point/smpl_config.dat new file mode 100755 index 0000000..46375bd --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Configuration/Access Point/smpl_config.dat @@ -0,0 +1,93 @@ +/************************************************************************************************** + Filename: smpl_config.dat + Revised: $Date: 2007-11-28 13:46:49 -0800 (Wed, 28 Nov 2007) $ + Revision: $Revision: 15977 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Customer Configuration for Access Points. + + Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/* Number of connections supported. Each connection supports bi-directional + * communication. Access Points and Range Extenders can set this to 0 if they + * do not host End Device objects. + */ +/*-DNUM_CONNECTIONS=8*/ +/* [BM] RF access point is limited to 1 end device */ +-DNUM_CONNECTIONS=1 + +/* *** Size of low level queues for sent and received frames. Affects RAM usage *** */ + +/* AP needs larger input frame queue if it is supporting store-and-forward + * clients because the forwarded messages are held here. + */ +-DSIZE_INFRAME_Q=6 + +/* The output frame queue can be small since Tx is done synchronously. Actually + * 1 is probably enough. If an Access Point device is also hosting an End Device + * that sends to a sleeping peer the output queue should be larger -- the waiting + * frames in this case are held here. In that case the output frame queue should + * be bigger. + */ +-DSIZE_OUTFRAME_Q=2 + +/* This device's address. The first byte is used as a filter on the CC1100/CC2500 + * radios so THE FIRST BYTE MUST NOT BE either 0x00 or 0xFF. Also, for these radios + * on End Devices the first byte should be the least significant byte so the filtering + * is maximally effective. Otherwise the frame has to be processed by the MCU before it + * is recognized as not intended for the device. APs and REs run in promiscuous mode so + * the filtering is not done. This macro intializes a static const array of unsigned + * characters of length NET_ADDR_SIZE (found in nwk_types.h). The quotes (") are + * necessary below unless the spaces are removed. + */ +/*-DTHIS_DEVICE_ADDRESS="{0x78, 0x56, 0x34, 0x12}"*/ +/* [BM] Use a slightly different device address */ +-DTHIS_DEVICE_ADDRESS="{0x78, 0x56, 0x34, 0x10}" + +/* device type */ +-DACCESS_POINT + +/* In the spcial case in which the AP is a data hub, the AP will automaically + * listen for a link each time a new device joins the network. This is a special + * case scenario in which all End Device peers are the AP and every ED links + * to the AP. In this scenario the ED must automatically try and link after the + * Join reply. + */ +-DAP_IS_DATA_HUB + +/* Store and forward support: number of clients */ +/*-DNUM_STORE_AND_FWD_CLIENTS=3*/ +/* [BM] Support just 1 client */ +-DNUM_STORE_AND_FWD_CLIENTS=3 + +-DSTARTUP_JOINCONTEXT_ON + + + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Configuration/smpl_nwk_config.dat b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Configuration/smpl_nwk_config.dat new file mode 100755 index 0000000..9f64bc1 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/Configuration/smpl_nwk_config.dat @@ -0,0 +1,79 @@ +/************************************************************************************************** + Filename: smpl_nwk_config.dat + Revised: $Date: 2009-02-07 14:21:07 -0700 (Sat, 07 Feb 2009) $ + Revision: $Revision: 19010 $ + Author: $Author: lfriedman $ + + Description: This file supports the SimpliciTI Customer Configuration for overall network. + + Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved. + + IMPORTANT: Your use of this Software is limited to those specific rights granted under + the terms of a software license agreement between the user who downloaded the software, + his/her employer (which must be your employer) and Texas Instruments Incorporated (the + "License"). You may not use this Software unless you agree to abide by the terms of the + License. The License limits your use, and you acknowledge, that the Software may not be + modified, copied or distributed unless embedded on a Texas Instruments microcontroller + or used solely and exclusively in conjunction with a Texas Instruments radio frequency + transceiver, which is integrated into your product. Other than for the foregoing purpose, + you may not use, reproduce, copy, prepare derivative works of, modify, distribute, + perform, display or sell this Software and/or its documentation for any purpose. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. + IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE + THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY + INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST + DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY + THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + + Should you have any questions regarding your right to use this Software, + contact Texas Instruments Incorporated at www.TI.com. +**************************************************************************************************/ + + +/* max hop count */ +-DMAX_HOPS=3 + +/* max hops away from and AP. Keeps hop count and therefore replay + * storms down for sending to and from polling End Devices. Also used + * when joining since the EDs can't be more than 1 hop away. + */ +-DMAX_HOPS_FROM_AP=1 + +/* Maximum size of Network application payload. Do not change unless + * protocol changes are reflected in different maximum network + * application payload size. + */ +-DMAX_NWK_PAYLOAD=9 + +/* Maximum size of application payload */ +/*-DMAX_APP_PAYLOAD=10*/ +/* [BM] Increase max payload size for sync application */ +-DMAX_APP_PAYLOAD=19 + +/* default Link token */ +-DDEFAULT_LINK_TOKEN=0x01020304 + +/* default Join token */ +-DDEFAULT_JOIN_TOKEN=0x05060708 + +/* define Frequency Agility as active for this build */ +/*-DFREQUENCY_AGILITY*/ + +/* Remove 'x' corruption to enable application autoacknowledge support. Requires extended API as well */ +-DAPP_AUTO_ACK + +/* Remove 'x' corruption to enable Extended API */ +-DEXTENDED_API + +/* Remove 'x' corruption to enable security. */ +-DxSMPL_SECURE + +/* Remove 'x' corruption to enable NV object support. */ +-DxNVOBJECT_SUPPORT + +/* Remove 'x' corruption to enable software timer. */ +-DxSW_TIMER diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/simpliciti.h b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/simpliciti.h new file mode 100755 index 0000000..25c1e6b --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/simpliciti.h @@ -0,0 +1,92 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Generic defines and variables + +// Macros +#define getFlag(val, flag) ((val&flag)==flag) +#define setFlag(val, flag) (val|=flag) +#define clearFlag(val, flag) (val&=(~flag)) +#define toggleFlag(val, flag) (val^=flag) + +// Entry point into SimpliciTI library +extern void simpliciti_main(void); + +// Maximum data length +#define SIMPLICITI_MAX_PAYLOAD_LENGTH (32u) + +// Data to send / receive +extern unsigned char simpliciti_data[SIMPLICITI_MAX_PAYLOAD_LENGTH]; + +// 1 = send one or more reply packets, 0 = no need to reply +extern unsigned char simpliciti_reply; + +// Radio frequency offset taken from calibration memory +// Compensates crystal deviation from 26MHz nominal value +extern unsigned char rf_frequoffset; + +// Flag for status information and external control through USB driver +extern volatile unsigned char simpliciti_flag; +#define SIMPLICITI_STATUS_LINKING (BIT0) +#define SIMPLICITI_STATUS_LINKED (BIT1) +#define SIMPLICITI_STATUS_ERROR (BIT2) +#define SIMPLICITI_TRIGGER_SEND_DATA (BIT3) +#define SIMPLICITI_TRIGGER_RECEIVED_DATA (BIT4) +#define SIMPLICITI_TRIGGER_STOP (BIT5) +#define SIMPLICITI_TRIGGER_SEND_CMD (BIT6) + + +// --------------------------------------------------------------- +// SimpliciTI Sync + +// 1 = data in buffer, 0 = buffer empty +extern unsigned char simpliciti_sync_buffer_status; + +#define BM_SYNC_DATA_LENGTH (19u) + +// Device data (0)TYPE (1) - (31) DATA +#define SYNC_ED_TYPE_R2R (1u) +#define SYNC_ED_TYPE_MEMORY (2u) +#define SYNC_ED_TYPE_STATUS (3u) + +// Host data (0)CMD (1) - (31) DATA +#define SYNC_AP_CMD_NOP (1u) +#define SYNC_AP_CMD_GET_STATUS (2u) +#define SYNC_AP_CMD_SET_WATCH (3u) +#define SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_1 (4u) +#define SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_2 (5u) +#define SYNC_AP_CMD_ERASE_MEMORY (6u) +#define SYNC_AP_CMD_EXIT (7u) + + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/simpliciti_readme.txt b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/simpliciti_readme.txt new file mode 100755 index 0000000..f9f8b05 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/simpliciti/simpliciti_readme.txt @@ -0,0 +1,36 @@ +Some notes about the SimpliciTI configuration used in this project + +- The source code is based on the SimpliciTI 1.1.1 release. + +- A full SimpliciTI installation contains configurations for many targets and device types. To avoid confusion, + only the configuration (Access Point) and target files (RFUSB) required for the eZ430-Chronos have been used. + +- All source code files have been copied into the project physically. Symbolic links have been replaced with + the real source code file. + +- Due to the indirect inclusion scheme of hardware-dependent source code, some source code files have been + excluded from build. However, they will be included through higher level source code. + +- Some modifications where required to the original source code. All these changes have been marked with [BM]. + + mrfi_f1f2.c Changed channel assignment (mrfiLogicalChanTable) for three ISM bands + Changed power output settings (mrfiRFPowerTable) for three ISM bands + + mrfi_radio.c/MRFI_Init(void) Added frequency offset correction to use calibrated frequency offset + when starting RF communication + + mrfi_radio.c/MRFI_RfIsr(void) Changed radio ISR to normal function, since we have a shared radio ISR + + nwk_api.c Made variable sInit_done globally available to allow SimpliciTI to shutdown + and restart multiple times + + +- If you (for whatever reason) want to upgrade to a newer version of SimpliciTI, please bear in mind that + + a) the access point SimpliciTI version is 1.1.1 (and cannot be updated) + + b) the workarounds used here to enable SimpliciTI to shutdown and restart multiple times might not necessarily + work when used with later revisions + + + \ No newline at end of file diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/timer1.c b/chronos-ti/Software Projects/RF Access Point/IAR/timer1.c new file mode 100755 index 0000000..399fca1 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/timer1.c @@ -0,0 +1,202 @@ +// ************************************************************************************************* +// +// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Timer1 driver +// ************************************************************************************************* + + +// ************************************************************************************************* +// Include section +#include "timer1.h" + + +// ************************************************************************************************* +// Defines section +#define ACLK_SPEED_HZ 32768u +#define TCLK_SPEED_HZ 187500u +#define ACLK_PER_FULL_CYCLE 11453u // (32768*65536/187500=11453,25) - round up for later correction + + +// ************************************************************************************************* +// Global Variable section +struct timer1 sTimer1; + + + +// ************************************************************************************************* +// Implementation + +void reset_timer1(void) +{ + sTimer1.enable = 0; + sTimer1.iflag = 0; + sTimer1.aclk = 0; + sTimer1.nb_full_cycles = 0; + sTimer1.last_cycle_count = 0; + sTimer1.usb_service_disable = 0; + sTimer1.cycles = 0; +} + + + +u8 set_timer1_cycles(void) +{ + int t1cc0; + char repeat = 0; + + if (sTimer1.nb_full_cycles > 0) + { + // Disable IM during timer set + T1CCTL0 &= ~BIT6; + + // Set compare value to 0xFFFF (wait 1 full cycle) + SET_WORD(T1CC0H, T1CC0L, 0xFFFF); + // Make sure compare value is written correctly + GET_WORD(T1CC0H, T1CC0L, t1cc0); + while (t1cc0 != 0xFFFF) + { + SET_WORD(T1CC0H, T1CC0L, 0xFFFF); + GET_WORD(T1CC0H, T1CC0L, t1cc0); + if (repeat++ > 10) break; + } + // Decrease full cycle count + sTimer1.nb_full_cycles--; + + // Clear Timer 1 Channel 0-2 + overflow interrupt flag + T1CTL &= ~0xF0; + // Enable IM after timer set + T1CCTL0 |= BIT6; + } + else if (sTimer1.last_cycle_count > 5) //1) // Skip last 5 TCLK (~ 1 ACLK) - too close for IRQ + { + // Disable IM during timer set + T1CCTL0 &= ~BIT6; + + // Set compare value to last period lenght - 1 + SET_WORD(T1CC0H, T1CC0L, sTimer1.last_cycle_count-1); + // Make sure compare value is written correctly + GET_WORD(T1CC0H, T1CC0L, t1cc0); + while (t1cc0 != sTimer1.last_cycle_count-1) + { + SET_WORD(T1CC0H, T1CC0L, sTimer1.last_cycle_count-1); + GET_WORD(T1CC0H, T1CC0L, t1cc0); + if (repeat++ > 10) break; + } + // Clear last cycle count - next IRQ calls s/w handler + sTimer1.last_cycle_count = 0; + + // Suspend USB service via Timer4 until TX is over + sTimer1.usb_service_disable = 1; + + // Clear Timer 1 Channel 0-2 + overflow interrupt flag + T1CTL &= ~0xF0; + // Enable IM after timer set + T1CCTL0 |= BIT6; + } + else return (0); // no cycles could be set + + return (1); // cycles successfully set + +} + + +// Set up Timer1 in compare mode to emulate 32kHz timer +void set_timer1(u16 aclk) +{ + //u32 total_ticks; + + // Disable IM during timer set + T1CCTL0 &= ~BIT6; + + // Disable s/w timer int + sTimer1.enable = 0; + + // Calculate number of full cycles + sTimer1.nb_full_cycles = 0; + while(aclk >= ACLK_PER_FULL_CYCLE) + { + aclk -= ACLK_PER_FULL_CYCLE; + sTimer1.nb_full_cycles++; + } + + // remainder is last timer period + sTimer1.last_cycle_count = (aclk * TCLK_SPEED_HZ) / ACLK_SPEED_HZ; + + // Set Timer1 registers + set_timer1_cycles(); + + // Clear Timer 1 Channel 0-2 + overflow interrupt flag + T1CTL &= ~0xF0; + // Enable IM after timer set + T1CCTL0 |= BIT6; + + // Enable s/w timer int + sTimer1.enable = 1; +} + + +void set_timer1_abs(u16 aclk) +{ + u16 timediff; + + // Calculate time distance between last compare time and next compare time + if (aclk > sTimer1.aclk) + timediff = aclk - sTimer1.aclk; + else if (aclk == sTimer1.aclk) + timediff = 0xFFFF; + else + timediff = (65536 - sTimer1.aclk) + aclk; + + // Keep current value for next delta calculation + sTimer1.aclk = aclk; + + // Set timer1 relative to current time + set_timer1(timediff); +} + + +void enable_timer1_irq(void) +{ + sTimer1.enable = 1; +} + +void disable_timer1_irq(void) +{ + sTimer1.enable = 0; +} + +void clear_timer1_irq(void) +{ + sTimer1.iflag = 0; +} diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/timer1.h b/chronos-ti/Software Projects/RF Access Point/IAR/timer1.h new file mode 100755 index 0000000..2ad6bbd --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/timer1.h @@ -0,0 +1,21 @@ +#include "project.h" + +extern void reset_timer1(void); +extern u8 set_timer1_cycles(void); +extern void set_timer1(u16 aclk); +extern void set_timer1_abs(u16 aclk); +extern void enable_timer1_irq(void); +extern void disable_timer1_irq(void); +extern void clear_timer1_irq(void); + +struct timer1 +{ + u8 enable; + u8 iflag; + u16 aclk; + u8 nb_full_cycles; // 0xFFFF + u16 last_cycle_count; // 0x???? + u8 usb_service_disable; + u8 cycles; +}; +extern struct timer1 sTimer1; \ No newline at end of file diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_cdc.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_cdc.h new file mode 100755 index 0000000..e6dee54 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_cdc.h @@ -0,0 +1,118 @@ +/*********************************************************************************** + + Filename: usb_cdc.h + + Description: USB CDC definitions. + +***********************************************************************************/ + +#ifndef USB_CDC_H +#define USB_CDC_H + +/* Device Class Code */ +#define CDC_DEVICE 0x02 + +/* Communication Interface Class Code */ +#define COMM_INTF 0x02 + +/* Communication Interface Class SubClass Codes */ +#define ABSTRACT_CONTROL_MODEL 0x02 + +/* Communication Interface Class Control Protocol Codes */ +#define V25TER 0x01 // Common AT commands ("Hayes(TM)") + + +/* Data Interface Class Codes */ +#define DATA_INTF 0x0A + +/* Data Interface Class Protocol Codes */ +#define NO_PROTOCOL 0x00 // No class specific protocol required + + +/* Communication Feature Selector Codes */ +#define ABSTRACT_STATE 0x01 +#define COUNTRY_SETTING 0x02 + +/* Functional Descriptors */ +/* Type Values for the bDescType Field */ +#define CS_INTERFACE 0x24 +#define CS_ENDPOINT 0x25 + +/* bDescSubType in Functional Descriptors */ +#define DSC_FN_HEADER 0x00 +#define DSC_FN_CALL_MGT 0x01 +#define DSC_FN_ACM 0x02 // ACM - Abstract Control Management +#define DSC_FN_DLM 0x03 // DLM - Direct Line Managment +#define DSC_FN_TELEPHONE_RINGER 0x04 +#define DSC_FN_RPT_CAPABILITIES 0x05 +#define DSC_FN_UNION 0x06 +#define DSC_FN_COUNTRY_SELECTION 0x07 +#define DSC_FN_TEL_OP_MODES 0x08 +#define DSC_FN_USB_TERMINAL 0x09 +/* more.... see Table 25 in USB CDC Specification 1.1 */ + + +#define CDC_COMM_INTF_ID 0x00 +#define CDC_DATA_INTF_ID 0x01 + + + +// CLASS REQUESTS +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define CDC_SET_COMM_FEATURE 0x02 //optional +#define CDC_GET_COMM_FEATURE 0x03 //optional +#define CDC_CLEAR_COMM_FEATURE 0x04 //optional +#define CDC_SET_LINE_CODING 0x20 //optional +#define CDC_GET_LINE_CODING 0x21 //optional +#define CDC_SET_CONTROL_LINE_STATE 0x22 //optional +#define CDC_SEND_BREAK 0x23 //optional + + + +#define CDC_CHAR_FORMAT_1_STOP_BIT 0 +#define CDC_CHAR_FORMAT_1_5_STOP_BIT 1 +#define CDC_CHAR_FORMAT_2_STOP_BIT 2 + +#define CDC_PARITY_TYPE_NONE 0 +#define CDC_PARITY_TYPE_ODD 1 +#define CDC_PARITY_TYPE_EVEN 2 +#define CDC_PARITY_TYPE_MARK 3 +#define CDC_PARITY_TYPE_SPACE 4 + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2009 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_cdc_descriptor.s51 b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_cdc_descriptor.s51 new file mode 100755 index 0000000..090d1af --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_cdc_descriptor.s51 @@ -0,0 +1,303 @@ +/*********************************************************************************** + + Filename: usb_cdc_descriptor.s51 + + Description: Descriptor for USB CDC class. + +***********************************************************************************/ +/* ++------------------------------------------------------------------------------ +|The default USB descriptor defines a minimum configuration, with no endpoints +|apart from EP0. The application can define 3 IN and OUT endpoints, and override +|the configuration and interface descriptor (only one of each). +|The device and string descriptors are locked. ++------------------------------------------------------------------------------*/ + + +#define ASM_FILE +#include "..\library\usb_descriptor.h" +#include "usb_cdc.h" + + MODULE usb_descriptor + + RSEG RCODE + + PUBLIC usbDescStart; + PUBLIC usbDescEnd; + PUBLIC usbDescLut; + PUBLIC usbDescLutEnd; + PUBLIC usbDblbufLut; + PUBLIC usbDblbufLutEnd; + +;;------------------------------------------------------------------------------------------------------- +;; USB descriptors +usbDescStart: +deviceDesc: ; Device descriptor + DB deviceDescEnd - deviceDesc + DB DESC_TYPE_DEVICE ; bDescriptorType + DB 10H, 01H ; bcdUSB + DB CDC_DEVICE ; bDeviceClass + DB 00H ; bDeviceSubClass + DB 00H ; bDeviceProtocol + DB EP0_PACKET_SIZE + DB 51H, 04H ; idVendor Texas Instruments + #if (chip==2531) + DB 0A8H, 16H ; idProduct CC2531 + #elif (chip==2511) + DB 0A4H, 16H ; idProduct CC2511 + #else + DB 0A6H, 16H ; idProduct CC1111 + #endif + DB 09H, 00H ; bcdDevice + DB 01H ; iManufacturer + DB 02H ; iProduct + DB 03H ; iSerialNumber + DB 01H ; bNumConfigurations +deviceDescEnd: + +config1LengthStart: +configDesc: ; Configuration descriptor + DB configDescEnd - configDesc + DB DESC_TYPE_CONFIG ; bDescriptorType + DB config1LengthEnd - config1LengthStart, 00H + DB 02H ; NumInterfaces + DB 01H ; bConfigurationValue + DB 00H ; iConfiguration + DB 80H ; bmAttributes + DB 25 ; MaxPower +configDescEnd: + + +; +; INTERFACE 0 +; + + +interface0Desc: ; Interface descriptor + DB interface0DescEnd - interface0Desc + DB DESC_TYPE_INTERFACE ; bDescriptorType + DB 00H ; bInterfaceNumber + DB 00H ; bAlternateSetting + DB 01H ; bNumEndpoints + DB COMM_INTF ; bInterfaceClass + DB ABSTRACT_CONTROL_MODEL ; bInterfaceSubClass + DB V25TER ; bInterfaceProcotol + DB 00H ; iInterface +interface0DescEnd: + +;; CDC Class-Specific Descriptors + +headerFunctionalDesc: ; Header Functional Descriptor + DB headerFunctionalDescEnd - headerFunctionalDesc + DB CS_INTERFACE + DB DSC_FN_HEADER + DB 10H, 01H +headerFunctionalDescEnd: + + +absCtrlManFuncDesc: ; Abstract Control Management Functional Descriptor + DB absCtrlManFuncDescEnd - absCtrlManFuncDesc + DB CS_INTERFACE + DB DSC_FN_ACM + DB 02H ;set the supported class requests +absCtrlManFuncDescEnd: + +unionFunctionalDesc: ; Union Functional Descriptor + DB unionFunctionalDescEnd - unionFunctionalDesc + DB CS_INTERFACE + DB DSC_FN_UNION + DB CDC_COMM_INTF_ID + DB CDC_DATA_INTF_ID +unionFunctionalDescEnd: + + +callMngFuncDesc: ; Call Management Functional Descriptor + DB callMngFuncDescEnd - callMngFuncDesc + DB CS_INTERFACE + DB DSC_FN_CALL_MGT + DB 00H + DB CDC_DATA_INTF_ID +callMngFuncDescEnd: + + + +endpoint0Desc: ; Endpoint descriptor (EP2 IN) + DB endpoint0DescEnd - endpoint0Desc + DB DESC_TYPE_ENDPOINT ; bDescriptorType + DB 82H ; bEndpointAddress + DB EP_ATTR_INT ; bmAttributes + DB 40H, 00H ; wMaxPacketSize + DB 40H ; bInterval +endpoint0DescEnd: + +; +; INTERFACE 1 +; + +interface1Desc: ; Interface descriptor + DB interface1DescEnd - interface1Desc + DB DESC_TYPE_INTERFACE ; Interface descriptor type + DB 01H ; Interface Number + DB 00H ; Alternate Setting Number + DB 02H ; Number of endpoints in this intf + DB DATA_INTF ; Class code + DB 00H ; Subclass code + DB NO_PROTOCOL ; Protocol code + DB 00H ; Interface string index +interface1DescEnd: + + +endpoint1Desc: ; Endpoint descriptor (EP4 OUT) + DB endpoint1DescEnd - endpoint1Desc + DB DESC_TYPE_ENDPOINT ; bDescriptorType + DB 84H ; bEndpointAddress + DB EP_ATTR_BULK ; bmAttributes + DB 40H, 00H ; wMaxPacketSize + DB 01H ; bInterval +endpoint1DescEnd: + +endpoint2Desc: ; Endpoint descriptor (EP4 IN) + DB endpoint2DescEnd - endpoint2Desc + DB DESC_TYPE_ENDPOINT ; bDescriptorType + DB 04H ; bEndpointAddress + DB EP_ATTR_BULK ; bmAttributes + DB 40H, 00H ; wMaxPacketSize + DB 01H ; bInterval +endpoint2DescEnd: +config1LengthEnd: +;;------------------------------------------------------------------------------------------------------- + + +;;------------------------------------------------------------------------------------------------------- +;; String descriptors +string0Desc: ; Language ID + DB string0DescEnd - string0Desc + DB DESC_TYPE_STRING ; bDescriptorType + DB 09H ; US-EN + DB 04H +string0DescEnd: + +string1Desc: ; Manufacturer + DB string1DescEnd - string1Desc + DB DESC_TYPE_STRING ; bDescriptorType + DB 'T', 0 + DB 'e', 0 + DB 'x', 0 + DB 'a', 0 + DB 's', 0 + DB ' ', 0 + DB 'I', 0 + DB 'n', 0 + DB 's', 0 + DB 't', 0 + DB 'r', 0 + DB 'u', 0 + DB 'm', 0 + DB 'e', 0 + DB 'n', 0 + DB 't', 0 + DB 's', 0 + +string1DescEnd: + +string2Desc: ; Product + DB string2DescEnd - string2Desc + DB DESC_TYPE_STRING ; bDescriptorType + DB 'C', 0 + DB 'C', 0 + + #if (chip==2531) + DB '2', 0 + DB '5', 0 + DB '3', 0 + DB '1', 0 + #elif (chip==2511) + DB '2', 0 + DB '5', 0 + DB '1', 0 + DB '1', 0 + #else + DB '1', 0 + DB '1', 0 + DB '1', 0 + DB '1', 0 + #endif + + DB ' ', 0 + DB 'U', 0 + DB 'S', 0 + DB 'B', 0 + DB ' ', 0 + DB 'C', 0 + DB 'D', 0 + DB 'C', 0 +string2DescEnd: + +string3Desc: ; Serial number + DB string3DescEnd - string3Desc + DB DESC_TYPE_STRING ; bDescriptorType + DB '0', 0 + DB '0', 0 + DB '1', 0 +string3DescEnd: + +usbDescEnd: +;;------------------------------------------------------------------------------------------------------- + + +;;------------------------------------------------------------------------------------------------------- +;; Look-up table for descriptors that are not returned through requests for DSC_DEVICE, DSC_CONFIG or +;; DSC_STRING (e.g. HID report descriptors) +usbDescLut: +usbDescLutEnd: +;;------------------------------------------------------------------------------------------------------- + + +;;------------------------------------------------------------------------------------------------------- +;; Look-up table for double buffer settings (one set of bit masks for each defined interface) +usbDblbufLut: DW interface0Desc ; pInterface + DB 00H ; inMask + DB 00H ; outMask + DW interface1Desc ; pInterface + DB 00H ; inMask + DB 00H ; outMask +usbDblbufLutEnd: +;;------------------------------------------------------------------------------------------------------- + + + END; + + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| +*/ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_cdc_hooks.c b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_cdc_hooks.c new file mode 100755 index 0000000..1821443 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_cdc_hooks.c @@ -0,0 +1,162 @@ +/*********************************************************************************** + + Filename: usb_cdc_hooks.c + + Contains the necessary hook functions for various USB request processing + that is featured from the USB firmware library. Some + functions are empty. + +***********************************************************************************/ + + +/********************************************************************************** + * INCLUDES + */ + +#include "usb_firmware_library_headers.h" +#include "usb_cdc.h" +#include "usb_uart.h" +//#include "hal_led.h" + +/* Global data */ + +extern CDC_LINE_CODING_STRUCTURE currentLineCoding; +extern uint16 cdcRTS; + + +// ********************************************************************************* +// All Hooks and functions required by the USB library. +// ********************************************************************************* + +// **************** Process USB class requests with OUT data phase ***************** +void usbcrHookProcessOut(void) +{ + // Process USB class requests with OUT data phase, or stall endpoint 0 when unsupported + if (usbSetupHeader.request == CDC_SET_CONTROL_LINE_STATE) { + // Control line state from host + if(usbfwData.ep0Status == EP_IDLE) + { + cdcRTS= usbSetupHeader.value; + /* if (cdcRTS) + halLedSet(2); + else + halLedClear(2);*/ + + usbfwData.ep0Status = EP_RX; + } + + + } else if(usbSetupHeader.request == CDC_SET_LINE_CODING) { + + if(usbfwData.ep0Status == EP_IDLE) + { + usbSetupData.pBuffer = (uint8 __xdata *) ¤tLineCoding; + usbfwData.ep0Status = EP_RX; + } + else if(usbfwData.ep0Status == EP_RX) { } + } + // Unknown request? + else { + usbfwData.ep0Status = EP_STALL; + } +} + +// **************** Process USB class requests with IN data phase ****************** +void usbcrHookProcessIn(void) +{ + // Process USB class requests with IN data phase, or stall endpoint 0 when unsupported + if (usbSetupHeader.request == CDC_GET_LINE_CODING) { + // First the endpoint status is EP_IDLE... + if (usbfwData.ep0Status == EP_IDLE) { + usbSetupData.pBuffer = (uint8 __xdata *) ¤tLineCoding; + usbSetupData.bytesLeft = 7; + usbfwData.ep0Status = EP_TX; + // Then the endpoint status is EP_TX (remember: we did that here when setting up the buffer) + } else if (usbfwData.ep0Status == EP_TX) { + // usbfwData.ep0Status is automatically reset to EP_IDLE when returning to usbfwSetupHandler() + } + } else { + usbfwData.ep0Status = EP_STALL; + } +} + +// ******************************** Unsupported USB hooks ************************* +void usbvrHookProcessOut(void) {usbfwData.ep0Status = EP_STALL; } +void usbvrHookProcessIn(void) {usbfwData.ep0Status = EP_STALL; } + +// ************************ unsupported/unhandled standard requests *************** +void usbsrHookSetDescriptor(void) { usbfwData.ep0Status = EP_STALL; } +void usbsrHookSynchFrame(void) { usbfwData.ep0Status = EP_STALL; } +void usbsrHookClearFeature(void) { usbfwData.ep0Status = EP_STALL; } +void usbsrHookSetFeature(void) { usbfwData.ep0Status = EP_STALL; } +void usbsrHookModifyGetStatus(uint8 recipient, uint8 index, uint16 __xdata *pStatus) { } + + +// ************************ USB standard request event processing ****************** +void usbsrHookProcessEvent(uint8 event, uint8 index) +{ + // Process relevant events, one at a time. + switch (event) { + case USBSR_EVENT_CONFIGURATION_CHANGING : //(the device configuration is about to change) + break; + case USBSR_EVENT_CONFIGURATION_CHANGED :// (the device configuration has changed) + break; + case USBSR_EVENT_INTERFACE_CHANGING ://(the alternate setting of the given interface is about to change) + break; + case USBSR_EVENT_INTERFACE_CHANGED : //(the alternate setting of the given interface has changed) + break; + case USBSR_EVENT_REMOTE_WAKEUP_ENABLED ://(remote wakeup has been enabled by the host) + break; + case USBSR_EVENT_REMOTE_WAKEUP_DISABLED ://(remote wakeup has been disabled by the host) + break; + case USBSR_EVENT_EPIN_STALL_CLEARED ://(the given IN endpoint's stall condition has been cleared the host) + break; + case USBSR_EVENT_EPIN_STALL_SET ://(the given IN endpoint has been stalled by the host) + break; + case USBSR_EVENT_EPOUT_STALL_CLEARED ://(the given OUT endpoint's stall condition has been cleared the host) + break; + case USBSR_EVENT_EPOUT_STALL_SET ://(the given OUT endpoint has been stalled by the PC) + break; + } +} + +// ************************ USB interrupt event processing ************************* +void usbirqHookProcessEvents(void) +{ + // Handle events that require immediate processing here +} + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_firmware_library_config.c b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_firmware_library_config.c new file mode 100755 index 0000000..5b4614f --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_firmware_library_config.c @@ -0,0 +1,68 @@ +/*********************************************************************************** + + Filename: usb_firmware_library_config.c + + Description: USB library configuration. + +***********************************************************************************/ + +/// \addtogroup module_usb_firmware_library_config +/// @{ +#define USBFIRMWARELIBRARYCONFIG_C ///< Modifies the behavior of "EXTERN" in usb_interrupt.h +#include "usb_firmware_library_headers.h" + +//----------------------------------------------------------------------------- +// READ THIS!! +// +// This file configures the USB Firmware Library. +// To use the library, make a copy of this file, rename it to "usb_firmware_library_config.c", and +// put it in the project catalog. Then edit the code below as needed: +//----------------------------------------------------------------------------- + +// Declaration of global USB descriptor pointers +USB_DESCRIPTOR_MARKER usbDescriptorMarker= { + (uint8 __code *)&usbDescStart, + (uint8 __code *)&usbDescEnd, + (DESC_LUT_INFO __code *) &usbDescLut, + (DESC_LUT_INFO __code *) &usbDescLutEnd, + (DBLBUF_LUT_INFO __code *) &usbDblbufLut, + (DBLBUF_LUT_INFO __code *) &usbDblbufLutEnd +}; + +/// @} + + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_firmware_library_config.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_firmware_library_config.h new file mode 100755 index 0000000..8b9b92c --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_firmware_library_config.h @@ -0,0 +1,64 @@ +/*********************************************************************************** + + Filename: usb_firmware_library_config.h + + Description: USB library configuration. + +***********************************************************************************/ +#ifndef USBFIRMWARELIBRARYCONFIG_H // Don't modify +#define USBFIRMWARELIBRARYCONFIG_H // Don't modify + +//----------------------------------------------------------------------------- +// READ THIS!! +// +// This file configures the USB Firmware Library. +// To use the library, make a copy of this file, rename it to "usb_firmware_library_config.h", and +// put it in the project catalog. Then edit the definitions below: +//----------------------------------------------------------------------------- +// Includes + + +//----------------------------------------------------------------------------- +// Defines + +// Enter the maximum number of interfaces that are used in the configurations (used to calculate the size +// of the table that stores the currently selected alternate setting for each interface) +#define USB_SETUP_MAX_NUMBER_OF_INTERFACES 5 + + +#endif //#ifndef USBFIRMWARELIBRARYCONFIG_H +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_firmware_library_headers.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_firmware_library_headers.h new file mode 100755 index 0000000..5d2d80a --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_firmware_library_headers.h @@ -0,0 +1,64 @@ +/*********************************************************************************** + + Filename: usb_firmware_library_headers.h + + Description: Common inclusion of all USB library headers. + +***********************************************************************************/ + +#ifndef USB_FIRMWARE_LIBRARY_HEADERS_H +#define USB_FIRMWARE_LIBRARY_HEADERS_H + + +// This file includes all of the USB Library header files. +// When using the library, include this file only. + +// Also make a copy of usb_firmware_library_config_template.c and usb_firmware_library_config_template.h +// and add it to your project as usb_firmware_library_config.c and +// usb_firmware_library_config.h. The definitions in these files should be adapted to your project. + +#include "usb_firmware_library_config.h" +#include "usb_descriptor.h" +#include "usb_descriptor_parser.h" +#include "usb_interrupt.h" +#include "usb_framework.h" +#include "usb_reg.h" +#include "usb_standard_requests.h" +#include "usb_suspend.h" + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ +#endif //USB_FIRMWARE_LIBRARY_HEADERS_H + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_uart.c b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_uart.c new file mode 100755 index 0000000..9623e7b --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_uart.c @@ -0,0 +1,362 @@ +/*********************************************************************************** + + Filename: usb_uart.h + + Description: USB Virtual UART implementation. + +***********************************************************************************/ + + +/*********************************************************************************** + * INCLUDES + */ +#include "hal_types.h" +#include "hal_board.h" +#include "hal_int.h" +#include "hal_led.h" + +#include "usb_cdc.h" +#include "usb_firmware_library_config.h" +#include "usb_firmware_library_headers.h" + +#include "usb_uart.h" +//#include "util_buffer.h" + + +/*********************************************************************************** + * MACROS and DEFINITIONS + */ + +#define HAL_LED_DEBUG + + + + +/*********************************************************************************** + * EXTERNAL VARIABLES + */ + +/* Ring buffers defined in hal_uart.c */ + +//extern ringBuf_t rbRxBuf; +//extern ringBuf_t rbTxBuf; + + +/*********************************************************************************** + * GLOBAL VARIABLES + */ +CDC_LINE_CODING_STRUCTURE __xdata currentLineCoding; +uint16 cdcRTS; // Request-To-Send modem control line +uint8 cdcCTS; // Clear-To-Send modem control line + +unsigned char message_length = USB_MAX_MESSAGE_LENGTH; +unsigned char usb_buffer[USB_MAX_MESSAGE_LENGTH+2]; +char usb_bufferIndex = 0; +unsigned char usb_newdata = 0; +unsigned char usb_sendack = 0; + + +/*********************************************************************************** + * LOCAL DATA + */ +//static uint8 __xdata buffer[USB_MAX_PACKET_SIZE]; +static uint8 oldEndpoint; + + +/*********************************************************************************** + * LOCAL FUNCTIONS + */ +static void usbEventProcess(void); +static void usbOutProcess(void); +static void usbInProcess(void); + + +/****************************************************************************** + * FUNCTIONS + */ +extern void usb_decode(void); + + +/*********************************************************************************** +* @fn usbUartInit +* +* @brief USB UART init function. +* - Set initial line decoding to 8/NONE/1. +* - Initialise the USB Firmware Library and the USB controller. +* +* @param none +* +* @return none +*/ +void usbUartInit(uint32 baudrate) +{ + usb_bufferIndex = 0; + usb_newdata = 0; + usb_sendack = 0; + + // Set default line coding. + currentLineCoding.dteRate = baudrate; + currentLineCoding.charFormat = CDC_CHAR_FORMAT_1_STOP_BIT; + currentLineCoding.parityType = CDC_PARITY_TYPE_NONE; + currentLineCoding.dataBits = 8; + + // Initialise hardware flow control + cdcRTS= 0; // TRUE when DCE connected + cdcCTS= 1; // Indicate CTS to DCE (here handled internally as CDC does + // not directly support CTC). + + // Init USB library + usbfwInit(); + + // Initialize the USB interrupt handler with bit mask containing all processed USBIRQ events + usbirqInit(0xFFFF); + + // Enable pullup on D+ + HAL_USB_PULLUP_ENABLE(); + + // Enable global interrupts + halIntOn(); +} + + + +/*********************************************************************************** +* @fn usbUartProcess +* +* @brief The USB UART main task function. Must be called from the +* applications main loop. +* +* @param none +* +* @return none +*/ +void usbUartProcess(void) +{ + // Process USB events + usbEventProcess(); + + if (cdcCTS) { + + // Process USB OUT data (USB -> RF) + usbOutProcess(); + + // Process USB IN data (RF -> USB) + usbInProcess(); + } +} + + + +/*********************************************************************************** +* @fn usbEventProcess +* +* @brief Handle the USB events which are not directly related to the UART. +* +* @param none +* +* @return none +*/ +static void usbEventProcess(void) +{ + // Handle reset signaling on the bus + if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_RESET) { + USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_RESET); + usbfwResetHandler(); + } + + // Handle packets on EP0 + if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_SETUP) { + USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_SETUP); + usbfwSetupHandler(); + } + + // Handle USB suspend + if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_SUSPEND) { + + // Clear USB suspend interrupt + USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_SUSPEND); + + // Take the chip into PM1 until a USB resume is deteceted. + usbsuspEnter(); + + // Running again; first clear RESUME interrupt + USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_RESUME); + } +} + + + +/*********************************************************************************** +* @fn usbInProcess +* +* @brief Handle traffic flow from RF to USB. +* +* @param none +* +* @return none +*/ +static void usbInProcess(void) +{ + //uint8 length; + + // USB ready to accept new IN packet + halIntOff(); + + oldEndpoint = USBFW_GET_SELECTED_ENDPOINT(); + USBFW_SELECT_ENDPOINT(4); + + // The IN endpoint is ready to accept data + if ( USBFW_IN_ENDPOINT_DISARMED() ) + { + if (usb_sendack) + { + // modify and return received packet + usbfwWriteFifo(&USBF4, usb_buffer[2], &usb_buffer[0]); + usb_sendack = 0; + + // Flag USB IN buffer as not ready (disarming EP4) + USBFW_SELECT_ENDPOINT(4); + USBFW_ARM_IN_ENDPOINT(); // Send data to the host + } + +/* // Number of bytes present in RF buffer + length= bufNumBytes(&rbTxBuf); + + if (length>0) { + + // Limit the size + if (length > USB_MAX_PACKET_SIZE) + { + length = USB_MAX_PACKET_SIZE; + } + + // Read from UART TX buffer + bufGet(&rbTxBuf,buffer,length); + + // Write to USB FIFO + usbfwWriteFifo(&USBF4, length, buffer); + + // Flag USB IN buffer as not ready (disarming EP4) + USBFW_SELECT_ENDPOINT(4); + USBFW_ARM_IN_ENDPOINT(); // Send data to the host + + }*/ + } + + USBFW_SELECT_ENDPOINT(oldEndpoint); + halIntOn(); + +} + + +/*********************************************************************************** +* @fn usbOutProcess +* +* @brief Handle traffic flow from USB to RF. +* +* @param none +* +* @return none +*/ +static void usbOutProcess(void) +{ + uint8 length, /*nToSend,*/ packetlength=0; + + // If new packet is ready in USB FIFO + halIntOff(); + + oldEndpoint = USBFW_GET_SELECTED_ENDPOINT(); + USBFW_SELECT_ENDPOINT(4); + + + if (USBFW_OUT_ENDPOINT_DISARMED() ) { + + // Get length of USB packet, this operation must not be interrupted. + length = USBFW_GET_OUT_ENDPOINT_COUNT_LOW(); + length+= USBFW_GET_OUT_ENDPOINT_COUNT_HIGH() >> 8; + + // Avoid overflow + message_length = USB_MAX_MESSAGE_LENGTH; + if (usb_bufferIndex + length > USB_MAX_MESSAGE_LENGTH) usb_bufferIndex=0; + + // Copy received bytes from FIFO to buffer + usbfwReadFifo(&USBF4, length, &usb_buffer[usb_bufferIndex]); + + // Increase buffer index + usb_bufferIndex += length; + + // If entire USB packet is read from buffer + USBFW_SELECT_ENDPOINT(4); + USBFW_ARM_OUT_ENDPOINT(); + + // get packet lenght from byte #2 of received packet + if ((usb_bufferIndex >= 2) && (packetlength == 0)) packetlength = usb_buffer[2]; + if ((usb_bufferIndex > packetlength-1) && (packetlength >= USB_MIN_MESSAGE_LENGTH)) + { + //extract data from packet + usb_decode(); + usb_bufferIndex = 0; + } + + /* + // Calculate number of bytes available in RF buffer; and the number + // of bytes we may transfer in this operation. + nToSend= MIN(BUF_SIZE - bufNumBytes(&rbRxBuf), length); + + // Space available in UART RX buffer ? + if (nToSend>0) + { + // Read from USB FIFO + usbfwReadFifo(&USBF4, nToSend, buffer); + + // Write to radio TX buffer + bufPut(&rbRxBuf,buffer,nToSend); + + // If entire USB packet is read from buffer + if (length == nToSend) + { + USBFW_SELECT_ENDPOINT(4); + USBFW_ARM_OUT_ENDPOINT(); + } + + }*/ + } + + USBFW_SELECT_ENDPOINT(oldEndpoint); + halIntOn(); +} +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2009 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ + diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_uart.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_uart.h new file mode 100755 index 0000000..6e7a310 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/class_cdc/usb_uart.h @@ -0,0 +1,47 @@ +/*********************************************************************************** + + Filename: usb_uart.h + + Description: USB Virtual UART interface. + +***********************************************************************************/ + + +#ifndef USB_UART_H +#define USB_UART_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define USB_MAX_PACKET_SIZE 64 // As set in USB endpoint descriptor +#define UART_SET_RTS_LIMIT 200 +#define UART_RELEASE_RTS_LIMIT 100 + +#define UART_FLOW_CTRL_STOP 1 +#define UART_FLOW_CTRL_GO 0 + +#define UART_TX_BUFFER_EMPTY 0x01 +#define UART_TX_STOPED_BY_FLOW_CTRL 0x02 + +#define USB_MIN_MESSAGE_LENGTH (3u) +#define USB_MAX_MESSAGE_LENGTH (32u) + +typedef struct { + uint32 dteRate; + uint8 charFormat; + uint8 parityType; + uint8 dataBits; +} __xdata CDC_LINE_CODING_STRUCTURE; + + +void usbUartInit(uint32 baudrate); +void usbUartProcess(void); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/ccxx11/usb_interrupt.c b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/ccxx11/usb_interrupt.c new file mode 100755 index 0000000..666899c --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/ccxx11/usb_interrupt.c @@ -0,0 +1,163 @@ +/*********************************************************************************** + + Filename: usb_interrupt.c + + Description: USB library interrupt initialisation and ISR. + +***********************************************************************************/ + +/// \addtogroup module_usb_interrupt +/// @{ +#define USBINTERRUPT_C ///< Modifies the behavior of "EXTERN" in usb_interrupt.h +#include "usb_firmware_library_headers.h" +#include "hal_board.h" +#include "clock.h" + + +/** \brief Initializes the \ref module_usb_interrupt module + * + * This function should be called after the \ref module_usb_framework module has been initialized. + * Use interrupt group priority control (refer to the CC2511/CC1111 datasheet) to adjust the priority of the + * USB interrupt relative to other interrupts. + * + * \param[in] irqMask + * A bit mask containing USBIRQ_EVENT bits for all events that shall be reported + */ +void usbirqInit(uint16 irqMask) +{ + // Initialize variables + usbirqData.eventMask = 0x0000; + usbirqData.inSuspend = FALSE; + usbirqData.irqMask = irqMask; + + // Select IRQ flags to handle + USBCIE = irqMask; + USBIIE = irqMask >> 4; + USBOIE = (irqMask >> 9) & 0x3E; + + // Configure P0 for rising edge detection on P0[7:4], but keep the interrupt disabled until it is + // needed. + PICTL |= 0x10; + HAL_USB_RESUME_INT_CLEAR(); + HAL_USB_INT_CLEAR(); + HAL_USB_INT_ENABLE(); + +} // usbirqInit + + + + +/** \brief USB interrupt handler + * + * Clears the P2 interrupt flag and converts all USB interrupt flags into events. + * The interrupt also lets \ref usbsuspEnter() break from the suspend loop. + */ +#pragma vector=P2INT_VECTOR +__interrupt void usbirqHandler(void) +{ + uint8 usbcif; + + // First make sure that the crystal oscillator is stable + while (!IS_XOSC_STABLE()); + + // Special handling for reset interrupts + usbcif = USBCIF; + if (usbcif & USBCIF_RSTIF) { + + // All interrupts (except suspend) are by default enabled by hardware, so + // re-initialize the enable bits to avoid unwanted interrupts + USBCIE = usbirqData.irqMask; + USBIIE = usbirqData.irqMask >> 4; + USBOIE = (usbirqData.irqMask >> 9) & 0x3E; + + // Enable suspend mode when suspend signaling is detected on the bus + USBPOW |= USBPOW_SUSPEND_EN; + } + + // Record events (keeping existing) + usbirqData.eventMask |= (uint16) usbcif; + usbirqData.eventMask |= (uint16) USBIIF << 4; + usbirqData.eventMask |= (uint16) USBOIF << 9; + + // If we get a suspend event, we should always enter suspend mode. We must, + // however be sure that we exit the suspend loop upon resume or reset + // signaling. + if (usbcif & USBCIF_SUSPENDIF) { + usbirqData.inSuspend = TRUE; + } + if (usbcif & (USBCIF_RSTIF | USBCIF_RESUMEIF)) { + usbirqData.inSuspend = FALSE; + } + + // Hand them over to the application + usbirqHookProcessEvents(); + + // Clear the P2 interrupt flag + HAL_USB_INT_CLEAR(); + +} // usbirqHandler + + + + +/** \\brief USB resume interrupt handler + * + * This routine clears the USB resume interrupt flag, and makes sure that MCU does not return to power + * mode 1 again until the the suspend loop has been exited. + */ +#pragma vector = P0INT_VECTOR +__interrupt void usbirqResumeHandler(void) +{ + uint8 flags; + + // First make sure that the crystal oscillator is stable + while (!IS_XOSC_STABLE()); + + // Clear and disable the interrupt flag + flags = P0IFG; + if (flags & 0x80) { + // We have a USB_RESUME interrupt (which could also be a USB reset) + HAL_USB_RESUME_INT_DISABLE(); + usbsuspStopPm1(); + } + + HAL_USB_RESUME_INT_CLEAR(); + +} // usbResumeHandler + +/// @} + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/ccxx11/usb_suspend.c b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/ccxx11/usb_suspend.c new file mode 100755 index 0000000..23dae90 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/ccxx11/usb_suspend.c @@ -0,0 +1,182 @@ +/*********************************************************************************** + + Filename: usb_framework.c + + Description: USB library common functionality. + +***********************************************************************************/ + +/// \addtogroup module_usb_suspend +/// @{ +#include "usb_firmware_library_headers.h" +#include "hal_int.h" +#include "hal_mcu.h" +#include "hal_board.h" + +static __xdata uint8 usbsuspEnterXdata[14]; +static __xdata VFPTR pUsbsuspEnterXdata = NULL; + +__xdata VFPTR pFnSuspendEnterHook= NULL; +__xdata VFPTR pFnSuspendExitHook= NULL; + + + +/** \brief Puts the chip into power mode 1 during USB suspend. + * + * This function must be called from main (i.e. not from interrupt context) upon the reception of a + * \ref USBIRQ_EVENT_SUSPEND event. To comply with the USB specification, this must happen within 10 ms + * after the event occurs. The chip will stay in power mode 1 until a USB resume or USB reset is detected + * on the USB bus, or remote wakeup is used. During this period, the MCU can only run code from + * interrupt context. + */ +void usbsuspEnter(void) +{ + if (pFnSuspendEnterHook!=NULL) + pFnSuspendEnterHook(); + + // SLEEP &= ~0x03; / ANL SLEEP, #0xFC + usbsuspEnterXdata[0] = 0x53; + usbsuspEnterXdata[1] = 0xBE; + usbsuspEnterXdata[2] = 0xFC; + + // SLEEP |= 0x01; / ORL SLEEP, #0x01 + usbsuspEnterXdata[3] = 0x43; + usbsuspEnterXdata[4] = 0xBE; + usbsuspEnterXdata[5] = 0x01; + + // PCON = 0x01; / MOV PCON, #0x01 + usbsuspEnterXdata[6] = 0x75; + usbsuspEnterXdata[7] = 0x87; + usbsuspEnterXdata[8] = 0x01; + + // The CPU will be halted here while suspended (in PM1). + + // while (inSuspend); / MOV A, inSuspend + usbsuspEnterXdata[9] = 0xE5; + usbsuspEnterXdata[10] = (uint8) ((__data uint8 *) &usbirqData.inSuspend); + + // ... Restart ... / JNZ -12 + usbsuspEnterXdata[11] = 0x70; + usbsuspEnterXdata[12] = 0xF3; + + // return; / RET + usbsuspEnterXdata[13] = 0x22; + + // Enable the resume and reset detection interrupt + HAL_USB_RESUME_INT_CLEAR(); + HAL_USB_RESUME_INT_ENABLE(); + + // Call the suspend loop routine from XDATA + // The routine is in XDATA so that usbsuspExit() wipe out the power-down instruction in the loop (by + // replacing "MOV PCON, #0x01" with three NOP instructions). + pUsbsuspEnterXdata = (VFPTR) ((uint16) usbsuspEnterXdata); + pUsbsuspEnterXdata(); + + if (pFnSuspendExitHook!=NULL) + pFnSuspendExitHook(); + +} // usbsuspEnter + + + + +/** \brief Attempts USB remote wakeup. + * + * This function can be called from interrupt context while the USB device is suspend mode. If the device + * is privileged to do so (see \c usbfwData.remoteWakeup and the \ref USBSR_EVENT_REMOTE_WAKEUP_ENABLED + * and \ref USBSR_EVENT_REMOTE_WAKEUP_DISABLED events), remote wakeup will be performed. Note that this + * function will block for 10 ms while the resume signal is set on the bus. Note: This function can only + * be called when the 48 MHz XOSC is stable. + * + * \return + * \c TRUE if the remote wakeup was performed (the privilege had been granted), otherwise \c FALSE + * (the device is still in suspend mode). + */ +uint8 usbsuspDoRemoteWakeup(void) +{ + + // Make sure that it's OK + if (!usbfwData.remoteWakeup) return FALSE; + + halIntOff(); + + // Make sure that the suspend loop does not power down the chip again + usbsuspStopPm1(); + usbirqData.inSuspend = FALSE; + + // Perform remote wakeup by holding the USB resume signal for 10 ms + USBPOW |= 0x04; + halMcuWaitMs(10); // ms + USBPOW &= ~0x04; + + // Clear and disable the interrupt flag + HAL_USB_RESUME_INT_DISABLE(); + HAL_USB_RESUME_INT_CLEAR(); + + halIntOn(); + + return TRUE; + +} // usbsuspDoRemoteWakeup + + + + +/** \brief Internal function, do not call from application.. + * + * This internal function is called by the P0 "USB resume and reset" detection interrupt, and by + * \ref usbsuspDoRemoteWakeup() to prevent \ref usbsuspEnter() from putting the device back in power + * mode 1. \ref usbsuspEnter() will, however, not break out of the suspend loop until the resume event + * has been received. + */ +void usbsuspStopPm1(void) +{ + + // Disable the "ORL SLEEP, #0x01" instruction to make sure we avoid having + // SLEEP.MODE != 0 after MCU has resumed to active mode. Otherwise all port + // and sleep timer interrupts will be blocked. + usbsuspEnterXdata[5] = 0x00; // Change it to: "ORL SLEEP, #0x00" (no effect) + + // Remove the "MOV PCON, #0x01" instruction (which puts MCU into power mode 1) from the suspend + // loop + usbsuspEnterXdata[6] = 0x00; // NOP + usbsuspEnterXdata[7] = 0x00; // NOP + usbsuspEnterXdata[8] = 0x00; // NOP + +} // usbsuspStopPm1 + +//@} +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_descriptor.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_descriptor.h new file mode 100755 index 0000000..122f0e1 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_descriptor.h @@ -0,0 +1,199 @@ +/*********************************************************************************** + + Filename: usb_descriptor.h + + Description: Interface to USB descriptors. + +***********************************************************************************/ +#ifndef USBDESCRIPTOR_H +#define USBDESCRIPTOR_H + + +#ifndef ASM_FILE +#include "usb_framework_structs.h" +#endif + +/** \addtogroup module_usb_descriptor USB Descriptor + * \brief This module contains contains USB descriptor definitions, and guidelines on how to write + * descriptor sets that work with the USB library. + * + * Information on the specific USB descriptor types is available in the USB 2.0 specification and + * in device class documentation. Examples of complete descriptor sets can be found in the Chipcon USB + * application examples. + * + * \section section_usbdsc_standard Standard Descriptors + * The library requires the USB descriptor set to be organized as follows: + * - Device descriptor (\ref USB_DEVICE_DESCRIPTOR) + * - Configuration descriptor (\ref USB_CONFIGURATION_DESCRIPTOR) + * - Interface descriptor (\ref USB_INTERFACE_DESCRIPTOR) + * - Endpoint descriptor (\ref USB_ENDPOINT_DESCRIPTOR) + * - More endpoint descriptors + * - More interface descriptors + * - More configuration descriptors + * - String descriptor (\ref USB_STRING_DESCRIPTOR) + * - More string descriptors + * + * Different USB device classes, such as "HID" and "Audio", may add other standard format descriptor + * types to the hierarchy, and even extend the existing types. This is also supported by the library. + * + * Refer to the \ref module_usb_descriptor_parser module for information on + * \li Where in memory the descriptor set can be placed + * \li How to set the required markers (symbols), \ref usbDescStart and \ref usbDescEnd. + * + * \section section_usbdsc_other Other Descriptors + * Differently formatted descriptors are not supported by the parsing mechanism, and are instead located + * through a \ref DESC_LUT_INFO look-up table. Each entry in the \ref usbDescLut table contains the + * index and value parameters for relevant \ref GET_DESCRIPTOR requests, and the locations and lengths + * of the corresponding descriptors: + * \code + * ; Make the symbols public + * PUBLIC usbDescLut; + * PUBLIC usbDescLutEnd; + * + * ... + * + * usbDescLut: DB HID_REPORT, 00H ; value (MSB, LSB) + * DB 00H, 00H ; index (MSB, LSB) + * DW hidReportDesc0Start ; pDescStart + * DW hidReportDesc0End - hidReportDesc0Start ; length + * + * DB HID_REPORT, 01H ; value (MSB, LSB) + * DB 00H, 00H ; index (MSB, LSB) + * DW hidReportDesc1Start ; pDescStart + * DW hidReportDesc1End - hidReportDesc1Start ; length + * usbDescLutEnd: + * \endcode + * + * An additional look-up table is needed configure endpoint double-buffering. The table must contain one + * \ref DBLBUF_LUT_INFO entry for each interface descriptor with non-zero \c bNumEndpoints: + * \code + * ; Make the symbol public + * PUBLIC usbDblbufLut; + * + * ... + * + * usbDblbufLut: DW interface0Desc ; pInterface + * DB 02H ; inMask (example: EP1 IN is double-buffered) + * DB 00H ; outMask (example: No double-buffered OUT endpoints) + * + * DW interface1Desc ; pInterface + * DB 10H ; inMask (example: EP4 IN is double-buffered) + * DB 08H ; outMask (example: EP3 OUT is double-buffered) + * \endcode + * @{ + */ + + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef USBDESCRIPTORPARSER_C + #define EXTERN ///< Definition used only for usb_descriptor_parser.c +#else + #define EXTERN extern ///< Definition used in other source files to declare external +#endif + + +//------------------------------------------------------------------------------------------------------- +/// \name Sizes +//@{ +#define EP0_PACKET_SIZE 32 ///< The maximum data packet size for endpoint 0 +//@} + +/// \name Standard Descriptor Types +//@{ +#define DESC_TYPE_DEVICE 0x01 ///< Device +#define DESC_TYPE_CONFIG 0x02 ///< Configuration +#define DESC_TYPE_STRING 0x03 ///< String +#define DESC_TYPE_INTERFACE 0x04 ///< Interface +#define DESC_TYPE_ENDPOINT 0x05 ///< Endpoint +//@} + +/// \name HID Class Descriptor Types +//@{ +#define DESC_TYPE_HID 0x21 ///< HID descriptor (included in the interface descriptor) +#define DESC_TYPE_HIDREPORT 0x22 ///< Report descriptor (referenced in \ref usbDescLut) +//@} + +/// \name Endpoint Types +//@{ +#define EP_ATTR_CTRL 0x00 ///< Control (endpoint 0 only) +#define EP_ATTR_ISO 0x01 ///< Isochronous (not acknowledged) +#define EP_ATTR_BULK 0x02 ///< Bulk +#define EP_ATTR_INT 0x03 ///< Interrupt (guaranteed polling interval) +#define EP_ATTR_TYPE_BM 0x03 ///< Endpoint type bitmask +//@} +//------------------------------------------------------------------------------------------------------- + + +#ifndef ASM_FILE + +//------------------------------------------------------------------------------------------------------- +/// \name USB Descriptor Marker +//@{ +/// USB descriptor markers which the USB Firmware Library imports from the application +typedef struct { + uint8 __code* const pUsbDescStart; ///< USB descriptor start pointer + uint8 __code* const pUsbDescEnd; ///< USB descriptor end pointer + DESC_LUT_INFO __code* const pUsbDescLut; ///< Start of USB desc look-up table pointer + DESC_LUT_INFO __code* const pUsbDescLutEnd; ///< End of USB desc look-up table pointer + DBLBUF_LUT_INFO __code* const pUsbDblbufLut; ///< Start of double-buffering look-up table pointer + DBLBUF_LUT_INFO __code* const pUsbDblbufLutEnd; ///< End of double-buffering look-up table pointer +} USB_DESCRIPTOR_MARKER; + +extern USB_DESCRIPTOR_MARKER __xdata usbDescriptorMarker; ///< USB descriptor marker + +//------------------------------------------------------------------------------------------------------- + +// Import marker symbols for the USB descriptor to use (from _usb_descriptor.s51) +// They need to be defined here or in application FW +// The source file _usb_descriptor.s51 need to use these names, or update +// the names used here with the ones used in _usb_descriptor.s51. +extern void __code* usbDescStart; ///< Pointer to start of (standard) USB descriptor +extern void __code* usbDescEnd; ///< Pointer to end of (standard) USB descriptor +extern void __code* usbDescLut; ///< Pointer to start of lookup table for non-standard USB descriptors +extern void __code* usbDescLutEnd; ///< Pointer to end of lookup table for non-standard USB descriptors +extern void __code* usbDblbufLut; ///< Pointer to start of lookup table for endpoints' double-buffer settings +extern void __code* usbDblbufLutEnd; ///< Pointer to end of lookup table for endpoints' double-buffer settings +//@} + + +#endif // ASM_FILE +//@} + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2009 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_descriptor_parser.c b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_descriptor_parser.c new file mode 100755 index 0000000..45cb6b3 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_descriptor_parser.c @@ -0,0 +1,242 @@ +/*********************************************************************************** + + Filename: usb_descriptor_parser.c + + Description: Parser for USB descriptor structures. + +***********************************************************************************/ + +/// \addtogroup module_usb_descriptor_parser +/// @{ +#define USBDESCRIPTORPARSER_C ///< Modifies the behavior of "EXTERN" in usb_descriptor_parser.h +#include "usb_firmware_library_headers.h" + +//------------------------------------------------------------------------------------------------------- +// USBDP internal module data +static USBDP_DATA __xdata usbdpData; ///< USBDP internal module data + + +/** \brief Initializes a search +* +* This function must be called before each new search to reset \ref USBDP_DATA.pDesc. +*/ +void usbdpInit(void) +{ + usbdpData.pDesc = (const uint8 __code *) usbDescriptorMarker.pUsbDescStart; +} // usbdpInit + + + + +/** \brief Locates the descriptor of the wanted type +* +* This function parses through the USB descriptors until: +* \li It hits one with bDescriptorType = wantedType, in which case it returns a pointer to +* that descriptor, and exits. \ref USBDP_DATA.pDesc will then point to the next descriptor. +* \li It hits one with bDescriptorType = haltAtType, in which case it returns a NULL-pointer, +* and exits. \ref USBDP_DATA.pDesc will then point to that descriptor. +* \li \ref USBDP_DATA.pDesc = \ref usbDescEnd, in which case it returns a NULL-pointer, and exits. +* \ref USBDP_DATA.pDesc will continue to point to \ref usbDescEnd. +* +* \note To begin a search with this function, \ref usbdpInit should be called first. It should not be +* called when continuing a search - for instance after a call to \ref usbdpGetConfigurationDesc(). +* +* \param[in] wantedType +* The wanted descriptor type (e.g. \ref DESC_TYPE_CONFIG) +* \param[in] haltAtType +* The parser halts when it reaches this descriptor type, unless \c haltAtType is \c 0 (which in any +* case is an invalid \c bDescriptorType value). +* +* \return +* A pointer to the wanted descriptor type, or \c NULL if it was not found. +*/ +void __code* usbdpFindNext(uint8 wantedType, uint8 haltAtType) +{ + void __code *pResult; + pResult = NULL; + + // As long as we haven't reached the end... + while (usbdpData.pDesc != (void __code *) usbDescriptorMarker.pUsbDescEnd) { + + // If we have a match on wantedType... + if (usbdpData.pDesc[DESC_TYPE_IDX] == wantedType) { + pResult = (void __code*) usbdpData.pDesc; + usbdpData.pDesc += usbdpData.pDesc[DESC_LENGTH_IDX]; + break; + + // If we have a match on haltAtType... + } else if (usbdpData.pDesc[DESC_TYPE_IDX] == haltAtType) { + if (haltAtType) break; + } + + // Move on to the next descriptor + usbdpData.pDesc += usbdpData.pDesc[DESC_LENGTH_IDX]; + } + + return pResult; +} // usbdpFindNext + + + + +/** \brief Locates the (one and only) device descriptor +* +* \note It is not necessary to call \ref usbdpInit() before this function. +* +* \return +* A pointer to the \ref USB_DEVICE_DESCRIPTOR, or \c NULL if it was not found. +*/ +USB_DEVICE_DESCRIPTOR __code* usbdpGetDeviceDesc(void) +{ + usbdpInit(); + return usbdpFindNext(DESC_TYPE_DEVICE, 0); +} // usbdpGetDeviceDesc + + + + +/** \brief Locates a configuration descriptor +* +* The search will either look for a descriptor with a specific +* \ref USB_CONFIGURATION_DESCRIPTOR.bConfigurationValue, or simply take the n'th descriptor (by "index") +* +* \note It is not necessary to call \ref usbdpInit() before this function. +* +* \param[in] cfgValue +* The configuration value to search for (\ref USB_CONFIGURATION_DESCRIPTOR.bConfigurationValue), or +* 0 to find descriptor by index +* \param[in] cfgIndex +* A zero-based index for the configuration descriptor to find. +* This value is ignored unless \c cfgValue is 0. +* +* \return +* A pointer to the \ref USB_DEVICE_DESCRIPTOR, or \c NULL if it was not found. +*/ +USB_CONFIGURATION_DESCRIPTOR __code* usbdpGetConfigurationDesc(uint8 cfgValue, uint8 cfgIndex) +{ + USB_CONFIGURATION_DESCRIPTOR __code *pConfigurationDesc; + usbdpInit(); + + // As long as there are more configuration descriptors... + while (pConfigurationDesc = usbdpFindNext(DESC_TYPE_CONFIG, 0)) { + + // Search by value? + if (cfgValue) { + if (cfgValue == pConfigurationDesc->bConfigurationValue) break; + + // Search by index? (search cfgIndex+1 times) + } else if (!cfgIndex--) { + break; + } + } + + return pConfigurationDesc; +} // usbdpGetConfigurationDesc + + + + +/** \brief Locates an interface descriptor +* +* The function will first go to the configuration descriptor that matches the supplied configuration +* value, and then locate the interface descriptor that matches the given interface number and alternate +* setting. +* +* \note It is not necessary to call \ref usbdpInit() before this function. +* +* \param[in] cfgValue +* The configuration value (\ref USB_CONFIGURATION_DESCRIPTOR.bConfigurationValue) +* \param[in] intNumber +* The interface number (\ref USB_INTERFACE_DESCRIPTOR.bInterfaceNumber) +* \param[in] altSetting +* The alternate setting (\ref USB_INTERFACE_DESCRIPTOR.bAlternateSetting) +* +* \return +* A pointer to the \ref USB_INTERFACE_DESCRIPTOR, or \c NULL if it was not found. +*/ +USB_INTERFACE_DESCRIPTOR __code* usbdpGetInterfaceDesc(uint8 cfgValue, uint8 intNumber, uint8 altSetting) +{ + USB_INTERFACE_DESCRIPTOR __code *pInterfaceDesc; + + // First get to the correct configuration + usbdpGetConfigurationDesc(cfgValue, 0); + + // Then find a match on the interface + while (pInterfaceDesc = usbdpFindNext(DESC_TYPE_INTERFACE, DESC_TYPE_CONFIG)) { + if ((pInterfaceDesc->bInterfaceNumber == intNumber) && (pInterfaceDesc->bAlternateSetting == altSetting)) { + break; + } + } + + return pInterfaceDesc; +} // usbdpGetInterfaceDesc + + + + +/** \brief Locates a string descriptor +* +* \note It is not necessary to call \ref usbdpInit() before this function. +* +* \param[in] strIndex +* A zero-based index that matches the "iXxxxxxxxxx" string indexes in the other descriptors +* +* \return +* A pointer to the \ref USB_INTERFACE_DESCRIPTOR, or \c NULL if it was not found. +*/ +USB_STRING_DESCRIPTOR __code* usbdpGetStringDesc(uint8 strIndex) +{ + USB_STRING_DESCRIPTOR __code *pStringDesc; + usbdpInit(); + +#ifdef MS_EXT_C_ID + if (strIndex == 0xEE){ + // Find the Microsoft OS String Descriptor + do{ + pStringDesc = usbdpFindNext(DESC_TYPE_STRING, 0); + }while (pStringDesc != NULL && pStringDesc->bLength != 18); + } else +#endif + { + // Search strIndex+1 times + do { + pStringDesc = usbdpFindNext(DESC_TYPE_STRING, 0); + } while (strIndex--); + } + return pStringDesc; +} // usbdpGetStringDesc +/// @} +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_descriptor_parser.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_descriptor_parser.h new file mode 100755 index 0000000..9cad6fb --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_descriptor_parser.h @@ -0,0 +1,129 @@ +/*********************************************************************************** + + Filename: usb_descriptor_parser.h + + Description: Parser for USB descriptor structures. + +***********************************************************************************/ + +#ifndef USBDESCRIPTORPARSER_H +#define USBDESCRIPTORPARSER_H +/** \addtogroup module_usb_descriptor_parser USB Descriptor Parser (usbdp) + * \brief This module contains internally used functions for locating USB descriptors. + * + * The parsing mechanism supports all standard descriptors, i.e. DEVICE, CONFIGURATION, INTERFACE, + * ENDPOINT and STRING, but also other types that use the standard descriptor format: + * \code + * typedef struct { + * uint8 bLength; // Size of this descriptor (in bytes) + * uint8 bDescriptorType; // Descriptor type + * ... + * } USB_XXXXXXXX_DESCRIPTOR; + * \endcode + * + * \section section_usbdp_requirements Requirements + * The standard-formatted descriptors must be placed back-to-back in either XDATA or CODE memory. + * In the current version of the library, the USB descriptors are assumed to reside in CODE. + * Two markers (XDATA or CODE memory pointers), \ref usbDescStart and \ref usbDescEnd, define where + * the first descriptor begins and where the last descriptor ends, respectively + * (so that usbDescStart - usbDescEnd equals the total length of the descriptors). + * + * The markers can be dynamic, provided that they are not changed while the descriptor parser is in use. + * However, in most cases the USB descriptor set will be static, hence the markers are also static. + * The following example shows how static markers are declared and made public in 8051 assembler: + * \code + * ; Make the symbols public + * PUBLIC usbDescStart; + * PUBLIC usbDescEnd; + * + * ... + * + * usbDescStart: + * deviceDesc: ; Device descriptor (the first descriptor) + * DB deviceDescEnd - deviceDesc + * DB DESC_TYPE_DEVICE ; bDescriptorType + * DB 10H, 01H ; bcdUSB + * DB 00H ; bDeviceClass + * DB 00H ; bDeviceSubClass + * + * ... + * + * string3Desc: ; String descriptor: Serial number (the last descriptor) + * DB string3DescEnd - string3Desc; + * DB DESC_TYPE_STRING ; bDescriptorType + * DB '1', 0; + * DB '2', 0; + * DB '3', 0; + * string3DescEnd: + * usbDescEnd: + * \endcode + * @{ + */ + +#include "usb_descriptor.h" + + +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// \name Indexes Into USB Descriptors +//@{ +#define DESC_LENGTH_IDX 0 ///< Index of the bLength field (all descriptors) +#define DESC_TYPE_IDX 1 ///< Index of the bDescriptorType field (all descriptors) +#define DESC_CONFIG_LENGTH_LSB_IDX 2 ///< Index of LOUINT8(USB_CONFIGURATION_DESCRIPTOR.wTotalLength) +#define DESC_CONFIG_LENGTH_MSB_IDX 3 ///< Index of HIUINT8(USB_CONFIGURATION_DESCRIPTOR.wTotalLength) +//@} +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +// Function prototypes +void usbdpInit(void); +void __code *usbdpFindNext(uint8 wantedType, uint8 haltAtType); + +USB_DEVICE_DESCRIPTOR __code* usbdpGetDeviceDesc(void); +USB_CONFIGURATION_DESCRIPTOR __code* usbdpGetConfigurationDesc(uint8 cfgValue, uint8 cfgIndex); +USB_INTERFACE_DESCRIPTOR __code* usbdpGetInterfaceDesc(uint8 cfgValue, uint8 intNumber, uint8 altSetting); +USB_STRING_DESCRIPTOR __code* usbdpGetStringDesc(uint8 strIndex); +//------------------------------------------------------------------------------------------------------- + + +//@} + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_framework.c b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_framework.c new file mode 100755 index 0000000..d9fe76d --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_framework.c @@ -0,0 +1,333 @@ +/*********************************************************************************** + + Filename: usb_framework.c + + Description: USB library common functionality. + +***********************************************************************************/ + +/// \addtogroup module_usb_framework +/// @{ +#define USBFRAMEWORK_C ///< Modifies the behavior of "EXTERN" in usb_framework.h +#include "usb_firmware_library_headers.h" +#include "hal_int.h" +#include "hal_board.h" + +// Function pointer used by usbfwSetupHandler() +static VFPTR __data ProcessFunc; + +/** \brief Initializes the USB framework + * + * This function should be called when the microcontroller is ready to accept USB traffic. It enables the + * USB peripheral unit and enables the pull-up resistor on the D+ line. Endpoint status, current + * configuration value, etc. are initialized and evenetually re-initialized in the + * \ref usbfwResetHandler() function. + */ +void usbfwInit(void) +{ + // Set default values + usbfwData.selfPowered = (usbdpGetConfigurationDesc(1, 0)->bmAttributes & 0x40) ? TRUE : FALSE; + usbfwData.remoteWakeup = FALSE; + + HAL_USB_ENABLE(); + + // Enable Resume Interrupt + HAL_USB_RESUME_INT_ENABLE(); + +} // usbfwInit + + + + +/** \brief Handles USB reset signalling + * + * This function should be called, either from the USB interrupt or the main loop, when the \c USBCIF.RST + * flag has been set. Keep in mind that all bits in \c USBCIF register are cleared when the register is + * read. The function puts the device into the default state (not yet addressed), and puts all endpoints + * (except EP0) into the \ref EP_HALT state + */ +void usbfwResetHandler(void) +{ + + // Reset the USB state + usbfwData.usbState = DEV_DEFAULT; + usbfwData.configurationValue = 0; + + // Reset all endpoints + usbfwData.ep0Status = EP_IDLE; + usbfwSetAllEpStatus(EP_HALT); + + // Reset last function pointer + ProcessFunc = NULL; + +} // usbfwResetHandler + + + + +/** \brief USB Setup Handler + * + * This function should be called either from the USB interrupt or the main loop when the \c USBIIF.EP0IF + * flag has been set. Keep in mind that all bits in \c USBIIF register are cleared when the register is + * read. A detailed description of the framework is found in the \ref section_setup_handler_usage + * section. + * + * \note The USB header data is always little-endian, so if a big-endian compiler is used (such as Keil + * C51), the 16-bit values in the \ref usbSetupHeader must be flipped before they are used. + */ +void usbfwSetupHandler(void) +{ + uint8 controlReg; + uint8 bytesNow; + uint8 oldEndpoint; + + // Save the old index setting, then select endpoint 0 and fetch the control register + oldEndpoint = USBFW_GET_SELECTED_ENDPOINT(); + USBFW_SELECT_ENDPOINT(0); + controlReg = USBCS0; + + // The last transfer was ended prematurely by a new SETUP packet + if (controlReg & USBCS0_SETUP_END) { + USBCS0 = USBCS0_CLR_SETUP_END; + usbfwData.ep0Status = EP_CANCEL; + if (ProcessFunc) ProcessFunc(); + usbfwData.ep0Status = EP_IDLE; + } + + // A STALL handshake was transmitted to the PC + if (controlReg & USBCS0_SENT_STALL) { + USBCS0 = 0x00; + usbfwData.ep0Status = EP_IDLE; + } + + // Receive OUT packets + if (usbfwData.ep0Status == EP_RX) { + + // Read FIFO + bytesNow = USBCNT0; + usbfwReadFifo(&USBF0, bytesNow, usbSetupData.pBuffer); + usbSetupData.bytesLeft -= bytesNow; + usbSetupData.pBuffer += bytesNow; + + // Arm the endpoint + USBCS0 = usbSetupData.bytesLeft ? USBCS0_CLR_OUTPKT_RDY : (USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END); + + // Make a call to the appropriate request handler when done + if (usbSetupData.bytesLeft == 0) { + if (ProcessFunc) ProcessFunc(); + usbfwData.ep0Status = EP_IDLE; + } + + // Return here since nothing more will happen until the next interrupt + USBFW_SELECT_ENDPOINT(oldEndpoint); + return; + + // Let the application handle the reception + } else if (usbfwData.ep0Status == EP_MANUAL_RX) { + ProcessFunc(); + } + + // Receive SETUP header + if (usbfwData.ep0Status == EP_IDLE) { + if (controlReg & USBCS0_OUTPKT_RDY) { + usbfwReadFifo(&USBF0, 8, (uint8 __xdata *) &usbSetupHeader); + + // Handle control transfers individually + ProcessFunc = NULL; + switch (usbSetupHeader.requestType & (RT_MASK_TYPE | RT_MASK_DIR)) { + + // Standard requests with data from the host (OUT) + case RT_STD_OUT: + switch (usbSetupHeader.request) { + case SET_ADDRESS: usbsrSetAddress(); break; + case SET_FEATURE: usbsrSetFeature(); break; + case CLEAR_FEATURE: usbsrClearFeature(); break; + case SET_CONFIGURATION: usbsrSetConfiguration(); break; + case SET_INTERFACE: usbsrSetInterface(); break; + case SET_DESCRIPTOR: /*usbsrHookSetDescriptor(); break; - unsupported */ + default: usbfwData.ep0Status = EP_STALL; break; + } + break; + + // Standard requests with data to the host (IN) + case RT_STD_IN: + switch (usbSetupHeader.request) { + case GET_STATUS: usbsrGetStatus(); break; + case GET_DESCRIPTOR: usbsrGetDescriptor(); break; + case GET_CONFIGURATION: usbsrGetConfiguration(); break; + case GET_INTERFACE: usbsrGetInterface(); break; + case SYNCH_FRAME: /*usbsrHookSynchFrame(); break; - unsupported */ + default: usbfwData.ep0Status = EP_STALL; break; + } + break; + + // Vendor requests + case RT_VEND_OUT: + ProcessFunc = usbvrHookProcessOut; usbvrHookProcessOut(); + break; + case RT_VEND_IN: + ProcessFunc = usbvrHookProcessIn; usbvrHookProcessIn(); + break; + + // Class requests + case RT_CLASS_OUT: + ProcessFunc = usbcrHookProcessOut; usbcrHookProcessOut(); + break; + case RT_CLASS_IN: + ProcessFunc = usbcrHookProcessIn; usbcrHookProcessIn(); + break; + + // Unrecognized request: Stall the endpoint + default: + usbfwData.ep0Status = EP_STALL; + break; + } + + // Arm/stall the endpoint + USBCS0 = (usbfwData.ep0Status == EP_STALL) ? (USBCS0_CLR_OUTPKT_RDY | USBCS0_SEND_STALL) : USBCS0_CLR_OUTPKT_RDY; + } + } + + // Transmit IN packets + if (usbfwData.ep0Status == EP_TX) { + controlReg = USBCS0_INPKT_RDY; + + // The last frame should contain 0 to (EP0_PACKET_SIZE - 1) bytes + if (usbSetupData.bytesLeft < EP0_PACKET_SIZE) { + bytesNow = usbSetupData.bytesLeft; + controlReg |= USBCS0_DATA_END; + + // All other packets should have the maximum length + } else { + bytesNow = EP0_PACKET_SIZE; + } + + // Load the FIFO and move the pointer + usbfwWriteFifo(&USBF0, bytesNow, usbSetupData.pBuffer); + usbSetupData.pBuffer += bytesNow; + usbSetupData.bytesLeft -= bytesNow; + + // Arm the FIFO (even for a zero-length packet) + USBCS0 = controlReg; + + // Make a call to the appropriate request handler when done + if (bytesNow < EP0_PACKET_SIZE) { + if (ProcessFunc) ProcessFunc(); + usbfwData.ep0Status = EP_IDLE; + } + + // Let the application handle the transmission + } else if (usbfwData.ep0Status == EP_MANUAL_TX) { + ProcessFunc(); + } + + // Restore the old index setting + USBFW_SELECT_ENDPOINT(oldEndpoint); + +} // usbfwSetupHandler + + + + +/** \brief Changes the state of endpoint 1-5 IN/OUT + * + * This is an internal function used by the library. + * + * \param[in] status + * The new status for each endpoint + */ +void usbfwSetAllEpStatus(EP_STATUS status) +{ + uint8 n; + for (n = 0; n < sizeof(usbfwData.pEpInStatus); n++) + usbfwData.pEpInStatus[n] = status; + for (n = 0; n < sizeof(usbfwData.pEpOutStatus); n++) + usbfwData.pEpOutStatus[n] = status; +} // usbfwSetAllEpStatus + + + + +/** \brief Reads from the selected OUT endpoint FIFO, without using DMA + * + * The FIFO must be re-armed after reading it empty (using the \ref USBFW_ARM_OUT_ENDPOINT() macro). This + * is not necessary when flushing the FIFO. + * + * \param[in] *pFifo + * Pointer to the FIFO (\c &USBFx) + * \param[in] count + * The number of bytes to read + * \param[in] *pData + * A pointer to the storage location for the read data (in any memory space) + */ +void usbfwReadFifo(uint8 volatile __xdata *pFifo, uint8 count, void __generic *pData) +{ + uint8 __generic *pTemp = pData; + if (count) { + do { + *(pTemp++) = *pFifo; + } while (--count); + } +} // usbfwReadFifo + + + + +/** \brief Writes to the selected IN endpoint FIFO, without using DMA + * + * Note that the FIFO must be armed in order to be transmitted (using the \ref USBFW_ARM_IN_ENDPOINT() + * macro). + * + * \param[in] *pFifo + * Pointer to the FIFO (\c &USBFx) + * \param[in] count + * The number of bytes to write + * \param[in] *pData + * A pointer to the data to be written (from any memory space) + */ +void usbfwWriteFifo(uint8 volatile __xdata *pFifo, uint8 count, void __generic *pData) +{ + uint8 __generic *pTemp = pData; + if (count) { + do { + *pFifo = *(pTemp++); + } while (--count); + } +} // usbfwWriteFifo + + +/// @} +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_framework.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_framework.h new file mode 100755 index 0000000..ba7311a --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_framework.h @@ -0,0 +1,383 @@ +/*********************************************************************************** + + Filename: usb_framework.h + + Description: USB library common functionality. + +***********************************************************************************/ + +#ifndef USBFRAMEWORK_H +#define USBFRAMEWORK_H +/** \addtogroup module_usb_framework USB Framework (usbfw) + * \brief This module contains USB status information, functions for initialization, USB device reset + * handling, and most importantly, the framework for transfers on endpoint 0, FIFO access, and endpoint + * control. + * + * \section section_init Framework Initialization + * The framework and the USB peripheral unit can be initialized once the crystal oscillator (48 MHz for + * CC1111/CC2511, 32 MHz for CC2531) is running. This is done by \ref usbfwInit(), which: + * \li Initializes framework variables + * \li Enables the USB peripheral unit by setting the \c SLEEP.USB_EN bit + * \li Enables the pull-up resistor via a GPIO pin + * + * When completing the last step, the host will be recognize the USB device, and start the enumeration + * process. To reply to the shortly incoming standard requests, the call to \ref usbfwInit() must be + * followed immediately by USB Interrupt \ref section_usbirq_initialization. + * + * \section section_endpoint_0_transfers Endpoint 0 Transfers + * The USB interface uses endpoint 0 to perform setup requests of the standard, vendor and class types. + * Such transfers consist of three phases: + * - A setup phase, where an 8-byte \ref USB_SETUP_HEADER is transferred to the device. + * - An IN/OUT data phase, if the length field of the \ref USB_SETUP_HEADER structure is non-zero. + * - A handshake phase, where the application can stall the endpoint to indicate error conditions. + * + * The setup handler, \ref usbfwSetupHandler(), takes care of the low-level parts of these transfers, + * including the IN/OUT buffering during the data phase (when there is one). The transfers fall into two + * categories: + * - Most standard requests are processed internally, with little or no intervention form the user + * application. This is done by the \ref module_usb_standard_requests module. + * - Vendor and class requests are application specific and must always be processed by the application. + * Whenever such a request is received, the following hooks will be called between the phases: + * - \ref usbcrHookProcessOut(): Class requests with OUT data phase + * - \ref usbcrHookProcessIn(): Class requests with IN data phase + * - \ref usbvrHookProcessOut(): Vendor requests with OUT data phase + * - \ref usbvrHookProcessIn(): Vendor requests with IN data phase + * + * \section section_setup_handler_usage Setup Handler Usage + * This section describes what is required to make the vendor and class request hooks work. This + * information also applies to the standard requests that needs application processing + * (\ref usbsrHookSetDescriptor(), \ref usbsrHookSynchFrame(), and some cases of + * \ref usbsrHookSetFeature() and \ref usbsrHookClearFeature()). + * + * The transactions are made using a clean and efficient interface, consisting of two data structures and + * the endpoint 0 status byte: + * - The endpoint status is initially \ref EP_IDLE, which basically means that the setup handler is ready + * for a new setup phase (a new request). Upon an incoming request, the processing hook is called, and + * the \ref usbSetupHeader structure contains the 8 bytes received during the setup phase. At this + * point there are four different outcomes: + * - If the request is unknown or contains errors, the endpoint should be stalled. This is done by + * setting the endpoint status to \ref EP_STALL. + * - If there is no data phase (the length field is zero), the endpoint status should just remain in + * it's current state, \ref EP_IDLE. + * - If the request has an IN data phase, the \ref usbSetupData structure must be prepared. This + * includes setting a pointer to where IN data should be taken from, and the number of bytes to be + * transferred (usually the same number as indicated by the length field, but it can also be a + * lower number). The endpoint state is then changed to \ref EP_TX. + * - If the request has an OUT data phase, the \ref usbSetupData structure must be prepared. This + * includes setting a pointer to where OUT data should be stored, and the number of bytes to be + * transferred (always the same number as indicated by the length field). The endpoint state is + * then changed to \ref EP_RX. + * - When the data phase is complete, the processing hook function will be called a second time to notify + * the application. Under normal conditions the endpoint status will be either \ref EP_TX or \ref EP_RX, + * and does not need to be changed any further (as this is done automatically upon return). If the + * endpoint status is \ref EP_CANCEL, it means that the USB host cancelled the setup transfer. + * + * The following code examples illustrate practical usage (more code is available in the application + * example projects): + * + * \par Example 1: Endpoint 0 Requests With OUT Data phase + * + * \code + * uint8 pLcdBuffer[358]; + * + * void usbvrHookProcessOut(void) { + * + * // When this vendor request is received, we should either update a part of pLcdBuffer[] or leave + * // it as it is, and then refresh the LCD display. The index field of the setup header contains the + * // index of the first character to be updated, and the length field how many characters to update. + * if (usbSetupHeader.request == VR_LCD_UPDATE) { + * + * // First the endpoint status is EP_IDLE... (we have just received the Setup packet) + * if (usbfwData.ep0Status == EP_IDLE) { + * + * // There is no new data -> Just refresh the display + * if (usbSetupHeader.length == 0) { + * lcdRefresh(); + * // There is no change to the endpoint status in this case + * + * // The PC wants to send data that will be stored outside pLcdBuffer -> stall the endpoint! + * } else if ((usbSetupHeader.length > sizeof(pLcdBuffer) || + * (usbSetupHeader.index >= sizeof(pLcdBuffer) || + * ((usbSetupHeader.index + usbSetupHeader.length) > sizeof(pLcdBuffer)) { + * usbfwData.ep0Status = EP_STALL; + * + * // Prepare for OUT data phase, setup the data buffer to receive the LCD data + * } else { + * usbSetupData.pBuffer = &pLcdBuffer[usbSetupHeader.index]; + * usbSetupData.bytesLeft = usbSetupHeader.length; + * usbfwData.ep0Status = EP_RX; + * } + * + * // Then the endpoint status is EP_RX (remember: we did that here when setting up the buffer) + * } else if (usbfwData.ep0Status == EP_RX) { + * // usbfwSetupHandler() has now updated pLcdBuffer, so all we need to do is refresh the LCD + * lcdRefresh(); + * // usbfwData.ep0Status is automatically reset to EP_IDLE when returning to usbfwSetupHandler() + * } + * + * // Unknown vendor request? + * } else { + * usbfwData.ep0Status = EP_STALL; + * } + * } + * \endcode + * + * \par Example 2: Endpoint 0 Requests With IN Data phase + * + * \code + * uint8 keyBufferPos; + * BOOL blockKeyboard; + * char pKeyBuffer[150]; + * + * void usbvrProcessIn(void) { + * + * // When this vendor request is received, we should send all registered key-strokes, and reset the + * // position counter. New keystrokes are blocked during the transfer to avoid overwriting the buffer + * // before it has been sent to the host. + * if (usbSetupHeader.request == VR_GET_KEYS) { + * + * // First the endpoint status is EP_IDLE... + * if (usbfwData.ep0Status == EP_IDLE) { + * + * // Make sure that we do not send more than the PC asked for + * if (usbSetupHeader.length < keyBufferPos) { + * usbfwData.ep0Status = EP_STALL; + * + * // Otherwise... + * } else { + * // Block for new keystrokes + * blockKeyboard = TRUE; + * + * // Setup the buffer + * usbSetupData.pBuffer = pKeyBuffer; + * usbSetupData.bytesLeft = keyBufferPos; + * usbfwData.ep0Status = EP_TX; + * + * // Reset the position counter + * keyBufferPos = 0; + * } + * + * // Then the endpoint status is EP_TX (remember: we did that here when setting up the buffer) + * } else if (usbfwData.ep0Status == EP_TX) { + * + * // pKeyBuffer has now been sent to the host, so new keystrokes can safely be registered + * blockKeyboard = FALSE; + * + * // usbfwData.ep0Status is automatically reset to EP_IDLE when returning to usbfwSetupHandler() + * } + * + * // Unknown request? + * } else { + * usbfwData.ep0Status = EP_STALL; + * } + * } + * \endcode + * + * If automated data transfer is not desired, the application should set \c usbfwData.ep0Status to + * either \ref EP_MANUAL_RX or \ref EP_MANUAL_TX instead of \ref EP_RX or \ref EP_TX, respectively. Until + * the transfer is completed, the processing hook function (e.g. \ref usbvrHookProcessIn()) will be called + * at every endpoint 0 interrupt. + * @{ + */ +#include "hal_defs.h" +#include "usb_framework_structs.h" + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef USBFRAMEWORK_C + #define EXTERN ///< Definition used only for usb_framework.c +#else + #define EXTERN extern ///< Definition used in other source files to declare external +#endif + + +//------------------------------------------------------------------------------------------------------- +/// \name Module Data +//@{ +EXTERN USBFW_DATA __xdata usbfwData; ///< USBFW internal module data + +//@} +//------------------------------------------------------------------------------------------------------- + + +/// \name Setup Handler Data +//@{ +EXTERN USB_SETUP_DATA __xdata usbSetupData; ///< Setup handler data phase configuration +EXTERN USB_SETUP_HEADER __xdata usbSetupHeader; ///< Setup header +//@} +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// \name Request Type Fields +//@{ + +// Field masks +#define RT_MASK_DIR 0x80 ///< Request direction bit mask +#define RT_MASK_TYPE 0x60 ///< Request type bit mask +#define RT_MASK_RECIP 0x1F ///< Request recipient bit mask + +// Direction field +#define RT_DIR_IN 0x80 ///< IN Request +#define RT_DIR_OUT 0x00 ///< OUT Request + +// Type field +#define RT_TYPE_STD 0x00 ///< Standard Request +#define RT_TYPE_CLASS 0x20 ///< Class Request +#define RT_TYPE_VEND 0x40 ///< Vendor Request + +// Recipient field +#define RT_RECIP_DEV 0x00 ///< Device Request +#define RT_RECIP_IF 0x01 ///< Interface Request +#define RT_RECIP_EP 0x02 ///< Endpoint Request +#define RT_RECIP_OTHER 0x03 ///< Other Request + +// Type + direction +#define RT_STD_OUT (RT_TYPE_STD | RT_DIR_OUT) ///< Standard request, direction is OUT +#define RT_STD_IN (RT_TYPE_STD | RT_DIR_IN) ///< Standard request, direction is IN +#define RT_VEND_OUT (RT_TYPE_VEND | RT_DIR_OUT) ///< Vendor request, direction is OUT +#define RT_VEND_IN (RT_TYPE_VEND | RT_DIR_IN) ///< Vendor request, direction is IN +#define RT_CLASS_OUT (RT_TYPE_CLASS | RT_DIR_OUT) ///< Class request, direction is OUT +#define RT_CLASS_IN (RT_TYPE_CLASS | RT_DIR_IN) ///< Class request, direction is IN + +// Direction + recepient +#define RT_OUT_DEVICE (RT_DIR_OUT | RT_RECIP_DEV) ///< Request made to device, direction is OUT +#define RT_IN_DEVICE (RT_DIR_IN | RT_RECIP_DEV) ///< Request made to device, direction is IN +#define RT_OUT_INTERFACE (RT_DIR_OUT | RT_RECIP_IF) ///< Request made to interface, direction is OUT +#define RT_IN_INTERFACE (RT_DIR_IN | RT_RECIP_IF) ///< Request made to interface, direction is IN +#define RT_OUT_ENDPOINT (RT_DIR_OUT | RT_RECIP_EP) ///< Request made to endpoint, direction is OUT +#define RT_IN_ENDPOINT (RT_DIR_IN | RT_RECIP_EP) ///< Request made to endpoint, direction is IN +//@} +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// \name Vendor and Class Request Hooks +/// Unused hooks must stall endpoint 0. +//@{ + +/// Hook which is called upon reception of a class request with OUT data phase +void usbcrHookProcessOut(void); +/// Hook which is called upon reception of a class request with IN data phase +void usbcrHookProcessIn(void); +/// Hook which is called upon reception of a vendor request with OUT data phase +void usbvrHookProcessOut(void); +/// Hook which is called upon reception of a vendor request with IN data phase +void usbvrHookProcessIn(void); + +//@} +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// \name Endpoint Access Macros +/// Note that the endpoint control registers are indexed, meaning that an endpoint must be selected +/// before the control operations listed below can be used. Interrupts using any of these macros, must +/// save the current selection and restore it upon return. +//@{ + +/// Selects which IN/OUT endpoint (by index 0 to 5) to operate on +#define USBFW_SELECT_ENDPOINT(n) (USBINDEX = (n)) +/// Gets the currently selected IN/OUT endpoint +#define USBFW_GET_SELECTED_ENDPOINT() (USBINDEX) + +/// Stalls the selected IN endpoint +#define USBFW_STALL_IN_ENDPOINT() st (\ + USBCSIL = USBCSIL_SEND_STALL; \ + usbfwData.pEpInStatus[USBINDEX - 1] = EP_HALT; ) + +/// Returns the stall condition for the selected IN endpoint +#define USBFW_IN_ENDPOINT_STALLED() (USBCSIL & USBCSIL_SEND_STALL) +/// Flushes the FIFO for the selected IN endpoint (flush twice when using double-buffering) +#define USBFW_FLUSH_IN_ENDPOINT() st (\ + USBCSIL = USBCSIL_FLUSH_PACKET; \ + while (USBCSIL & USBCSIL_FLUSH_PACKET); ) + +/// Arms the selected IN endpoint, so that contents of the endpoint FIFO can be sent to the host +#define USBFW_ARM_IN_ENDPOINT() (USBCSIL = USBCSIL_INPKT_RDY) +/// Is the selected IN endpoint disarmed? +#define USBFW_IN_ENDPOINT_DISARMED() !(USBCSIL & USBCSIL_INPKT_RDY) +/// Is the FIFO for the selected IN endpoint empty? +#define USBFW_IN_ENDPOINT_FIFO_EMPTY() !(USBCSIL & USBCSIL_PKT_PRESENT) + +/// Stalls the selected OUT endpoint +#define USBFW_STALL_OUT_ENDPOINT() st ( \ + USBCSOL = USBCSOL_SEND_STALL; \ + usbfwData.pEpOutStatus[USBINDEX - 1] = EP_HALT; \ +} + +/// Returns the stall condition for the selected OUT endpoint +#define USBFW_OUT_ENDPOINT_STALLED() (USBCSOL & USBCSOL_SEND_STALL) +/// Flushes the FIFO for the selected OUT endpoint (flush twice when using double-buffering) +#define USBFW_FLUSH_OUT_ENDPOINT() st(\ + USBCSOL = USBCSOL_FLUSH_PACKET; \ + while (USBCSOL & USBCSOL_FLUSH_PACKET); ) + +/// Arms the selected OUT endpoint, so that the FIFO can receive data from the host +#define USBFW_ARM_OUT_ENDPOINT() (USBCSOL = 0) +/// Is the selected OUT endpoint disarmed? If so, there is data waiting in the FIFO +#define USBFW_OUT_ENDPOINT_DISARMED() (USBCSOL & USBCSOL_OUTPKT_RDY) +/// Returns the number of bytes currently in the FIFO of the selected OUT endpoint, low byte +#define USBFW_GET_OUT_ENDPOINT_COUNT_LOW() (USBCNTL) +/// Returns the number of bytes currently in the FIFO of the selected OUT endpoint, high byte +#define USBFW_GET_OUT_ENDPOINT_COUNT_HIGH() (USBCNTH) + +//@} +//------------------------------------------------------------------------------------------------------- + +// Little endian +#define LOBYTEPTR(w) ( (uint8 __generic *)(&(w)) + 1 ) +// Big endian +//#define LOBYTEPTR(w) ( (uint8 __generic *)&(w) ) + + + +//------------------------------------------------------------------------------------------------------- +// Function prototypes +void usbfwInit(void); +void usbfwResetHandler(void); +void usbfwSetupHandler(void); +void usbfwSetAllEpStatus(EP_STATUS status); +void usbfwWriteFifo(uint8 volatile __xdata *pFifo, uint8 count, void __generic *pData); +void usbfwReadFifo(uint8 volatile __xdata *pFifo, uint8 count, void __generic *pData); +//------------------------------------------------------------------------------------------------------- + +//@} + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_framework_structs.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_framework_structs.h new file mode 100755 index 0000000..4300637 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_framework_structs.h @@ -0,0 +1,233 @@ +/*********************************************************************************** + + Filename: usb_framework_structs.h + + Description: USB library common data structures. + +***********************************************************************************/ + +#ifndef USBFRAMEWORKSTRUCTS_H +#define USBFRAMEWORKSTRUCTS_H +/** \addtogroup module_usb_framework USB Framework (usbfw) + * \brief This module contains USB status and descriptor structs + * + * + * @{ + */ +#include "hal_types.h" +#include "usb_firmware_library_config.h" + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef USBFRAMEWORK_C + #define EXTERN ///< Definition used only for usb_framework.c +#else + #define EXTERN extern ///< Definition used in other source files to declare external +#endif + + +//------------------------------------------------------------------------------------------------------- +/// \name Module Data +//@{ + +/// Endpoint status (used with USB_INFO.ep0Status / pEpInStatus[] / pEpOutStatus[]) +typedef enum { + EP_IDLE = 0x00, ///< The endpoint is idle, or a setup token has been received + EP_TX = 0x01, ///< Setup IN data is transmitted automatically by the framework + EP_RX = 0x02, ///< Setup OUT data is received automatically by the framework + EP_HALT = 0x03, ///< The endpoint is halted (returns stalls to the host) + EP_STALL = 0x04, ///< Send procedural stall in the next status phase + EP_MANUAL_TX = 0x05, ///< Setup IN data is transmitted manually by the user application + EP_MANUAL_RX = 0x06, ///< Setup OUT data is received manually by the user application + EP_CANCEL = 0x07 ///< The current transfer was cancelled by the host +} EP_STATUS; + +/// Device state (used with USB_INFO.usbState) +typedef enum { + DEV_ATTACHED = 0x00, ///< Device attached (invisible state) + DEV_POWERED = 0x01, ///< Device powered (invisible state) + DEV_DEFAULT = 0x02, ///< Default state (the \c USBADDR register is 0) + DEV_ADDRESS = 0x03, ///< Addressed state (the \c USBADDR register has been set) + DEV_CONFIGURED = 0x04, ///< Configured state (\c usbfwData.configurationValue != 0) + DEV_SUSPENDED = 0x05 ///< Suspended state (never set) +} USB_STATE; + +/// USBFW internal module data +typedef struct { + USB_STATE usbState; ///< USB device state + uint8 configurationValue; ///< Current configuration value + uint8 pAlternateSetting[USB_SETUP_MAX_NUMBER_OF_INTERFACES]; ///< Current alternate settings + EP_STATUS ep0Status; ///< Endpoint 0 status + EP_STATUS pEpInStatus[5]; ///< Endpoint 1-5 IN status + EP_STATUS pEpOutStatus[5]; ///< Endpoint 1-5 OUT status + uint8 remoteWakeup; ///< Remote wakeup allowed + uint8 selfPowered; ///< Is currently self-powered? +} USBFW_DATA; + +//------------------------------------------------------------------------------------------------------- +/// Setup header (contains the 8 bytes received during the setup phase) +typedef struct { + uint8 requestType; ///< Request type (direction, type and recipient, see the \c RT_ definitions) + uint8 request; ///< Request ID + uint16 value; ///< Value field + uint16 index; ///< Index field + uint16 length; ///< Length of data phase +} USB_SETUP_HEADER; + +/// Setup handler data phase configuration +typedef struct { + uint8 __generic *pBuffer; ///< Pointer to where IN/OUT data should be taken from/received + uint16 bytesLeft; ///< The number of bytes to transfer +} USB_SETUP_DATA; + + +//@} +//------------------------------------------------------------------------------------------------------- + +// From usb_descriptor.h +/** \addtogroup module_usb_descriptor USB Descriptor*/ +//------------------------------------------------------------------------------------------------------- +/// USB device descriptor +typedef struct { + uint8 bLength; ///< Size of this descriptor (in bytes) + uint8 bDescriptorType; ///< Descriptor type = \ref DESC_TYPE_DEVICE + uint16 bcdUSB; ///< USB specification release number (in BCD, e.g. 0110 for USB 1.1) + uint8 bDeviceClass; ///< Device class code + uint8 bDeviceSubClass; ///< Device subclass code + uint8 bDeviceProtocol; ///< Device protocol code + uint8 bMaxPacketSize0; ///< Maximum packet size for EP0 + uint16 idVendor; ///< Vendor ID + uint16 idProduct; ///< Product ID + uint16 bcdDevice; ///< Device release number (in BCD) + uint8 iManufacturer; ///< Index of the string descriptor for manufacturer + uint8 iProduct; ///< Index of the string descriptor for product + uint8 iSerialNumber; ///< Index of the string descriptor for serial number + uint8 bNumConfigurations; ///< Number of possible configurations +} USB_DEVICE_DESCRIPTOR; + +/// USB configuration descriptor +typedef struct { + uint8 bLength; ///< Size of this descriptor (in bytes) + uint8 bDescriptorType; ///< Descriptor type = \ref DESC_TYPE_CONFIG + uint16 wTotalLength; ///< Total length of data for this configuration + uint8 bNumInterfaces; ///< Number of interfaces supported by this configuration (one-based index) + uint8 bConfigurationValue; ///< Designator value for this configuration + uint8 iConfiguration; ///< Index of the string descriptor for this configuration + uint8 bmAttributes; ///< Configuration characteristics + uint8 bMaxPower; ///< Maximum power consumption in this configuration (bMaxPower * 2 mA) +} USB_CONFIGURATION_DESCRIPTOR; + +/// USB interface descriptor +typedef struct { + uint8 bLength; ///< Size of this descriptor (in bytes) + uint8 bDescriptorType; ///< Descriptor type = \ref DESC_TYPE_INTERFACE + uint8 bInterfaceNumber; ///< Number of *this* interface (zero-based index) + uint8 bAlternateSetting; ///< Alternate setting index for this descriptor (zero-based index) + uint8 bNumEndpoints; ///< Number of endpoints for this interface (excl. EP0) + uint8 bInterfaceClass; ///< Interface class code + uint8 bInterfaceSubClass; ///< Interface subclass code + uint8 bInterfaceProtocol; ///< Interface protocol code + uint8 iInterface; ///< Index of the string descriptor for this interface +} USB_INTERFACE_DESCRIPTOR; + +/// USB endpoint descriptor +typedef struct { + uint8 bLength; ///< Size of this descriptor (in bytes) + uint8 bDescriptorType; ///< Descriptor type = \ref DESC_TYPE_ENDPOINT + uint8 bEndpointAddress; ///< Endpoint address (direction[7] + number[3:0]) + uint8 bmAttributes; ///< Endpoint attributes (ISO / BULK / INT) + uint16 wMaxPacketSize; ///< Maximum endpoint packet size + uint8 bInterval; ///< \ref EP_ATTR_INT : Polling interval (in ms) +} USB_ENDPOINT_DESCRIPTOR; + +/// USB string descriptor +typedef struct { + uint8 bLength; ///< Size of this descriptor (in bytes) + uint8 bDescriptorType; ///< Descriptor type = \ref DESC_TYPE_STRING + uint16 pString[1]; ///< Unicode string +} USB_STRING_DESCRIPTOR; + +/// USB HID descriptor +typedef struct { + uint8 bLength; ///< Size of this descriptor (in bytes) + uint8 bDescriptorType; ///< HID descriptor type + uint16 bscHID; ///< HID specification release number (in BCD) + uint8 bCountryCode; ///< Hardware target country + uint8 bNumDescriptors; ///< Number of HID class descriptors to follow + uint8 bRDescriptorType; ///< Report descriptor type + uint16 wDescriptorLength; ///< Total length of the associated report descriptor +} USB_HID_DESCRIPTOR; +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// Look-up table entry for non-standard descriptor types (used with \ref usbsrGetDescriptor) +typedef struct { + uint8 valueMsb; ///< LSB of the \ref USB_SETUP_HEADER.value request parameter + uint8 valueLsb; ///< MSB of the \ref USB_SETUP_HEADER.value request parameter + uint8 indexMsb; ///< LSB of the \ref USB_SETUP_HEADER.index request parameter + uint8 indexLsb; ///< MSB of the \ref USB_SETUP_HEADER.index request parameter + uint8 __code *pDescStart; ///< A pointer to the descriptor to be returned for the given index/value + uint16 length; ///< The length of the returned descriptor +} DESC_LUT_INFO; + +/// Look-up table for double-buffer settings +typedef struct { + USB_INTERFACE_DESCRIPTOR __code *pInterface; ///< Pointer to an interface descriptor + uint8 inMask; ///< Bitmask for IN endpoints (bit x maps to EPx IN) + uint8 outMask; ///< Bitmask for OUT endpoints (bit x maps to EPx OUT) +} DBLBUF_LUT_INFO; + +// From usb_interrupt.h +//------------------------------------------------------------------------------------------------------- +/// USBIRQ internal module data +typedef struct { + uint16 eventMask; ///< Bit mask containing all pending events (see the \c USBIRQ_EVENT definitions) + uint8 inSuspend; ///< Is currently in suspend? + uint16 irqMask; ///< USB interrupts to be enabled +} USBIRQ_DATA; + +//------------------------------------------------------------------------------------------------------- +/// USBDP internal module data +typedef struct { + const uint8 __code *pDesc; ///< Pointer to the current descriptor +} USBDP_DATA; +//@} + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_interrupt.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_interrupt.h new file mode 100755 index 0000000..feffcba --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_interrupt.h @@ -0,0 +1,209 @@ +/*********************************************************************************** + + Filename: usb_interrupt.h + + Description: USB library interrupt initialisation and ISR. + +***********************************************************************************/ + +#ifndef USBINTERRUPT_H +#define USBINTERRUPT_H +/** \addtogroup module_usb_interrupt USB Interrupt (usbirq) + * \brief This module contains the USB interrupt handler, which converts USB interrupts to USBIRQ events. + * + * This module contains two interrupt service routines: + * \li P0 ISR + * \li P2 ISR + * Both these are used by the USB part of the MCU. Hence it is recommended to only use P1 for + * interrupts from any peripherals connected to the MCU. Unless running low on GPIO pins, one should + * generally avoid using the P0 and P2 pins at all. + * + * The MCU contains three interrupt flag registers, USBCIE, USBIIE and USBOIE, which are all cleared + * upon read access. The \ref module_usb_interrupt module encapsulates the USB interrupts, and saves the + * three flag registers in a single 16-bit word. By doing that it becomes possible to process + * high-priority events in the interrupt context, and low-priority events in the main loop. + * + * \section section_usbirq_initialization Initialization + * After initializing the \ref module_usb_framework module, \c main() must call \ref usbirqInit(). The + * \c irqMask parameter of this function shall contain all \c USBIRQ_EVENT bits that will be handled + * either in the interrupt or in \c main(). Note, however, that the event reporting may not always be + * necessary. For instance, there is usually no reason to enable \c USBIRQ_EVENT_EPxIN or + * \c USBIRQ_EVENT_EPxOUT events when handling low-priority transfers in the \c main() loop. In these + * cases it is simpler and more efficient to check the arming condition of the endpoint in question. + * + * The following example enables the setup and reset events (which must always be enabled!), and turns on + * global interrupts: + * \code + * void main(void) { + * + * ... Initialize the crystal oscillator and USB framework first ... + * + * // Initialize the USB Interrupt module + * usbirqInit(USBIRQ_EVENT_RESET | USBIRQ_EVENT_SUSPEND | USBIRQ_EVENT_RESUME | USBIRQ_EVENT_SETUP); + * + * // Turn on interrupts + * INT_GLOBAL_ENABLE(); + * + * // Main loop + * while (1) { + * ... + * } + * \endcode + * + * \section section_usbirq_event_processing Event Processing + * Regardless of whether the interrupt event is processed in the interrupt or in the main loop, the code + * piece for doing it is the same (this example illustrates the processing of \ref USBIRQ_EVENT_RESET + * events): + * \code + * // Let the framework handle reset events :) + * if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_RESET) { + * USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_RESET); + * usbfwResetHandler(); + * } + * \endcode + * + * \section Hooks + * The following hook is called from the USB interrupt, and allows for event processing in the interrupt + * context: + * \code + * void usbirqHookProcessEvents(void) { + * // Process high-priority events here, or simply return if there are none + * } + * \endcode + * @{ + */ + + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef USBINTERRUPT_C + #define EXTERN ///< Definition used only for usb_interrupt.c to declare variable +#else + #define EXTERN extern ///< Definition used in other source files to declare external +#endif + + +//------------------------------------------------------------------------------------------------------- +/// USBIRQ internal module data +/*typedef struct { + uint16 eventMask; ///< Bit mask containing all pending events (see the \c USBIRQ_EVENT definitions) + BOOL inSuspend; ///< Is currently in suspend? + uint16 irqMask; ///< USB interrupts to be enabled +} USBIRQ_DATA;*/ +#ifdef USBIRQ_DATA_ADDR + EXTERN __no_init __data USBIRQ_DATA usbirqData @ USBIRQ_DATA_ADDR; ///< USBIRQ internal module data at fixed address +#else + EXTERN USBIRQ_DATA __data usbirqData; ///< USBIRQ internal module data +#endif +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// \name USB Interrupt Events +//@{ + +/// Suspend signaling detected on the USB bus +/// Note that the chip should not enter PM1 while still in the interrupt routine (inside the usbirqHookProcessEvents() function ) +#define USBIRQ_EVENT_SUSPEND 0x0001 +/// Resume signaling detected on the USB bus +#define USBIRQ_EVENT_RESUME 0x0002 +/// Reset signaling detected on the USB bus (call \ref usbfwResetHandler() for processing) +#define USBIRQ_EVENT_RESET 0x0004 +/// Start of frame token received (synthesized by hardware when the next SOF token is expected, so that missing or corrupted tokens have no effect) +#define USBIRQ_EVENT_START_OF_FRAME 0x0008 +/// Endpoint 0 IN/OUT setup/data transfer complete / stall sent / premature completion (call \ref usbfwSetupHandler() for processing) +#define USBIRQ_EVENT_SETUP 0x0010 +/// Endpoint 1 IN data successfully transmitted to host (FIFO disarmed) / FIFO flushed / stall sent +#define USBIRQ_EVENT_EP1IN 0x0020 +/// Endpoint 2 IN data successfully transmitted to host (FIFO disarmed) / FIFO flushed / stall sent +#define USBIRQ_EVENT_EP2IN 0x0040 +/// Endpoint 3 IN data successfully transmitted to host (FIFO disarmed) / FIFO flushed / stall sent +#define USBIRQ_EVENT_EP3IN 0x0080 +/// Endpoint 4 IN data successfully transmitted to host (FIFO disarmed) / FIFO flushed / stall sent +#define USBIRQ_EVENT_EP4IN 0x0100 +/// Endpoint 5 IN data successfully transmitted to host (FIFO disarmed) / FIFO flushed / stall sent +#define USBIRQ_EVENT_EP5IN 0x0200 +/// Endpoint 1 OUT data received from host (FIFO disarmed) / stall sent +#define USBIRQ_EVENT_EP1OUT 0x0400 +/// Endpoint 2 OUT data received from host (FIFO disarmed) / stall sent +#define USBIRQ_EVENT_EP2OUT 0x0800 +/// Endpoint 3 OUT data received from host (FIFO disarmed) / stall sent +#define USBIRQ_EVENT_EP3OUT 0x1000 +/// Endpoint 4 OUT data received from host (FIFO disarmed) / stall sent +#define USBIRQ_EVENT_EP4OUT 0x2000 +/// Endpoint 5 OUT data received from host (FIFO disarmed) / stall sent +#define USBIRQ_EVENT_EP5OUT 0x4000 +//@} +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// \name Interrupt Mask Access Macros +//@{ + +/// Clears one or more events (use one or more \c USBIRQ_EVENT bits OR'ed together) +#define USBIRQ_CLEAR_EVENTS(mask) (usbirqData.eventMask &= ~(mask)) +/// Get the bit mask containing all pending events +#define USBIRQ_GET_EVENT_MASK() (usbirqData.eventMask) +//@} +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// \name Interrupt Event Hooks +//@{ + +/// Called upon all USB interrupts for high-priority event processing +void usbirqHookProcessEvents(void); + +//@} +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +// Function prototypes +void usbirqInit(uint16 irqMask); +__near_func __interrupt void usbirqHandler(void); +__near_func __interrupt void usbirqResumeHandler(void); +//------------------------------------------------------------------------------------------------------- + + +//@} + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_reg.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_reg.h new file mode 100755 index 0000000..b3e544e --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_reg.h @@ -0,0 +1,153 @@ +/*********************************************************************************** + + Filename: usb_reg.h + + Description: Register bit defintions for CCxx11 and CC2531. + +***********************************************************************************/ + +#ifndef USBREG_H +#define USBREG_H + + +// USBADDR +#define USBADDR_UPDATE 0x80 +#define USBADDR_USBADDR 0x7F + +// USBPOW +#define USBPOW_ISO_WAIT_SOF 0x80 +#define USBPOW_RST 0x08 +#define USBPOW_RESUME 0x04 +#define USBPOW_SUSPEND 0x02 +#define USBPOW_SUSPEND_EN 0x01 + +// USBIIF +#define USBIIF_INEP5IF 0x20 +#define USBIIF_INEP4IF 0x10 +#define USBIIF_INEP3IF 0x08 +#define USBIIF_INEP2IF 0x04 +#define USBIIF_INEP1IF 0x02 +#define USBIIF_EP0IF 0x01 + +// USBOIF +#define USBOIF_OUTEP5IF 0x20 +#define USBOIF_OUTEP4IF 0x10 +#define USBOIF_OUTEP3IF 0x08 +#define USBOIF_OUTEP2IF 0x04 +#define USBOIF_OUTEP1IF 0x02 + +// USBCIF +#define USBCIF_SOFIF 0x08 +#define USBCIF_RSTIF 0x04 +#define USBCIF_RESUMEIF 0x02 +#define USBCIF_SUSPENDIF 0x01 + +// USBIIE +#define USBIIE_INEP5IE 0x20 +#define USBIIE_INEP4IE 0x10 +#define USBIIE_INEP3IE 0x08 +#define USBIIE_INEP2IE 0x04 +#define USBIIE_INEP1IE 0x02 +#define USBIIE_EP0IE 0x01 + +// USBOIE +#define USBOIE_OUTEP5IE 0x20 +#define USBOIE_OUTEP4IE 0x10 +#define USBOIE_OUTEP3IE 0x08 +#define USBOIE_OUTEP2IE 0x04 +#define USBOIE_OUTEP1IE 0x02 + +// USBCIE +#define USBCIE_SOFIE 0x08 +#define USBCIE_RSTIE 0x04 +#define USBCIE_RESUMEIE 0x02 +#define USBCIE_SUSPENDIE 0x01 + +// USBCS0 +#define USBCS0_CLR_SETUP_END 0x80 +#define USBCS0_CLR_OUTPKT_RDY 0x40 +#define USBCS0_SEND_STALL 0x20 +#define USBCS0_SETUP_END 0x10 +#define USBCS0_DATA_END 0x08 +#define USBCS0_SENT_STALL 0x04 +#define USBCS0_INPKT_RDY 0x02 +#define USBCS0_OUTPKT_RDY 0x01 + +// USBCSIL +#define USBCSIL_CLR_DATA_TOG 0x40 +#define USBCSIL_SENT_STALL 0x20 +#define USBCSIL_SEND_STALL 0x10 +#define USBCSIL_FLUSH_PACKET 0x08 +#define USBCSIL_UNDERRUN 0x04 +#define USBCSIL_PKT_PRESENT 0x02 +#define USBCSIL_INPKT_RDY 0x01 + +// USBCSIH +#define USBCSIH_AUTOSET 0x80 +#define USBCSIH_ISO 0x40 +#define USBCSIH_FORCE_DATA_TOG 0x08 +#define USBCSIH_IN_DBL_BUF 0x01 + +// USBCSOL +#define USBCSOL_CLR_DATA_TOG 0x80 +#define USBCSOL_SENT_STALL 0x40 +#define USBCSOL_SEND_STALL 0x20 +#define USBCSOL_FLUSH_PACKET 0x10 +#define USBCSOL_DATA_ERROR 0x08 +#define USBCSOL_OVERRUN 0x04 +#define USBCSOL_FIFO_FULL 0x02 +#define USBCSOL_OUTPKT_RDY 0x01 + +// USBCSOH +#define USBCSOH_AUTOCLEAR 0x80 +#define USBCSOH_ISO 0x40 +#define USBCSOH_OUT_DBL_BUF 0x01 + +#define SLEEP_USB_EN 0x80 + +#if (chip==2531) + +// USBCTRL +#define USBCTRL_PLL_LOCKED 0x80 +#define USBCTRL_PLL_EN 0x02 +#define USBCTRL_USB_EN 0x01 + +#define P2IFG_DPIF 0x20 + +#endif + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_standard_requests.c b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_standard_requests.c new file mode 100755 index 0000000..9f8669d --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_standard_requests.c @@ -0,0 +1,659 @@ +/*********************************************************************************** + + Filename: usb_standard_request.c + + Description: Handle USB standard requests. + +***********************************************************************************/ + +/// \addtogroup module_usb_standard_requests +/// @{ +#include "usb_firmware_library_headers.h" +#include "hal_types.h" +#include "hal_board.h" + + + +/** \brief Processes the \ref GET_STATUS request (returns status for the specified recipient) + * + * The recipient bits in \ref USB_SETUP_HEADER.requestType specify the desired recipient. This is either the + * (one and only) device, a specific interface, or a specific endpoint. Some of the status bits can be + * changed with the SET_FEATURE and CLEAR_FEATURE requests. + * + * Parameters: + * - VALUE: Always 0 + * - INDEX: Depends upon the recipient: + * - DEVICE: Always 0 + * - INTERFACE: Interface number + * - ENDPOINT: Endpoint address + * - LENGTH: Always 2 + * + * Data (IN): + * Depends upon the recipient (the bit field illustrations are MSB first, LSB last): + * - DEVICE: 00000000.000000RS, where R(1) = DEVICE_REMOTE_WAKEUP and S(0) = SELF_POWERED + * - INTERFACE: 00000000.00000000 (all bits are reserved) + * - ENDPOINT: 00000000.0000000H, where H(0) = ENDPOINT_HALT + */ +void usbsrGetStatus(void) +{ + uint8 endpoint; + static uint16 __xdata status; + + // Common sanity check + if (usbSetupHeader.value || HI_UINT16(usbSetupHeader.index) || (usbSetupHeader.length != 2)) { + usbfwData.ep0Status = EP_STALL; + + // Return status for device, interface, or endpoint + } else { + switch (usbSetupHeader.requestType) { + + // Device status: + // Bit 0: Self powered + // Bit 1: Remote wake-up allowed + case RT_IN_DEVICE: + + // Sanity check + if (LO_UINT16(usbSetupHeader.index)) { + usbfwData.ep0Status = EP_STALL; + + // Get the bit values from the USBFW_DATA struct + } else { + + // Self powered? + status = usbfwData.selfPowered ? 0x0001 : 0x0000; + + // Remote wakeup? + if (usbfwData.remoteWakeup) status |= 0x0002; + } + break; + + // Interface status: + // All bits are reserved + case RT_IN_INTERFACE: + + // Sanity check + if (usbfwData.usbState != DEV_CONFIGURED) { + usbfwData.ep0Status = EP_STALL; + } else { + status = 0x0000; + } + break; + + // Endpoint status: + // Bit 0: Endpoint halted + case RT_IN_ENDPOINT: + endpoint = LO_UINT16(usbSetupHeader.index) & 0x7F; + + // Sanity check + if ((usbfwData.usbState != DEV_CONFIGURED) || (endpoint > 5)) { + usbfwData.ep0Status = EP_STALL; + + // Translate endpoint address to status index and return the status + } else { + + // IN + if (LO_UINT16(usbSetupHeader.index) & 0x80) { + status = (usbfwData.pEpInStatus[endpoint - 1] == EP_HALT) ? 0x0001 : 0x0000; + + // OUT + } else { + status = (usbfwData.pEpOutStatus[endpoint - 1] == EP_HALT) ? 0x0001 : 0x0000; + } + } + break; + + default: + usbfwData.ep0Status = EP_STALL; + break; + } + + if (usbfwData.ep0Status != EP_STALL) { + // Send it + usbSetupData.pBuffer = (uint8 __generic *)&status; + usbSetupData.bytesLeft = 2; + usbfwData.ep0Status = EP_TX; + } + } +} // usbsrGetStatus + + + + +/** \brief Internal function used for the very similar \ref SET_FEATURE and \ref CLEAR_FEATURE requests + * + * This function either sets or clears the specified feature on the specified recipient. + * + * \param[in] set + * When TRUE, the feature is set. When FALSE, the feature is cleared. + * + * \return + * TRUE if the selected feature is supported by the USB library. FALSE to indicate that + * \ref usbsrHookClearFeature() or \ref usbsrHookSetFeature() must be called. + */ +static uint8 ChangeFeature(uint8 set) +{ + uint8 endpoint; + + // Sanity check + if (usbSetupHeader.length || (usbfwData.usbState != DEV_CONFIGURED) && (usbSetupHeader.index != 0)) { + usbfwData.ep0Status = EP_STALL; + + // Handle based on recipient + } else { + switch (usbSetupHeader.requestType & RT_MASK_RECIP) { + + // Device + case RT_RECIP_DEV: + + // Sanity check + if (LO_UINT16(usbSetupHeader.value) != DEVICE_REMOTE_WAKEUP) { + return FALSE; + } else { + usbfwData.remoteWakeup = set; + usbsrHookProcessEvent(set ? USBSR_EVENT_REMOTE_WAKEUP_ENABLED : USBSR_EVENT_REMOTE_WAKEUP_DISABLED, 0); + } + break; + + // Endpoint + case RT_RECIP_IF: + return FALSE; + + // Endpoint + case RT_RECIP_EP: + endpoint = LO_UINT16(usbSetupHeader.index) & 0x7F; + + // Sanity check + if (LO_UINT16(usbSetupHeader.value) != ENDPOINT_HALT) { + return FALSE; + } else if (endpoint > 5) { + usbfwData.ep0Status = EP_STALL; + } else { + USBFW_SELECT_ENDPOINT(endpoint); + + // IN + if (LO_UINT16(usbSetupHeader.index) & 0x80) { + USBCSIL = set ? USBCSIL_SEND_STALL : USBCSIL_CLR_DATA_TOG; + usbfwData.pEpInStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE; + usbsrHookProcessEvent(set ? USBSR_EVENT_EPIN_STALL_SET : USBSR_EVENT_EPIN_STALL_CLEARED, endpoint); + + // OUT + } else { + USBCSOL = set ? USBCSOL_SEND_STALL : USBCSOL_CLR_DATA_TOG; + usbfwData.pEpOutStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE; + usbsrHookProcessEvent(set ? USBSR_EVENT_EPOUT_STALL_SET : USBSR_EVENT_EPOUT_STALL_CLEARED, endpoint); + } + USBFW_SELECT_ENDPOINT(0); + } + break; + + default: + usbfwData.ep0Status = EP_STALL; + break; + } + } + return TRUE; +} // ChangeFeature + + + + +/** \brief Processes the \ref CLEAR_FEATURE request (clears or disables a specific feature) + * + * The feature selector value must be appropriate to the recipient. + * + * Parameters: + * - VALUE: Feature selector: + * - \c DEVICE_REMOTE_WAKEUP(1): Enable remote wakeup + * - \c ENDPOINT_HALT(0): Clear the halt feature for the specified endpoint (not endpoint 0!) + * - INDEX: Depends upon the recipient: + * - DEVICE: Always 0 + * - INTERFACE: Interface number + * - ENDPOINT: Endpoint address + * - LENGTH: Always 0 + */ +void usbsrClearFeature() +{ + if (!ChangeFeature(FALSE)) { + usbsrHookClearFeature(); + } +} // usbsrClearFeature + + + + +/** \brief Processes the \ref SET_FEATURE request (sets or enables a specific feature) + * + * The feature selector value must be appropriate to the recipient. + * + * Parameters: + * - VALUE: Feature selector: + * - \c DEVICE_REMOTE_WAKEUP(1): Enable remote wakeup + * - \c ENDPOINT_HALT(0): Set the halt feature for the specified endpoint (not endpoint 0!) + * - INDEX: Depends upon the recipient: + * - DEVICE: Always 0 + * - INTERFACE: Interface number + * - ENDPOINT: Endpoint address + * - LENGTH: Always 0 + */ +void usbsrSetFeature(void) +{ + if (!ChangeFeature(TRUE)) { + usbsrHookSetFeature(); + } +} // usbsrSetFeature + + + + +/** \brief Processes the \ref SET_ADDRESS request (sets the device address for all future device + * accesses) + * + * If the value is between 1 and 127 and the device is in the default state, it will enter the address + * state. If it already is in the address state, it starts to use the newly-specified address. + * + * If the value is 0 and the device is in the address state, it will enter the default state. If it + * already is in the default state, nothing happens. + * + * Parameters: + * - VALUE: The device address (0-127) + * - INDEX: Always 0 + * - LENGTH: Always 0 + */ +void usbsrSetAddress(void) +{ + + // Sanity check + if (usbSetupHeader.index || usbSetupHeader.length || HI_UINT16(usbSetupHeader.value) || (LO_UINT16(usbSetupHeader.value) & 0x80)) { + usbfwData.ep0Status = EP_STALL; + + // Update the device address + } else { + USBADDR = LO_UINT16(usbSetupHeader.value); + if (LO_UINT16(usbSetupHeader.value) != 0) { + if (usbfwData.usbState == DEV_DEFAULT) usbfwData.usbState = DEV_ADDRESS; + } else { + if (usbfwData.usbState == DEV_ADDRESS) usbfwData.usbState = DEV_DEFAULT; + } + } + +} // usbsrSetAddress + + + + +/** \brief Processes the \ref GET_DESCRIPTOR request (returns the specified USB descriptor) + * + * The \ref module_usb_descriptor_parser module is used to locate device, configuration and string + * descriptors. Note that configuration descriptors also include interface, endpoint and other + * "similar" descriptor types (e.g. HID descriptor), with the total descriptor length specified by + * the \ref USB_CONFIGURATION_DESCRIPTOR.wTotalLength field. + * + * Other descriptor types that are not returned with the configuration descriptor, must be defined in + * the usbDescriptorMarker.pUsbDescLut lookup-table. This table specifies the values of the VALUE and INDEX fields, and + * gives a pointer to the descriptor along with it's length. + * + * Parameters: + * - VALUE.MSB: Descriptor type + * - VALUE.LSB: Descriptor index + * - INDEX: 0, or language ID for string descriptors (currently not supported) + * - LENGTH: Descriptor length (either the requested number of bytes, or the length of the descriptor, + * whichever is the smallest) + * + * Data (IN): + * The descriptor(s) + */ +void usbsrGetDescriptor(void) +{ + uint8 n; + + // Which descriptor? + switch (HI_UINT16(usbSetupHeader.value)) { + + // Device descriptor + case DESC_TYPE_DEVICE: + usbSetupData.pBuffer = (uint8 __code*) usbdpGetDeviceDesc(); + usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_LENGTH_IDX]; + break; + + // Configuration descriptor + case DESC_TYPE_CONFIG: + usbSetupData.pBuffer = (uint8 __code*) usbdpGetConfigurationDesc(0, LO_UINT16(usbSetupHeader.value)); + usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_CONFIG_LENGTH_LSB_IDX] + + usbSetupData.pBuffer[DESC_CONFIG_LENGTH_MSB_IDX] * 256; + break; + + // String descriptor + case DESC_TYPE_STRING: + // TODO: Implement language ID + usbSetupData.pBuffer = (uint8 __code*) usbdpGetStringDesc(LO_UINT16(usbSetupHeader.value)); + usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_LENGTH_IDX]; + break; + + // Other descriptor type + default: + // Perform a table search (on index and value) + usbSetupData.pBuffer = NULL; + for (n = 0; n < ((uint16)usbDescriptorMarker.pUsbDescLutEnd - (uint16)usbDescriptorMarker.pUsbDescLut) / sizeof(DESC_LUT_INFO); n++) { + if ((usbDescriptorMarker.pUsbDescLut[n].valueMsb == HI_UINT16(usbSetupHeader.value)) + && (usbDescriptorMarker.pUsbDescLut[n].valueLsb == LO_UINT16(usbSetupHeader.value)) + && (usbDescriptorMarker.pUsbDescLut[n].indexMsb == HI_UINT16(usbSetupHeader.index)) + && (usbDescriptorMarker.pUsbDescLut[n].indexLsb == LO_UINT16(usbSetupHeader.index)) ) + { + usbSetupData.pBuffer = usbDescriptorMarker.pUsbDescLut[n].pDescStart; + usbSetupData.bytesLeft = usbDescriptorMarker.pUsbDescLut[n].length; + } + } + } + + // Stall EP0 if no descriptor was found + if (usbSetupData.pBuffer == NULL) usbfwData.ep0Status = EP_STALL; + + if (usbfwData.ep0Status != EP_STALL) { + + // Limit the returned descriptor size (the PC wants to know about sizes before + // polling the complete descriptors) + if (usbSetupData.bytesLeft > usbSetupHeader.length) { + usbSetupData.bytesLeft = usbSetupHeader.length; + } + + usbfwData.ep0Status = EP_TX; + } + +} // usbsrGetDescriptor + + + +/** \brief Internally used function that configures all endpoints for the specified interface + * + * The new endpoint setup overwrites the old, without any warning. Unused endpoints keep their current + * setup. The user is responsible for ensuring that no endpoint buffers overwrite each other, and that + * interfaces do not cause conflicts. The pUsbDblbufLutInfo table must contain an entry for each + * interface descriptor to define endpoint double-buffering. + * + * \param[in] *pInterface + * A pointer to the interface descriptor + */ +static void ConfigureEndpoints(USB_INTERFACE_DESCRIPTOR __code *pInterface) +{ + uint8 n; + uint16 maxpRegValue; + uint8 csRegValue; + uint8 endpoint; + USB_ENDPOINT_DESCRIPTOR __code *pEndpoint; + DBLBUF_LUT_INFO __code *pUsbDblbufLutInfo; + + // Locate the double buffer settings + if (pInterface->bNumEndpoints) { + pUsbDblbufLutInfo = (DBLBUF_LUT_INFO __code*) usbDescriptorMarker.pUsbDblbufLut; + while (pUsbDblbufLutInfo->pInterface != pInterface) { + pUsbDblbufLutInfo++; + } + } + + // For each endpoint in this interface + for (n = 0; n < pInterface->bNumEndpoints; n++) { + if (pEndpoint = usbdpFindNext(DESC_TYPE_ENDPOINT, 0)) { + + // Get the endpoint index + endpoint = pEndpoint->bEndpointAddress & 0x0F; + USBFW_SELECT_ENDPOINT(endpoint); + + csRegValue = 0x00; + maxpRegValue = (pEndpoint->wMaxPacketSize + 7) >> 3; + + // For IN endpoints... + if (pEndpoint->bEndpointAddress & 0x80) { + + // Clear data toggle, and flush twice (due to double buffering) + USBCSIL = USBCSIL_CLR_DATA_TOG | USBCSIL_FLUSH_PACKET; + USBCSIL = USBCSIL_FLUSH_PACKET; + + // USBCSIH + if ((pEndpoint->bmAttributes & EP_ATTR_TYPE_BM) == EP_ATTR_ISO) csRegValue |= USBCSIH_ISO; // ISO flag + if (pUsbDblbufLutInfo->inMask & (1 << endpoint)) csRegValue |= USBCSIH_IN_DBL_BUF; // Double buffering + USBCSIH = csRegValue; + + // Max transfer size + USBMAXI = maxpRegValue; + + // Endpoint status + usbfwData.pEpInStatus[endpoint - 1] = EP_IDLE; + + // For OUT endpoints... + } else { + + // Clear data toggle, and flush twice (due to double buffering) + USBCSOL = USBCSOL_CLR_DATA_TOG | USBCSOL_FLUSH_PACKET; + USBCSOL = USBCSOL_FLUSH_PACKET; + + // USBCSOH + if ((pEndpoint->bmAttributes & EP_ATTR_TYPE_BM) == EP_ATTR_ISO) csRegValue |= USBCSOH_ISO; // ISO flag + if (pUsbDblbufLutInfo->outMask & (1 << endpoint)) csRegValue |= USBCSOH_OUT_DBL_BUF; // Double buffering + USBCSOH = csRegValue; + + // Max transfer size + USBMAXO = maxpRegValue; + + // Endpoint status + usbfwData.pEpOutStatus[endpoint - 1] = EP_IDLE; + } + USBFW_SELECT_ENDPOINT(0); + } + } +} // ConfigureEndpoints + + + + +/** \brief Processes the \ref GET_CONFIGURATION request (returns the current device configuration value) + * + * If the returned value is 0, the device is not configured (not in the configured state) + * + * Parameters: + * - VALUE: Always 0 + * - INDEX: Always 0 + * - LENGTH: Always 1 + * + * Data (IN): + * The non-zero \ref USB_CONFIGURATION_DESCRIPTOR.bConfigurationValue of the currently selected + * configuration. + */ +void usbsrGetConfiguration(void) +{ + + // Sanity check + if (usbSetupHeader.value || usbSetupHeader.index || (usbSetupHeader.length != 1)) { + usbfwData.ep0Status = EP_STALL; + + // Return the current configuration + } else { + usbSetupData.pBuffer = &usbfwData.configurationValue; + usbSetupData.bytesLeft = 1; + usbfwData.ep0Status = EP_TX; + } + +} // usbsrGetConfiguration + + + + +/** \brief Processes the \ref SET_CONFIGURATION request (sets the device configuration) + * + * The configuration value must either be 0, in which case the device enters the address state, or it + * must match a configuration value from one of the USB configuration descriptors. If there is a match, + * the device enters the configured state. + * + * This request resets all interfaces to alternate setting 0, and uses the \c ConfigureEndpoints() + * function to automatically setup all endpoint registers. + * + * Parameters: + * - VALUE: The configuration value (0-255) + * - INDEX: Always 0 + * - LENGTH: Always 0 + */ +void usbsrSetConfiguration(void) +{ + uint8 n; + USB_CONFIGURATION_DESCRIPTOR __code *pConfiguration; + USB_INTERFACE_DESCRIPTOR __code *pInterface; + + // Sanity check + if ((usbfwData.usbState == DEV_DEFAULT) || usbSetupHeader.index || usbSetupHeader.length || HI_UINT16(usbSetupHeader.value)) { + usbfwData.ep0Status = EP_STALL; + + // Default endpoint setup + } else { + usbsrHookProcessEvent(USBSR_EVENT_CONFIGURATION_CHANGING, 0); + + // Configure relevant endpoints + if (LO_UINT16(usbSetupHeader.value)) { + + // Find the correct configuration descriptor... + pConfiguration = usbdpGetConfigurationDesc(LO_UINT16(usbSetupHeader.value), 0); + + // If it exists... + if (pConfiguration) { + usbfwData.usbState = DEV_CONFIGURED; + usbfwData.configurationValue = LO_UINT16(usbSetupHeader.value); + + // For each interface... + for (n = 0; n < pConfiguration->bNumInterfaces; n++) { + usbfwData.pAlternateSetting[n] = 0x00; + + // Look only for alternate setting 0 + do { + pInterface = usbdpFindNext(DESC_TYPE_INTERFACE, 0); + } while (pInterface->bAlternateSetting != usbfwData.pAlternateSetting[n]); + + // Configure all endpoints in this interface + ConfigureEndpoints(pInterface); + } + + // If not, then stall the endpoint + } else { + usbfwData.ep0Status = EP_STALL; + } + + // Unconfigure endpoints + } else { + usbfwData.configurationValue = LO_UINT16(usbSetupHeader.value); + usbfwData.usbState = DEV_ADDRESS; + usbfwSetAllEpStatus(EP_HALT); + } + usbsrHookProcessEvent(USBSR_EVENT_CONFIGURATION_CHANGED, 0); + } + +} // usbsrSetConfiguration + + + + +/** \brief Processes the \ref GET_INTERFACE request (returns the selected alternate setting for the + * specified interface) + * + * Some USB devices have configurations with mutually exclusive interface settings. This request allows + * the host to determine the currently selected alternate setting. + * + * Parameters: + * - VALUE: Always 0 + * - INDEX: Interface number + * - LENGTH: Always 1 + * + * Data (IN): + * The alternate setting for the selected interface + */ +void usbsrGetInterface(void) +{ + + // Sanity check + if ((usbfwData.usbState != DEV_CONFIGURED) || (usbSetupHeader.requestType != RT_IN_INTERFACE) || usbSetupHeader.value || (usbSetupHeader.length != 1)) { + usbfwData.ep0Status = EP_STALL; + + // Return the current alternate setting + } else { + usbSetupData.pBuffer = &usbfwData.pAlternateSetting[usbSetupHeader.index]; + usbSetupData.bytesLeft = 1; + usbfwData.ep0Status = EP_TX; + } + +} // usbsrGetInterface + + + + +/** \brief Processes the \ref SET_INTERFACE request (selects an alternate setting for the specified + * interface) + * + * Some USB devices have configurations with mutually exclusive interface settings. This request allows + * the host to select the desired alternate setting. + * + * This function uses the \c ConfigureEndpoints() to automatically setup the relevant endpoint + * registers. + * + * Parameters: + * - VALUE: Alternate setting + * - INDEX: Interface number + * - LENGTH: Always 0 + */ +void usbsrSetInterface(void) +{ + USB_INTERFACE_DESCRIPTOR __code *pInterface; + + // Sanity check + if ((usbfwData.usbState != DEV_CONFIGURED) || (usbSetupHeader.requestType != RT_OUT_INTERFACE) || usbSetupHeader.length) { + usbfwData.ep0Status = EP_STALL; + + // Verify that the desired alternate setting is available, and then make the switch + } else { + if (pInterface = usbdpGetInterfaceDesc(usbfwData.configurationValue, usbSetupHeader.index, usbSetupHeader.value)) { + usbsrHookProcessEvent(USBSR_EVENT_INTERFACE_CHANGING, usbSetupHeader.index); + usbfwData.pAlternateSetting[usbSetupHeader.index] = usbSetupHeader.value; + + // Configure all endpoints in this interface + ConfigureEndpoints(pInterface); + usbsrHookProcessEvent(USBSR_EVENT_INTERFACE_CHANGED, usbSetupHeader.index); + + // This interface does not exist + } else { + usbfwData.ep0Status = EP_STALL; + } + } + +} // usbsrSetInterface + +//@} + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_standard_requests.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_standard_requests.h new file mode 100755 index 0000000..783e167 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_standard_requests.h @@ -0,0 +1,201 @@ +/*********************************************************************************** + + Filename: usb_standard_request.h + + Description: Handle USB standard requests. + +***********************************************************************************/ + +#ifndef USBSTANDARDREQUESTS_H +#define USBSTANDARDREQUESTS_H +/** \addtogroup module_usb_standard_requests USB Standard Requests (usbsr) + * \brief This module contains automated functions for processing USB standard requests + * + * The processing functions are based on the \ref module_usb_framework, and access to the user-provided + * USB descriptors through the \ref module_usb_descriptor_parser. All device classes and descriptor + * combinations are supported, with no need to write or modify any source code. However, as described + * below, some standard request must be fully or partially implemented by the user. + * + * \section section_usbsr_hooks Hooks + * Standard requests that are not supported by the USB library or that refer to non-standard features, + * are forwarded to the application via function hooks. This includes: + * \li All \ref SET_DESCRIPTOR requests (see \ref usbsrHookSetDescriptor()) + * \li All \ref SYNCH_FRAME requests (see \ref usbsrHookSynchFrame()) + * \li \ref CLEAR_FEATURE requests that refer to unknown features (see \ref usbsrHookClearFeature()) + * \li \ref SET_FEATURE requests that refer to unknown features (see \ref usbsrHookSetFeature()) + * + * These hooks must always be provided, however if the application does not either support the requests, + * it should just stall endpoint 0. The processing uses the same mechanisms as for class and vendor + * requests (refer to the \ref module_usb_framework module for detailed description and examples). + * + * When the \ref GET_STATUS request is received, the \ref usbsrHookModifyGetStatus() hook is always + * called, so that additional status bits may be added. + * + * To have any practical purpose, "OUT data phase" standard requests need to notify the application of + * certain events. This is done by passing the event via yet another function hook, + * \ref usbsrHookProcessEvent(uint8 event, uint8 index). For events related to interfaces and endpoints, + * the \c index parameter refers to an interface number or the least significant nibble of the endpoint + * address. The following events can be generated: + * \li \ref USBSR_EVENT_CONFIGURATION_CHANGING (the device configuration is about to change) + * \li \ref USBSR_EVENT_CONFIGURATION_CHANGED (the device configuration has changed) + * \li \ref USBSR_EVENT_INTERFACE_CHANGING (the alternate setting of the given interface is about to + * change) + * \li \ref USBSR_EVENT_INTERFACE_CHANGED (the alternate setting of the given interface has changed) + * \li \ref USBSR_EVENT_REMOTE_WAKEUP_ENABLED (remote wakeup has been enabled by the host) + * \li \ref USBSR_EVENT_REMOTE_WAKEUP_DISABLED (remote wakeup has been disabled by the host) + * \li \ref USBSR_EVENT_EPIN_STALL_CLEARED (the given IN endpoint's stall condition has been cleared the + * host) + * \li \ref USBSR_EVENT_EPIN_STALL_SET (the given IN endpoint has been stalled by the host) + * \li \ref USBSR_EVENT_EPOUT_STALL_CLEARED (the given OUT endpoint's stall condition has been cleared + * the host) + * \li \ref USBSR_EVENT_EPOUT_STALL_SET (the given OUT endpoint has been stalled by the PC) + * @{ + */ + + +//------------------------------------------------------------------------------------------------------- +/// \name Standard Request Codes +//@{ + +/// Standard request that returns status for the specified recipient +#define GET_STATUS 0x00 +/// Standard request that clears or disables a specific feature +#define CLEAR_FEATURE 0x01 +/// Standard request that sets or enables a specific feature +#define SET_FEATURE 0x03 +/// Standard request that sets the device address for all future device accesses +#define SET_ADDRESS 0x05 +/// Standard request that returns the specified USB descriptor +#define GET_DESCRIPTOR 0x06 +/// Standard request that may be used to update exitsting descriptors or new descriptors may be added +#define SET_DESCRIPTOR 0x07 +/// Standard request that returns the current device configuration value +#define GET_CONFIGURATION 0x08 +/// Standard request that sets the device configuration +#define SET_CONFIGURATION 0x09 +/// Standard request that returns the selected alternate setting for the specified interface +#define GET_INTERFACE 0x0A +/// Standard request that selects an alternate setting for the specified interface +#define SET_INTERFACE 0x0B +/// Standard request that is used to set and then report an endpoint's synchronization frame +#define SYNCH_FRAME 0x0C +//@} +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// \name Features Indexes +//@{ + +/// Endpoint feature: Halt +#define ENDPOINT_HALT 0x00 +/// Device feature: Remote wakeup +#define DEVICE_REMOTE_WAKEUP 0x01 +//@} +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// \name Event Types +//@{ + +/// The device configuration is about to change +#define USBSR_EVENT_CONFIGURATION_CHANGING 0x01 +/// The device configuration has changed +#define USBSR_EVENT_CONFIGURATION_CHANGED 0x02 +/// The alternate setting of the given interface about to change (index = "interface index") +#define USBSR_EVENT_INTERFACE_CHANGING 0x03 +/// The alternate setting of the given interface has changed (index = "interface index") +#define USBSR_EVENT_INTERFACE_CHANGED 0x04 +/// Remote wakeup has been enabled by the host +#define USBSR_EVENT_REMOTE_WAKEUP_ENABLED 0x05 +/// Remote wakeup has been disabled by the host +#define USBSR_EVENT_REMOTE_WAKEUP_DISABLED 0x06 +/// The given IN endpoint has been unstalled by the PC (index = "endpoint address" & 0x0F) +#define USBSR_EVENT_EPIN_STALL_CLEARED 0x07 /* Endpoint index */ +/// The given IN endpoint has been stalled by the PC (index = "endpoint address" & 0x0F) +#define USBSR_EVENT_EPIN_STALL_SET 0x08 /* Endpoint index */ +/// The given OUT endpoint has been unstalled by the PC (index = "endpoint address" & 0x0F) +#define USBSR_EVENT_EPOUT_STALL_CLEARED 0x09 /* Endpoint index */ +/// The given OUT endpoint has been stalled by the PC (index = "endpoint address" & 0x0F) +#define USBSR_EVENT_EPOUT_STALL_SET 0x0A /* Endpoint index */ +//@} +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// \name Standard Request Hooks +//@{ +/// Refer to the \ref section_setup_handler_usage section for a description on how to process standard +/// requests. + +/// Hook which is called upon reception of a \ref SET_DESCRIPTOR request +void usbsrHookSetDescriptor(void); +/// Hook which is called upon reception of a \ref SYNCH_FRAME request (unsupported). +void usbsrHookSynchFrame(void); +/// Hook which is called when a \ref CLEAR_FEATURE request refers to a an unsupported featureted. +void usbsrHookClearFeature(void); +/// Hook which is called when a \ref SET_FEATURE request refers to a an unsupported feature. +void usbsrHookSetFeature(void); +/// Hook for modifying a \ref GET_STATUS request before the status value is returned to the PC. +void usbsrHookModifyGetStatus(uint8 recipient, uint8 index, uint16 __xdata *pStatus); +/// Hook which is called upon a standard request generated event (unsupported). +void usbsrHookProcessEvent(uint8 event, uint8 index); +//@} +//------------------------------------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------------------------------- +/// \name Handled Standard Requests +//@{ +void usbsrGetStatus(void); +void usbsrClearFeature(void); +void usbsrSetFeature(void); +void usbsrSetAddress(void); +void usbsrGetDescriptor(void); +void usbsrGetConfiguration(void); +void usbsrSetConfiguration(void); +void usbsrGetInterface(void); +void usbsrSetInterface(void); +//@} +//------------------------------------------------------------------------------------------------------- + + +//@} + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_suspend.h b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_suspend.h new file mode 100755 index 0000000..9fa4bb5 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/usb/library/usb_suspend.h @@ -0,0 +1,142 @@ +/*********************************************************************************** + + Filename: usb_suspend.h + + Description: Handle the USB suspend state. + +***********************************************************************************/ + +#ifndef USBSUSPEND_H +#define USBSUSPEND_H +/** \addtogroup module_usb_suspend USB Suspend (usbsusp) + * \brief This module contains the functionality for USB suspend, USB resume and USB remote wakeup. + * + * All USB devices must support the suspended state to fully comply with the USB specification. Special + * care must be taken to implement this functionality correctly, so follow the instructions below + * carefully. Refer to the USB specification for detailed information on current consumption in suspend + * mode (how power consumption shall be measured, averaging, peak value etc.). + * + * \section usb_suspend_resume USB Suspend and Resume + * If there is no activity on the USB bus for a period longer than 3 ms, the MCU will generate a + * \ref USBIRQ_EVENT_SUSPEND event. The USB device must then enter suspend mode within 10 ms, where it + * draws no more than: + * \li 500 uA for low-power devices or high-power devices operating at lower-power + * \li 2.5 mA for high-power devices with remote wake-up enabled + * + * The library supports the USB suspend and resume functionality through a simple interface: + * \li Make sure that the 48 MHz XOSC is never turned off anywhere in the application. + * \li In the call to \ref usbirqInit(), add \ref USBIRQ_EVENT_SUSPEND and \ref USBIRQ_EVENT_RESUME + * (optional) to the interrupt mask. + * \li Do NOT process \ref USBIRQ_EVENT_SUSPEND in \ref usbirqHookProcessEvents() or in any other + * interrupt service routine. This may (or in most cases will) prevent the USB device from getting + * out of suspend mode. + * + * \li In the main loop, add the code shown below. Make sure that this code is visited at least every + * 10 ms. If the worst-case path through the main loop uses more than 10 ms, the code block can be + * inserted in multiple places in the loop until the requirement is met. + * \code + * // Process USB suspend events + * if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_SUSPEND) { + * + * // Clear the suspend event + * USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_SUSPEND); + * + * ... Do what needs to be done before entering power mode 1 here (e.g. turn off the radio, configure + * I/O to minimize power consumption, start the sleep timer etc.) ... + * + * // This function call will take the USB device into power mode 1. It will not return until resume + * // signaling has been detected on the bus, or the remote wake-up function has been used. Other + * // interrupts (for instance from I/O ports or the sleep timer) can be used during this period. When + * // returning from these interrupts, the \ref usbsuspEnter() function (running here) will put the + * // MCU back into power mode 1. + * usbsuspEnter(); + * + * // At this point the event handler is up and running again. Clear the resume event. + * USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_RESUME); + * + * ... If a USBIRQ_EVENT_RESET event will affect the code that follows (before the event is processed + * elsewhere), then make sure to handle it here also ... + * + * ... Do what needs to be done to wake up from suspend mode (e.g. turn on the radio, reactivate I/O + * and peripherals, turn off the sleep timer ... + * } + * \endcode + * + * \li All interrupts that run during suspension mode must start with the following code: + * \code + * while (!XOSC_STABLE); + * \endcode + * + * \section usb_remote_wakeup USB Remote Wakeup: + * Remote wakeup should be used when the USB device desires to initiate the resume process and wake up + * the host. In a radio application this may happen when a particular radio packet is received, for + * instance from a wireless keyboard or mouse. + * + * USB remote wakeup can only be performed if the host has given the device the privilege to do so. The + * privilege to perform remote wakeup is requested by setting bit 5 in the \c bmAttributes field in + * the \ref USB_CONFIGURATION_DESCRIPTOR. The host will then grant or recall the privilege through a + * SET_FEATURE request, which is communicated through a \ref USBSR_EVENT_REMOTE_WAKEUP_ENABLED or + * \ref USBSR_EVENT_REMOTE_WAKEUP_DISABLED event, respectively. + * + * The USB library handles the remote wakeup sequence automatically. Do the following to incorporate it + * into the application: + * \li Implement suspend and resume as described above. + * \li In the USB descriptor, set bit 5 in bmAttributes in the configuration descriptor. + * \li While the USB MCU is in USB suspend mode, remote wakeup can be performed from interrupt context + * (e.g. the sleep timer interrupt) by calling \ref usbsuspDoRemoteWakeup(). This function will + * return TRUE if successful or FALSE if remote wakeup is not permitted (by the host). + * @{ + */ +#include "usb_firmware_library_headers.h" + + +//------------------------------------------------------------------------------------------------------- +// Suspend enter/exit hooks +extern __xdata VFPTR pFnSuspendEnterHook; +extern __xdata VFPTR pFnSuspendExitHook; + +//------------------------------------------------------------------------------------------------------- +// Function prototypes +void usbsuspEnter(void); +uint8 usbsuspDoRemoteWakeup(void); +void usbsuspStopPm1(void); +//------------------------------------------------------------------------------------------------------- + +//@} + +/* ++------------------------------------------------------------------------------ +| Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved. +| +| IMPORTANT: Your use of this Software is limited to those specific rights +| granted under the terms of a software license agreement between the user who +| downloaded the software, his/her employer (which must be your employer) and +| Texas Instruments Incorporated (the "License"). You may not use this Software +| unless you agree to abide by the terms of the License. The License limits +| your use, and you acknowledge, that the Software may not be modified, copied +| or distributed unless embedded on a Texas Instruments microcontroller or used +| solely and exclusively in conjunction with a Texas Instruments radio +| frequency transceiver, which is integrated into your product. Other than for +| the foregoing purpose, you may not use, reproduce, copy, prepare derivative +| works of, modify, distribute, perform, display or sell this Software and/or +| its documentation for any purpose. +| +| YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE +| PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +| INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, +| NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL +| TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, +| NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER +| LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING +| BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR +| CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF +| SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES +| (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. +| +| Should you have any questions regarding your right to use this Software, +| contact Texas Instruments Incorporated at www.TI.com. +| ++------------------------------------------------------------------------------ +*/ + +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/usb/usb_driver.r51 b/chronos-ti/Software Projects/RF Access Point/IAR/usb/usb_driver.r51 new file mode 100755 index 0000000..8a78fa5 Binary files /dev/null and b/chronos-ti/Software Projects/RF Access Point/IAR/usb/usb_driver.r51 differ diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/wbsl/ioCCxx10_bitdef.h b/chronos-ti/Software Projects/RF Access Point/IAR/wbsl/ioCCxx10_bitdef.h new file mode 100755 index 0000000..7c84a0a --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/wbsl/ioCCxx10_bitdef.h @@ -0,0 +1,1284 @@ +/****************************************************************************** + Filename: ioCCxx10_bitdef.h + + This file contains the bit definitions of registers in CCxx10 + + Copyright 2008 Texas Instruments, Inc. +******************************************************************************/ +#ifndef _IOCCXX10_BITDEF_H +#define _IOCCXX10_BITDEF_H + + + +/* SEE DATA SHEET FOR DETAILS ABOUT THE FOLLOWING BIT MASKS */ + + + +/******************************************************************************* + * Memory Control Registers + */ + +// MPAGE (0x93) - Memory Page Select + +// MEMCTR (0xC7) - Memory Arbiter Control +#define MEMCTR_CACHD 0x02 +#define MEMCTR_PREFD 0x01 + + +/******************************************************************************* + * CPU Registers + */ + +// DPH0 (0x83) - Data Pointer 0 High Byte + +// DPL0 (0x82) - Data Pointer 0 Low Byte + +// DPH1 (0x85) - Data Pointer 1 High Byte + +// DPL1 (0x84) - Data Pointer 1 Low Byte + +// DPS (0x92) - Data Pointer Select +#define DPS_VDPS 0x01 + + +// PSW (0xD0) - Progrttus Word - bit accessible SFR register + +// ACC (0xE0) - Accumulator - bit accessible SFR register + +// B (0xF0) - B Register - bit accessible SFR register + +// SP (0x81) - Stack Pointer + + +/******************************************************************************* + * Interrupt Control Registers + */ + +// IEN0 (0xA8) - Interrupt Enable 0 Register - bit accessible SFR register + +// IEN1 (0xB8) - Interrupt Enable 1 Register - bit accessible SFR register + +// IEN2 (0x9A) - Interrupt Enable 2 Register +#define IEN2_WDTIE 0x20 +#define IEN2_P1IE 0x10 +#define IEN2_UTX1IE 0x08 +#define IEN2_I2STXIE 0x08 +#define IEN2_UTX0IE 0x04 +#define IEN2_P2IE 0x02 +#define IEN2_USBIE 0x02 +#define IEN2_RFIE 0x01 + + +// TCON (0x88) - CPU Interrupt Flag 1 - bit accessible SFR register + +// S0CON (0x98) - CPU Interrupt Flag 2 - bit accessible SFR register + +// S1CON (0x9B) - CPU Interrupt Flag 3 +#define S1CON_RFIF_1 0x02 +#define S1CON_RFIF_0 0x01 + + +// IRCON (0xC0) - CPU Interrupt Flag 4 - bit accessible SFR register + +// IRCON2 (0xE8) - CPU Interrupt Flag 5 - bit accessible SFR register + +// IP1 (0xB9) - Interrupt Priority 1 +#define IP1_IPG5 0x20 +#define IP1_IPG4 0x10 +#define IP1_IPG3 0x08 +#define IP1_IPG2 0x04 +#define IP1_IPG1 0x02 +#define IP1_IPG0 0x01 + +// IP0 (0xA9) - Interrupt Priority 0 +#define IP0_IPG5 0x20 +#define IP0_IPG4 0x10 +#define IP0_IPG3 0x08 +#define IP0_IPG2 0x04 +#define IP0_IPG1 0x02 +#define IP0_IPG0 0x01 + + + +/******************************************************************************* + * Power Management and Clocks + */ + +// PCON (0x87) - Power Mode Control +#define PCON_IDLE 0x01 + + +// SLEEP (0xBE) - Sleep Mode Control +#define SLEEP_USB_EN 0x80 +#define SLEEP_XOSC_S 0x40 +#define SLEEP_HFRC_S 0x20 +#define SLEEP_RST 0x18 +#define SLEEP_RST0 0x08 +#define SLEEP_RST1 0x10 +#define SLEEP_OSC_PD 0x04 +#define SLEEP_MODE 0x03 +#define SLEEP_MODE1 0x02 +#define SLEEP_MODE0 0x01 + +#define SLEEP_RST_POR_BOD (0x00 << 3) +#define SLEEP_RST_EXT (0x01 << 3) +#define SLEEP_RST_WDT (0x02 << 3) + +#define SLEEP_MODE_PM0 (0x00) +#define SLEEP_MODE_PM1 (0x01) +#define SLEEP_MODE_PM2 (0x02) +#define SLEEP_MODE_PM3 (0x03) + + +// CLKCON (0xC6) - Clock Control +#define CLKCON_OSC32 0x80 // bit mask, for the slow 32k clock oscillator +#define CLKCON_OSC 0x40 // bit mask, for the system clock oscillator +#define CLKCON_TICKSPD 0x38 // bit mask, for timer ticks output setting +#define CLKCON_TICKSPD0 0x08 // bit mask, for timer ticks output setting +#define CLKCON_TICKSPD1 0x10 // bit mask, for timer ticks output setting +#define CLKCON_TICKSPD2 0x20 // bit mask, for timer ticks output setting +#define CLKCON_CLKSPD 0x07 // bit mask, for the clock speed +#define CLKCON_CLKSPD0 0x01 // bit mask, for the clock speed +#define CLKCON_CLKSPD1 0x02 // bit mask, for the clock speed +#define CLKCON_CLKSPD2 0x04 // bit mask, for the clock speed + +#define TICKSPD_DIV_1 (0x00 << 3) +#define TICKSPD_DIV_2 (0x01 << 3) +#define TICKSPD_DIV_4 (0x02 << 3) +#define TICKSPD_DIV_8 (0x03 << 3) +#define TICKSPD_DIV_16 (0x04 << 3) +#define TICKSPD_DIV_32 (0x05 << 3) +#define TICKSPD_DIV_64 (0x06 << 3) +#define TICKSPD_DIV_128 (0x07 << 3) + +#define CLKSPD_DIV_1 (0x00) +#define CLKSPD_DIV_2 (0x01) +#define CLKSPD_DIV_4 (0x02) +#define CLKSPD_DIV_8 (0x03) +#define CLKSPD_DIV_16 (0x04) +#define CLKSPD_DIV_32 (0x05) +#define CLKSPD_DIV_64 (0x06) +#define CLKSPD_DIV_128 (0x07) + + + +/******************************************************************************* + * Flash Controller + */ + +// FCTL (0xAE) - Flash Control +#define FCTL_BUSY 0x80 +#define FCTL_SWBSY 0x40 +#define FCTL_CONTRD 0x10 +#define FCTL_WRITE 0x02 +#define FCTL_ERASE 0x01 + + +// FWDATA (0xAF) - Flash Write Data + +// FADDRH (0xAD) - Flash Address High Byte + +// FADDRL (0xAC) - Flash Address Low Byte + +// FWT (0xAB) - Flash Write Timing (Only bit 0-5 R/W) + + +/******************************************************************************* + * I/O Ports + */ + +// P0 (0x80) - Port 0 - bit accessible SFR register + +// P1 (0x90) - Port 1 - bit accessible SFR register + +// P2 (0xA0) - Port 2 - bit accessible SFR register + +// PERCFG (0xF1) - Peripheral Control +#define PERCFG_T1CFG 0x40 +#define PERCFG_T3CFG 0x20 +#define PERCFG_T4CFG 0x10 +#define PERCFG_U1CFG 0x02 +#define PERCFG_U0CFG 0x01 + + + +// ADCCFG (0xF2) - ADC input Configuration +#define ADCCFG_7 0x80 +#define ADCCFG_6 0x40 +#define ADCCFG_5 0x20 +#define ADCCFG_4 0x10 +#define ADCCFG_3 0x08 +#define ADCCFG_2 0x04 +#define ADCCFG_1 0x02 +#define ADCCFG_0 0x01 + + +// P0SEL (0xF3) - Port 0 Function Select (bit 7 not used) + +// P1SEL (0xF4) - Port 1 Function Select + +// P2SEL (0xF5) - Port 2 Function Select +#define P2SEL_PRI3P1 0x40 +#define P2SEL_PRI2P1 0x20 +#define P2SEL_PRI1P1 0x10 +#define P2SEL_PRI0P1 0x08 +#define P2SEL_SELP2_4 0x04 +#define P2SEL_SELP2_3 0x02 +#define P2SEL_SELP2_0 0x01 + + +// P0DIR (0xFD) - Port 0 Direction Select + +// P1DIR (0xFE) - Port 1 Direction Select + +// P2DIR (0xFF) - Port 2 Direction +#define P2DIR_PRIP0 0xC0 +#define P2DIR_0PRIP0 0x40 +#define P2DIR_1PRIP0 0x80 +#define P2DIR_DIRP2 0x1F + +#define P2DIR_PRIP0_0 (0x00 << 6) +#define P2DIR_PRIP0_1 (0x01 << 6) +#define P2DIR_PRIP0_2 (0x02 << 6) +#define P2DIR_PRIP0_3 (0x03 << 6) + +#define P2DIR_DIRP2_4 (0x10) +#define P2DIR_DIRP2_3 (0x08) +#define P2DIR_DIRP2_2 (0x04) +#define P2DIR_DIRP2_1 (0x02) +#define P2DIR_DIRP2_0 (0x01) + + + +// P0INP (0x8F) - Port 0 Input Mode (bit 0 & 1 not used) + +// P1INP (0xF6) - Port 1 Input Mode (bit 0 & 1 not used) + +// P2INP (0xF7) - Port 2 Input Mode +#define P2INP_PDUP2 0x80 +#define P2INP_PDUP1 0x40 +#define P2INP_PDUP0 0x20 +#define P2INP_MDP2 0x1F + +#define P2INP_MDP2_0 (0x01) +#define P2INP_MDP2_1 (0x02) +#define P2INP_MDP2_2 (0x04) +#define P2INP_MDP2_3 (0x08) +#define P2INP_MDP2_4 (0x10) + + + +// P0IFG (0x89) - Port 0 Interrupt Status Flag + +// P1IFG (0x8A) - Port 1 Interrupt Status Flag + +// P2IFG (0x8B) - Port 2 Interrupt Status Flag (bit 7 - 5 not used) + +// PICTL (0x8C) - Port Interrupt Control +#define PICTL_PADSC 0x40 +#define PICTL_P2IEN 0x20 +#define PICTL_P0IENH 0x10 +#define PICTL_P0IENL 0x08 +#define PICTL_P2ICON 0x04 +#define PICTL_P1ICON 0x02 +#define PICTL_P0ICON 0x01 + + +// P1IEN (0x8D) - Port 1 Interrupt Mask + + + +/******************************************************************************* + * DMA Controller + */ + +// DMAARM (0xD6) - DMA Channel Arm +#define DMAARM_ABORT 0x80 +#define DMAARM4 0x10 +#define DMAARM3 0x08 +#define DMAARM2 0x04 +#define DMAARM1 0x02 +#define DMAARM0 0x01 + + +// DMAREQ (0xD7) - DMA Channel Start Request and Status +#define DMAREQ4 0x10 +#define DMAREQ3 0x08 +#define DMAREQ2 0x04 +#define DMAREQ1 0x02 +#define DMAREQ0 0x01 + + +// DMA0CFGH (0xD5) - DMA Channel 0 Configuration Address High Byte + +// DMA0CFGL (0xD4) - DMA Channel 0 Configuration Address Low Byte + +// DMA1CFGH (0xD3) - DMA Channel 1 - 4 Configuration Address High By + +// DMA1CFGL (0xD2) - DMA Channel 1 - 4 Configuration Address Low Byte + +// DMAIRQ (0xD1) - DMA Interrupt Flag +#define DMAIRQ_DMAIF4 0x10 +#define DMAIRQ_DMAIF3 0x08 +#define DMAIRQ_DMAIF2 0x04 +#define DMAIRQ_DMAIF1 0x02 +#define DMAIRQ_DMAIF0 0x01 + + +// T1CNTH (0xE3) - Timer 1 Counter High + +// T1CNTL (0xE2) - Timer 1 Counter Low + +// T1CTL (0xE4) - Timer 1 Control and Status +#define T1CTL_CH2IF 0x80 // Timer 1 channel 2 interrupt flag +#define T1CTL_CH1IF 0x40 // Timer 1 channel 1 interrupt flag +#define T1CTL_CH0IF 0x20 // Timer 1 channel 0 interrupt flag +#define T1CTL_OVFIF 0x10 // Timer 1 counter overflow interrupt flag +#define T1CTL_DIV 0x0C +#define T1CTL_DIV0 0x04 +#define T1CTL_DIV1 0x08 +#define T1CTL_MODE 0x03 +#define T1CTL_MODE0 0x01 +#define T1CTL_MODE1 0x02 + +#define T1CTL_DIV_1 (0x00 << 2) // Divide tick frequency by 1 +#define T1CTL_DIV_8 (0x01 << 2) // Divide tick frequency by 8 +#define T1CTL_DIV_32 (0x02 << 2) // Divide tick frequency by 32 +#define T1CTL_DIV_128 (0x03 << 2) // Divide tick frequency by 128 + +#define T1CTL_MODE_SUSPEND (0x00) // Operation is suspended (halt) +#define T1CTL_MODE_FREERUN (0x01) // Free Running mode +#define T1CTL_MODE_MODULO (0x02) // Modulo +#define T1CTL_MODE_UPDOWN (0x03) // Up/down + + +// T1CCTL0 (0xE5) - Timer 1 Channel 0 Capture/Compare Control +#define T1CCTL0_CPSEL 0x80 // Timer 1 channel 0 capture select +#define T1CCTL0_IM 0x40 // Channel 0 Interrupt mask +#define T1CCTL0_CMP 0x38 +#define T1CCTL0_CMP0 0x08 +#define T1CCTL0_CMP1 0x10 +#define T1CCTL0_CMP2 0x20 +#define T1CCTL0_MODE 0x04 // Capture or compare mode +#define T1CCTL0_CAP 0x03 +#define T1CCTL0_CAP0 0x01 +#define T1CCTL0_CAP1 0x02 + +#define T1C0_SET_ON_CMP (0x00 << 3) // Clear output on compare-up set on 0 +#define T1C0_CLR_ON_CMP (0x01 << 3) // Set output on compare-up clear on 0 +#define T1C0_TOG_ON_CMP (0x02 << 3) // Toggle output on compare +#define T1C0_SET_CMP_UP_CLR_0 (0x03 << 3) // Clear output on compare +#define T1C0_CLR_CMP_UP_SET_0 (0x04 << 3) // Set output on compare + +#define T1C0_NO_CAP (0x00) // No capture +#define T1C0_RISE_EDGE (0x01) // Capture on rising edge +#define T1C0_FALL_EDGE (0x02) // Capture on falling edge +#define T1C0_BOTH_EDGE (0x03) // Capture on both edges + + +// T1CC0H (0xDB) - Timer 1 Channel 0 Capture/Compare Value High + +// T1CC0L (0xDA) - Timer 1 Channel 0 Capture/Compare Value Low + +// T1CCTL1 (0xE6) - Timer 1 Channel 1 Capture/Compare Control +#define T1CCTL1_CPSEL 0x80 // Timer 1 channel 1 capture select +#define T1CCTL1_IM 0x40 // Channel 1 Interrupt mask +#define T1CCTL1_CMP 0x38 +#define T1CCTL1_CMP0 0x08 +#define T1CCTL1_CMP1 0x10 +#define T1CCTL1_CMP2 0x20 +#define T1CCTL1_MODE 0x04 // Capture or compare mode +#define T1CCTL1_DSM_SPD 0x04 +#define T1CCTL1_CAP 0x03 +#define T1CCTL1_CAP0 0x01 +#define T1CCTL1_CAP1 0x02 + +#define T1C1_SET_ON_CMP (0x00 << 3) // Set output on compare +#define T1C1_CLR_ON_CMP (0x01 << 3) // Clear output on compare +#define T1C1_TOG_ON_CMP (0x02 << 3) // Toggle output on compare +#define T1C1_SET_CMP_UP_CLR_0 (0x03 << 3) // Set output on compare-up clear on 0 +#define T1C1_CLR_CMP_UP_SET_0 (0x04 << 3) // Clear output on compare-up set on 0 +#define T1C1_SET_C1_CLR_C0 (0x05 << 3) // Set when equal to T1CC1, clear when equal to T1CC0 +#define T1C1_CLR_C1_SET_C0 (0x06 << 3) // Clear when equal to T1CC1, set when equal to T1CC0 +#define T1C1_DSM_MODE (0x07 << 3) // DSM mode + +#define T1C1_NO_CAP (0x00) // No capture +#define T1C1_RISE_EDGE (0x01) // Capture on rising edge +#define T1C1_FALL_EDGE (0x02) // Capture on falling edge +#define T1C1_BOTH_EDGE (0x03) // Capture on both edges + +#define DSM_IP_ON_OS_ON (0x00) // Interpolator & output shaping enabled +#define DSM_IP_ON_OS_OFF (0x01) // Interpolator enabled & output shaping disabled +#define DSM_IP_OFF_OS_ON (0x02) // Interpolator disabled & output shaping enabled +#define DSM_IP_OFF_OS_OFF (0x03) // Interpolator & output shaping disabled + + + +// T1CC1H (0xDD) - Timer 1 Channel 1 Capture/Compare Value High + +// T1CC1L (0xDC) - Timer 1 Channel 1 Capture/Compare Value Low + +// T1CCTL2 (0xE7) - Timer 1 Channel 2 Capture/Compare Control +#define T1CCTL2_CPSEL 0x80 // Timer 1 channel 2 capture select +#define T1CCTL2_IM 0x40 // Channel 2 Interrupt mask +#define T1CCTL2_CMP 0x38 +#define T1CCTL2_CMP0 0x08 +#define T1CCTL2_CMP1 0x10 +#define T1CCTL2_CMP2 0x20 +#define T1CCTL2_MODE 0x04 // Capture or compare mode +#define T1CCTL2_CAP 0x03 +#define T1CCTL2_CAP0 0x01 +#define T1CCTL2_CAP1 0x02 + +#define T1C2_SET_ON_CMP (0x00 << 3) // Set output on compare +#define T1C2_CLR_ON_CMP (0x01 << 3) // Clear output on compare +#define T1C2_TOG_ON_CMP (0x02 << 3) // Toggle output on compare +#define T1C2_SET_CMP_UP_CLR_0 (0x03 << 3) // Set output on compare-up clear on 0 +#define T1C2_CLR_CMP_UP_SET_0 (0x04 << 3) // Clear output on compare-up set on 0 +#define T1C2_SET_C2_CLR_C0 (0x05 << 3) // Set when equal to T1CC2, clear when equal to T1CC0 +#define T1C2_CLR_C2_SET_C0 (0x06 << 3) // Clear when equal to T1CC2, set when equal to T1CC0 + +#define T1C2_NO_CAP (0x00) // No capture +#define T1C2_RISE_EDGE (0x01) // Capture on rising edge +#define T1C2_FALL_EDGE (0x02) // Capture on falling edge +#define T1C2_BOTH_EDGE (0x03) // Capture on both edges + + +// T1CC2H (0xDF) - Timer 1 Channel 2 Capture/Compare Value High + +// T1CC2L (0xDE) - Timer 1 Channel 2 Capture/Compare Value Low + +// T2CTL (0x9E) - Timer 2 Control +#define T2CTL_TEX 0x40 +#define T2CTL_INT 0x10 // Enable Timer 2 interrupt +#define T2CTL_TIG 0x04 // Tick generator mode +#define T2CTL_TIP 0x03 +#define T2CTL_TIP0 0x01 +#define T2CTL_TIP1 0x02 + +#define T2CTL_TIP_64 (0x00) +#define T2CTL_TIP_128 (0x01) +#define T2CTL_TIP_256 (0x02) +#define T2CTL_TIP_1024 (0x03) + + +// T2CT (0x9C) - Timer 2 Count + +// T2PR (0x9D) - Timer 2 Prescaler + +// WORTIME0 (0xA5) - Sleep Timer Low Byte + +// WORTIME1 (0xA6) - Sleep Timer High Byte + +// WOREVT1 (0xA4) - Sleep Timer Event0 Timeout High + +// WOREVT0 (0xA3) - Sleep Timer Event0 Timeout Low + +// WORCTL (0xA2) - Sleep Timer Control +#define WORCTL_WOR_RESET 0x04 +#define WORCTL_WOR_RES 0x03 +#define WORCTL_WOR_RES0 0x01 +#define WORCTL_WOR_RES1 0x02 + +#define WORCTL_WOR_RES_1 (0x00) +#define WORCTL_WOR_RES_32 (0x01) +#define WORCTL_WOR_RES_1024 (0x02) +#define WORCTL_WOR_RES_32768 (0x03) + + +// WORIRQ (0xA1) - Sleep Timer Interrupt Control +#define WORIRQ_EVENT0_MASK 0x10 +#define WORIRQ_EVENT0_FLAG 0x01 + + +// T3CNT (0xCA) - Timer 3 Counter + +// T3CTL (0xCB) - Timer 3 Control +#define T3CTL_DIV 0xE0 +#define T3CTL_DIV0 0x20 +#define T3CTL_DIV1 0x40 +#define T3CTL_DIV2 0x80 +#define T3CTL_START 0x10 +#define T3CTL_OVFIM 0x08 +#define T3CTL_CLR 0x04 +#define T3CTL_MODE 0x03 +#define T3CTL_MODE0 0x01 +#define T3CTL_MODE1 0x02 + +#define T3CTL_DIV_1 (0x00 << 5) +#define T3CTL_DIV_2 (0x01 << 5) +#define T3CTL_DIV_4 (0x02 << 5) +#define T3CTL_DIV_8 (0x03 << 5) +#define T3CTL_DIV_16 (0x04 << 5) +#define T3CTL_DIV_32 (0x05 << 5) +#define T3CTL_DIV_64 (0x06 << 5) +#define T3CTL_DIV_128 (0x07 << 5) + +#define T3CTL_MODE_FREERUN (0x00) +#define T3CTL_MODE_DOWN (0x01) +#define T3CTL_MODE_MODULO (0x02) +#define T3CTL_MODE_UPDOWN (0x03) + + + +// T3CCTL0 (0xCC) - Timer 3 Channel 0 Compare Control +#define T3CCTL0_IM 0x40 +#define T3CCTL0_MODE 0x04 +#define T3CCTL0_CMP 0x38 +#define T3CCTL0_CMP0 0x08 +#define T3CCTL0_CMP1 0x10 +#define T3CCTL0_CMP2 0x20 + +#define T3C0_SET_ON_CMP (0x00 << 3) // Set output on compare +#define T3C0_CLR_ON_CMP (0x01 << 3) // Clear output on compare +#define T3C0_TOG_ON_CMP (0x02 << 3) // Toggle output on compare +#define T3C0_SET_CMP_UP_CLR_0 (0x03 << 3) // Set output on compare-up clear on 0 +#define T3C0_CLR_CMP_UP_SET_0 (0x04 << 3) // Clear output on compare-up set on 0 +#define T3C0_SET_CMP_CLR_255 (0x05 << 3) // Set when equal to T3CC0, clear on 255 +#define T3C0_CLR_CMP_SET_0 (0x06 << 3) // Clear when equal to T3CC0, set on 0 + + + +// T3CC0 (0xCD) - Timer 3 Channel 0 Compare Value + +// T3CCTL1 (0xCE) - Timer 3 Channel 1 Compare Control + +#define T3CCTL1_IM 0x40 +#define T3CCTL1_MODE 0x04 +#define T3CCTL1_CMP 0x38 +#define T3CCTL1_CMP0 0x08 +#define T3CCTL1_CMP1 0x10 +#define T3CCTL1_CMP2 0x20 + +#define T3C1_SET_ON_CMP (0x00 << 3) // Set output on compare +#define T3C1_CLR_ON_CMP (0x01 << 3) // Clear output on compare +#define T3C1_TOG_ON_CMP (0x02 << 3) // Toggle output on compare +#define T3C1_SET_CMP_UP_CLR_0 (0x03 << 3) // Set output on compare-up clear on 0 +#define T3C1_CLR_CMP_UP_SET_0 (0x04 << 3) // Clear output on compare-up set on 0 +#define T3C1_SET_CMP_CLR_C0 (0x05 << 3) // Set when equal to T3CC1, clear when equal to T3CC0 +#define T3C1_CLR_CMP_SET_C0 (0x06 << 3) // Clear when equal to T3CC1, set when equal to T3CC0 + + +// T3CC1 (0xCF) - Timer 3 Channel 1 Compare Value + +// T4CNT (0xEA) - Timer 4 Counter + +// T4CTL (0xEB) - Timer 4 Control +#define T4CTL_DIV 0xE0 +#define T4CTL_DIV0 0x20 +#define T4CTL_DIV1 0x40 +#define T4CTL_DIV2 0x80 +#define T4CTL_START 0x10 +#define T4CTL_OVFIM 0x08 +#define T4CTL_CLR 0x04 +#define T4CTL_MODE 0x03 +#define T4CTL_MODE0 0x01 +#define T4CTL_MODE1 0x02 + +#define T4CTL_MODE_FREERUN (0x00) +#define T4CTL_MODE_DOWN (0x01) +#define T4CTL_MODE_MODULO (0x02) +#define T4CTL_MODE_UPDOWN (0x03) + +#define T4CTL_DIV_1 (0x00 << 5) +#define T4CTL_DIV_2 (0x01 << 5) +#define T4CTL_DIV_4 (0x02 << 5) +#define T4CTL_DIV_8 (0x03 << 5) +#define T4CTL_DIV_16 (0x04 << 5) +#define T4CTL_DIV_32 (0x05 << 5) +#define T4CTL_DIV_64 (0x06 << 5) +#define T4CTL_DIV_128 (0x07 << 5) + + +// T4CCTL0 (0xEC) - Timer 4 Channel 0 Compare Control +#define T4CCTL0_IM 0x40 +#define T4CCTL0_CMP 0x38 +#define T4CCTL0_CMP0 0x08 +#define T4CCTL0_CMP1 0x10 +#define T4CCTL0_CMP2 0x20 +#define T4CCTL0_MODE 0x04 + +#define T4CCTL0_SET_ON_CMP (0x00 << 3) +#define T4CCTL0_CLR_ON_CMP (0x01 << 3) +#define T4CCTL0_TOG_ON_CMP (0x02 << 3) +#define T4CCTL0_SET_CMP_UP_CLR_0 (0x03 << 3) +#define T4CCTL0_CLR_CMP_UP_SET_0 (0x04 << 3) +#define T4CCTL0_SET_CMP_CLR_255 (0x05 << 3) +#define T4CCTL0_CLR_CMP_SET_0 (0x06 << 3) + + +// T4CC0 (0xED) - Timer 4 Channel 0 Compare Value + +// T4CCTL1 (0xEE) - Timer 4 Channel 1 Compare Control +#define T4CCTL1_IM 0x40 +#define T4CCTL1_CMP 0x38 +#define T4CCTL1_CMP0 0x08 +#define T4CCTL1_CMP1 0x10 +#define T4CCTL1_CMP2 0x20 +#define T4CCTL1_MODE 0x04 + +#define T4CCTL1_SET_ON_CMP (0x00 << 3) +#define T4CCTL1_CLR_ON_CMP (0x01 << 3) +#define T4CCTL1_TOG_ON_CMP (0x02 << 3) +#define T4CCTL1_SET_CMP_UP_CLR_0 (0x03 << 3) +#define T4CCTL1_CLR_CMP_UP_SET_0 (0x04 << 3) +#define T4CCTL1_SET_CMP_CLR_C0 (0x05 << 3) +#define T4CCTL1_CLR_CMP_SET_C0 (0x06 << 3) + + +// TIMIF (0xD8) - Timers 1/3/4 Interrupt Mask/Flag - bit accessible SFR register + + +/******************************************************************************* + * ADC + */ + +// ADCL (0xBA) - ADC Data Low (only bit 7-4 used) + +// ADCH (0xBB) - ADC Data High + +// ADCCON1 (0xB4) - ADC Control 1 +#define ADCCON1_EOC 0x80 +#define ADCCON1_ST 0x40 +#define ADCCON1_STSEL 0x30 +#define ADCCON1_STSEL0 0x10 +#define ADCCON1_STSEL1 0x20 +#define ADCCON1_RCTRL 0x0C +#define ADCCON1_RCTRL0 0x04 +#define ADCCON1_RCTRL1 0x08 + +#define STSEL_P2_0 (0x00 << 4) +#define STSEL_FULL_SPEED (0x01 << 4) +#define STSEL_T1C0_CMP_EVT (0x02 << 4) +#define STSEL_ST (0x03 << 4) + +#define ADCCON1_RCTRL_COMPL (0x00 << 2) +#define ADCCON1_RCTRL_LFSR13 (0x01 << 2) + + + +// ADCCON2 (0xB5) - ADC Control 2 +#define ADCCON2_SREF 0xC0 +#define ADCCON2_SREF0 0x40 +#define ADCCON2_SREF1 0x80 +#define ADCCON2_SDIV 0x30 +#define ADCCON2_SDIV0 0x10 +#define ADCCON2_SDIV1 0x20 +#define ADCCON2_SCH 0x0F +#define ADCCON2_SCH0 0x01 +#define ADCCON2_SCH1 0x02 +#define ADCCON2_SCH2 0x04 +#define ADCCON2_SCH3 0x08 + +#define ADCCON2_SREF_1_25V (0x00 << 6) +#define ADCCON2_SREF_P0_7 (0x01 << 6) +#define ADCCON2_SREF_AVDD (0x02 << 6) +#define ADCCON2_SREF_P0_6_P0_7 (0x03 << 6) + +#define ADCCON2_SDIV_64 (0x00 << 4) +#define ADCCON2_SDIV_128 (0x01 << 4) +#define ADCCON2_SDIV_256 (0x02 << 4) +#define ADCCON2_SDIV_512 (0x03 << 4) + +#define ADCCON2_SCH_AIN0 (0x00) +#define ADCCON2_SCH_AIN1 (0x01) +#define ADCCON2_SCH_AIN2 (0x02) +#define ADCCON2_SCH_AIN3 (0x03) +#define ADCCON2_SCH_AIN4 (0x04) +#define ADCCON2_SCH_AIN5 (0x05) +#define ADCCON2_SCH_AIN6 (0x06) +#define ADCCON2_SCH_AIN7 (0x07) +#define ADCCON2_SCH_AIN0_1 (0x08) +#define ADCCON2_SCH_AIN2_3 (0x09) +#define ADCCON2_SCH_AIN4_5 (0x0A) +#define ADCCON2_SCH_AIN6_7 (0x0B) +#define ADCCON2_SCH_GND (0x0C) +#define ADCCON2_SCH_POSVOL (0x0D) +#define ADCCON2_SCH_TEMPR (0x0E) +#define ADCCON2_SCH_VDD_3 (0x0F) + + +// ADCCON3 (0xB6) - ADC Control 3 +#define ADCCON3_EREF 0xC0 +#define ADCCON3_EREF0 0x40 +#define ADCCON3_EREF1 0x80 +#define ADCCON3_EDIV 0x30 +#define ADCCON3_EDIV0 0x10 +#define ADCCON3_EDIV1 0x20 +#define ADCCON2_ECH 0x0F +#define ADCCON2_ECH0 0x01 +#define ADCCON2_ECH1 0x02 +#define ADCCON2_ECH2 0x04 +#define ADCCON2_ECH3 0x08 + +#define ADCCON3_EREF_1_25V (0x00 << 6) +#define ADCCON3_EREF_P0_7 (0x01 << 6) +#define ADCCON3_EREF_AVDD (0x02 << 6) +#define ADCCON3_EREF_P0_6_P0_7 (0x03 << 6) + +#define ADCCON3_EDIV_64 (0x00 << 4) +#define ADCCON3_EDIV_128 (0x01 << 4) +#define ADCCON3_EDIV_256 (0x02 << 4) +#define ADCCON3_EDIV_512 (0x03 << 4) + +#define ADCCON3_ECH_AIN0 (0x00) +#define ADCCON3_ECH_AIN1 (0x01) +#define ADCCON3_ECH_AIN2 (0x02) +#define ADCCON3_ECH_AIN3 (0x03) +#define ADCCON3_ECH_AIN4 (0x04) +#define ADCCON3_ECH_AIN5 (0x05) +#define ADCCON3_ECH_AIN6 (0x06) +#define ADCCON3_ECH_AIN7 (0x07) +#define ADCCON3_ECH_AIN0_1 (0x08) +#define ADCCON3_ECH_AIN2_3 (0x09) +#define ADCCON3_ECH_AIN4_5 (0x0A) +#define ADCCON3_ECH_AIN6_7 (0x0B) +#define ADCCON3_ECH_GND (0x0C) +#define ADCCON3_ECH_POSVOL (0x0D) +#define ADCCON3_ECH_TEMPR (0x0E) +#define ADCCON3_ECH_VDD_3 (0x0F) + + + +/******************************************************************************* + * Random Number Generator + */ + +// RNDL (0xBC) - Random Number Generator Data Low Byte + +// RNDH (0xBD) - Random Number Generator Data High Byte + + +/******************************************************************************* + * AES + */ + +// ENCCS (0xB3) - Encryption Control and Status +#define ENCCS_MODE 0x70 +#define ENCCS_MODE0 0x10 +#define ENCCS_MODE1 0x20 +#define ENCCS_MODE2 0x40 +#define ENCCS_RDY 0x08 +#define ENCCS_CMD 0x06 +#define ENCCS_CMD0 0x02 +#define ENCCS_CMD1 0x04 +#define ENCCS_ST 0x01 + +#define ENCCS_MODE_CBC (0x00 << 4) +#define ENCCS_MODE_CFB (0x01 << 4) +#define ENCCS_MODE_OFB (0x02 << 4) +#define ENCCS_MODE_CTR (0x03 << 4) +#define ENCCS_MODE_ECB (0x04 << 4) +#define ENCCS_MODE_CBCMAC (0x05 << 4) + +#define ENCCS_CMD_ENC (0x00 << 1) +#define ENCCS_CMD_DEC (0x01 << 1) +#define ENCCS_CMD_LDKEY (0x02 << 1) +#define ENCCS_CMD_LDIV (0x03 << 1) + + +// ENCDI (0xB1) - Encryption Input Data + +// ENCDO (0xB2) - Encryption Output Data + + +/******************************************************************************* + * Watchdog Timer + */ + +// WDCTL (0xC9) - Watchdog Timer Control +#define WDCTL_CLR 0xF0 +#define WDCTL_CLR0 0x10 +#define WDCTL_CLR1 0x20 +#define WDCTL_CLR2 0x40 +#define WDCTL_CLR3 0x80 +#define WDCTL_EN 0x08 +#define WDCTL_MODE 0x04 +#define WDCTL_INT 0x03 +#define WDCTL_INT0 0x01 +#define WDCTL_INT1 0x02 + + +#define WDCTL_INT_SEC_1 (0x00) +#define WDCTL_INT1_MSEC_250 (0x01) +#define WDCTL_INT2_MSEC_15 (0x02) +#define WDCTL_INT3_MSEC_2 (0x03) + + + +/******************************************************************************* + * USART + */ + +// U0CSR (0x86) - USART 0 Control and Status + +#define U0CSR_MODE 0x80 +#define U0CSR_RE 0x40 +#define U0CSR_SLAVE 0x20 +#define U0CSR_FE 0x10 +#define U0CSR_ERR 0x08 +#define U0CSR_RX_BYTE 0x04 +#define U0CSR_TX_BYTE 0x02 +#define U0CSR_ACTIVE 0x01 + + +// U0UCR (0xC4) - USART 0 UART Control +#define U0UCR_FLUSH 0x80 +#define U0UCR_FLOW 0x40 +#define U0UCR_D9 0x20 +#define U0UCR_BIT9 0x10 +#define U0UCR_PARITY 0x08 +#define U0UCR_SPB 0x04 +#define U0UCR_STOP 0x02 +#define U0UCR_START 0x01 + + +// U0GCR (0xC5) - USART 0 Generic Control +#define U0GCR_CPOL 0x80 +#define U0GCR_CPHA 0x40 +#define U0GCR_ORDER 0x20 +#define U0GCR_BAUD_E 0x1F +#define U0GCR_BAUD_E0 0x01 +#define U0GCR_BAUD_E1 0x02 +#define U0GCR_BAUD_E2 0x04 +#define U0GCR_BAUD_E3 0x08 +#define U0GCR_BAUD_E4 0x10 + + +// U0DBUF (0xC1) - USART 0 Receive/Transmit Data Buffer + +// U0BAUD (0xC2) - USART 0 Baud Rate Control + +// U1CSR (0xF8) - USART 1 Control and Status - bit accessible SFR register +#define U1CSR_MODE 0x80 +#define U1CSR_RE 0x40 +#define U1CSR_SLAVE 0x20 +#define U1CSR_FE 0x10 +#define U1CSR_ERR 0x08 +#define U1CSR_RX_BYTE 0x04 +#define U1CSR_TX_BYTE 0x02 +#define U1CSR_ACTIVE 0x01 + + +// U1UCR (0xFB) - USART 1 UART Control +#define U1UCR_FLUSH 0x80 +#define U1UCR_FLOW 0x40 +#define U1UCR_D9 0x20 +#define U1UCR_BIT9 0x10 +#define U1UCR_PARITY 0x08 +#define U1UCR_SPB 0x04 +#define U1UCR_STOP 0x02 +#define U1UCR_START 0x01 + + +// U1GCR (0xFC) - USART 1 Generic Control +#define U1GCR_CPOL 0x80 +#define U1GCR_CPHA 0x40 +#define U1GCR_ORDER 0x20 +#define U1GCR_BAUD_E 0x1F +#define U1GCR_BAUD_E0 0x01 +#define U1GCR_BAUD_E1 0x02 +#define U1GCR_BAUD_E2 0x04 +#define U1GCR_BAUD_E3 0x08 +#define U1GCR_BAUD_E4 0x10 + + +// U1DBUF (0xF9) - USART 1 Receive/Transmit Data Buffer + +// U1BAUD (0xFA) - USART 1 Baud Rate Control + + +/******************************************************************************* + * I2S + */ + +// 0xDF40: I2SCFG0 - I2S Configuration Register 0 +#define I2SCFG0_TXIEN 0x80 +#define I2SCFG0_RXIEN 0x40 +#define I2SCFG0_ULAWE 0x20 +#define I2SCFG0_ULAWC 0x10 +#define I2SCFG0_TXMONO 0x08 +#define I2SCFG0_RXMONO 0x04 +#define I2SCFG0_MASTER 0x02 +#define I2SCFG0_ENAB 0x01 + + +// 0xDF41: I2SCFG1 - I2S Configuration Register 1 +#define I2SCFG1_WORDS 0xF8 +#define I2SCFG1_WORDS0 0x08 +#define I2SCFG1_WORDS1 0x10 +#define I2SCFG1_WORDS2 0x20 +#define I2SCFG1_WORDS3 0x40 +#define I2SCFG1_WORDS4 0x80 +#define I2SCFG1_TRIGNUM 0x06 +#define I2SCFG1_TRIGNUM0 0x02 +#define I2SCFG1_TRIGNUM1 0x04 +#define I2SCFG1_IOLOC 0x01 + +#define I2SCFG1_TRIGNUM_NO_TRIG (0x00 << 1) +#define I2SCFG1_TRIGNUM_USB_SOF (0x01 << 1) +#define I2SCFG1_TRIGNUM_IOC_1 (0x02 << 1) +#define I2SCFG1_TRIGNUM_T1_CH0 (0x03 << 1) + + + +// 0xDF42: I2SDATL - I2S Data Low Byte + +// 0xDF43: I2SDATH - I2S Data High Byte + +// 0xDF44: I2SWCNT - I2S Word Count Register + +// 0xDF45: I2SSTAT - I2S Status Register +#define I2SSTAT_TXUNF 0x80 +#define I2SSTAT_RXOVF 0x40 +#define I2SSTAT_TXLR 0x20 +#define I2SSTAT_RXLR 0x10 +#define I2SSTAT_TXIRQ 0x08 +#define I2SSTAT_RXIRQ 0x04 +#define I2SSTAT_WCNT 0x03 +#define I2SSTAT_WCNT0 0x01 +#define I2SSTAT_WCNT1 0x02 + +#define I2SSTAT_WCNT_10BIT (0x02) +#define I2SSTAT_WCNT_9BIT (0x01) +#define I2SSTAT_WCNT_9_10BIT (0x02) + + +// 0xDF46: I2SCLKF0 - I2S Clock Configuration Register 0 + +// 0xDF47: I2SCLKF1 - I2S Clock Configuration Register 1 + +// 0xDF48: I2SCLKF2 - I2S Clock Configuration Register 2 + + + + +/******************************************************************************* + * Radio Registers + */ + +// RFIF (0xE9) - RF Interrupt Flags +#define RFIF_IRQ_TXUNF 0x80 +#define RFIF_IRQ_RXOVF 0x40 +#define RFIF_IRQ_TIMEOUT 0x20 +#define RFIF_IRQ_DONE 0x10 +#define RFIF_IRQ_CS 0x08 +#define RFIF_IRQ_PQT 0x04 +#define RFIF_IRQ_CCA 0x02 +#define RFIF_IRQ_SFD 0x01 + + +// RFIM (0x91) - RF Interrupt Mask +#define RFIM_IM_TXUNF 0x80 +#define RFIM_IM_RXOVF 0x40 +#define RFIM_IM_TIMEOUT 0x20 +#define RFIM_IM_DONE 0x10 +#define RFIM_IM_CS 0x08 +#define RFIM_IM_PQT 0x04 +#define RFIM_IM_CCA 0x02 +#define RFIM_IM_SFD 0x01 + + +// 0xDF2F: IOCFG2 - Radio Test Signal Configuration (P1_7) +#define IOCFG2_GDO2_INV 0x40 +#define IOCFG2_GDO2_CFG 0x3F + + +// 0xDF30: IOCFG1 - Radio Test Signal Configuration (P1_6) +#define IOCFG1_GDO_DS 0x80 +#define IOCFG1_GDO1_INV 0x40 +#define IOCFG1_GDO1_CFG 0x3F + + +// 0xDF31: IOCFG0 - Radio Test Signal Configuration (P1_5) +#define IOCFG0_GDO0_INV 0x40 +#define IOCFG0_GDO0_CFG 0x3F + + +// 0xDF03: PKTCTRL1 - Packet Automation Control +#define PKTCTRL1_PQT 0xE0 +#define PKTCTRL1_PQT0 0x20 +#define PKTCTRL1_PQT1 0x40 +#define PKTCTRL1_PQT2 0x80 +#define PKTCTRL1_APPEND_STATUS 0x04 +#define PKTCTRL1_ADR_CHK 0x03 +#define PKTCTRL1_ADR_CHK0 0x01 +#define PKTCTRL1_ADR_CHK1 0x02 + +#define ADR_CHK_NONE (0x00) +#define ADR_CHK_NO_BRDCST (0x01) +#define ADR_CHK_0_BRDCST (0x02) +#define ADR_CHK_0_255_BRDCST (0x03) + + +// 0xDF04: PKTCTRL0 - Packet Automation Control +#define PKTCTRL0_WHITE_DATA 0x40 +#define PKTCTRL0_PKT_FORMAT 0x30 +#define PKTCTRL0_PKT_FORMAT0 0x10 +#define PKTCTRL0_PKT_FORMAT1 0x20 +#define PKTCTRL0_CC2400_EN 0x08 +#define PKTCTRL0_CRC_EN 0x04 +#define PKTCTRL0_LENGTH_CONFIG 0x03 +#define PKTCTRL0_LENGTH_CONFIG0 0x01 + +#define PKT_FORMAT_NORM (0x00) +#define PKT_FORMAT_RAND (0x02) + +#define PKTCTRL0_LENGTH_CONFIG_FIX (0x00) +#define PKTCTRL0_LENGTH_CONFIG_VAR (0x01) + + +// 0xDF05: ADDR - Device Address + +// 0xDF06: CHANNR - Channel Number + +// 0xDF07: FSCTRL1 - Frequency Synthesizer Control (only bit 0-4 used) + +// 0xDF08: FSCTRL0 - Frequency Synthesizer Control + +// 0xDF09: FREQ2 - Frequency Control Word, High Byte + +// 0xDF0A: FREQ1 - Frequency Control Word, Middle Byte + +// 0xDF0B: FREQ0 - Frequency Control Word, Low Byte + +// 0xDF0C: MDMCFG4 - Modem configuration + +// 0xDF0D: MDMCFG3 - Modem Configuration + +// 0xDF0E: MDMCFG2 - Modem Configuration +#define MDMCFG2_DEM_DCFILT_OFF 0x80 +#define MDMCFG2_MOD_FORMAT 0x70 +#define MDMCFG2_MOD_FORMAT0 0x10 +#define MDMCFG2_MOD_FORMAT1 0x20 +#define MDMCFG2_MOD_FORMAT2 0x40 +#define MDMCFG2_MANCHESTER_EN 0x08 +#define MDMCFG2_SYNC_MODE 0x07 +#define MDMCFG2_SYNC_MODE0 0x01 +#define MDMCFG2_SYNC_MODE1 0x02 +#define MDMCFG2_SYNC_MODE2 0x04 + +#define MOD_FORMAT_2_FSK (0x00 << 4) +#define MOD_FORMAT_GFSK (0x01 << 4) +#define MOD_FORMAT_MSK (0x07 << 4) + +#define SYNC_MODE_NO_PRE (0x00) +#define SYNC_MODE_15_16 (0x01) +#define SYNC_MODE_16_16 (0x02) +#define SYNC_MODE_30_32 (0x03) +#define SYNC_MODE_NO_PRE_CS (0x04) // CS = carrier-sense above threshold +#define SYNC_MODE_15_16_CS (0x05) +#define SYNC_MODE_16_16_CS (0x06) +#define SYNC_MODE_30_32_CS (0x07) + + +// 0xDF0F: MDMCG1 - Modem Configuration +#define MDMCG1_FEC_EN 0x80 +#define MDMCG1_NUM_PREAMBLE 0x70 +#define MDMCG1_NUM_PREAMBLE0 0x10 +#define MDMCG1_NUM_PREAMBLE1 0x20 +#define MDMCG1_NUM_PREAMBLE2 0x40 +#define MDMCG1_CHANSPC_E 0x03 +#define MDMCG1_CHANSPC_E0 0x01 +#define MDMCG1_CHANSPC_E1 0x02 + +#define MDMCG1_NUM_PREAMBLE_2 (0x00 << 4) +#define MDMCG1_NUM_PREAMBLE_3 (0x01 << 4) +#define MDMCG1_NUM_PREAMBLE_4 (0x02 << 4) +#define MDMCG1_NUM_PREAMBLE_6 (0x03 << 4) +#define MDMCG1_NUM_PREAMBLE_8 (0x04 << 4) +#define MDMCG1_NUM_PREAMBLE_12 (0x05 << 4) +#define MDMCG1_NUM_PREAMBLE_16 (0x06 << 4) +#define MDMCG1_NUM_PREAMBLE_24 (0x07 << 4) + + +// 0xDF10: MDMCFG0 - Modem Configuration + +// 0xDF11: DEVIATN - Modem Deviation Setting +#define DEVIATN_DEVIATION_E 0x70 +#define DEVIATN_DEVIATION_E0 0x10 +#define DEVIATN_DEVIATION_E1 0x20 +#define DEVIATN_DEVIATION_E2 0x40 +#define DEVIATN_DEVIATION_M 0x07 +#define DEVIATN_DEVIATION_M0 0x01 +#define DEVIATN_DEVIATION_M1 0x02 +#define DEVIATN_DEVIATION_M2 0x04 + + +// 0xDF12: MCSM2 - Main Radio Control State Machine Configuration +#define MCSM2_RX_TIME_RSSI 0x10 +#define MCSM2_RX_TIME_QUAL 0x08 +#define MCSM2_RX_TIME 0x07 + + +// 0xDF13: MCSM1 - Main Radio Control State Machine Configuration +#define MCSM1_CCA_MODE 0x30 +#define MCSM1_CCA_MODE0 0x10 +#define MCSM1_CCA_MODE1 0x20 +#define MCSM1_RXOFF_MODE 0x0C +#define MCSM1_RXOFF_MODE0 0x04 +#define MCSM1_RXOFF_MODE1 0x08 +#define MCSM1_TXOFF_MODE 0x03 +#define MCSM1_TXOFF_MODE0 0x01 +#define MCSM1_TXOFF_MODE1 0x02 + +#define MCSM1_CCA_MODE_ALWAYS (0x00 << 4) +#define MCSM1_CCA_MODE_RSSI0 (0x01 << 4) +#define MCSM1_CCA_MODE_PACKET (0x02 << 4) +#define MCSM1_CCA_MODE_RSSI1 (0x03 << 4) + +#define MCSM1_RXOFF_MODE_IDLE (0x00 << 2) +#define MCSM1_RXOFF_MODE_FSTXON (0x01 << 2) +#define MCSM1_RXOFF_MODE_TX (0x02 << 2) +#define MCSM1_RXOFF_MODE_RX (0x03 << 2) + +#define MCSM1_TXOFF_MODE_IDLE (0x00 << 0) +#define MCSM1_TXOFF_MODE_FSTXON (0x01 << 0) +#define MCSM1_TXOFF_MODE_TX (0x02 << 0) +#define MCSM1_TXOFF_MODE_RX (0x03 << 0) + + +// 0xDF14: MCSM0 - Main Radio Control State Machine Configuration +#define MCSM0_FS_AUTOCAL 0x30 + +#define FS_AUTOCAL_NEVER (0x00 << 4) +#define FS_AUTOCAL_FROM_IDLE (0x01 << 4) +#define FS_AUTOCAL_TO_IDLE (0x02 << 4) +#define FS_AUTOCAL_4TH_TO_IDLE (0x03 << 4) + + +// 0xDF15: FOCCFG - Frequency Offset Compensation Configuration +#define FOCCFG_FOC_BS_CS_GATE 0x20 +#define FOCCFG_FOC_PRE_K 0x18 +#define FOCCFG_FOC_PRE_K0 0x08 +#define FOCCFG_FOC_PRE_K1 0x10 +#define FOCCFG_FOC_POST_K 0x04 +#define FOCCFG_FOC_LIMIT 0x03 +#define FOCCFG_FOC_LIMIT0 0x01 +#define FOCCFG_FOC_LIMIT1 0x02 + +#define FOC_PRE_K_1K (0x00 << 3) +#define FOC_PRE_K_2K (0x02 << 3) +#define FOC_PRE_K_3K (0x03 << 3) +#define FOC_PRE_K_4K (0x04 << 3) + +#define FOC_LIMIT_0 (0x00) +#define FOC_LIMIT_DIV8 (0x01) +#define FOC_LIMIT_DIV4 (0x02) +#define FOC_LIMIT_DIV2 (0x03) + + +// 0xDF16: BSCFG - Bit Synchronization Configuration +#define BSCFG_BS_PRE_KI 0xC0 +#define BSCFG_BS_PRE_KI0 0x40 +#define BSCFG_BS_PRE_KI1 0x80 +#define BSCFG_BS_PRE_KP 0x30 +#define BSCFG_BS_PRE_KP0 0x10 +#define BSCFG_BS_PRE_KP1 0x20 +#define BSCFG_BS_POST_KI 0x08 +#define BSCFG_BS_POST_KP 0x04 +#define BSCFG_BS_LIMIT 0x03 +#define BSCFG_BS_LIMIT0 0x01 +#define BSCFG_BS_LIMIT1 0x02 + +#define BSCFG_BS_PRE_KI_1K (0x00 << 6) +#define BSCFG_BS_PRE_KI_2K (0x01 << 6) +#define BSCFG_BS_PRE_KI_3K (0x02 << 6) +#define BSCFG_BS_PRE_KI_4K (0x03 << 6) + +#define BSCFG_BS_PRE_KP_1K (0x00 << 4) +#define BSCFG_BS_PRE_KP_2K (0x01 << 4) +#define BSCFG_BS_PRE_KP_3K (0x02 << 4) +#define BSCFG_BS_PRE_KP_4K (0x03 << 4) + +#define BSCFG_BS_LIMIT_0 (0x00) +#define BSCFG_BS_LIMIT_3 (0x01) +#define BSCFG_BS_LIMIT_6 (0x02) +#define BSCFG_BS_LIMIT_12 (0x03) + + +// 0xDF17: AGCCTRL2 - AGC Control +#define AGCCTRL2_MAX_DVGA_GAIN 0xC0 +#define AGCCTRL2_MAX_LNA_GAIN 0x38 +#define AGCCTRL2_MAGN_TARGET 0x07 + + +// 0xDF18: AGCCTRL1 - AGC Control +#define AGCCTRL1_AGC_LNA_PRIORITY 0x40 +#define AGCCTRL1_CARRIER_SENSE_REL_THR 0x30 +#define AGCCTRL1_CARRIER_SENSE_ABS_THR 0x0F + + +// 0xDF19: AGCCTRL0 - AGC Control +#define AGCCTRL0_HYST_LEVEL 0xC0 +#define AGCCTRL0_WAIT_TIME 0x30 +#define AGCCTRL0_AGC_FREEZE 0x0C +#define AGCCTRL0_FILTER_LENGTH 0x03 + + +// 0xDF1A: FREND1 - Front End RX Configuration +#define FREND1_LNA_CURRENT 0xC0 +#define FREND1_LNA2MIX_CURRENT 0x30 +#define FREND1_LODIV_BUF_CURRENT_RX 0x0C +#define FREND1_MIX_CURRENT 0x03 + + +// 0xDF1B: FREND0 - Front End TX Configuration +#define FREND0_LODIV_BUF_CURRENT_TX 0x30 + + +// 0xDF1C: FSCAL3 - Frequency Synthesizer Calibration +#define FSCAL3_FSCAL3 0xC0 +#define FSCAL3_CHP_CURR_CAL_EN 0x30 + + +// 0xDF1D: FSCAL2 - Frequency Synthesizer Calibration +#define FSCAL2_VCO_CORE_H_EN 0x20 +#define FSCAL2_FSCAL2 0x1F + + +// 0xDF1E: FSCAL1 - Frequency Synthesizer Calibration + +// 0xDF1F: FSCAL0 - Frequency Synthesizer Calibration + +// 0xDF25: TEST0 - Various Test Settings + + +// RFST (0xE1) - RF Strobe Commands +#define RFST_SFSTXON 0x00 +#define RFST_SCAL 0x01 +#define RFST_SRX 0x02 +#define RFST_STX 0x03 +#define RFST_SIDLE 0x04 +#define RFST_SNOP 0x05 + +// 0xDF3B: MARCSTATE - Main Radio Control State Machine State +#define MARCSTATE_MARC_STATE 0x1F + +#define MARC_STATE_SLEEP 0x00 +#define MARC_STATE_IDLE 0x01 +#define MARC_STATE_VCOON_MC 0x03 +#define MARC_STATE_REGON_MC 0x04 +#define MARC_STATE_MANCAL 0x05 +#define MARC_STATE_VCOON 0x06 +#define MARC_STATE_REGON 0x07 +#define MARC_STATE_STARTCAL 0x08 +#define MARC_STATE_BWBOOST 0x09 +#define MARC_STATE_FS_LOCK 0x0A +#define MARC_STATE_IFADCON 0x0B +#define MARC_STATE_ENDCAL 0x0C +#define MARC_STATE_RX 0x0D +#define MARC_STATE_RX_END 0x0E +#define MARC_STATE_RX_RST 0x0F +#define MARC_STATE_TXRX_SWITCH 0x10 +#define MARC_STATE_RX_OVERFLOW 0x11 +#define MARC_STATE_FSTXON 0x12 +#define MARC_STATE_TX 0x13 +#define MARC_STATE_TX_END 0x14 +#define MARC_STATE_RXTX_SWITCH 0x15 +#define MARC_STATE_TX_UNDERFLOW 0x16 + + + +/***********************************************************************/ +#endif diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/wbsl/wbsl.c b/chronos-ti/Software Projects/RF Access Point/IAR/wbsl/wbsl.c new file mode 100755 index 0000000..2539b29 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/wbsl/wbsl.c @@ -0,0 +1,874 @@ +// ************************************************************************************************* +// +// Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* +// Wireless Update function +// ************************************************************************************************* + +// ************************************************************************************************* +// Include section +#include "wbsl.h" +#include "hal.h" +#include "ioCCxx10_bitdef.h" +#include + + +// ************************************************************************************************* +// Local Functions Define +u8 transmitDMA(unsigned char *src, u8 size); +void rxModeOff(void); +void rxModeOn(void); +void sendDataPacket(void); +void sendInitPacket(void); + + +// ************************************************************************************************* +// Global Variable section + +/* reserve space for the maximum possible peer Link IDs */ +static unsigned char wNumCurrentPeers; + +// extern defines +volatile u8 wbsl_flag; +volatile u8 wbsl_packet_flag; +u8 wbsl_data[WBSL_MAX_PAYLOAD_LENGTH]; +u8 wbsl_data_length = 0; +volatile u8 packet_ready_flag; +u8 TxBuffer[TX_SIZE]; + +u32 total_size_in_bytes; + +TIMER_TABLE_ENTRY timeout_table[MAX_TIMEOUT_TABLE_SIZE]; + +volatile u8 rxtx_flag = 0; + +// Handle number of ACKs sent for an indivudual packet +unsigned char wbsl_number_of_retries; + +unsigned char RxBuffer[255]; +unsigned char discoveryPayload[8] = {7,0,WBSL_AP_ADDRESS,0xBA,0x5E,0xBA,0x11,9}; +unsigned char discoveryAck[4] = {3, 0, WBSL_AP_ADDRESS, 0}; +unsigned char initPacket[] = {5,0,WBSL_AP_ADDRESS,0,0,0}; +unsigned char wbsl_status; +unsigned char wbsl_rftxif = 0; +unsigned char wbsl_irq_done = 0; +unsigned char wbsl_txfifo_filled = 0; +unsigned char update_complete = 0; +unsigned char wbsl_rxtxMode = 0; +unsigned char ed_address; +u16 watchVoltage; + + +//Settings Structure for the RX/TX DMA Channel +DMA_DESC dmachs; + +// Store the total number of packets to be sent to the Watch +//u16 totalPackets = 0; +unsigned int total_packets; +// Keep track of which packet needs to be sent to the Watch +u16 currentPacket = 0; +// Variable to see if the Init Packet has been successfully sent +u8 initOk = 0; + + + +// ************************************************************************************************* +// @fn wbsl_config +// @brief Configures the Radio Settings for WBSL +// @param none +// @return none +// ************************************************************************************************* +void wbsl_config(void) +{ + + // WBSL will set the ones needed + RFIM = 0; + RFIF = 0; // Clear Interrupts + + // OSC=XT, TICKSPD=fref/128, CLKSPD=24MHz + CLKCON = BIT7 | BIT5 | BIT4 | BIT3; + + //Set the SYNC words to be used + SYNC1 = 0xD3; // SYNC1: high nyte of Sync Word + SYNC0 = 0x91; // SYNC0: low nyte of Sync Word + //Setup radio + FSCTRL1 = 0x12; // Frequency synthesizer control. + FSCTRL0 = 0x00; // Frequency synthesizer control. +#ifdef ISM_EU + // 869.525MHz + FREQ2 = 0x24; // Frequency control word, high byte + FREQ1 = 0x3A; // Frequency control word, middle byte + FREQ0 = 0xEE; // Frequency control word, low byte + CHANNR = 0; // Channel number. + PA_TABLE0 = 0x8C; // PA output power setting. +#else +#ifdef ISM_US + // 902MHz (CHANNR=20 --> 906MHz) + FREQ2 = 0x25; // Frequency control word, high byte + FREQ1 = 0x95; // Frequency control word, middle byte + FREQ0 = 0x55; // Frequency control word, low byte + CHANNR = 20; // Channel number. + PA_TABLE0 = 0x8B; // PA output power setting. +#else +#ifdef ISM_LF + // 433.30MHz + FREQ2 = 0x12; // Frequency control word, high byte + FREQ1 = 0x14; // Frequency control word, middle byte + FREQ0 = 0x7A; // Frequency control word, low byte + CHANNR = 0; // Channel number. + PA_TABLE0 = 0x8D; // PA output power setting. +#else + #error "Wrong ISM band specified (valid are ISM_LF, ISM_EU and ISM_US)" +#endif // ISM_LF +#endif // ISM_US +#endif // ISM_EU + MDMCFG4 = 0x1D; // Modem configuration. + MDMCFG3 = 0x55; // Modem configuration. + MDMCFG2 = 0x13; // Modem configuration. + MDMCFG1 = 0x23; // Modem configuration. + MDMCFG0 = 0x11; // Modem configuration. + + DEVIATN = 0x63; // Modem deviation setting (when FSK modulation is enabled). + FREND1 = 0xB6; // Front end RX configuration. + FREND0 = 0x10; // Front end TX configuration. + MCSM0 = 0x18; // Main Radio Control State Machine configuration. + MCSM1 = 0x3C; + MCSM2 = 0x07; + WOREVT1 = 0x87; + WOREVT0 = 0x6B; + WORCTL = 0xF8; + FOCCFG = 0x1D; // Frequency Offset Compensation Configuration. + BSCFG = 0x1C; // Bit synchronization Configuration. + AGCCTRL2 = 0xC7; // AGC control. + AGCCTRL1 = 0x00; // AGC control. + AGCCTRL0 = 0xB0; // AGC control. + FSCAL3 = 0xEA; // Frequency synthesizer calibration. + FSCAL2 = 0x2A; // Frequency synthesizer calibration. + FSCAL1 = 0x00; // Frequency synthesizer calibration. + FSCAL0 = 0x1F; // Frequency synthesizer calibration. + FSTEST = 0x59; + TEST2 = 0x88; // Various test settings. + TEST1 = 0x31; // Various test settings. + TEST0 = 0x09; // Various test settings. + PTEST = 0x7F; + AGCTEST = 0x88; + IOCFG2 = 0x29; + IOCFG1 = 0x1E; + IOCFG0 = 0x1B; + + PKTCTRL1 = 0x06; // Packet automation control. + PKTCTRL0 = 0x45; // Packet automation control. + ADDR = WBSL_AP_ADDRESS; // Device address. + PKTLEN = 0xFE; // Packet length. +} + +// ************************************************************************************************* +// @fn wbsl_RfIsr +// @brief called when the a packet has been received, the actual packet handling is done +// by the DMA. In this function we check for RX Overflow and set the corresponding +// flags to inform the application a packet is ready on the RxBuffer +// @param none +// @return none +// ************************************************************************************************* +void wbsl_RfIsr(void) +{ + u8 rfif_reg = RFIF; + + // We should only be here in RX mode, not in TX mode, nor if RX mode was turned on during CCA + if(wbsl_rxtxMode != WBSL_RX_MODE) + { + RFIF = 0; + return; + } + + // Check for RX Overflow + if((rfif_reg & IRQ_DONE) && (rfif_reg & IRQ_RXOVF)) + { + RFIF &= ~IRQ_DONE; + RFIF &= ~IRQ_RXOVF; + S1CON &= ~(0x03); /* Clear MCU interrupt flag */ + + // Go to IDLE state to get out of overflow + rxModeOff(); + + /* clean out buffer to help protect against spurious frames */ + memset(RxBuffer, 0x00, sizeof(RxBuffer)); + + // Start again RX Mode + rxModeOn(); + + return; + } + + RFIF &= IRQ_DONE; // Clear the RF interrupt + S1CON &= ~(0x03); // Clear CPU int flag + + rxtx_flag = WBSL_RXTX_RECEIVED; //Signal the application that a packet is in RxBuffer +} + +// ************************************************************************************************* +// @fn resetTimer +// @brief resets the timeout table, so that the timer interrupt does not check +// the timeout values +// @param u8 index index of the timer in the timeout_table you want to use +// @return none +// ************************************************************************************************* +void resetTimer(u8 index) +{ + // Check that the index doesn't exceed the number of timeouts we have + if(index >= MAX_TIMEOUT_TABLE_SIZE) + return; + + timeout_table[index].counter = 0; // Reset counter + timeout_table[index].timeout = 0; // Reset timeout (Disable) + timeout_table[index].flag = 0; // Reset Flag +} + +// ************************************************************************************************* +// @fn setTimer +// @brief sets the timeout table values, so that the timer interrupt checks +// these values and sets the timeout flag accordingly +// @param u8 index index of the timer in the timeout_table you want to use +// u16 timeout number of interrupts that have to happen before we set the timeout flag +// @return none +// ************************************************************************************************* +void setTimer(unsigned char index, unsigned int timeout) +{ + // Check that the index doesn't exceed the number of timeouts we have + if(index >= MAX_TIMEOUT_TABLE_SIZE) + return; + + timeout_table[index].counter = 0; // Reset counter + timeout_table[index].flag = 0; // Reset Flag + timeout_table[index].timeout = timeout; // Set timeout +} + +// ************************************************************************************************* +// @fn rxModeOn +// @brief Puts the radio in RX Mode, sets all the needed values to activate the DMA +// and enables the needed interrupts +// @param none +// @return none +// ************************************************************************************************* +void rxModeOn(void) +{ + u8 *dstAdd = RxBuffer; + DMA_DESC *dmach; + dmach = (DMA_DESC *)(&dmachs); + + // Configure the DMA to move a packet from the RFD register to the RxBuffer + SET_WORD(dmach->DESTADDRH, dmach->DESTADDRL, (u16)dstAdd); + SET_WORD(dmach->SRCADDRH, dmach->SRCADDRL, (u16)&X_RFD); // Set the source address to RFD to get Data from the RF + SET_WORD(dmach->LENH, dmach->LENL, 0x0100); + dmach->VLEN = VLEN_1_P_VALOFFIRST_P_2; // Use first byte for transfer count + 2 more status bytes + dmach->PRIORITY = PRI_HIGH; // High Priority. + dmach->M8 = M8_USE_8_BITS; // Transfer all 8 bits in each byte + dmach->IRQMASK = IRQMASK_DISABLE; // Don't generate an interrupt when DMA is done + dmach->DESTINC = DESTINC_1; // Increment the Destination address 1 byte each transfer + dmach->SRCINC = SRCINC_0; // source Address is constant + dmach->TRIG = DMATRIG_RADIO; // RF packet byte received/transmit + dmach->TMODE = TMODE_SINGLE; // Transfer block of data (length len) after each DMA trigger + dmach->WORDSIZE = WORDSIZE_BYTE; // Transfer a byte at a time + + /* abort any DMA transfer that might be in progress */ + DMAARM = DMA_ABORT | BM( WBSL_DMA_CHAN ); + + /* clean out buffer to help protect against spurious frames */ + memset(RxBuffer, 0x00, sizeof(RxBuffer)); + + DMAARM |= BM( WBSL_DMA_CHAN ); + + /* Clear interrupts */ + S1CON &= ~(0x03); /* Clear MCU interrupt flag */ + RFIF &= ~IRQ_DONE; /* Clear the interrupt at the source */ + + //Set Mode to RX + wbsl_rxtxMode = WBSL_RX_MODE; + SRX(); // Strobe RX Mode + + /* enable "receive/transmit done" interrupts */ + RFIM |= IRQ_DONE; +} + +// ************************************************************************************************* +// @fn rxModeOff +// @brief Puts the radio in Idle Mode, disables the DMA and RF Interrupts +// @param none +// @return none +// ************************************************************************************************* +void rxModeOff(void) +{ + /*disable RF receive interrupts */ + RFIM &= ~IRQ_DONE; + + //Go to RF Idle mode + wbsl_rxtxMode = WBSL_IDLE_MODE; + SIDLE(); + while(MARCSTATE != MARC_STATE_IDLE); + + /* Abort any ongoing DMA transfer */ + DMAARM = DMA_ABORT | BM( WBSL_DMA_CHAN ); + + /* Clear any pending DMA interrupts */ + DMAIRQ &= ~BM(WBSL_DMA_CHAN); + + /* Clear interrupts */ + S1CON &= ~(0x03); /* Clear MCU interrupt flag */ + RFIF &= ~IRQ_DONE; /* Clear the interrupt at the source */ +} + +// ************************************************************************************************* +// @fn transmitDMA +// @brief Sets all the needed values to activate the DMA transfer and puts the Radio in Tx Mode +// to transmit the Buffer received, either in CCA Mode or in Force Mode. +// @param u8* src The Buffer which is going to be sent through RF +// u8 size The size of the buffer received +// @return none +// ************************************************************************************************* +u8 transmitDMA(u8 *src, u8 size){ + + u8 retValue = WBSL_TX_RES_SUCCESS; +#ifdef CCA_MODE + u8 ccaRetries; + // u16 backOffDelay; +#endif + + DMA_DESC *dmach; + dmach = (DMA_DESC *)(&dmachs); + + /* Turn off reciever. We can ignore/drop incoming packets during transmit. */ + rxModeOff(); + + // Configure DMA to transfer from the SOURCE to the RFD register + SET_WORD(dmach->DESTADDRH, dmach->DESTADDRL, (u16)&X_RFD); + SET_WORD(dmach->SRCADDRH, dmach->SRCADDRL, (u16)src); // Set the source address to TxBuffer for testing + SET_WORD(dmach->LENH, dmach->LENL, 0x0100); + dmach->VLEN = VLEN_1_P_VALOFFIRST; // Use first byte for transfer count N + 1 + dmach->PRIORITY = PRI_HIGH; // High Priority. + dmach->M8 = M8_USE_8_BITS; // Transfer all 8 bits in each byte + dmach->IRQMASK = IRQMASK_DISABLE; // Don't generate an interrupt when DMA is done + dmach->DESTINC = DESTINC_0; // Destination Address is constant + dmach->SRCINC = SRCINC_1; // Increment the source address 1 byte each transfer + dmach->TRIG = DMATRIG_RADIO; // RF packet byte received/transmit + dmach->TMODE = TMODE_SINGLE; // Transfer block of data (length len) after each DMA trigger + dmach->WORDSIZE = WORDSIZE_BYTE; // Transfer a byte at a time + +#ifdef CCA_MODE + ccaRetries = 4; + + /* =============================================================================== + * CCA Loop + * ============= + */ + while(1) + { + // Arm the DMA Channel used for the WBSL + DMAARM |= BM( WBSL_DMA_CHAN ); + + //Strobe RX to sense air for CCA + SRX(); + + /* Wait for radio to enter the RX mode */ + while(MARCSTATE != MARC_STATE_RX); + + /* Check RSSI */ + { + u16 delay = 30 * 16 * 12; + do{ + if(PKTSTATUS & (CCA_FLAG | CS_FLAG)) + { + break; + } + delay -= 16; + }while(delay > 0); + } + /*End of RSSI Check */ + + // Strobe TX to send the message + STX(); + + if(MARCSTATE != MARC_STATE_RX) + { + // Clear Channel Assessment Passed + /* wait for transmit to complete */ + while(!(RFIF & IRQ_DONE)); + + /* Clear the interrupt flag */ + RFIF &= ~IRQ_DONE; + + break; + } + else + { + // Clear Channel Assessment Failed + if(ccaRetries != 0) + { + // Go to idle during Backoff + SIDLE(); + while(MARCSTATE != MARC_STATE_IDLE); + + //backOffDelay = 10000; + //while(--backOffDelay > 0); + // Back off delay + setTimer(WBSL_TIMEOUT_INDEX,1); + // Wait for either the Timeout or packet received flag + while(!timeout_table[WBSL_TIMEOUT_INDEX].flag); + // Reset timer so that next time it starts fresh + resetTimer(WBSL_TIMEOUT_INDEX); + + ccaRetries--; + } + else /* No CCA retries are left, abort */ + { + /* set return value for failed transmit and break */ + return; + } + + } + } +#else + // Arm the DMA Channel used for the WBSL + DMAARM |= BM( WBSL_DMA_CHAN ); + //Set Mode to TX + wbsl_rxtxMode = WBSL_TX_MODE; + + STX(); // Strobe TX Mode + + /* wait for transmit to complete */ + while(!(RFIF & IRQ_DONE)); + + /* Clear the interrupt flag */ + RFIF &= ~IRQ_DONE; +#endif + // Go to IDLE + rxModeOff(); + + return (retValue); +} + +// ************************************************************************************************* +// @fn wbsl_link +// @brief Checks if a discovery packet has been received, checks the integrity of it +// and sends the discovery ACK +// @param none +// @return u8 status +// WBSL_LINK_FAIL No discovery packet was received +// WBSL_LINK_SUCC Discovery packet received and ACK sent +// ************************************************************************************************* +u8 wbsl_link(void) +{ + u8 status = WBSL_LINK_FAIL; + u8 i = 0; + u8 validPacket = 0; + //u32 timeout = 0; + u8 crcOk = 0; + + //Check if packet was received + if(rxtx_flag == WBSL_RXTX_RECEIVED) + { + // Clear RX Flag + rxtx_flag = 0; + + // Get CRC Status, which is appended in the last bit of the 2nd byte of the status bytes + crcOk = RxBuffer[RxBuffer[0] + WBSL_CRC_STATUS_OFFSET] & CRC_STATUS; + + //Check that packet was a broadcast packet and that the CRC Status is Ok + if((RxBuffer[AP_ADDRESS_OFFSET_RX] == 0x0) && crcOk) + { + + // Check if packet has the discovery Payload + validPacket = 1; + for (i=0; i 0); + // Give time to watch to be on RX Mode + setTimer(WBSL_TIMEOUT_INDEX,1); + // Wait for either the Timeout or packet received flag + while(!timeout_table[WBSL_TIMEOUT_INDEX].flag); + // Reset timer so that next time it starts fresh + resetTimer(WBSL_TIMEOUT_INDEX); + + + LED_ON; + transmitDMA(discoveryAck, sizeof(discoveryAck)); // Send discovery ACK to Watch + LED_OFF; + + status = WBSL_LINK_SUCC; + wbsl_flag = WBSL_STATUS_LINKED; + } + } + } + + return status; +} + +// ************************************************************************************************* +// @fn sendInitPacket +// @brief Send the Init packet to the Watch, which contains the total packets to be received +// during the communication, it also waits for the ACK of the Init packet, if it is not +// received this function will be called again by the main process +// @param none +// @return none +// ************************************************************************************************* +void sendInitPacket(void) +{ + u8 crcOk = 0; + // Initialize the INIT packet to be sent to the newly paired device + // initPacket[INIT_TOTAL_PACKETS_OFFSET] = totalPackets; + initPacket[ED_ADDRESS_OFFSET_TX] = ed_address; + // Test REMOVE + initPacket[5] = wbsl_number_of_retries; + + setTimer(WBSL_TIMEOUT_INDEX,TIMEOUT_FOR_ACK); + + //Wait until packet is ready to be sent or timeout + while(packet_ready_flag != WBSL_PACKET_FULL && !timeout_table[WBSL_TIMEOUT_INDEX].flag ); + + /* Check if the timeout happened before the packet was full, + * if so, trigger the update to stop, there is an error in communication between + * GUI and Dongle has ocurred or a manual stop has been triggered + */ + if(packet_ready_flag != WBSL_PACKET_FULL) + { + setFlag(wbsl_flag, WBSL_TRIGGER_STOP); + return; + } + // Reset timer so that next time it starts fresh + resetTimer(WBSL_TIMEOUT_INDEX); + + LED_ON; // Mark Initiate Transmit + transmitDMA(initPacket, sizeof( initPacket)); + LED_OFF; //Turn off led after packet sent + rxModeOn(); // Turn on RX Mode to wait for the Discovery ACK package + + // Set timeout to receive + setTimer(WBSL_TIMEOUT_INDEX,TIMEOUT_FOR_ACK); + // Wait for either the Timeout or packet received flag + while(!timeout_table[WBSL_TIMEOUT_INDEX].flag && rxtx_flag != WBSL_RXTX_RECEIVED); + + // Reset timer so that next time it starts fresh + resetTimer(WBSL_TIMEOUT_INDEX); + + // Radio off during decoding + rxModeOff(); + + //Check if packet was received + if(rxtx_flag == WBSL_RXTX_RECEIVED) + { + // Get CRC Status, which is appended in the last bit of the 2nd byte of the status bytes + crcOk = RxBuffer[RxBuffer[0] + WBSL_CRC_STATUS_OFFSET] & CRC_STATUS; + // Clear RX Flag + rxtx_flag = 0; + if(RxBuffer[AP_ADDRESS_OFFSET_RX] == WBSL_AP_ADDRESS && + RxBuffer[ED_ADDRESS_OFFSET_RX] == ed_address && + RxBuffer[ED_ADDRESS_OFFSET_RX + 1] == WBSL_ACK_SUCC && + crcOk) + { + // Reset the retry counter for ACKs + wbsl_number_of_retries = 0; + initOk = 1; + + // Flag that the buffer is ready to be filled again + packet_ready_flag = WBSL_PACKET_EMPTY; + // Trigger GUI to send first data packet + wbsl_packet_flag = WBSL_SEND_NEW_DATA_PACKET; + } + } +} + +// ************************************************************************************************* +// @fn sendDataPacket +// @brief Send the next data packet to the watch and waits for the ACK, if received it triggers +// the GUI to send the next packet to be sent to the watch, if not, the same packet will +// be sent again the next time this function is called +// @param none +// @return none +// ************************************************************************************************* +void sendDataPacket(void) +{ + u8 crcOk = 0; + // Change the needed fields for the TX Buffer + TxBuffer[CURRENT_PACKET_NR_OFFSET] = (currentPacket >> 8) & 0xFF; + TxBuffer[CURRENT_PACKET_NR_OFFSET + 1] = currentPacket & 0xFF; + + // Address the packet to the Watch we're synched to + TxBuffer[ED_ADDRESS_OFFSET_TX] = ed_address; + + setTimer(WBSL_TIMEOUT_INDEX,TIMEOUT_FOR_ACK); + + //Wait until packet is ready to be sent or timeout + while(packet_ready_flag != WBSL_PACKET_FULL && !timeout_table[WBSL_TIMEOUT_INDEX].flag ); + + /* Check if the timeout happened before the packet was full, + * if so, trigger the update to stop, there is an error in communication between + * GUI and Dongle has ocurred or a manual stop has been triggered + */ + if(packet_ready_flag != WBSL_PACKET_FULL) + { + setFlag(wbsl_flag, WBSL_TRIGGER_STOP); + return; + } + // Reset timer so that next time it starts fresh + resetTimer(WBSL_TIMEOUT_INDEX); + + // Send packet to ED + LED_ON; + transmitDMA(TxBuffer,TxBuffer[0]+1); + LED_OFF; //Transmit Complete + + rxModeOn(); // Turn on RX Mode to wait for the ACK package + + // Set timeout to receive ACK + setTimer(WBSL_TIMEOUT_INDEX,TIMEOUT_FOR_ACK); + // Wait for either the Timeout or packet received flag + while(!timeout_table[WBSL_TIMEOUT_INDEX].flag && rxtx_flag != WBSL_RXTX_RECEIVED); + + // Radio off during decoding + rxModeOff(); + + // Reset timer so that next time it starts fresh + resetTimer(WBSL_TIMEOUT_INDEX); + + //Check if packet was received and check for status fields + if(rxtx_flag == WBSL_RXTX_RECEIVED) + { + // Get CRC Status, which is appended in the last bit of the 2nd byte of the status bytes + crcOk = RxBuffer[RxBuffer[0] + WBSL_CRC_STATUS_OFFSET] & CRC_STATUS; + + // Clear RX Flag + rxtx_flag = 0; + if(RxBuffer[AP_ADDRESS_OFFSET_RX] == WBSL_AP_ADDRESS && + RxBuffer[ED_ADDRESS_OFFSET_RX] == ed_address && + RxBuffer[ED_ADDRESS_OFFSET_RX + 1] == WBSL_ACK_SUCC && + RxBuffer[ED_ADDRESS_OFFSET_RX + 2] == ((currentPacket >> 8) & 0x7F) && + RxBuffer[ED_ADDRESS_OFFSET_RX + 3] == (currentPacket & 0xFF) && + crcOk) + { + // Reset the retry counter for ACKs + wbsl_number_of_retries = 0; + currentPacket++; + wbsl_status = (currentPacket*100)/total_packets; + // Trigger GUI to send next data packet + wbsl_packet_flag = WBSL_SEND_NEW_DATA_PACKET; + + // Flag that the buffer is ready to be filled again + packet_ready_flag = WBSL_PACKET_EMPTY; + } + } +} + +// ************************************************************************************************* +// @fn wbsl_sendPacket +// @brief This function handles the sending of the different packets that conform the whole +// firmware download, it checks if a packet is ready to be sent and sends it, it also waits +// for the ACK of the packet or a timeout, in the latter case when called again, it will send +// the same packet. +// @param none +// @return none +// ************************************************************************************************* +void wbsl_sendPacket(void) +{ + // Increment the number of retries to send a packet + wbsl_number_of_retries++; + + // Check if too many retries for one packet have been already made + if(wbsl_number_of_retries > WBSL_MAXIMUM_RETRIES) + { + // Trigger the stop of the WBSL Update procedure + setFlag(wbsl_flag, WBSL_TRIGGER_STOP); + setFlag(wbsl_flag, WBSL_STATUS_ERROR); + return; + } + + if(!initOk) + { + // Send the init packet + sendInitPacket(); + } + else if(currentPacket < total_packets) + { + // Send a regular data packet + sendDataPacket(); + } +} + +// ************************************************************************************************* +// @fn wbsl_reset +// @brief Reset variables needed for the WBSL +// @param none +// @return none +// ************************************************************************************************* +void wbsl_reset(void) +{ + wbsl_number_of_retries = 0; + wbsl_status = 0; + wbsl_flag = WBSL_STATUS_LINKING; + // Initialize the packet status flag so that GUI knows when it needs to send next packet + wbsl_packet_flag = WBSL_DISABLED; + currentPacket = 0; + total_packets = 0; + packet_ready_flag = WBSL_PACKET_EMPTY; + initOk = 0; + //Initialize the RX Flag + rxtx_flag = 0; +} + +// ************************************************************************************************* +// @fn wbsl_main +// @brief This is the main routine, which calls the Link function, if succesfull, it keeps calling +// the sendPacket function until all packages has been sent, it also checks for the wbsl_flag +// in case the procedure is stopped before completing the download, either manually or due to an +// error +// @param none +// @return none +// ************************************************************************************************* +void wbsl_main(void) +{ + //u32 txDelay; + + // Assign DMA Configuration Struct to the DMA Channel 0 + DMA0CFGH = HIBYTE( &dmachs ); + DMA0CFGL = LOBYTE( &dmachs ); + + // Initialize used variables + wbsl_reset(); + + //Init TX Buffer + TxBuffer[0] = sizeof(TxBuffer) - 1; // Substract the length field (1 byte) + TxBuffer[AP_ADDRESS_OFFSET_TX] = WBSL_AP_ADDRESS; // Include my address in all packets + + //Update WBSL Flag + wbsl_flag = WBSL_STATUS_LINKING; + + //Enable/Disable all the needed RF interrupts + INT_ENABLE(INUM_RFTXRX, INT_OFF); // Disable RXTX Interrupt + INT_ENABLE(INUM_RF, INT_ON); // Enable General RF Interrupt + + LED_OFF; + + wNumCurrentPeers = 0; + + wbsl_status = 0; + + // Make sure radio is in IDLE Mode before starting + rxModeOff(); + + while(1) + { + if(!wNumCurrentPeers) + { + rxModeOn(); // Turn on RX Mode to wait for the Discovery package + //First try pairing with an End Device + while(1) + { + // Try to link with an end device + if(wbsl_link() == WBSL_LINK_SUCC) + { + wbsl_flag = WBSL_STATUS_LINKED; + //Keep track of how many peers are connected + wNumCurrentPeers++; + // Trigger GUI to send first info packet (total bytes of file) + wbsl_packet_flag = WBSL_SEND_INFO_PACKET; + rxModeOff(); // Turn off RX Mode after succesfully linking with ED + break; + } + + // If GUI has triggered to stop WBSL, do so + if(getFlag(wbsl_flag,WBSL_TRIGGER_STOP)) + { + break; + } + } + } + + // If GUI or Watch has triggered to stop WBSL, do so, but leave everything + // in a workable state. + if(getFlag(wbsl_flag,WBSL_TRIGGER_STOP)) + { + // Immediately turn off RF interrupts + INT_ENABLE(INUM_RFTXRX, INT_OFF); + INT_ENABLE(INUM_RF, INT_OFF); + RFIM &= ~IRQ_DONE; // Disable Packet Received/Transmitted Interrupt + RFIF = 0; // Clear Interrupts + //Put radio in Idle mode + rxModeOff(); + + break; + } + + //Keep downloading update image + if (currentPacket < total_packets || !initOk) + { + // txDelay = 6000; + // while(txDelay-->0); + wbsl_sendPacket(); // Send the packet + + // Delay to give time to watch to be in RX after sending ACK + setTimer(WBSL_TIMEOUT_INDEX,1); + // Wait for either the Timeout or packet received flag + while(!timeout_table[WBSL_TIMEOUT_INDEX].flag); + // Reset timer so that next time it starts fresh + resetTimer(WBSL_TIMEOUT_INDEX); + } + + //If the update has complete, finish the Transmission and turn off WBSL + if(update_complete || currentPacket >= total_packets) + { + setFlag(wbsl_flag, WBSL_TRIGGER_STOP); + } + } + + wNumCurrentPeers = 0; + // Set timeout to receive ACK + // This is to allow the GUI to read the last progress status in case it reached 100 + setTimer(WBSL_TIMEOUT_INDEX,300); + while(!timeout_table[WBSL_TIMEOUT_INDEX].flag); + // Reset timer before exiting + resetTimer(WBSL_TIMEOUT_INDEX); +} \ No newline at end of file diff --git a/chronos-ti/Software Projects/RF Access Point/IAR/wbsl/wbsl.h b/chronos-ti/Software Projects/RF Access Point/IAR/wbsl/wbsl.h new file mode 100755 index 0000000..97a7a72 --- /dev/null +++ b/chronos-ti/Software Projects/RF Access Point/IAR/wbsl/wbsl.h @@ -0,0 +1,213 @@ +// ************************************************************************************************* +// +// Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************************************* + +#ifndef __WBSL_H +#define __WBSL_H + +#include + +//#define CCA_MODE + +// ************************************************************************************************* +// Defines section +#define BIT0 (0x0001) +#define BIT1 (0x0002) +#define BIT2 (0x0004) +#define BIT3 (0x0008) +#define BIT4 (0x0010) +#define BIT5 (0x0020) +#define BIT6 (0x0040) +#define BIT7 (0x0080) +#define BIT8 (0x0100) +#define BIT9 (0x0200) +#define BITA (0x0400) +#define BITB (0x0800) +#define BITC (0x1000) +#define BITD (0x2000) +#define BITE (0x4000) +#define BITF (0x8000) + + +// Macros +#define getFlag(val, flag) ((val&flag)==flag) +#define setFlag(val, flag) (val|=flag) +#define clearFlag(val, flag) (val&=(~flag)) +#define toggleFlag(val, flag) (val^=flag) + + +typedef struct { + unsigned int counter; + unsigned int timeout; + unsigned char flag; +}TIMER_TABLE_ENTRY; + +/* bit value */ +#ifndef BV +#define BV(n) (1 << (n)) +#endif + +#define WBSL_AP_ADDRESS (0xCA) +#define WBSL_MAX_PAYLOAD_LENGTH (247u) + +#if WBSL_MAX_PAYLOAD_LENGTH < 50 +#error "MAXIMUM PAYLOAD CANNOT BE LOWER TO 50 BYTES, DUE TO PROTOCOL TIMING CONSTRAINTS" +#elif WBSL_MAX_PAYLOAD_LENGTH > 247 +#error "MAXIMUM PAYLOAD CANNOT BE HIGHER THAN 247 BYTES. +#endif + +#define WBSL_OVERHEAD_LENGTH (6u) +#define WBSL_TOTAL_LENGTH WBSL_MAX_PAYLOAD_LENGTH + WBSL_OVERHEAD_LENGTH +#define DISCOVERY_PAYLOAD_LENGTH (4u) +#define DISCOVERY_OVERHEAD_LENGTH (3u) +#define AP_ADDRESS_OFFSET_RX (1u) +#define ED_ADDRESS_OFFSET_RX (2u) +#define BATTERY_VOLTAGE_OFFSET (3u) + +#define WBSL_CRC_STATUS_OFFSET (2) +#define CRC_STATUS (0x80) + +#define WBSL_OPCODE_OFFSET (5u) + +#define AP_ADDRESS_OFFSET_TX (2u) +#define ED_ADDRESS_OFFSET_TX (1u) + +#define DISCOVERY_ACK_OFFSET (3u) +#define INIT_TOTAL_PACKETS_OFFSET (3u) +#define CURRENT_PACKET_NR_OFFSET (3u) + +#define WBSL_TX_RES_FAILED (0) +#define WBSL_TX_RES_SUCCESS (1u) + +#define WBSL_ACK_PKT_SIZE (5u) + +/* DMA channel number */ +#define WBSL_DMA_CHAN 0 +#define DMA_ABORT (0x80) + +// Battery end of life voltage threshold -> do not accept connection +#define BATTERY_LOW_THRESHOLD (240u) + +// Flag for status information and external control through USB driver +extern volatile unsigned char wbsl_flag; +#define WBSL_STATUS_LINKING (BIT0) +#define WBSL_STATUS_LINKED (BIT1) +#define WBSL_STATUS_ERROR (BIT2) +#define WBSL_TRIGGER_SEND_DATA (BIT3) +#define WBSL_TRIGGER_RECEIVED_DATA (BIT4) +#define WBSL_TRIGGER_STOP (BIT5) +#define WBSL_TRIGGER_SEND_CMD (BIT6) +#define WBSL_LOW_BATT (BIT7) + +// Flag to check if a new packet is needed from the GUI +extern volatile unsigned char wbsl_packet_flag; +#define WBSL_DISABLED (BIT0) +#define WBSL_PROCESSING_PACKET (BIT1) +#define WBSL_SEND_INFO_PACKET (BIT2) +#define WBSL_SEND_NEW_DATA_PACKET (BIT3) +#define WBSL_ERROR (BIT7) + +// Flag for status information, to see if WBSL is in RX/TX/IDLE mode +extern volatile unsigned char wbslMode_flag; +#define WBSL_IDLE_MODE (BIT0) +#define WBSL_RX_MODE (BIT1) +#define WBSL_TX_MODE (BIT2) + +extern volatile unsigned char rxtx_flag; +#define WBSL_RXTX_RECEIVED (BIT0) +#define WBSL_RXTX_SEND (BIT1) + +// Values for linking failed or successful +#define WBSL_LINK_FAIL 0 +#define WBSL_LINK_SUCC 1 + +// Values for Packet ACK +#define WBSL_ACK_FAIL (0) +#define WBSL_ACK_SUCC (1u) + +#define TIMEOUT_FOR_ACK (440) + +#define WBSL_MAXIMUM_RETRIES (5u) + +extern volatile unsigned char packet_ready_flag; +#define WBSL_PACKET_EMPTY (BIT0) +#define WBSL_PACKET_FILLING (BIT1) +#define WBSL_PACKET_FULL (BIT2) +#define WBSL_PACKET_ADDRESS (BIT3) + +//WBSL OP Code Type +#define WBSL_INIT_PACKET 0x00 +#define WBSL_ADDRESS_PACKET 0x01 +#define WBSL_NORMAL_PACKET 0x02 + +#define ADDRESS_FLAG_BIT 0x80 + +#define MAX_TIMEOUT_TABLE_SIZE (1u) +#define WBSL_TIMEOUT_INDEX (0u) + +// 1 = data in buffer, 0 = buffer empty +extern unsigned char wbsl_sync_buffer_status; +extern unsigned char ed_address; + + +extern unsigned char wbsl_data[WBSL_MAX_PAYLOAD_LENGTH]; +extern unsigned char wbsl_status; +extern unsigned char wbsl_txfifo_filled; + +extern unsigned long total_size_in_bytes; +extern unsigned int total_packets; + +#define TX_SIZE WBSL_TOTAL_LENGTH +extern unsigned char TxBuffer[TX_SIZE]; +extern unsigned char initPacket[6]; + +// Table that stores the timeout value, this will be used by Timer4 and WBSL.c to detect timeout in ACK +extern TIMER_TABLE_ENTRY timeout_table[MAX_TIMEOUT_TABLE_SIZE]; + + +// Function Prototypes +extern void wbsl_main(void); +extern void wbsl_config(void); +extern void wbsl_RfIsr(void); +extern void wbsl_RfTxRxIsr(void); +extern void wbsl_sendPacket(void); +extern void wbsl_stopRadio(void); +extern void wbsl_enableRadio(void); +extern unsigned char wbsl_link(void); +extern void wbsl_reset(void); + +extern void resetTimer(unsigned char index); +extern void setTimer(unsigned char index, unsigned int timeout); + +#endif diff --git a/chronos-ti/uninstall b/chronos-ti/uninstall new file mode 100755 index 0000000..ee7eacb Binary files /dev/null and b/chronos-ti/uninstall differ