查看: 5656|回复: 9

[其他] MCF52233_CFM  

[复制链接]

该用户从未签到

6

主题

45

帖子

0

新手上路

Rank: 1

积分
105
最后登录
1970-1-1
发表于 2009-11-15 20:43:05 | 显示全部楼层 |阅读模式
MCF52233_CFM——Coldfire Flash Module
  Coldfire的CFM功能是把它的flash当作EEPROM来用。使用起来还是很方便的,只要完成几个小的功能函数就行了:
  第一个是CFM的初始化CFM_init(),完成时钟的设置;
  第二个是页擦除CFM_Page_eraser(),完成一页的擦除工作,Coldfire的256K flash被分成128页,每2K为1页,只有在擦除后才能正确地向一个地址中写入数据;
  第三个是CFM_Write(),完成向某地址写入数据的功能,Coldfire的CFM是按字操作的,以4B为一个最小单位。
  CFM有5个CMD:Blank Check 、Pageerase verify、 Word program 、Page erase 、Mass erase但只要其中Word program 、Page erase 两个就能满足一般的使用了。
  在使用CFM功能时对它的地址这块可能会有些迷惑,这里简单介绍下:MCF52233有256K的flash,默认情况下起始地址是0x44000000(#define CFM_IPS_FLASH_ADDR      0x44000000),我们不能在存有程序的地方擦、写数据,最简单的办法就是在flash的最后面操作,这样就不要考虑烧进去的程序结束的位置了。起始地址加上256K得到最后一个存储单元的地址即#define FLASH_END_ADDRESS CFM_IPS_FLASH_ADDR+0x40000),我们就从FLASH_END_ADDRESS 开始往前写我们的数据。
  最后一点就是怎样读我们写的数据,其实非常简单,用read_data=(*(uint32 *)(address))就将address处的数据赋给了read_data;同样,在写数据的时候会用到(*(uint32*)(address))=write_data来将数据写到address地址处。
程序如下:
/*CFM初始化*/
uint8 CFM_init(unsigned long FlashClk)
{
 unsigned char fclk_val;
 
 if ((MCF_CFM_CFMCLKD & MCF_CFM_CFMCLKD_DIVLD)==0)
 {
     //Initialize FCLKDIV register to ensure we can program/erase */
   fclk_val = (unsigned char)(FlashClk/8/200-1);
   MCF_CFM_CFMCLKD |= MCF_CFM_CFMCLKD_DIV(fclk_val)
              | MCF_CFM_CFMCLKD_PRDIV8;
 }
 //Disable all protection (if LOCK not set)*/
 MCF_CFM_CFMPROT=0;
 
 //Clear any errors 
 MCF_CFM_CFMUSTAT |=MCF_CFM_CFMUSTAT_PVIOL
            |MCF_CFM_CFMUSTAT_ACCERR;
 return 0;
}
 
 
/*页擦除*/ 
uint8 CFM_page_erase(unsigned char page)
{
 while (!(MCF_CFM_CFMUSTAT&MCF_CFM_CFMUSTAT_CBEIF));
 //Clear any errors 
 MCF_CFM_CFMUSTAT =MCF_CFM_CFMUSTAT_PVIOL
            |MCF_CFM_CFMUSTAT_ACCERR;
 
 (*(vuint32*)(FLASH_START_ADDRESS+page*0x800))=1;
 
 MCF_CFM_CFMCMD=MCF_CFM_CFMCMD_PAGE_ERASE;
 //Launch CMD
 MCF_CFM_CFMUSTAT=MCF_CFM_CFMUSTAT_CBEIF;
 //wait for complete and check result
 while(!(MCF_CFM_CFMUSTAT&MCF_CFM_CFMUSTAT_CCIF))
 {
  if(MCF_CFM_CFMUSTAT&MCF_CFM_CFMUSTAT_PVIOL) return 0; 
 }
 if(MCF_CFM_CFMUSTAT&MCF_CFM_CFMUSTAT_ACCERR) return 0;
 return 1;
}
 
/*flash写操作*/
uint8 CFM_write(unsigned int address ,unsigned int data)
{
 if((uint32)address&0x00000001) return 0;
 //Clear any errors
 MCF_CFM_CFMUSTAT=MCF_CFM_CFMUSTAT_PVIOL
           |MCF_CFM_CFMUSTAT_ACCERR;
 
 (*(vuint32*)(FLASH_END_ADDRESS-4-address))=data;
 //launch command
 MCF_CFM_CFMCMD=MCF_CFM_CFMCMD_WORD_PROGRAM;
 MCF_CFM_CFMUSTAT=MCF_CFM_CFMUSTAT_CBEIF;
 //wait for complete and check result
 while(!(MCF_CFM_CFMUSTAT&MCF_CFM_CFMUSTAT_CCIF))
 {
  if(MCF_CFM_CFMUSTAT&MCF_CFM_CFMUSTAT_PVIOL) return 0;
 }
 if(MCF_CFM_CFMUSTAT&MCF_CFM_CFMUSTAT_ACCERR) return 0;
 return 1;
}
 
我知道答案 目前已有9人回答
回复

使用道具 举报

该用户从未签到

33

主题

441

帖子

0

新手上路

Rank: 1

积分
7703
最后登录
1970-1-1
发表于 2009-11-16 12:10:02 | 显示全部楼层

回复:MCF52233_CFM  

 好文章要顶!!!!!

该用户从未签到

4

主题

9

帖子

0

新手上路

Rank: 1

积分
32
最后登录
1970-1-1
发表于 2009-11-16 17:21:13 | 显示全部楼层

RE:MCF52233_CFM  

不错!正好现在在学Coldfire,可以参考一下!

该用户从未签到

0

主题

3

帖子

0

新手上路

Rank: 1

积分
5
最后登录
1970-1-1
发表于 2009-11-24 15:58:08 | 显示全部楼层

RE:MCF52233_CFM  

好东西,学习学习!

该用户从未签到

8

主题

89

帖子

0

中级会员

Rank: 3Rank: 3

积分
255
最后登录
2025-8-21
发表于 2009-11-25 23:34:26 | 显示全部楼层

RE:MCF52233_CFM  

同样,在写数据的时候会用到(*(uint32))(address)=write_data来将数据写到address地址处。
这里有点疑问?写flash应该是有专用指令吧,要么就是用CMD_WRITE之类封装好了
上述语句只能用在ram地址上的赋值把?
如果移植一个web server之类的在coldfire上,如果有参数存储需要自己去管理flash吗?

该用户从未签到

6

主题

45

帖子

0

新手上路

Rank: 1

积分
105
最后登录
1970-1-1
 楼主| 发表于 2009-11-26 09:52:16 | 显示全部楼层

回复:MCF52233_CFM  

回复第 5 楼 winricky于2009-11-25 15:34:26发表:
同样,在写数据的时候会用到(*(uint32))(address)=write_data来将数据写到address地址处。
这里有点疑问?写flash应该是有专用指令吧,要么就是用CMD_WRITE之类封装好了
上述语句只能用在ram地址上的赋值把?
如果移植一个web server之类的在coldfire上,如果有参数存储需要自己去管理flash吗? 

 嗯,不是单独一句( *(vuint32*)(address))=write_data就可以的。在手册269页的program这地方有这样一句话:"Write to a  word address in a flash physical block to start the command write sequence for the program command." 。(*(vuint32*)(address))=write_data只是为了说明这句话的,因为我当时看这句话的时候对到底是怎么Write to a  word address in a flash physical block 的感到很迷惑。
具体怎么往flash里写数据,看代码中的uint8 CFM_write(unsigned int address ,unsigned int data)函数。

*(vuint32*)(FLASH_END_ADDRESS-4-address)=data;

 MCF_CFM_CFMCMD=MCF_CFM_CFMCMD_WORD_PROGRAM;
 MCF_CFM_CFMUSTAT=MCF_CFM_CFMUSTAT_CBEIF;
需要用到Word program 这个命令。
 
移植web server没弄过,但有参数存储的话觉得还是要自己管理flash的,请bluehacker回答下吧。

该用户从未签到

2

主题

14

帖子

0

新手上路

Rank: 1

积分
35
最后登录
1970-1-1
发表于 2009-12-11 13:40:30 | 显示全部楼层

回复:MCF52233_CFM  

初始化这里,首先MCF_CFM_CFMCLKD_PRDIV8要在总线频率大于12.8M的时候才置位。
其次fclk_val = (unsigned char)(FlashClk/8/200-1);不够严谨。
datasheet里面有下面这段话

For frequencies of the input clock greater than 12.8 MHz, the CFMCLKD bit PRDIV8 must be set.
CFMCLKD DIV bit field must be chosen such that the following equation is valid:
If PRDIV8 == 1 then FCLK = input clock / 8, else FCLK = input clock
If (FCLK[KHz] / 200KHz) is integer then DIV = (FCLK[KHz] / 200KHz) - 1,
else DIV = INT (FCLK[KHz] / 200kHz)
FCLK, the clock to the flash block timing control, is therefore:
FCLK = (input clock) / (DIV + 1)
150KHz < FCLK

该用户从未签到

33

主题

441

帖子

0

新手上路

Rank: 1

积分
7703
最后登录
1970-1-1
发表于 2009-12-11 21:33:04 | 显示全部楼层

回复:MCF52233_CFM  

 移植web server,那些参数我觉得最好还是写到外部的eeprom之类的存储器里。coldfire的flash毕竟主要是程序存储器,只能在极端情况下(比如成本机器敏感),才有必要把flash用作用户数据存储

该用户从未签到

6

主题

45

帖子

0

新手上路

Rank: 1

积分
105
最后登录
1970-1-1
 楼主| 发表于 2009-12-11 23:12:00 | 显示全部楼层

回复:MCF52233_CFM  

<div style="border-right: #ccc 1px dashed; padding-right: 5px; border-top: #ccc 1px dashed; padding-left: 5px; padding-bottom: 5px; border-left: #ccc 1px dashed; padding-top: 5px; border-bottom: #ccc 1px dashed">回复第 7 楼 fishandbear于2009-12-11 05:40:30发表:
初始化这里,首先MCF_CFM_CFMCLKD_PRDIV8要在总线频率大于12.8M的时候才置位。
其次fclk_val = (unsigned char)(FlashClk/8/200-1);不够严谨。
datasheet里面有下面这段话

For frequencies of the input clock greater than 12.8 MHz, the CFMCLKD bit PRDIV8 must be set.
CFMCLKD DIV bit field must be chosen such that the following equation is valid:
If PRDIV8 == 1 then FCLK = input clock / 8, else FCLK = input clock
If (FCLK[KHz] / 200KHz) is integer then DIV = (FCLK[KHz] / 200KHz) - 1,
else DIV = INT (FCLK[KHz] / 200kHz)
FCLK, the clock to the flash block timing control, is therefore:
FCLK = (input clock) / (DIV + 1)
150KHz < FCLK

该用户从未签到

1

主题

3

帖子

0

新手上路

Rank: 1

积分
11
最后登录
2015-1-20
发表于 2015-1-19 11:53:29 | 显示全部楼层
想想你请教一下关于程序问题,怎么确定地址
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2025-9-12 08:08 , Processed in 0.105368 second(s), 30 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表