硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1428|回复: 10
收起左侧

[SPI/QSPI] 求职!STM32H7使用SPI+DMA方式,访问外部FLASH的问题

[复制链接]

1

主题

9

回帖

12

积分

新手上路

积分
12
发表于 2021-11-15 20:12:29 | 显示全部楼层 |阅读模式
  如题,我用STM32H7的SPI模块+DMA的方式访问外部FLASH,在我开始读数据的时候,发送全是0XFF的数据去产生时钟,通过仿真看发送的BUFF的地址里的数据确实是都是0xFF,但是我用逻辑分析仪去看的时候,发现发送的数据有些不是0XFF,而是一些无规则的数,虽然不影响读取,但是感觉这样的问题有点莫名其妙,之前也会以是D-CACHE导致的,但是真实的地址上的数据确实是没错的,那应该是发送到总线上导致出错的。麻烦各路大神指导下,谢谢。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2021-11-16 08:58:30 | 显示全部楼层
可以考虑直接关闭所使用RAM区的Cache试试。或者发送前调用下Clean Cache操作。

http://www.armbbs.cn/forum.php?m ... 6980&extra=page%3D1

QQ截图20211116085751.png
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
 楼主| 发表于 2021-11-16 13:52:53 | 显示全部楼层
eric2013 发表于 2021-11-16 08:58
可以考虑直接关闭所使用RAM区的Cache试试。或者发送前调用下Clean Cache操作。

http://www.armbbs.cn/fo ...

谢谢,我把GPIO的翻转速度降低和SPI的速度降低之后问题就解决了。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2021-11-16 15:28:15 | 显示全部楼层
醉心客丶 发表于 2021-11-16 13:52
谢谢,我把GPIO的翻转速度降低和SPI的速度降低之后问题就解决了。

好的,你说的降低GPIO速度等级吧
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
 楼主| 发表于 2021-11-17 08:54:42 | 显示全部楼层
eric2013 发表于 2021-11-16 15:28
好的,你说的降低GPIO速度等级吧

是的,再打扰一下,我的W25Q128挂载Fatfs文件系统,格式化成功后挂载成功,第一次打开文件成功,然后写入数据之后,关闭,我再打开这个文件,返回值是FR_NO_FILE,请问会是什么原因呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2021-11-17 13:48:29 | 显示全部楼层
醉心客丶 发表于 2021-11-17 08:54
是的,再打扰一下,我的W25Q128挂载Fatfs文件系统,格式化成功后挂载成功,第一次打开文件成功,然后写入 ...

这个也有例子,二楼的链接里面,我们的QSPI Flash挂的是W25Q128
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
 楼主| 发表于 2021-11-18 14:43:24 | 显示全部楼层
eric2013 发表于 2021-11-17 13:48
这个也有例子,二楼的链接里面,我们的QSPI Flash挂的是W25Q128

我现在的问题定位到的是:
1、FLASH格式化后,FATFS会将根目录扇区全部清0,而f_open会从根目录扇区读取文件的起始簇,当起始簇不为0时,才回写文件信息,但是格式化之后明明根目录扇区的数据全是0,那创建文件后的文件信息是肯定不会被回写到根目录扇区的,这好奇怪啊,硬汉哥可以解答一下吗?
2、/* 4.把根目录所在的扇区全部清0 */
                nsect = (fmt == FS_FAT32) ? pau : sz_dir;        /* Number of root directory sectors */
                do {
                        n = (nsect > sz_buf) ? sz_buf : nsect;
                        if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) return FR_DISK_ERR;
                        sect += n; nsect -= n;
                } while (nsect);
3、/* Set directory entry initial state */
                                        cl = ld_clust(fs, dj.dir);                        /* Get current cluster chain */
                                        st_dword(dj.dir + DIR_CrtTime, GET_FATTIME());        /* Set created time */
                                        dj.dir[DIR_Attr] = AM_ARC;                        /* Reset attribute */
                                        st_clust(fs, dj.dir, 0);                        /* Reset file allocation info */
                                        st_dword(dj.dir + DIR_FileSize, 0);
                                        fs->wflag = 1;
                                        if (cl != 0) {                                                /* Remove the cluster chain if exist */
                                                dw = fs->winsect;
                                                res = remove_chain(&dj.obj, cl, 0;
                                                if (res == FR_OK) {
                                                        res = move_window(fs, dw);
                                                        fs->last_clst = cl - 1;                /* Reuse the cluster hole */
                                                }
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2021-11-18 15:29:52 | 显示全部楼层
醉心客丶 发表于 2021-11-18 14:43
我现在的问题定位到的是:
1、FLASH格式化后,FATFS会将根目录扇区全部清0,而f_open会从根目录扇区读取 ...

这样的话,估计你的diskio.c文件里面接口函数有点问题了。
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
 楼主| 发表于 2021-11-18 16:13:22 | 显示全部楼层
eric2013 发表于 2021-11-18 15:29
这样的话,估计你的diskio.c文件里面接口函数有点问题了。

可是,我现在挂载文件系统正常,创建文件正常,写入数据正常关闭正常,只有第二次打开第一次创建的文件返回是No file~
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
 楼主| 发表于 2021-11-18 21:26:33 | 显示全部楼层
eric2013 发表于 2021-11-18 15:29
这样的话,估计你的diskio.c文件里面接口函数有点问题了。

关于底层接口的问题,我做了相关测试,我一直从0x00这个地址开始写数据,写数据的数量每次+1,写完之后读相同的数量,判断读出来和写进去的不等就打印出来,一直都没有问题,diskio的接口函数就是读和写,现在底层接口的发和收应该是没问题的,剩下的就是IOCTRL了,我设置是这样的:
#define EXTERNAL_FLASH_SECTOR_SIZE 512
uint16_t u16ExternalFlashSectorCount = 2048 * 16;
#define EXTERNAL_FLASH_BLOCK_SIZE   8
else if(pdrv == DEV_EX_FLASH)        //外部FLASH  
        {
            switch(cmd)
            {
                    case CTRL_SYNC:
                                {
                                                res = RES_OK;
                        break;         
                                }
                    case GET_SECTOR_SIZE:
                                {
                        *(WORD*)buff = EXTERNAL_FLASH_SECTOR_SIZE;
                        res = RES_OK;
                        break;         
                                }
                    case GET_BLOCK_SIZE:
                                {
                        *(WORD*)buff = EXTERNAL_FLASH_BLOCK_SIZE;
                        res = RES_OK;
                        break;         
                                }
                    case GET_SECTOR_COUNT:
                                {
                        *(DWORD*)buff = u16ExternalFlashSectorCount;
                        res = RES_OK;
                        break;
                                }
                    default:
                                {
                        res = RES_PARERR;
                        break;
                                }
                        }
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2021-11-19 01:09:59 | 显示全部楼层
醉心客丶 发表于 2021-11-18 21:26
关于底层接口的问题,我做了相关测试,我一直从0x00这个地址开始写数据,写数据的数量每次+1,写完之后读 ...

初步看没什么问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-17 20:18 , Processed in 0.304421 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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