From 95beb35e2e2213ef8e608dcfa576a99eb0583164 Mon Sep 17 00:00:00 2001 From: ayer1 Date: Fri, 4 Sep 2009 18:04:35 +0000 Subject: [PATCH] adding this directory so we have more fine-grained control over app-waits on msp430 mcus; tosh_uwait is much more accurate than busywaitmicro. --- .../shimmer/chips/msp430/msp430hardware.h | 288 ++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 tos/platforms/shimmer/chips/msp430/msp430hardware.h diff --git a/tos/platforms/shimmer/chips/msp430/msp430hardware.h b/tos/platforms/shimmer/chips/msp430/msp430hardware.h new file mode 100644 index 00000000..7911e9b3 --- /dev/null +++ b/tos/platforms/shimmer/chips/msp430/msp430hardware.h @@ -0,0 +1,288 @@ + +/* "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 +// @author Joe Polastre +// @author Cory Sharp + +#ifndef _H_msp430hardware_h +#define _H_msp430hardware_h + +#include +#include +#include "msp430regtypes.h" +#include "Msp430DcoSpec.h" + +// 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) @safe() { 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 + + +// Re-definitions for safe tinyOS +// These rely on io.h being included at the top of this file +// thus pulling the affected header files before the re-definitions +#ifdef SAFE_TINYOS +#undef ADC12MEM +#define ADC12MEM TCAST(int* ONE, ADC12MEM_) /* ADC12 Conversion Memory (for C) */ +#undef ADC12MCTL +#define ADC12MCTL TCAST(char * ONE, ADC12MCTL_) +#endif + +// 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 + +// backwards compatibility to older versions of the header files +#ifdef __MSP430_HAS_I2C__ +#define __msp430_have_usart0_with_i2c +#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 +// Our worst case is 250 ns = 1 cycle. + +inline void TOSH_wait_250ns(void) +{ + nop(); +} + +/* + Following the suggestion of the mspgcc.sourceforge.net site + for an intelligent pause routine +*/ +void brief_pause(register unsigned int n) +{ + asm volatile( "1: \n\t" + "dec %0 \n\t" + "jne 1b\n\t" + : "+r" (n)); +} + +#define TOSH_uwait(n) brief_pause((((unsigned long long)n) * TARGET_DCO_KHZ * 1024 / 1000000 - 2) / 3) + +#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() @safe() { MSP430REG_NORACE2(r,P##port##OUT); r |= hex; } \ +void TOSH_CLR_##name##_PIN() @safe() { MSP430REG_NORACE2(r,P##port##OUT); r &= ~hex; } \ +void TOSH_TOGGLE_##name##_PIN() @safe(){ MSP430REG_NORACE2(r,P##port##OUT); r ^= hex; } \ +uint8_t TOSH_READ_##name##_PIN() @safe() { MSP430REG_NORACE2(r,P##port##IN); return (r & hex); } \ +void TOSH_MAKE_##name##_OUTPUT() @safe() { MSP430REG_NORACE2(r,P##port##DIR); r |= hex; } \ +void TOSH_MAKE_##name##_INPUT() @safe() { MSP430REG_NORACE2(r,P##port##DIR); r &= ~hex; } \ +void TOSH_SEL_##name##_MODFUNC() @safe() { MSP430REG_NORACE2(r,P##port##SEL); r |= hex; } \ +void TOSH_SEL_##name##_IOFUNC() @safe() { MSP430REG_NORACE2(r,P##port##SEL); r &= ~hex; } + +#define TOSH_ASSIGN_PIN(name, port, bit) \ +TOSH_ASSIGN_PIN_HEX(name,port,(1<<(bit))) + +typedef uint8_t mcu_power_t @combine("mcombine"); +mcu_power_t mcombine(mcu_power_t m1, mcu_power_t m2) @safe() { + return (m1 < m2) ? m1: m2; +} +enum { + MSP430_POWER_ACTIVE = 0, + MSP430_POWER_LPM0 = 1, + MSP430_POWER_LPM1 = 2, + MSP430_POWER_LPM2 = 3, + MSP430_POWER_LPM3 = 4, + MSP430_POWER_LPM4 = 5 +}; + +void __nesc_disable_interrupt(void) @safe() +{ + dint(); + nop(); +} + +void __nesc_enable_interrupt(void) @safe() +{ + eint(); +} + +typedef bool __nesc_atomic_t; +__nesc_atomic_t __nesc_atomic_start(void); +void __nesc_atomic_end(__nesc_atomic_t reenable_interrupts); + +#ifndef NESC_BUILD_BINARY +/* @spontaneous() functions should not be included when NESC_BUILD_BINARY + is #defined, to avoid duplicate functions definitions when binary + components are used. Such functions do need a prototype in all cases, + though. */ +__nesc_atomic_t __nesc_atomic_start(void) @spontaneous() @safe() +{ + __nesc_atomic_t result = ((READ_SR & SR_GIE) != 0); + __nesc_disable_interrupt(); + asm volatile("" : : : "memory"); /* ensure atomic section effect visibility */ + return result; +} + +void __nesc_atomic_end(__nesc_atomic_t reenable_interrupts) @spontaneous() @safe() +{ + asm volatile("" : : : "memory"); /* ensure atomic section effect visibility */ + if( reenable_interrupts ) + __nesc_enable_interrupt(); +} +#endif + +/* Floating-point network-type support. + These functions must convert to/from a 32-bit big-endian integer that follows + the layout of Java's java.lang.float.floatToRawIntBits method. + Conveniently, for the MSP430 family, this is a straight byte copy... +*/ + +typedef float nx_float __attribute__((nx_base_be(afloat))); + +inline float __nesc_ntoh_afloat(const void *COUNT(sizeof(float)) source) @safe() { + float f; + memcpy(&f, source, sizeof(float)); + return f; +} + +inline float __nesc_hton_afloat(void *COUNT(sizeof(float)) target, float value) @safe() { + memcpy(target, &value, sizeof(float)); + return value; +} + +#endif//_H_msp430hardware_h + -- 2.39.2