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

📄 telos-flash.c

📁 MANTIS是由科罗拉多大学开发的传感器网络嵌入式操作系统。 这是mantis的0.9.5版本的源码。
💻 C
字号:
//  This file is part of MANTIS OS, Operating System//  See http://mantis.cs.colorado.edu/////  Copyright (C) 2003,2004,2005 University of Colorado, Boulder////  This program is free software; you can redistribute it and/or//  modify it under the terms of the mos license (see file LICENSE)/* * @file telos-flash.c * @brief driver for the ST M25P80 flash * @author John Ledbetter * @date 07/01/2005 */#include "mos.h"#ifdef PLATFORM_TELOSB#include "telos-flash.h"#include "bitops.h"#include "spi.h"#include "mutex.h"#include "dev.h"// Command Bytes fo the M25P80#define WREN  0x06#define WRDI  0x04#define RDSR  0x05#define WRSR  0x01#define READ  0x03#define FREAD 0x0B#define PP    0x02#define SE    0xD8#define BE    0xC7#define DP    0xB9#define RES   0xAB#define DUMMY 0xAA// Status Register Masks for the M25P80#define WIP  0x01#define WEL  0x02#define BP0  0x04#define BP1  0x08#define BP2  0x10#define SRWD 0x80mos_mutex_t telos_flash_mutex;static uint32_t st_flash_addr;static uint8_t mode;/** @brief block until write in progress is no longer set in the status register */static inline void st_flash_block_wip(){   UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(RDSR);   while(spi_rx() & WIP)      ;   SET_PORT_1(ST_FLASH_CS);}/** @brief enable writing to the st flash */static inline void st_flash_write_enable(){   UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(WREN);   SET_PORT_1(ST_FLASH_CS);}/** @brief disable writing to the st flash */static inline void st_flash_write_disable(){   UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(WRDI);   SET_PORT_1(ST_FLASH_CS);}/** @brief send a 24bit address over the SPI */static inline void st_flash_tx_addr(uint32_t addr){   spi_tx_byte((uint8_t)((addr >> 16) & 0xFF));   spi_tx_byte((uint8_t)((addr >>  8) & 0xFF));   spi_tx_byte((uint8_t)((addr >>  0) & 0xFF)); }/** @brief read the st flash status register */static inline uint8_t st_flash_read_sr(){   uint8_t sr;   UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(RDSR);   sr = spi_rx();   SET_PORT_1(ST_FLASH_CS);   return sr;}/** @brief write to the st flash status register */static inline void st_flash_write_sr(uint8_t new_sr){   st_flash_block_wip();   st_flash_write_enable();      UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(WRSR);   spi_tx_byte(new_sr);   SET_PORT_1(ST_FLASH_CS);}/** @brief erase the entire flash */static inline void st_flash_bulk_erase(){   st_flash_block_wip();   st_flash_write_enable();      UNSET_PORT_1(ST_FLASH_CS);      spi_tx_byte(BE);      SET_PORT_1(ST_FLASH_CS);}/** @brief enter low power mode */static inline void st_flash_deep_powerdown(){   UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(DP);   SET_PORT_1(ST_FLASH_CS);}/** @brief initialize the st flash, enter deep power down mode */void st_flash_init(){   mos_mutex_init(&telos_flash_mutex);      SET_DIR_1(ST_FLASH_HOLD);   SET_DIR_1(ST_FLASH_CS);      SET_PORT_1(ST_FLASH_CS);   SET_PORT_1(ST_FLASH_HOLD);      SET_DIR_1(ST_FLASH_WP);   SET_PORT_1(ST_FLASH_WP);   SET_DIR_1(ST_FLASH_MOSI);   SET_DIR_1(ST_FLASH_SCLK);   UNSET_DIR_1(ST_FLASH_MISO);      // this macro need only be called once,   // either by the cc2420 init or here.   PLAT_SPI_INIT();   // initialize into low power mode   st_flash_deep_powerdown();     }/** @brief exit deep power down mode */static inline void st_flash_wake(){   UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(RES);   SET_PORT_1(ST_FLASH_CS);}/** @brief enter deep power down mode */static inline void st_flash_sleep(){   st_flash_block_wip();   st_flash_deep_powerdown();}/** @brief exit deep power down mode and/or read the signature */static inline uint8_t st_flash_read_sig(){   UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(RES);   spi_tx_byte(DUMMY);   spi_tx_byte(DUMMY);   spi_tx_byte(DUMMY);   uint8_t sig = spi_rx();   SET_PORT_1(ST_FLASH_CS);      return sig;}/** @brief read a block of data from addr in flash */static void st_flash_read(uint32_t addr, uint8_t* buffer, uint16_t count){      st_flash_block_wip();   mos_led_on(0);   UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(READ);   st_flash_tx_addr(addr);      uint16_t i = 0;       for(i = 0; i < count; ++i)   {      buffer[i] = spi_rx();      mos_led_toggle(2);   }       SET_PORT_1(ST_FLASH_CS);   mos_led_on(1);}/** @brief read a block of data from addr in flash, only faster! (supposedly) */static inline void st_flash_fast_read(uint32_t addr, uint8_t* buffer, uint16_t count){   st_flash_block_wip();      UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(FREAD);   st_flash_tx_addr(addr);   spi_tx_byte(DUMMY);      uint16_t i = 0;   for(i = 0; i < count; ++i)      buffer[i] = spi_rx();   SET_PORT_1(ST_FLASH_CS);}/** @brief write to a page in flash at addr */static void st_flash_page_program(uint32_t addr, const uint8_t* buffer, uint16_t count){         st_flash_block_wip();   st_flash_write_enable();   UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(PP);   st_flash_tx_addr(addr);   uint16_t i = 0;   for(i = 0; i < count; ++i)      spi_tx_byte(buffer[i]);   SET_PORT_1(ST_FLASH_CS);   }/** @brief erase the sector which contains address addr */static void st_flash_erase_sector(uint32_t addr){//   printf("addr = %d\n", (uint16_t)addr);      st_flash_block_wip();   st_flash_write_enable();   UNSET_PORT_1(ST_FLASH_CS);   spi_tx_byte(SE);   st_flash_tx_addr(addr);   SET_PORT_1(ST_FLASH_CS);   }/*interrupt (UART0TX_VECTOR) uart0_tx_int(void){}interrupt (UART0RX_VECTOR) uart0_rx_int(void){}*//** @brief put the flash into deep powerdown mode or power it up */uint8_t dev_mode_DEV_TELOS_FLASH (uint8_t newMode){   switch(newMode) {   case DEV_MODE_ON:   case DEV_MODE_IDLE:      st_flash_wake();      break;   case DEV_MODE_OFF:      st_flash_sleep();      break;   default:      return DEV_UNSUPPORTED;      break;   }   mode = newMode;   return DEV_OK;}/** @brief seek or erase */uint8_t dev_ioctl_DEV_TELOS_FLASH (int8_t request, ...){   va_list ap;      va_start (ap, request);      switch (request)   {   case DEV_SEEK:      st_flash_addr = va_arg (ap, uint32_t);      break;   case TELOS_FLASH_BULK_ERASE:      if(mode == DEV_MODE_OFF)	 st_flash_wake();      st_flash_bulk_erase();      if(mode == DEV_MODE_OFF)	 st_flash_sleep();      break;   case TELOS_FLASH_SECT_ERASE:      if(mode == DEV_MODE_OFF)	 st_flash_wake();      st_flash_addr = va_arg (ap, uint32_t);      st_flash_erase_sector(st_flash_addr);      if(mode == DEV_MODE_OFF)	 st_flash_sleep();      break;   default:      return DEV_BAD_IOCTL;   }   va_end(ap);   return DEV_OK;   }/** @brief read data from flash */uint8_t dev_read_DEV_TELOS_FLASH (void *buf, uint16_t count){   if(mode == DEV_MODE_OFF)      st_flash_wake();   st_flash_read(st_flash_addr, (uint8_t*)buf, count);   if(mode == DEV_MODE_OFF)      st_flash_sleep();      return count;}/** @brief write up to 256 bytes of data to a page in flash */uint8_t dev_write_DEV_TELOS_FLASH (const void *buf, uint16_t count){   if (count > 256)      count = 256;   if(mode == DEV_MODE_OFF)      st_flash_wake();      st_flash_page_program(st_flash_addr, (const uint8_t*)buf, count);   if(mode == DEV_MODE_OFF)      st_flash_sleep();      return count;   }#endif

⌨️ 快捷键说明

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