This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F2370 Timer CCIFG not resetting

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

  • I'm not sure what your problem/quesiton is.

    Where do you look at CCIFG? How do ou know it is set?
    Doe syour code not work? If so what doesn't work?

    If you set a breakpoint inside the TIMERA0 _VECTOR, teh CCIF Gbit in TACCR0 is automatically cleared when teh ISR is entered. However, at the moment the debugger has fetched all data to present it to you, chances are that another interrupt has been already triggered in the meantime. The world doesn't stop turning just because the debugger hit a breakpoint.

    Even in main it is possible that an 'if (CCR=&CCIFG)' block in main is entered even though any possible interrupt should be handled by the ISR.
    It may be that the check was performed the very moment the IFG bit was set. So the ISR will be triggered and executed right after the check - however, the check was positive, even if only for one MCLK cycle.

    And as long as GIE is clear (and it is always clear implicitely while an ISR is executed) no interrupts are executed at all (else an ISR would infinitely interrupt itself)

  • I'm using IAR to watch the registers and it shows that once CCIFG gets set it doesn't clear, furthermore the last line of my code in the Transmit() function waits for CCIE to be cleared in the ISR, but when I step through my code it doesn't get past that line which suggests the ISR was never executed.

       while ( CCTL0 & CCIE ); // Wait for previous TX completion

  • James Yu said:
    while(1)
    {Transmit();}
     
    __bis_SR_register(GIE); // interrupts enabled

    Your code gets stuck in the while before it reaches the line that sets GIE and enables interrupts. If GIE is clear, interrupts are globally disabled, which is the power-on default.

    I didn't read further, so maybe there is more, but my office hours are over now :)

  • Ah I see! Can't believe I missed that, thanks!

**Attention** This is a public forum