📄 sflash.c
字号:
/*---------------------------------------------------------------------------+| This source code has been made available to you by IBM on an AS-IS| basis. Anyone receiving this source is licensed under IBM| copyrights to use it in any way he or she deems fit, including| copying it, modifying it, compiling it, and redistributing it either| with or without modifications. No license under IBM patents or| patent applications is to be implied by the copyright license.|| Any user of this software should understand that IBM cannot provide| technical support for this software and will not be responsible for| any consequences resulting from the use of this software.|| Any person who transfers this source code or any derivative work| must include the IBM copyright notice, this paragraph, and the| preceding two paragraphs in the transferred software.|| COPYRIGHT I B M CORPORATION 1997, 1999, 2001, 2003| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| Author: Sathyan Doraiswamy| Component: Serial Flash| File: sflash.c| Purpose: Data Flash driver.| Changes:| Date: Author Comment:| ----- ------ --------| 05-14-02 Sathyan API's for FLASH R/W| 09-26-03 MSD Ported to Linux+----------------------------------------------------------------------------*//* The necessary header files */#include <linux/config.h>#include <linux/version.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/stddef.h>#include <asm/system.h>#include <linux/ioctl.h>#include <asm/uaccess.h>#include <asm/io.h>#include "os/drv_debug.h"#include "os/os-types.h"#include "os/os-sync.h"#include "os/os-interrupt.h"/* local includes */#include "scp/scp_inf.h"#include "sflash.h"#include "sem.h"char flash_cmd[296];int sSFlashInUseSem;extern int fd;/*-----------------------------------------------------------------------------| Function : sflash_init|| Parameters : None|| Return Value : None|| Notes : +----------------------------------------------------------------------------*/void sflash_init(){ if(ioctl(fd, IOCTL_SFLASH_INIT) != 0) { printf("scp_flash_stat failed.\n"); return; } sSFlashInUseSem = CreateSemaphore(1);}/*-----------------------------------------------------------------------------| Function : sflash_deinit|| Parameters : None|| Return Value : None|| Notes : +----------------------------------------------------------------------------*/void sflash_deinit(){ DeleteSemaphore(sSFlashInUseSem);} /*-----------------------------------------------------------------------------| Function : sflash_ready|| Parameters : None|| Return Value : 1 - Device Ready,| 0 - Device is busy|| Notes : Waits or max of 25ms+----------------------------------------------------------------------------*/int sflash_ready(){ unsigned char btStatus; unsigned long dwNumOfTries = 5; while (dwNumOfTries > 0) { sflash_get_status(&btStatus); // see if the busy bit is not on. if (btStatus & 0x80) { return(1); } usleep(5000); dwNumOfTries--; } return(0);}/*-----------------------------------------------------------------------------| Function : sflash_send_cmd|| Parameters : IN : unsigned char * : Pointer to Input Buffer| OUT : unsigned char * : Pointer to Output Buffer| IN : unsigned long : Number of bytes|| Return Value : Return value of scp_rw|| Notes :+------------------------------x----------------------------------------------*/int sflash_send_cmd(unsigned char * pInput, unsigned char * pOutput, unsigned long dwLen){ SCP_RW_STRUCT scp_rw; int i; PDEBUG("sflash_send_cmd: pInput = 0x%8.8x, pOutput = 0x%8.8x, dwLen = %d\n", pInput, pOutput, dwLen); if(dwLen > SCP_BUFFER_SIZE) { printf("ERROR: sflash_send_cmd: dwLen 0x%x is larger than SCP_BUFFER_SIZE 0x%x\n",dwLen,SCP_BUFFER_SIZE); return -1; } // setup the SCP_RW structure scp_rw.write_ptr = pInput; scp_rw.read_ptr = pOutput; scp_rw.count = dwLen; /* Use SFLASH In Use Semaphore */ SemWait(sSFlashInUseSem); if(ioctl(fd, IOCTL_SCP_RW, &scp_rw) != 0) { printf("sflash_send_cmd failed.\n"); return -1; } SemPost(sSFlashInUseSem); return 0;}/*-----------------------------------------------------------------------------| Function : sflash_get_status|| Parameters : OUT : unsigned char * : Status of Flash Device|| Return Value : 0 - on Success, Non-zero on failure|+----------------------------------------------------------------------------*/int sflash_get_status( unsigned char *pStat){ int iRetVal = SFLASH_SUCCESS; char temp[5]; SCP_RW_STRUCT scp_rw;// int i; /* build the command */ memset(flash_cmd, 0, 296); flash_cmd[0] = S_FLASH_STATUS_CMD; flash_cmd[1] = S_FLASH_STATUS_CMD; flash_cmd[2] = 0x00; flash_cmd[3] = 0x00; flash_cmd[4] = 0x00; // setup the SCP_RW structure scp_rw.write_ptr = flash_cmd; scp_rw.read_ptr = temp; scp_rw.count = 4; /* Use SFLASH In Use Semaphore */ SemWait(sSFlashInUseSem); if(ioctl(fd, IOCTL_SCP_RW, &scp_rw) != 0) { printf("sflash_get_status failed with RC = %x \n", iRetVal); return -1; } *pStat = scp_rw.read_ptr[1]; SemPost(sSFlashInUseSem); return 0;}/*-----------------------------------------------------------------------------| Function : sflash_read_buffer|| Parameters : IN :unsigned char : BufferNumber| IN : unsigned short: Starting Address in the buffer| IN : unsigned short: Number of Bytes to Read| OUT : unsigned char *: Pointer to data buffer.|| Return Value : 0 - on Success, Non-zero on failure|| Notes :+----------------------------------------------------------------------------*/int sflash_read_buffer(unsigned char btBufNum, unsigned short wStartAddr, unsigned short wLen, unsigned char * pData){ int iRetVal = SFLASH_SUCCESS; unsigned char *pOutParam; unsigned long dwNumOfBytes; /* Setup the Input parameters */ memset(flash_cmd, 0, 296); if (btBufNum == SFLASH_BUFFER_1) flash_cmd[0] = SFLASH_READ_BUF1_CMD; else if (btBufNum == SFLASH_BUFFER_2) flash_cmd[0] = SFLASH_READ_BUF2_CMD; else return SFLASH_ERR_INVALID_PARAM; /* place address */ flash_cmd[1] = 0x0; flash_cmd[2] = (unsigned char)(wStartAddr & 0xFF00) >> 8; flash_cmd[3] = (unsigned char)(wStartAddr & 0x00FF); /* Setup the output parameters */ /* Total bytes = dwNumOfBytes + Flash Command to Read */ dwNumOfBytes = wLen + 5 ; pOutParam = (unsigned char *)malloc(dwNumOfBytes); if (pOutParam == NULL) { printf("SFLASH: sflash_read_buf: malloc failed()\n"); return SFLASH_ERR_MEM_ALLOC; } iRetVal = sflash_send_cmd(flash_cmd, pOutParam, dwNumOfBytes); if (iRetVal == SCP_SUCCESS) { memcpy(pData, pOutParam + 5, wLen); } else { printf("scp_flash_stat failed with RC = %x \n", iRetVal); } free(pOutParam); return (iRetVal);}/*-----------------------------------------------------------------------------| Function : sflash_write_buffer|| Parameters : IN :unsigned char : BufferNumber| IN : unsigned short: Starting Address in the buffer| IN : unsigned short: Number of Bytes to Write| IN : unsigned char *: Pointer to Data.|| Return Value : 0 - on Success, Non-zero on failure|| Notes :+----------------------------------------------------------------------------*/int sflash_write_buffer(unsigned char btBufNum, unsigned short wStartAddr, unsigned short wLen, unsigned char * pData){ unsigned int iRetVal = SFLASH_SUCCESS; unsigned char * pOutParam; unsigned long dwNumOfBytes; /* Setup the Input parameters */ memset(flash_cmd, 0, 296); if (btBufNum == SFLASH_BUFFER_1) flash_cmd[0] = SFLASH_WRITE_BUFFER1_CMD; else if (btBufNum == SFLASH_BUFFER_2) flash_cmd[0] = SFLASH_WRITE_BUFFER2_CMD; else return (SFLASH_ERR_INVALID_PARAM); /* place address */ flash_cmd[1] = 0x0; flash_cmd[2] = (wStartAddr & 0xFF00) >> 8; flash_cmd[3] = (wStartAddr & 0x00FF); memcpy(&flash_cmd[4], pData, wLen); /* Setup the output parameters */ /* Total bytes = dwNumOfBytes + Flash Command to Write */ dwNumOfBytes = wLen + 4 ; pOutParam = (unsigned char *)malloc(dwNumOfBytes); if (pOutParam == NULL) { printf("SFLASH: sflash_write_buf: malloc failed()\n"); return SFLASH_ERR_MEM_ALLOC; } iRetVal = sflash_send_cmd(flash_cmd, pOutParam, dwNumOfBytes); if(iRetVal != SCP_SUCCESS) { printf("scp_rw failed : RC = %x \n", iRetVal); } free(pOutParam); return (iRetVal);}/*-----------------------------------------------------------------------------| Function : sflash_write_page|| Parameters : IN : unsigned short: Page Number < 0 to 1023>| IN :unsigned char : Buffer Number to use| IN : unsigned short: Number of Bytes to Write| IN : unsigned char *: Pointer to Data.|| Return Value : 0 - on Success, Non-zero on failure|| Notes :+----------------------------------------------------------------------------*/int sflash_write_page(unsigned short wPageNum,unsigned char btBufNum, unsigned short wLen, unsigned char * pData){ int iRetVal = SFLASH_SUCCESS; unsigned long dwTemp; unsigned long dwNumOfBytes; unsigned char * pOutParam; /* Setup the Input parameters */ memset(flash_cmd, 0, 296); /* Use Buffer 1 for page writes */ if (btBufNum == SFLASH_BUFFER_1) flash_cmd[0] = SFLASH_WRITE_PAGE_1_CMD; else if (btBufNum == SFLASH_BUFFER_2) flash_cmd[1] = SFLASH_WRITE_PAGE_2_CMD; else return SFLASH_ERR_INVALID_PARAM; /* place address */ dwTemp = 0; /* Starting Address in Buffer */ dwTemp |= (wPageNum << 9); /* Page Number */ dwTemp <<= 8; /* Remove the first bytes */ memcpy(&flash_cmd[1], &dwTemp, 3); /* Copy the Data to write */ memcpy(&flash_cmd[4], pData, wLen); /* Setup the output parameters */ /* Total bytes = dwNumOfBytes + Flash Command to Write */ dwNumOfBytes = wLen + 4; pOutParam = (unsigned char *)malloc(dwNumOfBytes); if (pOutParam == NULL) { printf("SFLASH: sflash_page_write: malloc failed()\n"); return SFLASH_ERR_MEM_ALLOC; } iRetVal = sflash_send_cmd(flash_cmd, pOutParam, dwNumOfBytes); if(iRetVal != SCP_SUCCESS) { printf("scp_flash_stat failed with RC = %x \n", iRetVal); } free(pOutParam); return (iRetVal);}/*-----------------------------------------------------------------------------| Function : sflash_read_page|| Parameters : IN : unsigned short: Page Number < 0 to 1023>| IN : unsigned short: Start Address in Page| IN : unsigned short: Number of Bytes to Write| OUT : unsigned char *: Pointer to Data.|| Return Value : 0 - on Success, Non-zero on failure|| Notes : Direct Read: Bypasses Buffer1 and Buffer2.| IMPORTANT: sflash_read_page always returns data from| Start Address + 1. Use your judgment when using this| API. Sent an E-mail to Atmel. Expecting reply.+----------------------------------------------------------------------------*/int sflash_read_page(unsigned short wPageNum, unsigned short wStartAddr, unsigned short wLen, unsigned char * pData){ unsigned long dwTemp; unsigned long dwNumOfBytes; unsigned char * pOutParam; int iRetVal = SFLASH_SUCCESS; /* Setup the Input parameters */ memset(flash_cmd, 0, 296); /* Use Buffer 1 for page writes */ flash_cmd[0] = SFLASH_READ_PAGE_CMD; /* place address */ dwTemp = wStartAddr; /* Starting Address in Buffer */ dwTemp |= (wPageNum << 9); /* Page Number */ dwTemp <<= 8; /* Remove the first bytes */ memcpy(&flash_cmd[1], &dwTemp, 3); /* Setup the output parameters */ /* Total bytes = dwNumOfBytes + Flash Command to Write */ dwNumOfBytes = wLen + 4 + 4 ; pOutParam = (unsigned char *)malloc(dwNumOfBytes); if (pOutParam == NULL) { printf("SFLASH: sflash_page_write: malloc failed()\n"); return SFLASH_ERR_MEM_ALLOC; } iRetVal = sflash_send_cmd(flash_cmd, pOutParam, dwNumOfBytes); if(iRetVal == SFLASH_SUCCESS) { memcpy(pData, pOutParam + 8, wLen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -