//===================================================================
//
// MSP430F149 based direct digital conversion
// software defined radio receiver
//
// (C) 2005 Jan Florian Wagner OH2GHR, jwagner@cc.hut.fi
// http://users.tkk.fi/~jwagner/electr/dc-rx/
//
// Firmware Version 1.03
//
// Licence: free as per GNU GPL
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// For further details see the included GPL.TXT
// or go to http://www.gnu.org/copyleft/gpl.html
//
//===================================================================
//
// Interrupt handlers, with PC serial port receive and transmit.
// Also initializes the serial port to 9600 baud.
// Provides helper functions for AT keyboard access.
//
// - keyboard (i/o pins 2.5 clock & 2.6 data)
// - serial comm (uart1)
// - tuning wheel (i/o pins 2.0 & 2.1)
//
//===================================================================
//#define NEW_KBD_FUNCS 1
//#define WDT_SYSTICK_DEBUG 1 // define to blink the LED at system ticks
#include "MSP430-fw-stdincludes.h"
volatile unsigned char kbdBuf[KBD_BUFSIZE+1]; // keyboard scancode buf
volatile unsigned char kbdBufPos;
volatile char kbdUnreadCount;
volatile unsigned char pcRxBuf[PC_RXBUF+1]; // PC rx
volatile unsigned char pcRxBufPos;
volatile char pcRxUnreadCount;
volatile unsigned char pcTxBuf[PC_TXBUF+1]; // PC tx
volatile unsigned char pcTxBufPos;
volatile char pcTxUnsentCount;
volatile char pcTxDone;
volatile signed int wheel_counter; // wheel rx
#define KBD_DLY 2000
#ifdef __IAR_SYSTEMS_ICC__
// empty interrupt table, IAR EWB v3 style of declaration
#pragma vector=UART0TX_VECTOR
__interrupt void intUart0Tx(void) {};
#pragma vector=UART0RX_VECTOR
__interrupt void intUart0Rx(void) {};
#pragma vector=PORT1_VECTOR
__interrupt void intPort1(void) {};
#pragma vector=ADC_VECTOR
__interrupt void intADC(void) {};
#pragma vector=TIMERA1_VECTOR
__interrupt void intTimerA1(void) {};
#pragma vector=TIMERA0_VECTOR
__interrupt void intTimerA0(void) {};
#pragma vector=TIMERB1_VECTOR
__interrupt void intTimerB1(void) {};
#pragma vector=TIMERB0_VECTOR
__interrupt void intTimerB0(void) {};
#pragma vector=COMPARATORA_VECTOR
__interrupt void intComparator(void) {};
#else
// empty interrupt table, MSP-GCC style of declaration
interrupt (UART0TX_VECTOR) intUart0Tx(void) {};
interrupt (UART0RX_VECTOR) intUart0Rx(void) {};
interrupt (PORT1_VECTOR) intPort1(void) {};
interrupt (ADC_VECTOR) intADC(void) {};
interrupt (TIMERA1_VECTOR) intTimerA1(void) {};
interrupt (TIMERA0_VECTOR) intTimerA0(void) {};
interrupt (TIMERB1_VECTOR) intTimerB1(void) {};
interrupt (TIMERB0_VECTOR) intTimerB0(void) {};
interrupt (COMPARATORA_VECTOR) intComparator(void) {};
#endif
//===================================================================
//
// BASIC INIT
//
//-------------------------------------------------------------------
// initInterrupts ( )
// Set up the serial port, and wheel/keyboard port interrupts.
//
void initInterrupts(void) {
_DINT();
// -- reconfig watch dog timer as interval mode interrupt
WDTCTL = WDTPW + WDTCNTCL +
WDTTMSEL + WDTIS0; // clear counter, interval mode
// WDTIS0: 470..540Hz (SMCLK/8192)
// - : 122..135Hz (SMCLK/32768)
sys_ticks = 0;
// -- port 2 pin interrupts
// enable tuning wheel interrupt on pin 2.0 and
// AT keyboard clock int on 2.5 (users guide page 195 / 9-3)
P2SEL &= ~(BIT0+BIT1+KBD_CLK+KBD_DAT); // don't use modules, just i/o
P2DIR &= ~(BIT0+BIT1+KBD_CLK+KBD_DAT); // set 2.0 .1 .5 .6 as inputs
P2IES |= BIT0+KBD_CLK; // P2.0 or P2.5 high->low generates interrupt
P2IFG = 0x00; // clear interrupt flags
P2IE |= BIT0+KBD_CLK; // pin int enable
wheel_counter = 0;
kbdBufPos = 0;
kbdUnreadCount = 0;
// -- serial comm port config
P3DIR = 0xFF; // all pins as outputs (utxd0, utxd1)
P3DIR &= ~(BIT1+BIT3+BIT5+BIT7); // simo0, uclk0, urxd0 and urxd1 as inputs
P3SEL |= BIT1+BIT3+BIT5+BIT6+BIT7; // port 3 pins multiplexed to simo0, uclk0,
// urxd0, urxd1, utxd1
// PC serial comm : uart1 "9600,n,8,1"
// (page 244, 12.5.2)
U1CTL = SWRST; // reset, as in users guide
U1CTL |= CHAR;
U1TCTL |= SSEL0+SSEL1+TXEPT;
U1RCTL = 0;
U1MCTL = 0x0;
U1BR0 = (XTAL_FREQ/PCBAUDRT)&0x00FF;
U1BR1 = ((XTAL_FREQ/PCBAUDRT)&0xFF00)>>8;
pcRxBufPos = 0;
pcTxBufPos = 0;
pcRxUnreadCount = 0;
pcTxUnsentCount = 0;
pcTxDone = 1;
// enable uart modules (page 53, table 3-13)
// (unused:ME1 |= USPIE0; // uart 0 SPI enable
ME2 |= URXE1+UTXE1; // uart 1 rx tx enable
//U0CTL &= ~(SWRST); // USART init sequence last stage, as recommended
U1CTL &= ~(SWRST); // on page 242
// -- enable interrupts (page 47, table 3-5)
//IE1 |= URXIE0; // uart 0 rx int enable
IE2 |= URXIE1+UTXIE1; // enable UART 1 rx&tx interrupt
IE1 |= NMIIE+OFIE+WDTIE; // enable NMI, oscillator fault, watchdog/interval interrupt
_EINT();
return;
}
//===================================================================
//
// INTERRUPT HANDLERS
//
//-------------------------------------------------------------------
// intWDT ( )
// Watchdog interrupt handler, with watchdog in interval counter mode.
// Advances the system tick counter. 1 tick = 8192/crystalfreq seconds.
// If using 4.433Mhz xtal clock: 1 tick = ~1.8ms
//
#ifdef __IAR_SYSTEMS_ICC__
#pragma vector=WDT_VECTOR
__interrupt void intWDT(void)
#else
interrupt (WDT_VECTOR) intWDT(void)
#endif
{
++sys_ticks;
#ifdef WDT_SYSTICK_DEBUG
if(sys_ticks%128==0) { P6OUT^=LED_1; } // blink the LED
#endif
}
//-------------------------------------------------------------------
// intNMI ( )
// NMI handler, usually called when the crystal oscillator fails
//
#ifdef __IAR_SYSTEMS_ICC__
#pragma vector=NMI_VECTOR
__interrupt void intNMI(void)
#else
interrupt (NMI_VECTOR) intNMI(void)
#endif
{
int i;
// osc fault?
if((IFG1&OFIFG)!=0) {
do {
IFG1 &= ~OFIFG; // clear osc fault flag
for(i=0;i<256;i++) { _NOP(); }
//if((IFG1)&OFIFG!=0) P6OUT=0xFF; else P6OUT=0;
} while((IFG1&OFIFG)!=0); // try restarting the xtal2
IE1 |= OFIE;
}
}
//-------------------------------------------------------------------
// intUart1Rx ( )
// Received data on UART1 RX line, from the PC
//
#ifdef __IAR_SYSTEMS_ICC__
#pragma vector=UART1RX_VECTOR
__interrupt void intUart1Rx(void)
#else
interrupt (UART1RX_VECTOR) intUart1Rx(void)
#endif
{
int tmp = RXBUF1;
if(!(pcRxUnreadCount>=PC_RXBUF)) { pcRxUnreadCount++; }
++pcRxBufPos;
pcRxBufPos%=PC_RXBUF;
pcRxBuf[pcRxBufPos] = tmp;
}
//-------------------------------------------------------------------
// intUart1Tx ( )
// One data byte has been sent, check transmitter buffer to send more
//
#ifdef __IAR_SYSTEMS_ICC__
#pragma vector=UART1TX_VECTOR
__interrupt void intUar
- 1
- 2
前往页