예제 #1
0
char BSL430_writeMemory(unsigned long startAddr, unsigned int size,  char* data)
{
	unsigned long i;
	char exceptions = SUCCESSFUL_OPERATION;

	for (i = startAddr; i < startAddr + size; i++)
	{
#ifndef RAM_WRITE_ONLY_BSL
		if ((startAddr & 0x01) || i == startAddr + size - 1)
#endif
		{
			exceptions = BSL430_writeByte(i, *data);
			data += 1;
		}
#ifndef RAM_WRITE_ONLY_BSL
		else
		{
			exceptions = BSL430_writeWord(i, *(int *)data);
			data += 2;
			i++;
		}
		if (exceptions != SUCCESSFUL_OPERATION)
		{
			return exceptions;
		} // if
#endif
	}     // for
	return exceptions;
}
예제 #2
0
char flushBuffer(void)
{
    unsigned long i;
    char exceptions = SUCCESSFUL_OPERATION;
    unsigned char* data = &BlockBuffer[0];

    if (LockedStatus == UNLOCKED)
    {
        if (((BlockBufferStart & 0x7F) == 0) && (BlockBufferPtr == 128)) //Buffer is full and
                                                                         // aligned
        {
            while (FCTL3 & BUSY) ;
            FCTL3 = FWKEY;                                               // Clear Lock bit
            FCTL1 = FWKEY + BLKWRT + WRT;                                // Set write/block bit

            for (i = BlockBufferStart; i < BlockBufferStart + 128; i += 4)
            {
                __data20_write_long(i, *((long*)data));
                data += 4;
                while ((FCTL3 & WAIT) == 0) ;
            } // for
            FCTL1 = FwRamKey;
            while (FCTL3 & BUSY) ;
            FCTL3 = FwRamKey + LOCK;
        } // if
        else
        {
            FCTL3 = FwRamKey;                                            // Clear Lock bit
            FCTL1 = FwRamKey + WRT;                                      // Set write bit
            for (i = BlockBufferStart; i < BlockBufferStart + BlockBufferPtr; i++)
            {
                if ((BlockBufferStart & 0x01) || i == BlockBufferStart + BlockBufferPtr - 1)
                {
                    exceptions = BSL430_writeByte(i, *data);
                    data += 1;
                }
                else
                {
                    exceptions = BSL430_writeWord(i, *(int *)data);
                    data += 2;
                    i++;
                }
                if (exceptions != SUCCESSFUL_OPERATION)
                {
                    return exceptions;
                } // if
            }     // for
        }         // else
        BlockBufferStart = 0;
        BlockBufferNext = 0;
        BlockBufferPtr = 0;
    }
    else
    {
        exceptions = BSL_LOCKED;
    }
    return exceptions;
}
예제 #3
0
void FlashFirmware()
{
  unsigned int i;
  char *pBuffer;
  WriteState state;

  uint16_t NumByteToRead;
  uint32_t NumByteToWrite;

  uint32_t write_ptr;
  uint32_t buffer[32]; // 32 * 4 = 128
  
  __disable_interrupt();                    // 5xx Workaround: Disable global
                                            // interrupt while erasing. Re-Enable
                                            // GIE if needed

  state = STATE_NEEDSIGNATURE;
  // Start the loop
  while(state != STATE_DONE)
  {
    putchar_('a' + state);
    switch(state)
    {
      case STATE_NEEDSIGNATURE:
      NumByteToRead = 10; // the size of file header, sync with main.c under convert tool src
      SPI_FLASH_CS_LOW();
      SPI_FLASH_SendCommandAddress(W25X_ReadData, FIRMWARE_BASE);

      break;
      case STATE_NEEDADDR:
      NumByteToRead = 8; // one address and one 
      break;
      case STATE_WRITE:
      if (NumByteToWrite > 128)
        NumByteToRead = 128;
      else
        NumByteToRead = NumByteToWrite;
      break;
    }
 
    pBuffer = (char*)&buffer[0];;
    for(int i = 0; i < NumByteToRead; i++)
    {
      *pBuffer = ~SPI_FLASH_SendByte(Dummy_Byte);
      pBuffer++;
    }

    switch(state)
    {
      case STATE_NEEDSIGNATURE:
      {
        if (buffer[0] != SIGNATURE)
        {
          SPI_FLASH_CS_HIGH();
          state = STATE_DONE; // error
          continue;
        }

        // Erase Flash
        BSL430_massErase();
        state = STATE_NEEDADDR;
      }
      break;
      case STATE_NEEDADDR:
      {
        if (buffer[0] == 0 
          || buffer[0] == SIGNATURE) // hit the end
        {
          state = STATE_DONE;
          continue;
        }

        // first uint32 is start address, second uint32 is length
        write_ptr = buffer[0];
        NumByteToWrite = buffer[1];
        //putx_(write_ptr);
        //putx_(NumByteToWrite);
        state = STATE_WRITE;
      }
      break;
      case STATE_WRITE:
      {
        while(BUSY & FCTL3);                 // Test wait until ready for next byte
        // Write Flash
        FCTL1 = FWKEY+WRT;                 // Enable block write
        FCTL3 = FWKEY;                       // Set LOCK
        char* src = (char*)&buffer[0];
        for(i = 0; i < NumByteToRead; i++)
        {
          BSL430_writeByte(write_ptr++, *src++);
        }
        FCTL1 = FWKEY;
        FCTL3 = FWKEY+LOCK;                       // Set LOCK
        while(BUSY & FCTL3);                      // Check for write completion

        NumByteToWrite -= NumByteToRead;

        if (NumByteToWrite == 0)
          state = STATE_NEEDADDR;
      }
      break;
    }
  }

  // reboot
  WDTCTL = 0;
}
예제 #4
0
char BSL430_writeMemory(unsigned long startAddr, unsigned int size,  char* data)
{
    unsigned long i;
    char exceptions = SUCCESSFUL_OPERATION;

    // Note: this function compiles quite differently based on whether the
    // BSL is based out of RAM, or not.  RAM based BSLs can use buffering
    // and perform a block long word write.  This is primarily used for
    // USB BSLs for performance increase.
    // Flash based BSLs will use the second second of code, below

#ifdef RAM_BASED_BSL
    if (LockedStatus == UNLOCKED)
    {
        if ((BlockBufferStart == 0) || BlockBufferNext == startAddr)
        {
            // if we are starting, or continuing a block...
            if (BlockBufferStart == 0)
            {
                BlockBufferStart = startAddr;                 // if starting a new block, reset
                                                              // start addr
            }
            BlockBufferNext =  startAddr + size;              // always update the next addr for
                                                              // streaming
            for (i = 0; i < size;)
            {
                BlockBuffer[BlockBufferPtr++] = *data;        // add the incoming data to the buffer
                data++;
                startAddr++;
                i++;                                          // i incrimented here for check below
                if (((startAddr) & 0x7F) == 0x00)             // we've crossed a 128 byte block
                                                              // boundary
                {
                    flushBuffer();                            // flush out old buffer, writing...
                    // begin write on block boundary
                    return BSL430_writeMemory(startAddr, (size - i), data);
                } // if
            } // for
        } // if buffer start
        else
        {
            // for when data exists in the buffer, but we are jumping to a new place to write...
            flushBuffer();                                    // flush out old buffer, writing..
            return BSL430_writeMemory(startAddr, size, data); // begin buffering new data
        }
    } // if unlocked
    else
    {
        exceptions = BSL_LOCKED;
    }
    // Below is the writeMemory function compiled with Flash based BSLs.
#else
    for (i = startAddr; i < startAddr + size; i++)
    {
#    ifndef RAM_WRITE_ONLY_BSL
        // if the start address is odd, or we're 1 byte from end...
        if ((startAddr & 0x01) || i == startAddr + size - 1)
#    endif
        {
            exceptions = BSL430_writeByte(i, *data);
            data += 1;
        }
#    ifndef RAM_WRITE_ONLY_BSL
        // else, we're on an even addr, and have at least 1 word left..
        else
        {
            exceptions = BSL430_writeWord(i, *(int *)data);
            data += 2;
            i++;
        }
        if (exceptions != SUCCESSFUL_OPERATION)
        {
            return exceptions;
        } // if
#    endif
    }     // for
#endif
    return exceptions;
}