Other Parts Discussed in Thread: MSP430G2231
Hello,
I am using TimerA to implement a software UART but when CCIFG is set to 1 in TACCTL0 I assume that it has entered that interrupt, however during the interrupt I do TACCTL0 &= ~CCIFG to reset it back to 0, but it does not reset so I'm not sure if its actually entering the interrupt even though the flag is set. Can anyone help?
Here is the code:
/****************************************************************
*
* Copyright (C) 2006-2007 Texas Instruments, Inc.
*ShreHarsha Rao - RFID Systems
*----------------------------------------------------------------
* All software and related documentation is provided "AS IS" and
* without warranty or support of any kind and Texas Instruments
* expressly disclaims all other warranties, express or implied,
* including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. Under no
* circumstances shall Texas Instruments be liable for any
* incidental, special or consequential damages that result from
* the use or inability to use the software or related
* documentation, even if Texas Instruments has been advised of
* the liability.
*
* Unless otherwise stated, software written and copyrighted by
* Texas Instruments is distributed as "freeware". You may use
* and modify this software without any charge or restriction.
* You may distribute to others, as long as the original author
* is acknowledged.
*
****************************************************************/
//--------------------------------------
//Program with hardware USART and
//paralel communication interface
//with TIR reader chip.
//
//PORT 4.0-4.7 - (IO0-IO7) for parallel interface with reader chip
//PORT3.4 - PORT3.5 - USCI_A0 ---> USB/UART control signals
//PORT2.1 - IRQ
//PORT3.3 - DATA_CLK
//PORT1.7 - PORT1.3 - signaling LEDs
//--------------------------------------
#define DBG 0
#include <MSP430x23x0.h>
#include <stdlib.h> //Processor specific definitions
#include <stdio.h>
#include "hardware.h"
#include "parallel.h"
#include "anticollision.h"
#include "globals.h"
#include "tiris.h"
#include "14443.h"
#include "host.h"
#include "epc.h"
#include "automatic.h"
// =======================================================================
char rxdata; //RS232 RX data byte
unsigned char buf[BUF_LENGTH];
signed char RXTXstate; //used for transmit recieve byte count
unsigned char flags; //stores the mask value (used in anticollision)
unsigned char RXErrorFlag;
unsigned char RXflag; //indicates that data is in buffer
unsigned char i_reg; //interrupt register
unsigned char counter;
unsigned char CollPoss;
#include "msp430g2231.h"
#include "stdbool.h"
#define TXD BIT1 // TXD on P1.1
#define RXD BIT2 // RXD on P1.2
#define Bit_time 104 // 9600 Baud, SMCLK=1MHz (1MHz/9600)=104
#define Bit_time_5 52 // Time for half a bit.
unsigned char BitCnt; // Bit count, used when transmitting byte
unsigned int TXByte = 1; // Value sent over UART when Transmit() is called
unsigned int RXByte = 1; // Value recieved once hasRecieved is set
bool isReceiving; // Status for when the device is receiving
bool hasReceived; // Lets the program know when a byte is received
// =========================================================================
// Main function with init and an endless loop
//
void Transmit(void);
//
void main(void) {
// initialize peripherals
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
UARTset();
EnableSet;
TRFDisable;
delay_ms(1);
TRFEnable;
delay_ms(1);
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // SMCLK = DCO = 1MHz
P4SEL |= BIT4;
P4DIR |= BIT4;
P1IES |= RXD; // RXD Hi/lo edge interrupt
P1IFG &= ~RXD; // Clear RXD (flag) before enabling interrupt
P1IE |= RXD; // Enable RXD interrupt
isReceiving = false; // Set initial values
hasReceived = false;
while(1)
{Transmit();}
__bis_SR_register(GIE); // interrupts enabled
while(1)
{
if (hasReceived) // If the device has recieved a value
{
hasReceived = false; // Clear the flag
TXByte = RXByte; // Load the recieved byte into the byte to be transmitted
Transmit();
}
if (~hasReceived) // Loop again if another value has been received
__bis_SR_register(CPUOFF + GIE);
// LPM0, the ADC interrupt will wake the processor up. This is so that it does not
// endlessly loop when no value has been Received.
}
//Add logic for SPI/parallel selection.
if (SPIMODE)
{ //Set Port Functions for Serial Mode
EnableSet;
irqPINset;
irqEDGEset; /* rising edge interrupt */
LEDallOFF;
LEDportSET;
}
else
PARset(); //Set Port Functions for Parallel Mode
/* Use the DCO to program the SPI first*/
if (SPIMODE)
{
#ifndef SPI_BITBANG
USARTset(); //Set the USART */
#else
SlaveSelectPortSet // P3.0 - Slave Select
SlaveSelectHIGH // Slave Select - inactive ( high)
SIMOSet
clkPOUTset;
#endif
}
//test code
TRFDisable;
TRFEnable;
delay_ms(1);
//end test code
InitialSettings(); // Set MCU Clock Frequency to 13.56 MHz and OOK Modulation
/*Now switch from DCO to external 13.56 MHz clock*/
OSCsel(0x00); //set the oscilator
delay_ms(10);
/*Re-configure the USART with this external clock*/
if (SPIMODE)
{
#ifndef SPI_BITBANG
USARTEXTCLKset(); //Set the USART */
#endif
}
EnableInterrupts; // General enable interrupts
delay_ms(10);
LEDpowerON;
OOKdirIN; //set OOK port tristate
ENABLE = 1;
POLLING = 1;
FindTags(0x00);
}
void Transmit()
{
while(isReceiving); // Wait for RX completion
CCTL0 = OUT; // TXD Idle as Mark
TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode
BitCnt = 0xA; // Load Bit counter, 8 bits + ST/SP
CCR0 = TAR; // Initialize compare register
CCR0 += Bit_time; // Set time till first bit
TXByte |= 0x100; // Add stop bit to TXByte (which is logical 1)
TXByte = TXByte << 1; // Add start bit (which is logical 0)
CCTL0 = CCIS0 + OUTMOD0 + CCIE; // Set signal, intial value, enable interrupts
while ( CCTL0 & CCIE ); // Wait for previous TX completion
}
// === end of main =====================================================
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
isReceiving = true;
P1IE &= ~RXD; // Disable RXD interrupt
P1IFG &= ~RXD; // Clear RXD IFG (interrupt flag)
TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode
CCR0 = TAR; // Initialize compare register
CCR0 += Bit_time_5; // Set time till first bit
CCTL0 = OUTMOD1 + CCIE; // Dissable TX and enable interrupts
RXByte = 1; // Initialize RXByte
BitCnt = 0x9; // Load Bit counter, 8 bits + ST
}
// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
CCTL0 &= ~CCIFG;
if(!isReceiving)
{
CCR0 += Bit_time; // Add Offset to CCR0
if ( BitCnt == 0) // If all bits TXed
{
TACTL = TASSEL_2; // SMCLK, timer off (for power consumption)
CCTL0 &= ~ CCIE ; // Disable interrupt
}
else
{
CCTL0 |= OUTMOD2; // Set TX bit to 0
if (TXByte & 0x01)
CCTL0 &= ~ OUTMOD2; // If it should be 1, set it to 1
TXByte = TXByte >> 1;
BitCnt --;
}
}
else
{
CCR0 += Bit_time; // Add Offset to CCR0
if ( BitCnt == 0)
{
TACTL = TASSEL_2; // SMCLK, timer off (for power consumption)
CCTL0 &= ~ CCIE ; // Disable interrupt
isReceiving = false;
P1IFG &= ~RXD; // clear RXD IFG (interrupt flag)
P1IE |= RXD; // enabled RXD interrupt
if ( (RXByte & 0x201) == 0x200) // Validate the start and stop bits are correct
{
RXByte = RXByte >> 1; // Remove start bit
RXByte &= 0xFF; // Remove stop bit
hasReceived = true;
}
__bic_SR_register_on_exit(CPUOFF); // Enable CPU so the main while loop continues
}
else
{
if ( (P1IN & RXD) == RXD) // If bit is set?
RXByte |= 0x400; // Set the value in the RXByte
RXByte = RXByte >> 1; // Shift the bits down
BitCnt --;
}
}
}
James