[DemoCode下载] 从芯片的Flash中划出一块作为DATAFlash并读写数据

[复制链接]
2047|8
 楼主| Jessicakjdsl 发表于 2016-3-17 13:27 | 显示全部楼层 |阅读模式
之前接手了一个项目,它有个操作是将一些初始化数据写入DATAFlash区。
其做法是使用ICP下载工具在下载时配置ISD9160芯片的CONFIG[1:0],并下载DATAFlash和APROM。
这个做法繁琐、而且工厂生产时、生产人员去配置下载工具时可能会出错,所以又做了一个下载配置文件,也就是生产时需要3个文件才能完成对芯片的烧录:下载配置文件、DATAFlash.bin、APROM.bin。

现在用新方法将芯片配置过程和初始化数据一起包含于APROM.bin。
具体操作有2步:
1、配置芯片、从Flash中划出1K作为DATAFlash
  1. // DATAFlash配置
  2. #define CONFIG0_TEST_CODE   0xFFFFFFFE  // 使能DATAFlash
  3. #define CONFIG1_TEST_CODE   0x00023000  // DATAFlash基地址(对应1K)

  4. // 灯的模式和亮度参数存放于DATAFlash区,地址为0x23000开头的3个位置
  5. #define LAMP_DATA_ADDR      CONFIG1_TEST_CODE

  6. void config_init(void)
  7. {
  8.     int32_t  i32Err;
  9.     uint32_t u32Data;
  10.     uint32_t config0Bak, config1Bak;

  11.     // 开始操作
  12.     UNLOCKREG();

  13.     // 开启ISP模块
  14.     SYSCLK->AHBCLK.ISP_EN = 1;
  15.     DrvFMC_EnableISP(1);

  16.     // 检查boot源
  17.     LOG(("Boot Source ................................ "));
  18.     if(DrvFMC_GetBootSelect() == LDROM) {
  19.         printf("[LDROM]\n");
  20.         printf("WARNING: This code should be in AP mode but it is in LD mode now.\n\n");
  21.         while(1){}
  22.     } else {
  23.         printf("[APROM]\n");
  24.     }

  25.     // 读取IC配置CONFIG[1:0]
  26.     printf("Read config0 ............................... ");
  27.     DrvFMC_Read(CONFIG_BASE, &config0Bak);
  28.     printf("[0xx]\n", config0Bak);
  29.     printf("Read config1 ............................... ");
  30.     DrvFMC_Read(CONFIG_BASE+4, &config1Bak);
  31.     printf("[0xx]\n", config1Bak);

  32.     // 检查CONFIG[1:0]是否已经配置好
  33.     printf("Configuration .............................. ");
  34.     i32Err = 0;   
  35.     if((config0Bak != CONFIG0_TEST_CODE) || (config1Bak != CONFIG1_TEST_CODE)) {
  36.         i32Err = 1;
  37.         printf("[NOT MATCH]\n");
  38.     } else {
  39.         printf("[MATCH]\n");
  40.         printf("CONFIG0 .................................... [0x%x]\n",CONFIG0_TEST_CODE);
  41.         printf("DataFlash BASE ADDR ........................ [0x%x]\n",CONFIG1_TEST_CODE);
  42.     }

  43.     // IC配置不对或未配置、则修改配置
  44.     if(i32Err) {
  45.         // 擦除CONFIG[1:0]
  46.         printf("Erase config region ........................ ");
  47.         DrvFMC_EnableConfigUpdate(TRUE);
  48.         DrvFMC_Erase(CONFIG_BASE);
  49.         DrvFMC_Read(CONFIG_BASE, &u32Data);
  50.         if(u32Data != 0xFFFFFFFF) { printf("[FAIL]\n"); }
  51.         else                      { printf("[OK]\n");   }

  52.         // 修改CONFIG[1:0]
  53.         printf("Program config region ...................... ");
  54.         DrvFMC_Write(CONFIG_BASE, CONFIG0_TEST_CODE);
  55.         DrvFMC_Write(CONFIG_BASE+4, CONFIG1_TEST_CODE);

  56.         // 检查CONFIG[1:0]是否修改成功
  57.         i32Err = 0;   
  58.         DrvFMC_Read(CONFIG_BASE, &u32Data);
  59.         if(u32Data != CONFIG0_TEST_CODE) { i32Err = 1; }
  60.         DrvFMC_Read(CONFIG_BASE+4, &u32Data);
  61.         if(u32Data != CONFIG1_TEST_CODE) { i32Err = 1; }
  62.         if(i32Err) {
  63.             printf("[FAIL]\n");
  64.         } else {
  65.             printf("[OK]\n");
  66.             printf("CONFIG0 .................................... [0x%x]\n",CONFIG0_TEST_CODE);
  67.             printf("DataFlash BASE ADDR ........................ [0x%x]\n",CONFIG1_TEST_CODE);
  68.         }
  69.     }

  70.     // 关闭ISP模块
  71.     DrvFMC_EnableISP(0);
  72.     SYSCLK->AHBCLK.ISP_EN = 0;

  73.     // 结束操作
  74.     LOCKREG();
  75. }


 楼主| Jessicakjdsl 发表于 2016-3-17 13:28 | 显示全部楼层
2、保存数据、这个例程只保存2个数据到DATAFlash区,地址为0x23000开头的2个位置。
   如果需要将专门的一组初始化数据写入DATAFlash,可以将这些数据添加到一个数组,然后将数组放在一个专门的头文件里面。通过修改下面的保存函数,将其写入DATAFlash即可。
  1. void store_lamp_param(void)
  2. {
  3.     int32_t  i32Err  = 0;
  4.     uint32_t u32Data = 0;

  5.     static uint32_t mode  = 0;   // 模式
  6.     static uint32_t level = 0;   // 亮度等级

  7.     // 参数都没变化,则不用存储这些参数
  8.     if( (g_lamp_ctrl.mode == mode) && (g_lamp_ctrl.level == level) ) {
  9.         return ;
  10.     }

  11.     mode  = g_lamp_ctrl.mode;
  12.     level = g_lamp_ctrl.level;

  13.     printf("Store lamp param ...........................\r\n");

  14.     // 开始操作
  15.     UNLOCKREG();

  16.     // 开启ISP模块
  17.     SYSCLK->AHBCLK.ISP_EN = 1;
  18.     DrvFMC_EnableISP(1);

  19.     // 擦除数据
  20.     printf("Erase lamp param data ...................... ");
  21.     DrvFMC_Erase(LAMP_DATA_ADDR);
  22.     i32Err = 0;   
  23.     DrvFMC_Read(LAMP_DATA_ADDR + 0, &u32Data);
  24.     if(u32Data != 0xFFFFFFFF) { i32Err = 1; }
  25.     DrvFMC_Read(LAMP_DATA_ADDR + 4, &u32Data);
  26.     if(u32Data != 0xFFFFFFFF) { i32Err = 1; }
  27.     if(i32Err) { printf("[FAIL]\n"); goto ISP_OP_END;}
  28.     else       { printf("[OK]\n");                   }

  29.     // 修改数据
  30.     printf("Program lamp param data .................... ");
  31.     DrvFMC_Write(LAMP_DATA_ADDR + 0, g_lamp_ctrl.mode);
  32.     DrvFMC_Write(LAMP_DATA_ADDR + 4, g_lamp_ctrl.level);

  33.     // 检查数据是否修改成功
  34.     i32Err = 0;   
  35.     DrvFMC_Read(LAMP_DATA_ADDR + 0, &u32Data);
  36.     if(u32Data != g_lamp_ctrl.mode)  { i32Err = 1; }
  37.     DrvFMC_Read(LAMP_DATA_ADDR + 4, &u32Data);
  38.     if(u32Data != g_lamp_ctrl.level) { i32Err = 1; }
  39.     if(i32Err) {
  40.         printf("[FAIL]\n");
  41.     } else {
  42.         printf("[OK]");
  43.         printf("[mode = %d]",g_lamp_ctrl.mode);
  44.         printf("[level = %d]\n",g_lamp_ctrl.level);
  45.     }

  46. ISP_OP_END:
  47.     // 关闭ISP模块
  48.     DrvFMC_EnableISP(0);
  49.     SYSCLK->AHBCLK.ISP_EN = 0;

  50.     // 结束操作
  51.     LOCKREG();
  52. }

还有一个方法待测试:在.scatter文件中可以直接将初始化数据的头文件规划在指定的DATAFlash区:
  1. ROM_EXEC 0x23000 0x23400
  2.     {
  3.         Init_Data.o
  4.     }



gejigeji521 发表于 2016-3-17 13:56 | 显示全部楼层
好久没有看到谁用GOTO语句了,这个语句用好了就是神来一笔。
RAYINGPX 发表于 2019-9-12 14:02 | 显示全部楼层
dongnanxibei 发表于 2019-9-12 18:10 | 显示全部楼层
宝贵的经验。
643757107 发表于 2019-9-15 21:27 | 显示全部楼层
经验不错,发现大家的经验,比官方例子还靠谱
天灵灵地灵灵 发表于 2019-9-15 23:58 | 显示全部楼层
存储的顺序是从前到后按顺序就好办。
mintspring 发表于 2019-9-16 00:21 | 显示全部楼层
是不是很方便
zhuomuniao110 发表于 2019-9-16 20:51 | 显示全部楼层
多谢分享,原来可以这么利用
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

116

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部