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.

MSP430F1611: Storing byte array and comparing the value with Timer Count Register

Part Number: MSP430F1611


Dear All,

I am trying to store array of bytes as an integer and the compare this value to the value of Timer Count Register.

Referring to the code I have here, I am only interested in values of ASN. 

app_vars.uart_txFrame[0] = app_vars.rxpk_buf[17]; // ASN #1
app_vars.uart_txFrame[1] = app_vars.rxpk_buf[18]; // ASN #2
app_vars.uart_txFrame[2] = app_vars.rxpk_buf[19]; // ASN #3
app_vars.uart_txFrame[3] = app_vars.rxpk_buf[20]; // ASN #4
app_vars.uart_txFrame[4] = app_vars.rxpk_buf[21]; // ASN #5
app_vars.uart_txFrame[5] = 0xff; // closing flag
app_vars.uart_txFrame[6] = 0xfb; // closing flag

I have declared another varriable uint64_t ASN to make sure that maximum values can be stored.

Initially I thought that unit64_t ASN = apps.vars.uart_txFrame[0] + apps.vars.uart_txFrame[1] + apps.vars.uart_txFrame[2]+apps.vars.uart_txFrame[3] + apps.vars.uart_txFrame[4] would do the job

However, this just add bytes not representing the right values. For instance, 

apps.vars.uart_txFrame[0] = 0X61;
apps.vars.uart_txFrame[1] = 0XCC;
apps.vars.uart_txFrame[2] = 0X06;
apps.vars.uart_txFrame[3] = 0X00;
apps.vars.uart_txFrame[4] = 0X00;


which ASN should represent value of 445537; bytes are encoded in little endian.

If anyone could give me advice storing the byte array correctly, it will be really helpful.

Thank you

 

  • Assuming 32-bit ints: Use a union of "int" and "unsigned char[4]". Store your bytes in the unsigned char array per your endianness, then just read the int value.
  • Thank you for your input.
    Please correct me if I am wrong.
    But do you mean Usigned char[5] and int64?

    So if I do the following procedure I should get the right values of ASN?

    Unsigned char [0] =apps.vars.uart_txFrame[0] = 0X61;
    Unsigned char [1] =apps.vars.uart_txFrame[1] = 0X06;
    Unsigned char [0] =apps.vars.uart_txFrame[2] = 0Xcc;
    Unsigned char [3] =apps.vars.uart_txFrame[3] = 0X00;
    Unsigned char [4] =apps.vars.uart_txFrame[4] = 0X00;

    Then from here do I just add char arrays?
  • For int64_t, I would use unsigned char[8] just to be sure. This would make the data for 445537 you mentioned earlier as follows:
    [0] = 0x61
    [1] = 0xcc
    [2] = 0x06
    [3]..[7] = 0x00

    You would not add anything. The C language "union" would take care of it for you. See this link for unions: www.tutorialspoint.com/.../c_unions.htm
  • Thank you, could this work too?

    ASN = (uint64_t)app_vars.uart_txFrame[0] + ((uint64_t)app_vars.uart_txFrame[1]<<8) + ((uint64_t)app_vars.uart_txFrame[2]<<16)+((uint64_t)app_vars.uart_txFrame[3]<<24)+ ((uint64_t)app_vars.uart_txFrame[4]<<32);
  • #include "sctimer.h"
    #include "stdint.h" 
    #include "string.h"
    #include "board.h"
    #include "radio.h"
    #include "leds.h"
    #include "uart.h"
    
    //=========================== defines =========================================
    
    #define LENGTH_PACKET        125+LENGTH_CRC ///< maximum length is 127 bytes
    #define CHANNEL              20             
    #define LENGTH_SERIAL_FRAME  7              ///< length of the serial frame
    #define SCTIMER_PERIOD     32768            // @32kHz = 1s
    
    
    //=========================== variables =======================================
    
    typedef struct {
       uint8_t    num_startFrame;
       uint8_t    num_endFrame;
       uint64_t   num_asn;
    } app_dbg_t;
    
    app_dbg_t app_dbg;
    
    typedef struct {
       // rx packet
       volatile   uint8_t    rxpk_done;
                  uint8_t    rxpk_buf[LENGTH_PACKET];
                  uint8_t    rxpk_len;
       // uart
                  uint8_t    uart_txFrame[LENGTH_SERIAL_FRAME];
                  uint8_t    uart_lastTxByte;
       volatile   uint8_t    uart_done;
    
    } app_vars_t;
    
    app_vars_t app_vars;
    
    //=========================== prototypes ======================================
    
    // radio
    void cb_startFrame(PORT_TIMER_WIDTH timestamp);
    void cb_endFrame(PORT_TIMER_WIDTH timestamp);
    void cb_countASN();
    
    // uart
    void cb_uartTxDone(void);
    
    //=========================== main ============================================
    
    int mote_main(void) {
       
       // clear local variables
       memset(&app_vars,0,sizeof(app_vars_t));
       
       // initialize board
       board_init();
       
       // add callback functions radio
       sctimer_setStartFrameCb(cb_startFrame);
       sctimer_setEndFrameCb(cb_endFrame);
       sctimer_setCompare(sctimer_readCounter()+SCTIMER_PERIOD);
       
       // setup UART
       uart_setCallbacks(cb_uartTxDone);
       
       // prepare radio
       radio_rfOn();
       radio_setFrequency(CHANNEL);
       
       // switch in RX
       radio_rxEnable();
       radio_rxNow();
       
       while (1) {
          
          // sleep while waiting for at least one of the rxpk_done to be set
          app_vars.rxpk_done = 0;
          while (app_vars.rxpk_done==0) {
             board_sleep();
          
          }
          
          // if I get here, I just received a packet
          
          //===== send notification over serial port
          
          // format frame to send over serial port
          if (app_vars.rxpk_buf[0] == 0x08){
    
          app_vars.uart_txFrame[0] = app_vars.rxpk_buf[17];  // ASN #1
          app_vars.uart_txFrame[1] = app_vars.rxpk_buf[18];  // ASN #2
          app_vars.uart_txFrame[2] = app_vars.rxpk_buf[19];  // ASN #3
          app_vars.uart_txFrame[3] = app_vars.rxpk_buf[20];  // ASN #4
          app_vars.uart_txFrame[4] = app_vars.rxpk_buf[21];  // ASN #5
          app_vars.uart_txFrame[5] = 0xff;                   // closing flag
          app_vars.uart_txFrame[6] = 0xfb;                   // closing flag
    
          app_vars.uart_done          = 0;
          app_vars.uart_lastTxByte    = 0;
          
          // send app_vars.uart_txFrame over UART
          uart_clearTxInterrupts();
          uart_enableInterrupts();
          uart_writeByte(app_vars.uart_txFrame[app_vars.uart_lastTxByte]);
          while (app_vars.uart_done==0); // busy wait to finish
          uart_disableInterrupts();
       }
          else {
              app_vars.uart_done=1;
          }
    
       }
    }
    
    //=========================== callbacks =======================================
    
    //===== radio
    
    void cb_startFrame(PORT_TIMER_WIDTH timestamp) {
       
       // update debug stats
       app_dbg.num_startFrame++;
    
    }
    
    void cb_endFrame(PORT_TIMER_WIDTH timestamp) {
       
       // update debug stats
       app_dbg.num_endFrame++;
       // indicate I just received a packet
       app_vars.rxpk_done = 1;
    
       // get packet from radio
       radio_getReceivedFrame(
          app_vars.rxpk_buf,
          &app_vars.rxpk_len,
          sizeof(app_vars.rxpk_buf));
    }
    
    //===== uart
    
    void cb_uartTxDone(void) {
       
       uart_clearTxInterrupts();
       
       // prepare to send the next byte
       app_vars.uart_lastTxByte++;
       
       if (app_vars.uart_lastTxByte<sizeof(app_vars.uart_txFrame)) {
          uart_writeByte(app_vars.uart_txFrame[app_vars.uart_lastTxByte]);
       } else {
          app_vars.uart_done=1;
       }
    }
    
    
    
    
    I attached my code in here too for easier understanding.

  • Yes, that is another way of doing it.
  • Thank you. also I have another question.

    I am currently trying to build a counter that increments every 7.25ms.

    My device is TelosB, which is MSP430F1611 with Crystal Oscilator of 32768Hz.

    I set the Timer_B with ACLK which is the crystal and as time = number of counts/frequency.

    To increment every 7.25ms, 328 counts are required.  Please refer to the code attached.

    I have an issue, because two of capture/compare reigsters are occupied for radio capture and interval.

    Here I declared

    void sctimer_asncounter(void){

    TBCCTL3 = CCIE;

    TBCCR3 = 328;

    TBCCTL3 |= CCIFG;

    }

    which triggers the appropriate interrupt handler.

    case 0x0006: // CCR3 fires

    if (TBCCTL3 & CCI){

    if(sctimer_vars.asnreadcb !=NULL){

    sctimer_vars.asnreadcb();

    // kick the OS

    return KICK_SCHEDULER;

    }

    }

    where

    void cb_asnread(void){

    app_vars.num_asn++;

    uart_writeByte(app_vars.num_asn);

    sctimer_asncounter();

    sctimer_setCompare(sctimer_readCounter()+SCTIMER_PERIOD);

    }

    So it should constantly increases app_vars.numb_asn++ every 7.25ms but for somereason I can't even compile the code.

    any help will be greatly appreicated.

    Thank you.

    #include "stdint.h"
    #include "string.h"
    #include "board.h"
    #include "debugpins.h"
    #include "leds.h"
    #include "sctimer.h"
    #include "uart.h"
    
    
    //=========================== defines =========================================
    
    #define SCTIMER_PERIOD     32768 // @32kHz = 1s
    
    //=========================== variables =======================================
    
    typedef struct {
       uint16_t num_compare;
       uint16_t num_last_value;
       uint64_t num_asn;
    } app_vars_t;
    
    app_vars_t app_vars;
    
    //=========================== prototypes ======================================
    
    void cb_compare(void);
    void cb_asnread(void);
    
    //=========================== main ============================================
    
    /**
    \brief The program starts executing here.
    */
    int mote_main(void) {  
       
       // initialize board. 
       board_init();
       
       sctimer_set_callback(cb_compare);
       sctimer_set_setasnreadcb(cb_asnread);
       sctimer_setCompare(sctimer_readCounter()+SCTIMER_PERIOD);
    
    
       while (1) {
          board_sleep();
       }
    }
    
    //=========================== callbacks =======================================
    
    void cb_asnread(void){
      app_vars.num_asn++;
      uart_writeByte(app_vars.num_asn);
    
      sctimer_asncounter();
      sctimer_setCompare(sctimer_readCounter()+SCTIMER_PERIOD);
    
    }
    
    void cb_compare(void) {
       
       // increment counter
       app_vars.num_compare++;
    
       sctimer_setCompare(sctimer_readCounter()+SCTIMER_PERIOD);
    }
    
    #include "sctimer.h"
    #include "msp430f1611.h"
    #include "sctimer.h"
    #include "board.h"
    #include "leds.h"
    #include "radio.h"
    #include "uart.h"
    
    // ========================== define ==========================================
    
    #define TIMERLOOP_THRESHOLD    0x4000     // 0.5 seconds @ 32768Hz clock
    #define MINIMUM_COMPAREVALE_ADVANCE  3
    
    // ========================== variable ========================================
    
    typedef struct {
        sctimer_cbt         cb;
        sctimer_capture_cbt startFrameCb;
        sctimer_capture_cbt endFrameCb;
        sctimer_asn_cbt     asnreadcb;
        uint8_t             f_SFDreceived;
    } sctimer_vars_t;
    
    sctimer_vars_t sctimer_vars;
    
    // ========================== private ==========================================
    
    // ========================== protocol =========================================
    
    /**
    \brief Initialization sctimer.
    */
    void sctimer_init(void){
        memset(&sctimer_vars, 0, sizeof(sctimer_vars_t));
       
       // radio's SFD pin connected to P4.1
       P4DIR   &= ~0x02; // input
       P4SEL   |=  0x02; // in CCI1a/B mode
          
       // CCR1 in capture mode
       TBCCTL1  =  CM_3+SCS+CAP+CCIE;
       TBCCR1   =  0;
       
       // CCR2 in compare mode (disabled for now)
       TBCCTL2  =  0;
       TBCCR2   =  0;
    
       // CCR3 in Count mode (disabled for now)
       TBCCTL3  =  0;
       TBCCR3   =  0;
    
       // start counting
       TBCTL    =  MC_2+TBSSEL_1;                    // continue mode, clocked from ACLK
    }
    
    void sctimer_set_callback(sctimer_cbt cb){
        sctimer_vars.cb = cb;
    }
    
    void sctimer_setStartFrameCb(sctimer_capture_cbt cb){
        sctimer_vars.startFrameCb = cb;
    }
    
    void sctimer_setEndFrameCb(sctimer_capture_cbt cb){
        sctimer_vars.endFrameCb = cb;
    }
    
    void sctimer_setasnreadcb(sctimer_asn_cbt cb){
        sctimer_vars.asnreadcb = cb;
    
    }
    
    void sctimer_asncounter(void){
        TBCCTL3 = CCIE;
        TBCCR3 = 328;
        TBCCTL3 |= CCIFG;
    }
    /**
    \brief set compare interrupt
    */
    void sctimer_setCompare(PORT_TIMER_WIDTH val){
        TBCCTL2             =  CCIE;
        if (TBR - val < TIMERLOOP_THRESHOLD){
            // the timer is already late, schedule the ISR right now manually 
            // setting the interrupt flag triggers an interrupt
            TBCCTL2          |=  CCIFG;
        } else {
            if (val-TBR<MINIMUM_COMPAREVALE_ADVANCE){
                // there is hardware limitation to schedule the timer within TIMERTHRESHOLD ticks
                // setting the interrupt flag triggers an interrupt
                TBCCTL2          |=  CCIFG;
            } else {
                // schedule the timer at val
                TBCCR2            =  val;
            }
        }
    }
    
    /*
    \brief Return the current value of the timer's counter.
    
     \returns The current value of the timer's counter.
    */
    PORT_TIMER_WIDTH sctimer_readCounter(void){
        return TBR;
    }
    
    void sctimer_enable(void){
        TBCCTL2 |=  CCIE;
    }
    
    void sctimer_disable(void){
        TBCCTL2 &= ~CCIE;
    }
    
    // ========================== private =========================================
    
    
    //=========================== interrupt handlers ==============================
    
    /**
    \brief TimerB CCR1-6 interrupt service routine
    */
    kick_scheduler_t sctimer_isr() {
       PORT_TIMER_WIDTH tbiv_local;
       
       // reading TBIV returns the value of the highest pending interrupt flag
       // and automatically resets that flag. We therefore copy its value to the
       // tbiv_local local variable exactly once. If there is more than one 
       // interrupt pending, we will reenter this function after having just left
       // it.
       
       tbiv_local = TBIV;
       
       switch (tbiv_local) {
          case 0x0002: // CCR1 fires
             if (TBCCTL1 & CCI) {
                // SFD pin is high: this was the start of a frame
                if (sctimer_vars.startFrameCb!=NULL) {
                   sctimer_vars.startFrameCb(TBCCR1);
                   sctimer_vars.f_SFDreceived = 1;
                   // kick the OS
                   return KICK_SCHEDULER;
                }
             } else {
                // SFD pin is low: this was the end of a frame
                if (sctimer_vars.endFrameCb!=NULL) {
                   if (sctimer_vars.f_SFDreceived == 1) {
                      sctimer_vars.endFrameCb(TBCCR1);
                      sctimer_vars.f_SFDreceived = 0;
                   }
                   TBCCTL1 &= ~COV;
                   TBCCTL1 &= ~CCIFG;
                   // kick the OS
                   return KICK_SCHEDULER;
                }
             }
             break;
          case 0x0004: // CCR2 fires
             if (sctimer_vars.cb!=NULL) {
                sctimer_vars.cb();
                // kick the OS
                return KICK_SCHEDULER;
             }
             break;
          case 0x0006: // CCR3 fires
              if (TBCCTL3 & CCI){
                if(sctimer_vars.asnreadcb !=NULL){
                  sctimer_vars.asnreadcb();
                   // kick the OS
                   return KICK_SCHEDULER;
                }
              }
             break;
          case 0x0008: // CCR4 fires
             break;
          case 0x000a: // CCR5 fires
             break;
          case 0x000c: // CCR6 fires
             break;
          case 0x000e: // timer overflow
             break;
       }
       return DO_NOT_KICK_SCHEDULER;
    }
    

    2100.sctimer.h

**Attention** This is a public forum