[Tinyos-beta-commits]
CVS: tinyos-1.x/beta/Deluge/Deluge/TOSBoot/msp430
HPLUSART0M.nc, NONE, 1.1 ProgFlashM.nc, NONE, 1.1 hardware.h,
NONE, 1.1 msp430hardware.h, NONE, 1.1
Jonathan Hui
jwhui at users.sourceforge.net
Thu Apr 21 10:31:43 PDT 2005
- Previous message: [Tinyos-beta-commits] CVS: tinyos-1.x/beta/Deluge/Deluge/TOSBoot
Makefile, 1.2, 1.3 TOSBoot.nc, 1.2, 1.3 TOSBootM.nc, 1.3,
1.4 TOSBootProgFlashM.nc, 1.2, NONE TOSBootSTM25PC.nc, 1.2,
NONE TOSBootSTM25PM.nc, 1.3, NONE
- Next message: [Tinyos-beta-commits]
CVS: tinyos-1.x/beta/Deluge/Deluge/TOSBoot/stm25p
STM25PC.nc, NONE, 1.1 STM25PM.nc, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-1.x/beta/Deluge/Deluge/TOSBoot/msp430
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9078/msp430
Added Files:
HPLUSART0M.nc ProgFlashM.nc hardware.h msp430hardware.h
Log Message:
- Cleaned up bootloader for msp430. Reduces code size by more than
half and now sits at under 2K of code.
--- NEW FILE: HPLUSART0M.nc ---
/*
* Copyright (c) 2004-2005, Technische Universitat Berlin
* All rights reserved.
*
* 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 the Technische Universitat Berlin 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.
*
* - Description ----------------------------------------------------------
* Implementation of USART0 lowlevel functionality - stateless.
* Setting a mode will by default disable USART-Interrupts.
* - Revision -------------------------------------------------------------
* $Revision: 1.1 $
* $Date: 2005/04/21 17:31:41 $
* @author: Jan Hauer (hauer at tkn.tu-berlin.de)
* @author: Joe Polastre
* ========================================================================
*/
module HPLUSART0M {
provides interface HPLUSARTControl as USARTControl;
provides interface HPLUSARTFeedback as USARTData;
provides interface HPLI2CInterrupt;
}
implementation
{
MSP430REG_NORACE(ME1);
MSP430REG_NORACE(IFG1);
MSP430REG_NORACE(U0TCTL);
uint16_t l_br;
uint8_t l_mctl;
uint8_t l_ssel;
/*
TOSH_SIGNAL(UART0RX_VECTOR) {
uint8_t temp = U0RXBUF;
signal USARTData.rxDone(temp);
}
TOSH_SIGNAL(UART0TX_VECTOR) {
if (call USARTControl.isI2C())
signal HPLI2CInterrupt.fired();
else
signal USARTData.txDone();
}
*/
default async event void HPLI2CInterrupt.fired() { }
async command bool USARTControl.isSPI() {
bool _ret = FALSE;
// atomic{
if (ME1 & USPIE0)
_ret = TRUE;
// }
return _ret;
}
async command bool USARTControl.isUART() {
bool _ret = FALSE;
// atomic {
if ((ME1 & UTXE0) && (ME1 & URXE0) &&
TOSH_IS_URXD0_MODFUNC() &&
TOSH_IS_UTXD0_MODFUNC())
_ret = TRUE;
// }
return _ret;
}
async command bool USARTControl.isUARTtx() {
bool _ret = FALSE;
// atomic {
if ((ME1 & UTXE0) &&
TOSH_IS_UTXD0_MODFUNC() &&
TOSH_IS_URXD0_IOFUNC())
_ret = TRUE;
// }
return _ret;
}
async command bool USARTControl.isUARTrx() {
bool _ret = FALSE;
// atomic {
if ((ME1 & URXE0) &&
TOSH_IS_URXD0_MODFUNC() &&
TOSH_IS_UTXD0_IOFUNC())
_ret = TRUE;
// }
return _ret;
}
async command bool USARTControl.isI2C() {
bool _ret = FALSE;
#ifdef __msp430_have_usart0_with_i2c
// atomic {
if ((U0CTL & I2C) && (U0CTL & SYNC) && (U0CTL & I2CEN))
_ret = TRUE;
// }
#endif
return _ret;
}
async command msp430_usartmode_t USARTControl.getMode() {
if (call USARTControl.isUART())
return USART_UART;
else if (call USARTControl.isUARTrx())
return USART_UART_RX;
else if (call USARTControl.isUARTtx())
return USART_UART_TX;
else if (call USARTControl.isSPI())
return USART_SPI;
else if (call USARTControl.isI2C())
return USART_I2C;
else
return USART_NONE;
}
/**
* Sets the USART mode to one of the options from msp430_usartmode_t
* defined in MSP430USART.h
*/
async command void USARTControl.setMode(msp430_usartmode_t _mode) {
switch (_mode) {
case USART_UART:
call USARTControl.setModeUART();
break;
case USART_UART_RX:
call USARTControl.setModeUART_RX();
break;
case USART_UART_TX:
call USARTControl.setModeUART_TX();
break;
case USART_SPI:
call USARTControl.setModeSPI();
break;
case USART_I2C:
call USARTControl.setModeI2C();
break;
default:
break;
}
}
async command void USARTControl.enableUART() {
TOSH_SEL_UTXD0_MODFUNC();
TOSH_SEL_URXD0_MODFUNC();
ME1 |= (UTXE0 | URXE0); // USART0 UART module enable
}
async command void USARTControl.disableUART() {
ME1 &= ~(UTXE0 | URXE0); // USART0 UART module enable
TOSH_SEL_UTXD0_IOFUNC();
TOSH_SEL_URXD0_IOFUNC();
}
async command void USARTControl.enableUARTTx() {
TOSH_SEL_UTXD0_MODFUNC();
ME1 |= UTXE0; // USART0 UART Tx module enable
}
async command void USARTControl.disableUARTTx() {
ME1 &= ~UTXE0; // USART0 UART Tx module enable
TOSH_SEL_UTXD0_IOFUNC();
}
async command void USARTControl.enableUARTRx() {
TOSH_SEL_URXD0_MODFUNC();
ME1 |= URXE0; // USART0 UART Rx module enable
}
async command void USARTControl.disableUARTRx() {
ME1 &= ~URXE0; // USART0 UART Rx module disable
TOSH_SEL_URXD0_IOFUNC();
}
async command void USARTControl.enableSPI() {
TOSH_SEL_SIMO0_MODFUNC();
TOSH_SEL_SOMI0_MODFUNC();
TOSH_SEL_UCLK0_MODFUNC();
ME1 |= USPIE0; // USART0 SPI module enable
}
async command void USARTControl.disableSPI() {
ME1 &= ~USPIE0; // USART0 SPI module disable
TOSH_SEL_SIMO0_IOFUNC();
TOSH_SEL_SOMI0_IOFUNC();
TOSH_SEL_UCLK0_IOFUNC();
}
async command void USARTControl.enableI2C() {
#ifdef __msp430_have_usart0_with_i2c
/*atomic*/ U0CTL |= I2C | I2CEN | SYNC;
#endif
}
async command void USARTControl.disableI2C() {
#ifdef __msp430_have_usart0_with_i2c
// if (call USARTControl.isI2C())
/*atomic*/ U0CTL &= ~(I2C | I2CEN | SYNC);
#endif
}
async command void USARTControl.setModeSPI() {
// check if we are already in SPI mode
// if (call USARTControl.getMode() == USART_SPI)
// return;
call USARTControl.disableUART();
call USARTControl.disableI2C();
// atomic {
TOSH_SEL_SIMO0_MODFUNC();
TOSH_SEL_SOMI0_MODFUNC();
TOSH_SEL_UCLK0_MODFUNC();
IE1 &= ~(UTXIE0 | URXIE0); // interrupt disable
U0CTL = SWRST;
U0CTL |= CHAR | SYNC | MM; // 8-bit char, SPI-mode, USART as master
U0CTL &= ~(0x20);
U0TCTL = STC ; // 3-pin
U0TCTL |= CKPH; // half-cycle delayed UCLK
/*
if (l_ssel & 0x80) {
U0TCTL &= ~(SSEL_0 | SSEL_1 | SSEL_2 | SSEL_3);
U0TCTL |= (l_ssel & 0x7F);
}
else {
*/
U0TCTL &= ~(SSEL_0 | SSEL_1 | SSEL_2 | SSEL_3);
U0TCTL |= SSEL_SMCLK; // use SMCLK, assuming 1MHz
// }
/*
if (l_br != 0) {
U0BR0 = l_br & 0x0FF;
U0BR1 = (l_br >> 8) & 0x0FF;
}
else {
*/
U0BR0 = 0x02; // as fast as possible
U0BR1 = 0x00;
// }
U0MCTL = 0;
ME1 &= ~(UTXE0 | URXE0); //USART UART module disable
ME1 |= USPIE0; // USART SPI module enable
U0CTL &= ~SWRST;
IFG1 &= ~(UTXIFG0 | URXIFG0);
IE1 &= ~(UTXIE0 | URXIE0); // interrupt disabled
// }
return;
}
void setUARTModeCommon() {
// atomic {
U0CTL = SWRST;
U0CTL |= CHAR; // 8-bit char, UART-mode
U0RCTL &= ~URXEIE; // even erroneous characters trigger interrupts
U0CTL = SWRST;
U0CTL |= CHAR; // 8-bit char, UART-mode
if (l_ssel & 0x80) {
U0TCTL &= ~(SSEL_0 | SSEL_1 | SSEL_2 | SSEL_3);
U0TCTL |= (l_ssel & 0x7F);
}
else {
U0TCTL &= ~(SSEL_0 | SSEL_1 | SSEL_2 | SSEL_3);
U0TCTL |= SSEL_ACLK; // use ACLK, assuming 32khz
}
if ((l_mctl != 0) || (l_br != 0)) {
U0BR0 = l_br & 0x0FF;
U0BR1 = (l_br >> 8) & 0x0FF;
U0MCTL = l_mctl;
}
else {
U0BR0 = 0x03; // 9600 baud
U0BR1 = 0x00;
U0MCTL = 0x4A;
}
ME1 &= ~USPIE0; // USART0 SPI module disable
ME1 |= (UTXE0 | URXE0); //USART0 UART module enable;
U0CTL &= ~SWRST;
IFG1 &= ~(UTXIFG0 | URXIFG0);
IE1 &= ~(UTXIE0 | URXIE0); // interrupt disabled
// }
return;
}
async command void USARTControl.setModeUART_TX() {
// check if we are already in UART mode
if (call USARTControl.getMode() == USART_UART_TX)
return;
call USARTControl.disableSPI();
call USARTControl.disableI2C();
call USARTControl.disableUART();
// atomic {
TOSH_SEL_UTXD0_MODFUNC();
TOSH_SEL_URXD0_IOFUNC();
// }
setUARTModeCommon();
return;
}
async command void USARTControl.setModeUART_RX() {
// check if we are already in UART mode
if (call USARTControl.getMode() == USART_UART_RX)
return;
call USARTControl.disableSPI();
call USARTControl.disableI2C();
call USARTControl.disableUART();
// atomic {
TOSH_SEL_URXD0_MODFUNC();
TOSH_SEL_UTXD0_IOFUNC();
// }
setUARTModeCommon();
return;
}
async command void USARTControl.setModeUART() {
// check if we are already in UART mode
if (call USARTControl.getMode() == USART_UART)
return;
call USARTControl.disableSPI();
call USARTControl.disableI2C();
call USARTControl.disableUART();
// atomic {
TOSH_SEL_UTXD0_MODFUNC();
TOSH_SEL_URXD0_MODFUNC();
// }
setUARTModeCommon();
return;
}
// i2c enable bit is not set by default
async command void USARTControl.setModeI2C() {
#ifdef __msp430_have_usart0_with_i2c
// check if we are already in I2C mode
if (call USARTControl.getMode() == USART_I2C)
return;
call USARTControl.disableUART();
call USARTControl.disableSPI();
// atomic {
TOSH_MAKE_SIMO0_INPUT();
TOSH_MAKE_UCLK0_INPUT();
TOSH_SEL_SIMO0_MODFUNC();
TOSH_SEL_UCLK0_MODFUNC();
IE1 &= ~(UTXIE0 | URXIE0); // interrupt disable
U0CTL = SWRST;
U0CTL |= SYNC | I2C; // 7-bit addr, I2C-mode, USART as master
U0CTL &= ~I2CEN;
U0CTL |= MST;
I2CTCTL = I2CSSEL_2; // use 1MHz SMCLK as the I2C reference
I2CPSC = 0x00; // I2C CLK runs at 1MHz/10 = 100kHz
I2CSCLH = 0x03;
I2CSCLL = 0x03;
I2CIE = 0; // clear all I2C interrupt enables
I2CIFG = 0; // clear all I2C interrupt flags
// }
#endif
return;
}
async command void USARTControl.setClockSource(uint8_t source) {
// atomic {
l_ssel = source | 0x80;
U0TCTL &= ~(SSEL_0 | SSEL_1 | SSEL_2 | SSEL_3);
U0TCTL |= (l_ssel & 0x7F);
// }
}
async command void USARTControl.setClockRate(uint16_t baudrate, uint8_t mctl) {
// atomic {
l_br = baudrate;
l_mctl = mctl;
U0BR0 = baudrate & 0x0FF;
U0BR1 = (baudrate >> 8) & 0x0FF;
U0MCTL = mctl;
// }
}
async command result_t USARTControl.isTxIntrPending(){
if (IFG1 & UTXIFG0){
IFG1 &= ~UTXIFG0;
return SUCCESS;
}
return FAIL;
}
async command result_t USARTControl.isTxEmpty(){
if (U0TCTL & TXEPT) {
return SUCCESS;
}
return FAIL;
}
async command result_t USARTControl.isRxIntrPending(){
if (IFG1 & URXIFG0){
IFG1 &= ~URXIFG0;
return SUCCESS;
}
return FAIL;
}
async command result_t USARTControl.disableRxIntr(){
/*atomic*/ IE1 &= ~URXIE0;
return SUCCESS;
}
async command result_t USARTControl.disableTxIntr(){
/*atomic*/ IE1 &= ~UTXIE0;
return SUCCESS;
}
async command result_t USARTControl.enableRxIntr(){
// atomic {
IFG1 &= ~URXIFG0;
IE1 |= URXIE0;
// }
return SUCCESS;
}
async command result_t USARTControl.enableTxIntr(){
// atomic {
IFG1 &= ~UTXIFG0;
IE1 |= UTXIE0;
// }
return SUCCESS;
}
async command result_t USARTControl.tx(uint8_t data){
/*atomic*/ U0TXBUF = data;
return SUCCESS;
}
async command uint8_t USARTControl.rx(){
uint8_t value;
/*atomic*/ value = U0RXBUF;
return value;
}
default async event result_t USARTData.txDone() { return SUCCESS; }
default async event result_t USARTData.rxDone(uint8_t data) { return SUCCESS; }
}
--- NEW FILE: ProgFlashM.nc ---
// $Id: ProgFlashM.nc,v 1.1 2005/04/21 17:31:41 jwhui Exp $
/* tab:4
*
*
* "Copyright (c) 2000-2004 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
*/
/**
* @author Jonathan Hui <jwhui at cs.berkeley.edu>
*/
module ProgFlashM {
provides {
interface TOSBootProgFlash as ProgFlash;
}
}
implementation {
command result_t ProgFlash.write(uint32_t addr, uint8_t* buf, uint16_t len) {
volatile uint16_t *flashAddr = (uint16_t*)(uint16_t)addr;
uint16_t *wordBuf = (uint16_t*)buf;
uint16_t i = 0;
FCTL2 = FWKEY + FSSEL1 + FN2;
FCTL3 = FWKEY;
FCTL1 = FWKEY + ERASE;
*flashAddr = 0;
FCTL1 = FWKEY + WRT;
if (addr == (BL_MSP_RESET_ADDR/BL_INT_PAGE_SIZE)*BL_INT_PAGE_SIZE)
*(uint16_t*)BL_MSP_RESET_ADDR = BOOTLOADER_START;
for (i = 0; i < len / sizeof(uint16_t); i++) {
if ((uint16_t)flashAddr != BL_MSP_RESET_ADDR)
*flashAddr++ = wordBuf[i];
}
FCTL1 = FWKEY;
FCTL3 = FWKEY + LOCK;
return SUCCESS;
}
}
--- NEW FILE: hardware.h ---
#ifndef _H_hardware_h
#define _H_hardware_h
#include "msp430hardware.h"
#include "MSP430ADC12.h"
#include "CC2420Const.h"
#include "AM.h"
// LEDs
TOSH_ASSIGN_PIN(RED_LED, 5, 4);
TOSH_ASSIGN_PIN(GREEN_LED, 5, 5);
TOSH_ASSIGN_PIN(YELLOW_LED, 5, 6);
// CC2420 RADIO #defines
TOSH_ASSIGN_PIN(RADIO_CSN, 4, 2);
TOSH_ASSIGN_PIN(RADIO_VREF, 4, 5);
TOSH_ASSIGN_PIN(RADIO_RESET, 4, 6);
TOSH_ASSIGN_PIN(RADIO_FIFOP, 1, 0);
TOSH_ASSIGN_PIN(RADIO_SFD, 4, 1);
TOSH_ASSIGN_PIN(RADIO_GIO0, 1, 3);
TOSH_ASSIGN_PIN(RADIO_FIFO, 1, 3);
TOSH_ASSIGN_PIN(RADIO_GIO1, 1, 4);
TOSH_ASSIGN_PIN(RADIO_CCA, 1, 4);
TOSH_ASSIGN_PIN(CC_FIFOP, 1, 0);
TOSH_ASSIGN_PIN(CC_FIFO, 1, 3);
TOSH_ASSIGN_PIN(CC_SFD, 4, 1);
TOSH_ASSIGN_PIN(CC_VREN, 4, 5);
TOSH_ASSIGN_PIN(CC_RSTN, 4, 6);
// UART pins
TOSH_ASSIGN_PIN(SOMI0, 3, 2);
TOSH_ASSIGN_PIN(SIMO0, 3, 1);
TOSH_ASSIGN_PIN(UCLK0, 3, 3);
TOSH_ASSIGN_PIN(UTXD0, 3, 4);
TOSH_ASSIGN_PIN(URXD0, 3, 5);
TOSH_ASSIGN_PIN(UTXD1, 3, 6);
TOSH_ASSIGN_PIN(URXD1, 3, 7);
TOSH_ASSIGN_PIN(UCLK1, 5, 3);
TOSH_ASSIGN_PIN(SOMI1, 5, 2);
TOSH_ASSIGN_PIN(SIMO1, 5, 1);
// ADC
TOSH_ASSIGN_PIN(ADC0, 6, 0);
TOSH_ASSIGN_PIN(ADC1, 6, 1);
TOSH_ASSIGN_PIN(ADC2, 6, 2);
TOSH_ASSIGN_PIN(ADC3, 6, 3);
TOSH_ASSIGN_PIN(ADC4, 6, 4);
TOSH_ASSIGN_PIN(ADC5, 6, 5);
TOSH_ASSIGN_PIN(ADC6, 6, 6);
TOSH_ASSIGN_PIN(ADC7, 6, 7);
// HUMIDITY
TOSH_ASSIGN_PIN(HUM_SDA, 1, 5);
TOSH_ASSIGN_PIN(HUM_SCL, 1, 6);
TOSH_ASSIGN_PIN(HUM_PWR, 1, 7);
// GIO pins
TOSH_ASSIGN_PIN(GIO0, 2, 0);
TOSH_ASSIGN_PIN(GIO1, 2, 1);
TOSH_ASSIGN_PIN(GIO2, 2, 3);
TOSH_ASSIGN_PIN(GIO3, 2, 6);
// 1-Wire
TOSH_ASSIGN_PIN(ONEWIRE, 2, 4);
void HUMIDITY_MAKE_CLOCK_OUTPUT() { TOSH_MAKE_HUM_SCL_OUTPUT(); }
void HUMIDITY_MAKE_CLOCK_INPUT() { TOSH_MAKE_HUM_SCL_INPUT(); }
void HUMIDITY_CLEAR_CLOCK() { TOSH_CLR_HUM_SCL_PIN(); }
void HUMIDITY_SET_CLOCK() { TOSH_SET_HUM_SCL_PIN(); }
void HUMIDITY_MAKE_DATA_OUTPUT() { TOSH_MAKE_HUM_SDA_OUTPUT(); }
void HUMIDITY_MAKE_DATA_INPUT() { TOSH_MAKE_HUM_SDA_INPUT(); }
void HUMIDITY_CLEAR_DATA() { TOSH_CLR_HUM_SDA_PIN(); }
void HUMIDITY_SET_DATA() { TOSH_SET_HUM_SDA_PIN(); }
char HUMIDITY_GET_DATA() { return TOSH_READ_HUM_SDA_PIN(); }
#define HUMIDITY_TIMEOUT_MS 30
#define HUMIDITY_TIMEOUT_TRIES 20
enum {
// Sensirion Humidity addresses and commands
TOSH_HUMIDITY_ADDR = 5,
TOSH_HUMIDTEMP_ADDR = 3,
TOSH_HUMIDITY_RESET = 0x1E
};
// FLASH
TOSH_ASSIGN_PIN(FLASH_PWR, 4, 3);
TOSH_ASSIGN_PIN(FLASH_CS, 4, 4);
TOSH_ASSIGN_PIN(FLASH_HOLD, 4, 7);
// PROGRAMMING PINS (tri-state)
//TOSH_ASSIGN_PIN(TCK, );
TOSH_ASSIGN_PIN(PROG_RX, 1, 1);
TOSH_ASSIGN_PIN(PROG_TX, 2, 2);
// send a bit via bit-banging to the flash
void TOSH_FLASH_M25P_DP_bit(bool set) {
if (set)
TOSH_SET_SIMO0_PIN();
else
TOSH_CLR_SIMO0_PIN();
TOSH_SET_UCLK0_PIN();
TOSH_CLR_UCLK0_PIN();
}
// put the flash into deep sleep mode
// important to do this by default
void TOSH_FLASH_M25P_DP() {
// SIMO0, UCLK0
TOSH_MAKE_SIMO0_OUTPUT();
TOSH_MAKE_UCLK0_OUTPUT();
TOSH_MAKE_FLASH_HOLD_OUTPUT();
TOSH_MAKE_FLASH_CS_OUTPUT();
TOSH_SET_FLASH_HOLD_PIN();
TOSH_SET_FLASH_CS_PIN();
TOSH_wait();
// initiate sequence;
TOSH_CLR_FLASH_CS_PIN();
TOSH_CLR_UCLK0_PIN();
TOSH_FLASH_M25P_DP_bit(TRUE); // 0
TOSH_FLASH_M25P_DP_bit(FALSE); // 1
TOSH_FLASH_M25P_DP_bit(TRUE); // 2
TOSH_FLASH_M25P_DP_bit(TRUE); // 3
TOSH_FLASH_M25P_DP_bit(TRUE); // 4
TOSH_FLASH_M25P_DP_bit(FALSE); // 5
TOSH_FLASH_M25P_DP_bit(FALSE); // 6
TOSH_FLASH_M25P_DP_bit(TRUE); // 7
TOSH_SET_FLASH_CS_PIN();
TOSH_SET_SIMO0_PIN();
TOSH_MAKE_SIMO0_INPUT();
TOSH_MAKE_UCLK0_INPUT();
TOSH_CLR_FLASH_HOLD_PIN();
}
// need to undef atomic inside header files or nesC ignores the directive
#undef atomic
void TOSH_SET_PIN_DIRECTIONS(void)
{
// reset all of the ports to be input and using i/o functionality
atomic
{
P1SEL = 0;
P2SEL = 0;
P3SEL = 0;
P4SEL = 0;
P5SEL = 0;
P6SEL = 0;
P1DIR = 0xe0;
P1OUT = 0x00;
P2DIR = 0x7b;
P2OUT = 0x10;
P3DIR = 0xf1;
P3OUT = 0x00;
P4DIR = 0xfd;
P4OUT = 0xdd;
P5DIR = 0xff;
P5OUT = 0xff;
P6DIR = 0xff;
P6OUT = 0x00;
P1IE = 0;
P2IE = 0;
// the commands above take care of the pin directions
// there is no longer a need for explicit set pin
// directions using the TOSH_SET/CLR macros
// wait 10ms for the flash to startup
// TOSH_uwait(1024*10);
// Put the flash in deep sleep state
// TOSH_FLASH_M25P_DP();
}//atomic
}
#endif // _H_hardware_h
--- NEW FILE: msp430hardware.h ---
// $Id: msp430hardware.h,v 1.1 2005/04/21 17:31:41 jwhui Exp $
/* "Copyright (c) 2000-2003 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
* OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*/
// @author Vlado Handziski <handzisk at tkn.tu-berlin.de>
// @author Joe Polastre <polastre at cs.berkeley.edu>
// @author Cory Sharp <cssharp at eecs.berkeley.edu>
#ifndef _H_msp430hardware_h
#define _H_msp430hardware_h
#include <io.h>
#include <signal.h>
#include "msp430regtypes.h"
// define platform constants that can be changed for different compilers
// these are all msp430-gcc specific (add as necessary)
#ifdef __msp430_headers_adc10_h
#define __msp430_have_adc10
#endif
#ifdef __msp430_headers_adc12_h
#define __msp430_have_adc12
#endif
// assign a default DEFAULT_BAUDRATE
#ifndef DEFAULT_BAUDRATE
#define DEFAULT_BAUDRATE 57600
#endif
// CPU memory-mapped register access will cause nesc to issue race condition
// warnings. Race conditions are a significant conern when accessing CPU
// memory-mapped registers, because they can change even while interrupts
// are disabled. This means that the standard nesc tools for resolving race
// conditions, atomic statements that disable interrupt handling, do not
// resolve CPU register race conditions. So, CPU registers access must be
// treated seriously and carefully.
// The macro MSP430REG_NORACE allows individual modules to internally
// redeclare CPU registers as norace, eliminating nesc's race condition
// warnings for their access. This macro should only be used after the
// specific CPU register use has been verified safe and correct. Example
// use:
//
// module MyLowLevelModule
// {
// // ...
// }
// implementation
// {
// MSP430REG_NORACE(TACCTL0);
// // ...
// }
#undef norace
#define MSP430REG_NORACE_EXPAND(type,name,addr) \
norace static volatile type name asm(#addr)
#define MSP430REG_NORACE3(type,name,addr) \
MSP430REG_NORACE_EXPAND(type,name,addr)
// MSP430REG_NORACE and MSP430REG_NORACE2 presume naming conventions among
// type, name, and addr, which are defined in the local header
// msp430regtypes.h and mspgcc's header io.h and its children.
#define MSP430REG_NORACE2(rename,name) \
MSP430REG_NORACE3(TYPE_##name,rename,name##_)
#define MSP430REG_NORACE(name) \
MSP430REG_NORACE3(TYPE_##name,name,name##_)
// Avoid the type-punned pointer warnings from gcc 3.3, which are warning about
// creating potentially broken object code. Union casts are the appropriate work
// around. Unfortunately, they require a function definiton.
#define DEFINE_UNION_CAST(func_name,to_type,from_type) \
to_type func_name(from_type x) { union {from_type f; to_type t;} c = {f:x}; return c.t; }
// redefine ugly defines from msp-gcc
#ifndef DONT_REDEFINE_SR_FLAGS
#undef C
#undef Z
#undef N
#undef V
#undef GIE
#undef CPUOFF
#undef OSCOFF
#undef SCG0
#undef SCG1
#undef LPM0_bits
#undef LPM1_bits
#undef LPM2_bits
#undef LPM3_bits
#undef LPM4_bits
#define SR_C 0x0001
#define SR_Z 0x0002
#define SR_N 0x0004
#define SR_V 0x0100
#define SR_GIE 0x0008
#define SR_CPUOFF 0x0010
#define SR_OSCOFF 0x0020
#define SR_SCG0 0x0040
#define SR_SCG1 0x0080
#define LPM0_bits SR_CPUOFF
#define LPM1_bits SR_SCG0+SR_CPUOFF
#define LPM2_bits SR_SCG1+SR_CPUOFF
#define LPM3_bits SR_SCG1+SR_SCG0+SR_CPUOFF
#define LPM4_bits SR_SCG1+SR_SCG0+SR_OSCOFF+SR_CPUOFF
#endif//DONT_REDEFINE_SR_FLAGS
#ifdef interrupt
#undef interrupt
#endif
#ifdef wakeup
#undef wakeup
#endif
#ifdef signal
#undef signal
#endif
// I2CBusy flag is not defined by current MSP430-GCC
#ifdef __msp430_have_usart0_with_i2c
#ifndef I2CBUSY
#define I2CBUSY (0x01 << 5)
#endif
MSP430REG_NORACE2(U0CTLnr,U0CTL);
MSP430REG_NORACE2(I2CTCTLnr,I2CTCTL);
MSP430REG_NORACE2(I2CDCTLnr,I2CDCTL);
#endif
// The signal attribute has opposite meaning in msp430-gcc than in avr-gcc
#define TOSH_SIGNAL(signame) \
void sig_##signame() __attribute__((interrupt (signame), wakeup, C))
// TOSH_INTERRUPT allows nested interrupts
#define TOSH_INTERRUPT(signame) \
void isr_##signame() __attribute__((interrupt (signame), signal, wakeup, C))
inline void TOSH_wait(void)
{
nop(); nop();
}
#define TOSH_CYCLE_TIME_NS 250
inline void TOSH_wait_250ns(void)
{
// 4 MHz clock == 1 cycle per 250 ns
nop();
}
inline void TOSH_uwait(uint16_t u)
{
uint16_t i;
if (u < 500)
for (i=2; i < u; i++) {
asm volatile("nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
::);
}
else
for (i=0; i < u; i++) {
asm volatile("nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
::);
}
}
void __nesc_disable_interrupt()
{
dint();
nop();
}
void __nesc_enable_interrupt()
{
eint();
}
bool are_interrupts_enabled()
{
return ((READ_SR & SR_GIE) != 0);
}
typedef bool __nesc_atomic_t;
__nesc_atomic_t __nesc_atomic_start(void);
void __nesc_atomic_end(__nesc_atomic_t oldSreg);
#ifndef NESC_BUILD_BINARY
__nesc_atomic_t __nesc_atomic_start(void)
{
// __nesc_atomic_t result = are_interrupts_enabled();
// __nesc_disable_interrupt();
// return result;
return 0;
}
void __nesc_atomic_end( __nesc_atomic_t reenable_interrupts )
{
// if( reenable_interrupts )
// __nesc_enable_interrupt();
}
#endif
//Variable to keep track if Low Power Modes shoud not be used
norace bool LPMode_disabled = FALSE;
void LPMode_enable() {
LPMode_disabled = FALSE;
}
void LPMode_disable() {
LPMode_disabled = TRUE;
}
inline void TOSH_sleep() {
// The LPM we can go down to depends on the clocks used. We never go
// below LPM3, so ACLK is always enabled, also TimerB clock source
// is assumed to be ACLK.
// We check MSP430's TimerA, USART0/1, ADC12 peripheral modules if they
// use MCLK or SMCLK and switch to the lowest LPM that keeps
// the required clock(s) running.
extern uint8_t TOSH_sched_full;
extern volatile uint8_t TOSH_sched_free;
__nesc_atomic_t fInterruptFlags;
uint16_t LPMode_bits = 0;
fInterruptFlags = __nesc_atomic_start();
if ((LPMode_disabled) || (TOSH_sched_full != TOSH_sched_free)) {
__nesc_atomic_end(fInterruptFlags);
return;
} else {
LPMode_bits = LPM3_bits;
// TimerA, USART0, USART1 check
if ( (((TACCTL0 & CCIE) || (TACCTL1 & CCIE) || (TACCTL2 & CCIE))
&& ((TACTL & TASSEL_3) == TASSEL_2))
|| ((ME1 & (UTXE0 | URXE0)) && (U0TCTL & SSEL1))
|| ((ME2 & (UTXE1 | URXE1)) && (U1TCTL & SSEL1))
#ifdef __msp430_have_usart0_with_i2c
// registers end in "nr" to prevent nesC race condition detection
|| ((U0CTLnr & I2CEN) && (I2CTCTLnr & SSEL1) &&
(I2CDCTLnr & I2CBUSY) && (U0CTLnr & SYNC) && (U0CTLnr & I2C))
#endif
)
LPMode_bits = LPM1_bits;
#ifdef __msp430_have_adc12
// ADC12 check
if (ADC12CTL1 & ADC12BUSY){
if (!(ADC12CTL0 & MSC) && ((TACTL & TASSEL_3) == TASSEL_2))
LPMode_bits = LPM1_bits; // TimerA for ADC12
else
switch (ADC12CTL1 & ADC12SSEL_3){
case ADC12SSEL_2: LPMode_bits = 0; break;
case ADC12SSEL_3: LPMode_bits = LPM1_bits; break;
}
}
#endif
LPMode_bits |= SR_GIE;
__asm__ __volatile__( "bis %0, r2" : : "m" ((uint16_t)LPMode_bits) );
}
}
#define SET_FLAG(port, flag) ((port) |= (flag))
#define CLR_FLAG(port, flag) ((port) &= ~(flag))
#define READ_FLAG(port, flag) ((port) & (flag))
// TOSH_ASSIGN_PIN creates functions that are effectively marked as
// "norace". This means race conditions that result from their use will not
// be detectde by nesc.
#define TOSH_ASSIGN_PIN_HEX(name, port, hex) \
void TOSH_SET_##name##_PIN() { MSP430REG_NORACE2(r,P##port##OUT); r |= hex; } \
void TOSH_CLR_##name##_PIN() { MSP430REG_NORACE2(r,P##port##OUT); r &= ~hex; } \
void TOSH_TOGGLE_##name##_PIN() { MSP430REG_NORACE2(r,P##port##OUT); r ^= hex; } \
uint8_t TOSH_READ_##name##_PIN() { MSP430REG_NORACE2(r,P##port##IN); return (r & hex); } \
void TOSH_MAKE_##name##_OUTPUT() { MSP430REG_NORACE2(r,P##port##DIR); r |= hex; } \
void TOSH_MAKE_##name##_INPUT() { MSP430REG_NORACE2(r,P##port##DIR); r &= ~hex; } \
void TOSH_SEL_##name##_MODFUNC() { MSP430REG_NORACE2(r,P##port##SEL); r |= hex; } \
void TOSH_SEL_##name##_IOFUNC() { MSP430REG_NORACE2(r,P##port##SEL); r &= ~hex; } \
bool TOSH_IS_##name##_MODFUNC() { MSP430REG_NORACE2(r,P##port##SEL); return (r & hex); } \
bool TOSH_IS_##name##_IOFUNC() { MSP430REG_NORACE2(r,P##port##SEL); return (r | ~hex); }
#define TOSH_ASSIGN_PIN(name, port, bit) \
TOSH_ASSIGN_PIN_HEX(name,port,(1<<(bit)))
#endif//_H_msp430hardware_h
- Previous message: [Tinyos-beta-commits] CVS: tinyos-1.x/beta/Deluge/Deluge/TOSBoot
Makefile, 1.2, 1.3 TOSBoot.nc, 1.2, 1.3 TOSBootM.nc, 1.3,
1.4 TOSBootProgFlashM.nc, 1.2, NONE TOSBootSTM25PC.nc, 1.2,
NONE TOSBootSTM25PM.nc, 1.3, NONE
- Next message: [Tinyos-beta-commits]
CVS: tinyos-1.x/beta/Deluge/Deluge/TOSBoot/stm25p
STM25PC.nc, NONE, 1.1 STM25PM.nc, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-beta-commits
mailing list