📄 data_flash.c
字号:
#include <cdefBF533.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "flash.h"
#include "delay.h"
//ams2 base addr 0x20200000
#define pKM29_DATA ((volatile unsigned char *)0x20200000)
//R/W to this address asserts ALE
#define pKM29_ADDR ((volatile unsigned char *)0x20200002)
//R/W to this address asserts CLE
#define pKM29_CMD ((volatile unsigned char *)0x20200004)
//ams0 base addr 0x20000000, for use to terminate sequential row read
#define pAMSBANK0 ((volatile unsigned short *)0x20000000)
#define CMD_SEQUENTIAL_INPUT 0x80
#define CMD_READ1 0x00
#define CMD_READ2 0x50
#define CMD_READ_ID 0x90
#define CMD_RESET 0xFF
#define CMD_PAGE_PROGRAM 0x10
#define CMD_BLOCK_ERASE1 0x60
#define CMD_BLOCK_ERASE2 0xD0
#define CMD_READ_STATUS 0x70
/*
#define PAGES_PER_BLOCK 32
#define BYTES_PER_PAGE 512
#define BLOCK_SIZE (PAGES_PER_BLOCK*BYTES_PER_PAGE)
#define TOTAL_BLOCK 1024
//存储空间分配
#define BLOCK_GPRS_INFO_START 0 //included
#define BLOCK_GPRS_INFO_END 8 //not included
#define BLOCK_JPEG_START 8 //included
#define BLOCK_JPEG_END TOTAL_BLOCK //not included
*/
//block 0-2 used for GPRS_INFO, block 3-7 reserved
//block 8-1023 for jpeg storage
/*
typedef struct
{
char client_number[10][11]; //终端用户手机号码,支持10个
char passwords[8]; //该模块的密码
char ip_address[20]; //终端IP地址和端口号
char email[50]; //终端用户邮箱
char server_number[11]; //本机号码
char camera_switch[6]; //开哪几路摄像头,"1"开,"0"关
char pic_size; //图像的大小,"1"D1图像,"0"CIF图像
char pic_Q[2]; //图像的质量,默认为80
}gprs_information_t;
typedef struct
{
unsigned char time[14]; //图像的采集时间
char receive_num[11]; //保存接收方的手机,便于以后分析
char channel; //哪一路图像, -1 invalid data
char sent_flag; //是否发送成功的标志
char sys_status; //图片的状态,"1"报警图像,"0"正常图像
char pic_size; //图像的大小
char pic_Q[2]; //图像的质量
unsigned short start_block; //图像数据的起始块
unsigned short end_block; //图像数据的结束块
int size; //图像的数据长度
} jpeg_storage_t;
typedef struct
{
char block_valid[TOTAL];//块是否有效,"1"有效"0"无效
jpeg_storage_t jpeg[MAX_PIC_NUM];//图像的最大数目
}data_flash_t;
*/
DATA_FLASH_T Data_Info;
DATA_FLASH_T *data_flash;
JPEG_STORAGE_T jpeg_store;
JPEG_STORAGE_T *jpeg_storage;
int data_flash_updated;
char block_buf[BLOCK_SIZE];
int read_id()
{
unsigned char cmd = 0x90;
*pFIO_FLAG_C = (1 << 6);
// *pKM29_CMD = 0xff;
// delay(1000);
*pKM29_CMD = cmd;
*pKM29_ADDR = 1;
delay(10);
cmd = *pKM29_DATA;
if(cmd != 0xEC)
return -1;
cmd = *pKM29_DATA;
if(cmd != 0x73)
return -1;
cmd = *pKM29_DATA;
cmd = *pKM29_DATA;
*pFIO_FLAG_S |= (1 << 6);
return 0;
}
//return -1 error, 0 successful
//buffer: buffer to hold data
//data_type: 0:0-511byte data, 1:512-527byte infomation
int read_page(char* buffer, int data_type, int block, int page)
{
char cmd;
char addr1, addr2, addr3;
int i, cnt, retry = 10000;
//?: ecc check?
if(data_type == 0)
{
cmd = CMD_READ1;
cnt = 512;
}
else
{
cmd = CMD_READ2;
cnt = 16;
}
// page = 1;
// block = 1;
addr1 = 0;
addr2 = block * 32 + page;
addr3 = (block * 32 + page) >> 8;
*pFIO_FLAG_C = (1 << 6);
*pKM29_CMD = cmd;
// delay(1);
*pKM29_ADDR = addr1;
// delay(1);
*pKM29_ADDR = addr2;
// delay(1);
*pKM29_ADDR = addr3;
delay(20);
for(i = 0; i < cnt; i++)
{
*buffer++ = *pKM29_DATA;
}
*pFIO_FLAG_S |= (1 << 6);
return 0;
}
int read_block(char* buf, int size, int block)
{
char addr1, addr2, addr3, spare_area[16];
int i, pages, bytes, retry = 10000, page_index;
pages = size / BYTES_PER_PAGE;
if(size % BYTES_PER_PAGE)
pages++;
addr1 = 0;
addr2 = block * 32;
addr3 = (block * 32) >> 8;
*pFIO_FLAG_C = (1 << 6);
*pKM29_CMD = CMD_READ1;
*pKM29_ADDR = addr1;
*pKM29_ADDR = addr2;
*pKM29_ADDR = addr3;
for(page_index = 0; page_index < pages; page_index++)
{
delay(20);
bytes = BYTES_PER_PAGE;
if((page_index == pages-1) && (size % BYTES_PER_PAGE))
bytes = size % BYTES_PER_PAGE;
for(i = 0; i < bytes; i++)
{
*buf++ = *pKM29_DATA;
}
/*liu
for(i = 0; i < 16 + BYTES_PER_PAGE - bytes; i++)
{
spare_area[i] = *pKM29_DATA;
}*/
}
*pFIO_FLAG_S |= (1 << 6);
//?: sequential row read terminated?
// *pAMSBANK0 = 0;
return 0;
}
//return -1 error, 0 successful
//size: normally 512, should not exceed 512, if smaller than 512, 0s will be padded
int program_page(char* buffer, int size, int block, int page)
{
char addr1, addr2, addr3;
int i, retry = 2;
char status = 0;
int cnt = BYTES_PER_PAGE - size;
//?: calc ecc here if needed
addr1 = 0;
addr2 = block * 32 + page;
addr3 = (block * 32 + page) >> 8;
*pFIO_FLAG_C = (1 << 6);
*pKM29_CMD = CMD_READ1;
*pKM29_CMD = CMD_SEQUENTIAL_INPUT;
*pKM29_ADDR = addr1;
*pKM29_ADDR = addr2;
*pKM29_ADDR = addr3;
for(i = 0; i < size; i++)
*pKM29_DATA = *buffer++;
for(i = 0; i < cnt; i++)
*pKM29_DATA = 0;
for(i = 0; i < 16; i++)
*pKM29_DATA = 0xff;
*pKM29_CMD = CMD_PAGE_PROGRAM;
delay(1000);
*pKM29_CMD = CMD_READ_STATUS;
while(1)
{
status = *pKM29_DATA;
if((status & (char)0x40) == (char)0x40)
break;
}
if(status & 0x01)
return -1;
/**/
*pFIO_FLAG_S |= (1 << 6);
return 0;
}
//return -1 error, 0 successful
int erase_block(int block)
{
int retry = 10000;
char status;
*pFIO_FLAG_C = (1 << 6);
*pKM29_CMD = CMD_READ_STATUS;
status = *pKM29_DATA;
block <<= 5;
*pKM29_CMD = CMD_BLOCK_ERASE1;
*pKM29_ADDR = block;
*pKM29_ADDR = block >> 8;
*pKM29_CMD = CMD_BLOCK_ERASE2; //start erase
delay(4000); //Tbers 3ms
// status = *pKM29_DATA;
// status = *pKM29_DATA;
*pKM29_CMD = CMD_READ_STATUS;
while(1)
{
status = *pKM29_DATA;
if((status & (char)0x40) == (char)0x40)
break;
}
if(status & 0x01)
return -1;
/**/
*pFIO_FLAG_S |= (1 << 6);
return 0;
}
int program_block(char* buf, int size, int block)
{
int pages = size / BYTES_PER_PAGE;
int page_index = 0, program_size = 0, ret;
if(size % BYTES_PER_PAGE)
pages += 1;
for(page_index = 0; page_index < pages; page_index++)
{
if((page_index == pages-1) && (size % BYTES_PER_PAGE))
program_size = size % BYTES_PER_PAGE;
else
program_size = BYTES_PER_PAGE;
ret = program_page(buf + page_index*BYTES_PER_PAGE,
program_size, block, page_index);
if(ret < 0)
return ret;
}
return 0;
}
//以block为单位写数据
int program_blocks(char* buf, int size, int block, int start_block, int end_block)
{
int blocks = size / BLOCK_SIZE;
int i, ret, block_index = block, success_cnt = 0, program_size;
if(size % BLOCK_SIZE)
blocks += 1;
while(1)
{
while(1)
{
if(data_flash->block_invalid[block_index] == 0)
break;
block_index++;
if(block_index >= end_block)
block_index = start_block; //rewind
if(block_index == block)
return -1; //no good block to fill, severe error
}
ret = erase_block(block_index);
if(ret == 0)
{
//now we got good block for fill
program_size = BLOCK_SIZE;
if((size % BLOCK_SIZE) && (success_cnt == blocks -1))
program_size = size % BLOCK_SIZE;
ret = program_block(buf + success_cnt*BLOCK_SIZE, program_size, block_index);
if(ret == 0)
success_cnt++;
if(success_cnt >= blocks)
return block_index; //all data successfully programmed, return last block
}
if(ret < 0)
{
data_flash->block_invalid[block_index] = 1;
data_flash_updated = 1;
}
if(++block_index >= end_block)
block_index = start_block;
}
}
//return -1 critical error, else last block read
int read_data(char* buf, int size, int block, int start_block, int end_block)
{
int blocks = size / BLOCK_SIZE;
int i, block_index = block, ret, read_size, success_cnt = 0;
if(size % BLOCK_SIZE)
blocks += 1;
while(1)
{
while(1)
{
if(data_flash->block_invalid[block_index] == 0)
break;
block_index++;
if(block_index >= end_block)
block_index = start_block; //rewind
if(block_index == block)
return -1; //no good block to read from, severe error
}
read_size = BLOCK_SIZE;
if((size % BLOCK_SIZE) && (success_cnt == blocks -1))
read_size = size % BLOCK_SIZE;
//liu
BF533_WDOG_WRITE_STAT();
ret = read_block(buf + success_cnt*BLOCK_SIZE, read_size, block_index);
if(ret < 0 && block_index == 0)
return -2;
success_cnt++;
if(success_cnt >= blocks)
return block_index; //all data successfully programmed, return last block
if(++block_index >= end_block)
block_index = start_block;
}
}
/*
//channel 1,2,3,4; -1 mean all channel
int df_search_jpeg(char channel, char* start_time, char* end_time, jpeg_info_t* jpeg_info, int max_search)
{
int start_itime, end_itime, i, cnt = 0, ret;
start_itime = calc_itime(start_time);
end_itime = calc_itime(end_time);
jpeg_storage_t* jpeg = km29_ctrl->jpeg;
for(i = 0; i < MAX_JPEG; i++, jpeg++)
{
if(jpeg->channel == -1)
continue;
if(jpeg->itime >= start_itime && jpeg->itime <= end_itime)
{
if(channel == -1 || channel == jpeg->channel)
{
jpeg_info[cnt].channel = jpeg->channel;
jpeg_info[cnt].size = jpeg->size;
jpeg_info[cnt].pic_big = jpeg->pic_big;
jpeg_info[cnt].quality = jpeg->quality;
calc_time(jpeg->itime, jpeg_info[cnt].time);
if(++cnt >= max_search)
return cnt;
}
}
}
return cnt;
}
int df_check_jpeg_sent(jpeg_info_t* jpeg_info, int* index, int max_search)
{
int i, cnt = 0;
jpeg_storage_t* jpeg = km29_ctrl->jpeg;
for(i = 0; i < MAX_JPEG; i++, jpeg++)
{
if(jpeg->channel != -1 && jpeg->sent == 0)
{
jpeg_info[cnt].channel = jpeg->channel;
jpeg_info[cnt].size = jpeg->size;
jpeg_info[cnt].pic_big = jpeg->pic_big;
jpeg_info[cnt].quality = jpeg->quality;
calc_time(jpeg->itime, jpeg_info[cnt].time);
*index++ = i;
if(++cnt >= max_search)
return cnt;
}
}
return cnt;
}
int df_jpeg_sent(jpeg_pack_t* jpeg_pack, int index)
{
int i, itime;
jpeg_storage_t* jpeg = km29_ctrl->jpeg + index;
jpeg->sent = 1;
km29_ctrl_updated = 1;
return 0;
}
//return -1, not found; -2, not enough buffer
int df_read_jpeg(jpeg_pack_t* jpeg_pack, int index)
{
int itime, i, ret;
jpeg_storage_t* jpeg = km29_ctrl->jpeg + index;
ret = read_data(jpeg_pack->data, jpeg->size, jpeg->start_block,
BLOCK_JPEG_START, BLOCK_JPEG_END);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -