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

📄 flash.c

📁 ST flash driver
💻 C
字号:
/*******************************************************************************\
 *
 * Copyright (c) 2002,  KTWORTH BROADBAND TECH. CO. LTD. PROPERTY.
 *
 * Filename : flash.c
 * Author : fuxs
 * Creation Date : 09-08-2002
 * Description : flash相关函数
 * Subsystem : 
 *
\*******************************************************************************/

#include <stdio.h>
#include <string.h>
#include <ktcable.h>

#include <ostime.h>

#include "flash.h"
#include "stflashd.h"

#define BLOCKSIZE_LYQ (0x10000) /*64Kbytes*/
unsigned char	Tembuf[BLOCKSIZE_LYQ];/*5.23 add by kt,pls compare with original*/

STATUS Init(sk_Flash *flash)
{
	return STATUS_OK;
}

STATUS ID(sk_Flash *flash, u32 *id)
{
	return STATUS_OK;
}

STATUS Size(sk_Flash *flash, u32 *size)
{
	if (size == NULL)
	{
		return STATUS_ERR;
	}

	*size = 1024 * 1024 * 4;
	return STATUS_OK;
}

STATUS BlockSize(sk_Flash *flash, i32 *blksize, i32 nBlock)
{
	if (blksize == NULL)
	{
		return STATUS_ERR;
	}

	*blksize = 0;

	if (nBlock <= 62)
	{
		*blksize = 0x10000;
	}
	else
	{
		*blksize = 0x2000;
	}

	return STATUS_OK;
}

/*
从flash中读取数据

输入参数:
startOffset 起始地址,注意应为相对地址
size 欲读取的字节数
buf 保存读取数据的缓冲区

返回值:
STATUS_OK 成功读取
STATUS_ERR 传送的参数错误,如buf为空等
*/
STATUS Read(sk_Flash *flash, u32 startOffset, i32 size, u8 *buf)
{
	unsigned int flash_addr;
	if (startOffset > (FLASH_TOTAL_SIZE - size) || size < 0 || buf == NULL)
	{
		return STATUS_ERR;
	}
	flash_addr = FLASH_START_ADDR + startOffset;
	memcpy((void *) buf, (const void *) flash_addr, size);

	return STATUS_OK;
}


/*---------------------------------------------------------------
将缓冲区中的内容写入flash中

输入参数:
startOffset 起始地址,注意应是相对地址
size 写入的字节数
buf 数据缓冲区地址

返回值:
STATUS_OK 成功写入
STATUS_ERR 发生错误
-----------------------------------------------------------------*/
STATUS Write(sk_Flash *flash, u32 startOffset, i32 size, u8 *buf)
{
	int	i, k, len, needcopy, havecopy, startOffset1, result, flag, flash_addr;
	unsigned char * sourcedata;

	if ((startOffset > (FLASH_TOTAL_SIZE - size)) || (size < 0) || (buf == NULL))
	{
		return STATUS_ERR;
	}

	sourcedata = buf;

	flag = 0;
	if (startOffset % BLOCKSIZE_LYQ != 0)
	{
		startOffset1 = startOffset / BLOCKSIZE_LYQ * BLOCKSIZE_LYQ;
		needcopy = startOffset - startOffset1;
		havecopy = BLOCKSIZE_LYQ - needcopy;

		if (havecopy >= size)
		{
			havecopy = size;
			flag = 1;
		}

		Read(sysFlash, startOffset1, BLOCKSIZE_LYQ, Tembuf);
		memcpy((void *) (&Tembuf[needcopy]), sourcedata, havecopy);

		result = EraseBlock((unsigned short *) (FLASH_START_ADDR + startOffset1));
		if (!result)
		{
			return STATUS_ERR;
		}

		if (FLASH_START_ADDR + startOffset1 >= 0x7fff0000)
		{
			result = EarseBootBlock();  
			if (!result)
			{
				return STATUS_ERR;
			}
		}

		result = ProgramFlashMiCo(FLASH_START_ADDR
				 + (unsigned long int) startOffset1,
				 Tembuf,
				 BLOCKSIZE_LYQ);
		if (!result)
		{
			return STATUS_ERR;
		}

		if (flag == 1)
		{
			return STATUS_OK;
		}

		sourcedata += havecopy;
		size -= havecopy;

		startOffset = startOffset1 + BLOCKSIZE_LYQ;
	}

	k = size / BLOCKSIZE_LYQ;
	if (size % BLOCKSIZE_LYQ != 0)
	{
		k++;
	}

	flash_addr = FLASH_START_ADDR + startOffset;
	for (i = 0; i < k; i++)
	{
		if ((i == (k - 1)) && (size % BLOCKSIZE_LYQ))
		{
			len = size % BLOCKSIZE_LYQ;
		}
		else
		{
			len = BLOCKSIZE_LYQ;
		}

		memcpy((void *) Tembuf, (const void *) sourcedata, len);

		if (len != BLOCKSIZE_LYQ)
		{
			needcopy = BLOCKSIZE_LYQ - len;
			memcpy((void *) (&Tembuf[len]),
			 (const void *) (flash_addr + len),
			 needcopy);
		}

		result = EraseBlock((unsigned short *) flash_addr);
		if (!result)
		{
			return STATUS_ERR;
		}

		if (flash_addr >= 0x7fff0000)
		{
			result = EarseBootBlock();  
			if (!result)
			{
				return STATUS_ERR;
			}
		}

		result = ProgramFlashMiCo((unsigned long int) flash_addr,
				 Tembuf,
				 BLOCKSIZE_LYQ);
		if (!result)
		{
			print("Write flash error when call ProgramFlashMiCo.\n");
			return STATUS_ERR;
		}

		if (flash_addr == 0x7fff0000)
		{
			break;
		}

		flash_addr += BLOCKSIZE_LYQ;
		sourcedata += BLOCKSIZE_LYQ;
	}

	return STATUS_OK;
}


STATUS Erase(sk_Flash *flash, u32 startOffset)
{
	int	i, result;
	unsigned int flash_addr;

	if (startOffset >= FLASH_TOTAL_SIZE)
	{
		return STATUS_ERR;
	}

	startOffset = startOffset / BLOCKSIZE_LYQ * BLOCKSIZE_LYQ;

	for (i = 0; i < 100; i++)
	{
		flash_addr = FLASH_START_ADDR + startOffset + i * BLOCKSIZE_LYQ;

		result = EraseBlock((unsigned short *) flash_addr);
		if (!result)
		{
			return STATUS_ERR;
		}

		if (flash_addr == 0x7fff0000)
		{
			result = EarseBootBlock();  

			if (!result)
			{
				return STATUS_ERR;
			}

			return STATUS_OK;
		}
	}

	return STATUS_OK;
}

STATUS Protect(sk_Flash *flash, Bool on)
{
	return STATUS_OK;
}

STATUS BlockWrite(sk_Flash *flash,
 i32 blockSize,
 u32 startOffset,
 i32 size,
 u8 *buf)
{
	int	result;
	unsigned long int flash_addr;

	if (startOffset >= BLOCKSIZE_LYQ || buf == NULL)
	{
		return STATUS_ERR;
	}

	startOffset = startOffset / BLOCKSIZE_LYQ * BLOCKSIZE_LYQ;
	flash_addr = FLASH_START_ADDR + (unsigned long int) startOffset;

	result = EraseBlock((unsigned short *) flash_addr);
	if (!result)
	{
		return STATUS_ERR;
	}

	result = ProgramFlashMiCo(flash_addr, buf, blockSize);

	return !result;
}

STATUS BlockErase(sk_Flash *flash, i32 blockSize, u32 startOffset)
{
	int	result;
	u32	flash_addr;

	if (startOffset >= FLASH_TOTAL_SIZE)
	{
		return STATUS_ERR;
	}

	startOffset = startOffset / BLOCKSIZE_LYQ * BLOCKSIZE_LYQ;
	flash_addr = FLASH_START_ADDR + startOffset;

	result = EraseBlock((unsigned short *) flash_addr);

	return !result;
}

STATUS Term(sk_Flash *flash)
{
	return STATUS_OK;
}

STATUS Close(sk_Flash *flash)
{
	return STATUS_OK;
}

STATUS Img2Int(unsigned char *str, int *result)
{
	int	i, j, k, x, y, z;

	if (str == NULL)
	{
		return STATUS_ERR;
	}

	x = 0;
	k = 0;
	for (i = 0; i < 4; i++)
	{
		y = (int) str[i];

		z = 1;
		for (j = 0; j < k; j++)
		{
			z *= 0x100;
		}

		x += y * z;
		k++;
	}

	*result = x;

	return STATUS_OK;
}

/*---------------------------------------------------------------
将bin形式的数据写入flash中,注意:如果写入的长度超过1.5M,
最好分开写

bin文件由一至多个数据块组成,每个块的格式如下:
{
 地址(int型,4字节)+数据长度(int型,4字节)+数据区
}

数据以0xFFFFFFFF结束,最后跟一个 unsigned long int 型的crc校验码,
四个字节宽

输入参数:
buffer 欲写入的数据缓冲区
length 缓冲区长度

返回值:
STATUS_OK 成功写入
STATUS_ERR 发生错误,可能为bin文件的数据错误或者写入flash时发生错误
-----------------------------------------------------------------*/
STATUS Burn2Flash(sk_Flash *flash, unsigned char *buffer, int length)
{
	int	k, len, flash_addr, result;

	if (buffer == NULL || length < 0)
	{
		print("Parameter error, please check.\n");
		return STATUS_ERR;
	}

	k = 0;
	for (; ;)
	{
		Img2Int(&buffer[k], &flash_addr);

		if (flash_addr == 0xffffffff)
		{
			break;
		}

		flash_addr -= FLASH_START_ADDR;

		k += 4;
		Img2Int(&buffer[k], &len);

		k += 4;

		if (len > length)
		{
			len = length;
		}

		result = flash->Write(flash, flash_addr, len, buffer + k);
		if (result != STATUS_OK)
		{
			print("Write to flash error.\n");
			return STATUS_ERR;
		}

		k += len;

		if (k >= length)
		{
			break;
		}
	}

	return STATUS_OK;
}
int CAMODULE_Flash_Write(unsigned char *pbBuffer,
 unsigned int uDest,
 unsigned int  uLength)
{
	int	result;
	result = sysFlash->Write(sysFlash,
						(unsigned int) (uDest - FLASH_START_ADDR),
						(unsigned int) uLength,
						(unsigned char *) pbBuffer);
	if (result == STATUS_OK)
	{
		return 0;
	}
	else
	{
		return -1;
	}
}

int CAMODULE_Flash_Read(unsigned char *pbBuffer,
 unsigned int  uDest,
 unsigned int  uLength)
{
	sysFlash->Read(sysFlash,
			  (unsigned int) (uDest - FLASH_START_ADDR),
			  uLength,
			  pbBuffer);
	return 0;
}


⌨️ 快捷键说明

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