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.

Flash problem

Other Parts Discussed in Thread: MSP430FW427

Hello, I have a problem.

In msp430fw427,  after receiving some bytes, i'm save them into a flash.

And, i use scan interface.

My problem is after saving into a flash, programm goes in ISR for Scan interface, in this subroutine i have a counter,and it's incremented by 1, however no rotation in system.

Can you help why it's happens?

In subroutine for writting in flash, i'm disable and enable interruprt after writting is complete.

  • Hi Shubin,

    You have posted very general question. I am afraid that you will get very general answers for this. Rather post your code stating where you have struck and what you are looking for.

    Posting your code might be helpful for us to look in to your problem.  Please use "Syntax hilighter" while posting your code it helps other to look at your code easily. 

    Cheers.

  • Disabling interrupts does not stop the scan operation, it only blocks execution for the ISR. So maybe while writing to flash, multiple interrupts happen, and you only serve the last.
    Writing to flash takes a long time!

  • int main(void)
    {
        //int i=0;

          SCFQCTL = SCFQ_256K;
            FLL_CTL1 = FLL_DIV_8;
          WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
      while(FLL_CTL0 & LFOF);                      // Wait until LF OSC stabilizes

      GPIOConfig();                                // GPIO Configuration

      CCTL0 = OUT;                              // TXD Idle as Mark
      TACTL = TASSEL_1 + MC_2;                  // SMCLK, continuous mode

      // SIFCalib();                                //Working with fast rotation

      SIFDACR0 = 0x0237;                        //Manual calibration
      SIFDACR1 = 0x01FB;
      SIFDACR2 = 0x0237;
      SIFDACR3 = 0x01FB;

      InitScanIF();
      MbusInit();
      MBusAlarmInit();

      FCTL2 = FWKEY +FSSEL_2+FN0; // FWKEY+FSSEL1+FN1;

      while(1){

          RX_Ready();                                                 // UART ready to RX one Byte
          _BIS_SR(CPUOFF+GIE);                                        //Wait RX byte

           if(RXTXData == 0x10){                                    //if short frame
               length = 5;
               MakeMassive (length);                                //Buffering packet
                if (Buffer[1]==C_SNDNKE && Buffer[2]==Address){        //Request for ASK
                   checksum = Buffer[1]+Buffer[2];
                   checksum = checksum&0xff;
                   if(checksum == Buffer[3]){
                       MBusSend_ACK();                                //Response to Short Frame
                   }
              

          else if (RXTXData == 0x68){
              unsigned int j;

              RX_Ready();                                             // UART ready to RX one Byte
              _BIS_SR(CPUOFF+GIE);
              length = RXTXData;
              length = length + 5;
              SIFCTL1 &= ~0x1000;
             // while(BitCnt !=0);
              MakeMassive (length);
              if(Buffer[2] == 0x68 && Buffer[3] == C_SNDUD && Buffer[4]==BRDCST_ADDR && Buffer[5] ==  CI_DATASEND && Buffer[6] == DIF_ChangeAddress &&
                                              Buffer[7] == VIF_ChangeAddress){                                                                                        //Change address
                              checksum = 0;
                              for(j=3;j<length-2;j++){
                                       checksum = checksum + Buffer[j];
                                       checksum = checksum & 0xff;
                              }
                              if(checksum == Buffer[9]){
                                Address = Buffer[8];
                                MBusSend_ACK();

                            WriteCountToFlash(Address,IDENT,unit,WaterCounter); //function for writting
                        SIFCTL1 &= ~0x0060;

                              }
              }
             
    }

    #pragma vector = SCANIF_VECTOR
      __interrupt void ISR_ScanIF(void)
    {
    if(SIFCTL1&0x1000){
          if (FirstRotation == 0){                                                            //Not first rotation
              if (PreviousCount == 0x00 && SIFCNT == 0xff){                                    //if rotation CounterClockwise --> SIFCNT--; --> BackWaterCounter++
                        AlarmBckRt = 1;
                        BackWaterCounter++;
                        PreviousCount = SIFCNT;
              }
              else if(PreviousCount<SIFCNT | (PreviousCount==0xff && SIFCNT==0x00)){        //if rotation Clockwise --> SIFCNT++;
                     WaterCounter++;
                     PreviousCount = SIFCNT;
              }

              else{                                                                            //if start from Clockwise = 1 and rotate CounterClockwise
                     AlarmBckRt = 1;
                     BackWaterCounter++;
                     PreviousCount = SIFCNT;
              }
          }

          if(FirstRotation == 1){                                                             //check first rotation
              if (SIFCNT == 0xff){                                                            //if start from 0xff it means rotation is CounterClockwise
                    CounterClockwise = 1;
                    PreviousCount = 0xff;
                  }
              if (SIFCNT == 0x01){                                                            //if start from 0x00 it means rotation is Clockwise
                      Clockwise = 1;
                      PreviousCount = 0x01;
              }
          FirstRotation = 0;
          }
    SIFCTL1 &= ~0x0060;                                                                        //Clear Interrupt flag
    }
    }

    void WriteCountToFlash(unsigned add,unsigned long id, unsigned int unit, unsigned long count)
    {
    //    __disable_interrupt();
        unsigned int wait;
        wait = FCTL3&BIT3;
        wait = wait>>3;
      int *Flash_add, *Flash_id0,*Flash_id1,*Flash_unit,*Flash_count0,*Flash_count1;
      Flash_add = (int *) 0x1000; //
      Flash_id0 = (int *) 0x101C;
      Flash_id1 = (int *) 0x101E;
      Flash_unit = (int *) 0x1038;
      Flash_count0 = (int *) 0x1054;
      Flash_count1 = (int *) 0x1056;
      FCTL3 = FWKEY;
      FCTL1 = FWKEY + ERASE; // Установка бита стирания сегмента
      *Flash_id0 = 1; // Инициализация указателя
      FCTL3 = FWKEY+LOCK;

      FCTL3 = FWKEY;
      FCTL1 = FWKEY + WRT;
      //*Flash_ptr++ = value; // Запись значения во Flash
      *Flash_add = add;
      while(wait != 1);
      *Flash_id0 = id&0xffff;
      while(wait != 1);
      *Flash_id1 = (id&0xffff0000)>>16;
      while(wait != 1);
      *Flash_unit = unit;
      while(wait != 1);
      *Flash_count0 = count&0xffff;
      while(wait != 1);
      *Flash_count1 = (count&0xffff0000)>>16;
      while(wait != 1);
      FCTL1 = FWKEY;
      FCTL3 = FWKEY + LOCK; // Установка бита запрещения записи
      SIFCTL1 &= ~0x01F8;
    //  __enable_interrupt();

    }

    void InitScanIF(void)
    { int i;

      // Initialize Timing State Machine
      SIFTSM0 = 0x8800;   // DAC=off, CA=off, 31xSMCLK    (delay for proper timing for both LC sensors)

      SIFTSM1 = 0x002C;   // DAC=off, CA=off,  1xSIFCLK, excitation  SIFCH.0
      SIFTSM2 = 0x0424;   // DAC=off, CA=off,  1xACLK                SIFCH.0
      SIFTSM3 = 0x1934;   // DAC=on,  CA=on,   4xSIFCLK              SIFCH.0
      SIFTSM4 = 0x4134;   // DAC=on,  CA=on,  14xSIFCLK              SIFCH.0
      SIFTSM5 = 0x2174;   // DAC=on,  CA=on,  14xSIFCLK              SIFCH.0

      SIFTSM6 = 0x002D;   // DAC=off, CA=off,  1xSIFCLK, excitation  SIFCH.1
      SIFTSM7 = 0x0425;   // DAC=off, CA=off,  1xACLK                SIFCH.1
      SIFTSM8 = 0x1935;   // DAC=on,  CA=on,   4xSIFCLK              SIFCH.1
      SIFTSM9 = 0x4135;   // DAC=on,  CA=on,  14xSIFCLK              SIFCH.1
      SIFTSM10 = 0x2175;  // DAC=on,  CA=on,  14xSIFCLK              SIFCH.1

      SIFTSM11 = 0x0220;   // stop

      // Initialize Scan Interface Control Registers
      SIFCTL2 = 0x0140;  // DAC and comparator are controlled by SIFTSMx
      for (i=0;i<=857;i++); // wait loop. SIFVCCEx has to settle
      SIFCTL3 = 0x4000;  // SIF0OUT selected for S1, SIF1OUT selected for S2
                         // (S1 and S2 are input signals of Processing State Machine)
      SIFCTL4 = 0x33F0;  // initialize PSM counters
      SIFCTL5 = 0x0045;  // SIFCLK is controlled by SIFTSMx
                         // SIFCLK = 1MHz
      SIFPSMV = (unsigned int) &PSM; // Definition of PSM vector
      SIFCTL1 |= 0x1001; // switch on Scan Interface. enable interrupt
    }


    It's my code. Hope it's not obstruct you!!

  • Thank you for you helps :)

    In my experiments, then I'm writting into a flash, no rotation and interrupt can come on.

  • In your flash write function, you definitely need to disable interrupts (currently, you have disabled the interrupt disable). If an interrupt is serviced during flash write, the system will likely crash, as the CPU will read 0x3fff as ISR address from the inaccessible flash. Be safe, don’t assume that there will be no interrupt from anywhere.

    Also, in your write code, you do “write >>3” and later “while (wait !=1)” First, the shift is unnecessary. After FCTL3&BIT3, wait will either be 0 or BIT3. 0 is false and BIT3 is as true as BIT3>>3 is. So a “while (!wait)” is sufficient.
    However, your wait won’t ever change state. It holds the value at the time you read FCTL3. At which the wait bit was clear. And wait stays 0, no matter whether the wait bit in FCTL3 changes state later. If wait were 1 for some reason when you read FCTL3, then your code would be stuck forever in the first while loop. But this won’t happen. If your code runs form flash, it will never see the wait bit set, except for a block erase. While the flash is busy writing, the CPU will fetch 0x3fff as next instruction, which is JMP $. So it jumps on place doing nothing but jumping, until the flash write is done, the wait bit is clear and the flash controller delivers the real next CPU instruction.

  • Jens-Michael Gross, it's means I don't need to do :

    while (wait !=1) ?

    And that about my main problem in folling down in ISR?

    Thank you,  for help!

  • You don’t need to check for !=1 when the variable can only be zero or non-zero (whether it is “BIT3” or “1” doesn’t matter). A check for zero can be done with a simple (!wait) while a check for non-zero (bit set) is done with an even simpler (wait).
    Also, you don’t need to wait for the wait bit, as the bit is always clear when the CPU is executing code from flash. Except for a block erase, where you would need to check it.
    Finally, you have to check the FCTL3 register itself in the while, not the content of the register that you recorded long ago. Your variable ‘wait’ is static. It won’t change ever. So a while(wait); either loops forever or not at all.

    About the ScanIF ISR, sorry, I don't have ever worked with it, so I don't know why the ISR is called and what it should do. I can only tell you that during a flash write, interrupts must be disabled, but while the flash write is done, interrupts may be pending, even multiple interrupts.
    Imagine what happens when lastCount is 0 and two interrupts happened during flash write (overflow). Then SIFCNT is 0xFE and not 0xFF and none of your cases will apply.

    BTW: don't use a for loop for a delay. The compiler might optimize it away, and even if not, the execution time is unknown. eithe ruse __delayCycles() or a timer delay.

     

**Attention** This is a public forum