⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hplm16c62pflashc.nc

📁 tinyos-2.x.rar
💻 NC
字号:
/*
 * Copyright (c) 2009 Communication Group and Eislab at
 * Lulea University of Technology
 *
 * Contact: Laurynas Riliskis, LTU
 * Mail: laurynas.riliskis@ltu.se
 * All rights reserved.
 *
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of Communication Group at Lulea University of Technology
 *   nor the names of its contributors may be used to endorse or promote
 *    products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
 * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "M16c62pFlash.h"
#include "iom16c62p.h"

/**
 * Implementation of the HplM16c62pFlash interface. Note that this module
 * should be used with caution so that one doesn't erase the flash where the
 * executing program lies.
 * 
 * @author Henrik Makitaavola <henrik.makitaavola@gmail.com>
 * @author Renesas
 */
// TODO(henrik) This implementation expects a main clock speed <=10 MHz, fix it.
module HplM16c62pFlashC
{
  provides interface HplM16c62pFlash;
}
implementation
{

// Defines an array of highest even addresses for each block
const unsigned long block_addresses[14] =
  {0xFFFFE,0xFEFFE,0xFDFFE,0xFBFFE,0xF9FFE,0xF7FFE,0xEFFFE,0xDFFFE,0xCFFFE,
   0xBFFFE,0xAFFFE,0x9FFFE,0x8FFFE,0xFFFE };
  
unsigned char cm0_saved;			// For saving the Clock Mode 0 register
unsigned char cm1_saved;			// For saving the Clock Mode 1 register
unsigned char pm0_saved;			// For saving the Processor Mode 0 register
unsigned char pm1_saved;			// For saving the Processor Mode 1 register
unsigned char prcr_saved;			//  Save Protection register
  
/**   
 * Sets the processor mode for programming flash and saves current
 * settings to restore later. You cannot run the processor faster
 * than 10.0 MHz (with wait state) or 6.25MHz (without wait state)
 * when sending commands to the flash controller.
 */
void SlowMCUClock(void)
{
  // Unprotect registers CM0 and CM1 and PM0 registers by writting to protection register
  prcr_saved = *((char *)0xA);	// Save Protection register
  *((char *)0xA) = 3;				// Allow writting to protected system registers
  // Force to Single chip mode for processors that have memory expansion mode
  pm0_saved = *((char *)0x4);				// Save pm0 register
  *((char *)0x4) = pm0_saved & 0xFC;		// bit 0 and 1 to zero

  cm0_saved = *((char *)0x6);		// Save cm0 register
  cm1_saved = *((char *)0x7);		// Save cm1 register
  pm1_saved = *((char *)0x5);		// Save pm1 register

  // Insert Wait state for all bus access (needed for talking to the
  // internal flash controller)
  asm("BSET	7,0x05"); // Set bit PM17
  CM0.BYTE = 0;
  CM1.BYTE = 0;
}

/**
 * Restores the processor mode back to original settings.
 */
void RestoreMCUClock(void)			
{
  *((char *)0x4) = pm0_saved;		// Restore pm0 register

  /* Clock settings for R8C and M16C */
  *((char *)0x7) = cm1_saved;		// Restore cm1 register
  *((char *)0x6) = cm0_saved;		// Restore cm0 register
  *((char *)0x5) = pm1_saved;		// Restore pm1 register
  *((char *)0xA) = prcr_saved;	// Protection back on
}

command bool HplM16c62pFlash.FlashErase( unsigned char block )
{
    unsigned int low = (unsigned int) block_addresses[ block ];
    unsigned int high = (unsigned int)( block_addresses[ block ] >> 16);

	// Must change main clock speed to meet flash requirements
	SlowMCUClock();			
        FMR0.BIT.FMR01 = 0;
        FMR0.BIT.FMR01 = 1;
        FMR1.BIT.FMR11 = 0;
        FMR1.BIT.FMR11 = 1;

    asm volatile ("mov.w %[low], a0\n\t"
                  "mov.w %[high], a1\n\t"
                  
                  "mov.w #0x0050, r0\n\t"
                  "ste.w r0, [a1a0]\n\t"
                  
                  "mov.w #0x0020, r0\n\t"
                  "ste.w r0, [a1a0]\n\t"
                  
                  "mov.w #0x00D0, r0\n\t"
                  "ste.w r0, [a1a0]\n\t"
                  :
                  :[low] "r" (low), [high] "r" (high)
                  : "memory", "r0", "a0", "a1");

	// Note: In EW1 Mode, the MCU is suspended until the operation is completed.
    while (!FMR0.BIT.FMR00);
	// Disable CPU rewriting commands by clearing EW entry bit.
	FMR0.BYTE = 0;

	RestoreMCUClock(); // Restore clock back to original speed

	if( FMR0.BIT.FMR07)	// Erasing error?
	{
		return 1;  // Erase Fail
	}

	return 0;  // Erase Pass
}

command uint8_t HplM16c62pFlash.FlashWrite( unsigned long flash_addr,
			     unsigned int * buffer_addr,
			     unsigned int bytes)
{
  unsigned char ret_value = 0;
  unsigned int low = (unsigned int) flash_addr;
  unsigned int high = (unsigned int)( flash_addr >> 16);
  unsigned int i;
  // Check for odd number of bytes 
  if( bytes & 1)
    return 2;	// ERROR!! You must always pass an even number of bytes.

  // Check for odd address
  if( (int)flash_addr & 1)
    return 2;	// ERROR!! You must always pass an even flash address

  // Must change main clock speed to meet flash requirements
  SlowMCUClock();			

  FMR0.BIT.FMR01 = 0;
  FMR0.BIT.FMR01 = 1;
  FMR1.BIT.FMR11 = 0;
  FMR1.BIT.FMR11 = 1;

  // Clear status register
  asm volatile ("mov.w %[low], a0\n\t"
      "mov.w %[high], a1\n\t"

      "mov.w #0x0050, r0\n\t"
      "ste.w r0, [a1a0]\n\t"
      :
      :[low] "r" (low), [high] "r" (high)
      : "memory", "r0", "a1", "a0");

  for (i = 0; i < (bytes >> 1); ++i)
  {
    // Write to the flash sequencer by writing to that area of flash memory
    asm volatile (
        "mov.w %[low], a0\n\t"
        "mov.w %[high], a1\n\t"

        "mov.w #0x0040, r1\n\t" // Send write command
        "ste.w r1, [a1a0]\n\t"

        "mov.w %[data], r1\n\t" // Write data
        "ste.w r1, [a1a0]\n\t"
        :
        :[low] "r" (low), [high] "r" (high), [data] "r" (*buffer_addr)
        : "memory", "a1", "a0", "r1");

    // Note: In EW1 Mode, the MCU is suspended until the operation completed

    // Read flash program status flag
    if( FMR0.BIT.FMR06 ) // Write error?
    {
      ret_value = 1;		// Signal that we had got an error
      break;				// Break out of while loop
    }

    flash_addr += 2;		// Advance to next flash write address
    buffer_addr++;			// Advance to next data buffer address
    low = (unsigned int) flash_addr;
    high = (unsigned int)( flash_addr >> 16);
  }

    asm volatile ("mov.w %[low], a0\n\t"
                  "mov.w %[high], a1\n\t"
                  "ste.w 0x00FF, [a1a0]\n\t"
                  :
                  :[low] "r" (low), [high] "r" (high)
                  : "memory", "a0", "a1");

  // Disable CPU rewriting commands by clearing EW entry bit
  FMR0.BYTE = 0;
  RestoreMCUClock();		// Restore clock back to original speed

  return ret_value;		// Return Pass/Fail
}

command uint8_t HplM16c62pFlash.FlashRead(unsigned long address) {
  unsigned int low = (unsigned int)(address);
  unsigned int high = (unsigned int)(address >> 16);
  unsigned int data;
  asm volatile ("mov.w %[low], a0\n\t"
                "mov.w %[high], a1\n\t"
                "ste.w 0x00FF, [a1a0]\n\t"
                "lde.w [a1a0], %[data]"
                :[data] "=r" (data)
                :[low] "r" (low), [high] "r" (high)
                : "memory", "a0", "a1");
  return data;
}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -