查看: 2114|回复: 2

[原创] LPC54114 USB 读卡器

[复制链接]
  • TA的每日心情
    开心
    2022-11-9 15:32
  • 签到天数: 188 天

    [LV.7]常住居民III

    3

    主题

    288

    帖子

    4

    高级会员

    Rank: 4

    积分
    820
    最后登录
    2023-8-23
    发表于 2018-7-28 14:07:35 | 显示全部楼层 |阅读模式
    恩智浦提供的LPC54114的USB例程十分丰富,包括了比较常用的HID、CDC、MSC等设备类的实现,只需适当修改就能实现需要的自定义功能。

    利用板载TF卡槽和USB外设,配合官方例程进行修改可以很容易的实现USB读卡器功能,由于没有进行进一步优化,所以读卡器传输速度并不是很快。

    板载TF卡采用的是SPI总线,官方提供的SDK中已经有对TF卡的支持及移植好的fatfs文件系统,使用起来很方便,在USB读卡器的实现过程中并未用到fatfs,只用到了TF卡初始化、读扇区、写扇区这几个基本功能。

    官方提供的USB大容量存储设备是将内部48K内存虚拟成了一个存储器,在发生读写操作时便直接对这块内存进行读写,要将该程序修改成适合读卡器使用,只要将对应读写部分进行修改即可。

    disk.c文件中的 USB_DeviceMscCallback 函数是大容量存储设备USB请求最终执行及实现功能的地方。修改也主要集中在这里,这里有几个枚举类型定义需要了解
    Value Mean
    kUSB_DeviceMscEventReadResponse Send data completed
    kUSB_DeviceMscEventWriteResponse Data received
    kUSB_DeviceMscEventWriteRequest Host write data
    kUSB_DeviceMscEventReadRequest Host read data
    kUSB_DeviceMscEventGetLbaInformation Get device information
    修改主要就是在对应请求发生时对tf卡进行读写操作,这里我们仍然需要一个缓冲区来对读写的数据进行暂存,这里直接将原来用于模拟存储设备的数组调整了一下大小后拿来使用了。

    将disk.c中100行左右
    1. USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_StorageDisk[DISK_SIZE_NORMAL];
    复制代码
    修改为
    1. USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_StorageDisk[512];
    复制代码
    修改成512的原因是我们以扇区为单位对tf卡进行读写,而在tf卡初始化过程中设置的扇区大小为512字节。

    将 USB_DeviceMscCallback 函数中

    1. case kUSB_DeviceMscEventReadResponse:
    2.         lbaData = (usb_device_lba_app_struct_t *)param;
    3.         break;
    4. case kUSB_DeviceMscEventWriteResponse:
    5.         lbaData = (usb_device_lba_app_struct_t *)param;
    6.         break;
    7. case kUSB_DeviceMscEventWriteRequest:
    8.         lbaData = (usb_device_lba_app_struct_t *)param;
    9.         /*offset is the write start address get from write command, refer to class driver*/
    10.         lbaData->buffer = g_msc.storageDisk + lbaData->offset * LENGTH_OF_EACH_LBA;
    11.         break;
    12. case kUSB_DeviceMscEventReadRequest:
    13.         lbaData = (usb_device_lba_app_struct_t *)param;
    14.         /*offset is the read start address get from read command, refer to class driver*/
    15.         lbaData->buffer = g_msc.storageDisk + lbaData->offset * LENGTH_OF_EACH_LBA;
    16.         break;
    17. case kUSB_DeviceMscEventGetLbaInformation:
    18.         lbaInformationStructure = (usb_device_lba_information_struct_t *)param;
    19.         lbaInformationStructure->lengthOfEachLba = LENGTH_OF_EACH_LBA;
    20.         lbaInformationStructure->totalLbaNumberSupports = TOTAL_LOGICAL_ADDRESS_BLOCKS_NORMAL;
    21.         lbaInformationStructure->logicalUnitNumberSupported = LOGICAL_UNIT_SUPPORTED;
    22.         lbaInformationStructure->bulkInBufferSize = DISK_SIZE_NORMAL;
    23.         lbaInformationStructure->bulkOutBufferSize = DISK_SIZE_NORMAL;
    24.         break;
    复制代码
    修改为
    1. case kUSB_DeviceMscEventReadResponse:
    2.         lbaData = (usb_device_lba_app_struct_t *)param;
    3.         break;
    4. case kUSB_DeviceMscEventWriteResponse:
    5.         //usb_echo("data received\r\n");
    6.         lbaData = (usb_device_lba_app_struct_t *)param;
    7.         do
    8.         {
    9.                 fres = disk_write(SDSPIDISK, lbaData->buffer, lbaData->offset, 1);
    10.         }while(fres != FR_OK);
    11.         break;
    12. case kUSB_DeviceMscEventWriteRequest:
    13.         lbaData = (usb_device_lba_app_struct_t *)param;
    14.         /*offset is the write start address get from write command, refer to class driver*/
    15.         lbaData->buffer = g_msc.storageDisk;
    16.         break;
    17. case kUSB_DeviceMscEventReadRequest:
    18.         lbaData = (usb_device_lba_app_struct_t *)param;
    19.         /*offset is the read start address get from read command, refer to class driver*/
    20.         lbaData->buffer = g_msc.storageDisk;
    21.         do
    22.         {
    23.                 fres = disk_read(SDSPIDISK, lbaData->buffer, lbaData->offset, 1);
    24.         }while(fres != FR_OK);

    25.         break;
    26. case kUSB_DeviceMscEventGetLbaInformation:
    27.         lbaInformationStructure = (usb_device_lba_information_struct_t *)param;
    28.         lbaInformationStructure->lengthOfEachLba = g_card.blockSize;
    29.         lbaInformationStructure->totalLbaNumberSupports = g_card.blockCount;
    30.         lbaInformationStructure->logicalUnitNumberSupported = LOGICAL_UNIT_SUPPORTED;
    31.         lbaInformationStructure->bulkInBufferSize = 512; //change this value to define buffer size
    32.         lbaInformationStructure->bulkOutBufferSize = 512;
    33.         break;
    复制代码
    kUSB_DeviceMscEventGetLbaInformation 请求设备的信息以及批量端点缓冲区大小,设备信息是根据tf卡的大小来进行设置的,而端点大小跟上面读写缓冲期大小相等即可。

    kUSB_DeviceMscEventWriteRequest 主机发起写请求,只需将指针指向缓冲区即可。

    kUSB_DeviceMscEventWriteResponse 从机已收到主机发送的数据,只需要将数据写入tf卡即可,需要注意这里的读写长度均以扇区为单位

    kUSB_DeviceMscEventReadRequest 主机发起读请求,根据参数从tf读取数据至缓冲区,再将指针指向缓冲区即可。


    编译完成下载至开发板使用CN3接口连接电脑即可对tf卡进行读写了。

    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2018-12-3 15:59
  • 签到天数: 1 天

    [LV.1]初来乍到

    5

    主题

    38

    帖子

    0

    注册会员

    Rank: 2

    积分
    195
    最后登录
    2019-12-19
    发表于 2018-12-3 17:08:17 | 显示全部楼层
    你好,例程中都是把54114当从设备来用。当主设备的例程有么?我没找到啊
    今天天气不错!签到!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2022-11-9 15:32
  • 签到天数: 188 天

    [LV.7]常住居民III

    3

    主题

    288

    帖子

    4

    高级会员

    Rank: 4

    积分
    820
    最后登录
    2023-8-23
     楼主| 发表于 2018-12-7 07:00:07 | 显示全部楼层
    wangzhipeng877 发表于 2018-12-3 17:08
    你好,例程中都是把54114当从设备来用。当主设备的例程有么?我没找到啊

    54114的USB外设本来就是从机,这种问题问出来,你不看手册的吗?
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2024-4-30 00:41 , Processed in 0.123672 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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