1、rfbsl.c
2、rfbsl.h
3、ports.c
4、ports.h
代码阅读笔记:
rfbsl.c 的主要行为是通过 rfbsl.h 中定义的这一行代码起作用的:
// Entry point of of the Flash Updater in BSL memory
#define CALL_RFSBL() ((void (*)())0x1000)()
也就是说,它什么也不做,只是提供了一个 0x1000 的地址,这个地址是flash中储存BSL的存储区域首地址,BSL在CC430F6137的FLASH分布如下:
rfbsl.c
// *************************************************************************************************
//
// 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"
// *************************************************************************************************
// @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;
// 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_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)
{
display_chars(LCD_SEG_L2_5_0, (u8 *)" RFBSL", SEG_ON);
}
}
rfbsl.h
// *************************************************************************************************
//
// 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)()
#endif /*RFBSL_H_*/
ports.c
// *************************************************************************************************
//
// 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)
{
u8 int_flag, int_enable;
u8 buzzer = 0;
u8 simpliciti_button_event = 0;
static u8 simpliciti_button_repeat = 0;
// Clear button flags
button.all_flags = 0;
// Remember interrupt enable bits
int_enable = BUTTONS_IE;
// 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;
// Generate button click
buzzer = 1;
}
}
// ---------------------------------------------------
// NUM button IRQ
else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN))
{
// Filter bouncing noise
if (BUTTON_NUM_IS_PRESSED)
{
button.flag.num = 1;
// Generate button click
buzzer = 1;
}
}
// ---------------------------------------------------
// 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)
{
button.flag.backlight = 1;
}
}
}
// 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
Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT));
// Check if this button event is short enough
if (BUTTON_STAR_IS_PRESSED) button.flag.star = 0;
if (BUTTON_NUM_IS_PRESSED) button.flag.num = 0;
}
// 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();
}
}
ports.h
// *************************************************************************************************
//
// 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 BUTTONS_H_
#define BUTTONS_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)
// 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
} 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;
u8 num_timeout;
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 /*BUTTONS_H_*/