直接控制GPIO引脚读取磁卡数据

2019-04-14 08:30发布

1、硬件GPIO引脚使用情况: GPIO[495557]对应磁卡器的RCP[3]RDD[3]CLSNPWN 2、磁卡各引脚的使用情况: CLS 刷卡开始为下降沿,磁卡走行中保持低电频,走向结束上升沿,无磁卡走行时保持高电频 RCP记录采样频率,每半个周期的幅度为100千欧 14毫秒;620千欧 60毫秒,前半周期高电,后半周期为低频 RDD数据采样端,当采样引脚RCP为高电频(前半周期)时,该段开始采样 CLS 为共用引脚,RCPRDD在磁卡不同的情况下分别使用1-3个不同的引脚 3、实现读取磁卡数据的思路:   思路一 ACLS下降沿时发生中断,置bit计数器为0,以便记录最终得到数据量(以bit为单位);上升沿时,返回逻辑中断向量,唤醒IST   BRCP上升沿时发生中断,使用时钟中断(2-3微妙发生一次),RDD端进行数据采样;RCP下降沿时关闭时钟中断,根据RDD数据采样计算最终数据,将数据保存至共享的内存空间,以便磁卡驱动来读取数据   思路二: A   CLS下降沿时发生中断,置位计数器为0,以便记录最终得到数据量(以bit为单位);上升沿时结束中 BRCP上升沿时发生中断,使用while语句以轮询方式,采样RDD段的数据;RCP下降沿时,根据RDD数据采样计算最终数据,将数据保存至共享的内存空间,以便磁卡驱动来读取数据 4、实现步骤:   1)、CLS端中断机制的建立,   2)、RCP端中断机制的建立   3)、时钟中断机制的建立(暂时忽略,数据采样工作在RCP上升沿发生中断时进行一次) 5、具体实现方法:    比较觉得:思路二轮询采样RDD数据线的方式不合适,其效率比较低,并且,对于采样的时机比较难把握,因此思路一成为首选方案。按照思路一,已经实现磁卡的读写功能。   1)、中断机制的建立: a. BSP中定义中断的逻辑值。如:wince60/PlatForm/XXX/src/inc/bsp_cfg.h中添加定义 #define  SYSINTR_MYINTR  (SYSINTR_FIRMWARW+23) b. BSPOALintr.c文件中,添加具体的物理中断的定义以及中断处理代码。 根据硬件连接情况及资料得知,需要将相关中断是作为IRQ_GPIOXX_2的子中断进行处理。在XXX/SoC/PXA310/OAL/INTR/intr.c中,IRQ_GPIOXX_2的相关处理会调用到XXX/ src /oal/oallib/intr.c中的中断处理函数BSPIntrActiveIrq()(该函数会返回对应得物理中断号)、BSPIntrDisableIrq()、BSPIntrDoneIrq()、BSPIntrEnableIrq()、BSPIntrInit()、BSPIntrRequestIrqs()等。因此,在XXX/ src /oal/oallib/intr.c中添加相应得物理中断的定义和处理代码,如: #define  IRQ_GPIO55_MCARD_CLS_R  (IRQ_MONAHANS_MAX + 17) 需要注意的是,定义物理中断号的同时,不要忘记修改IRQ_XXX_GPIO_MAX等的定义,至于具体实现操作的代码,就是根据需要来修改了。 c. 修改OEMInterruptHandler()函数对应逻辑中断和物理中断 在这里添加的这个中断GPIO55_R的物理中断号,就是用于在读卡结束时(GPIO55号引脚回有上升沿的跳变),对应逻辑中断SYSINTR_MYINTR,唤起相应的中断程序。对于逻辑中断和物理中断的对应,是由XXX/SoC/PXA310/OAL/INTR/intr.c中的OEMInterruptHandler()函数来完成的,它会调用BSPIntrActiveIrq(),然后,根据返回的物理中断值来修改sysIntr值。 [小结]:如果一切顺利,那么,到此有关于由IRQ_GPIOXX_2的子中断引起的中断机制就建立完毕了,重新编译生成新的nk.bin就可以了。该中断与非IRQ_GPIOXX_2的中断相比可能会麻烦一些。对于非IRQ_GPIOXX_2的中断,直接在XXX/SoC/PXA310/OAL/INTR/intr.c文件中修改代码即可。   2)、用户层对内核数据的使用: a.对于数据的读取,是在RCP引脚的发生跳变的时候进行的,因此,代码是写在XXX/ src /oal/oallib/intr.c中的,在RCP[n]引脚发生中断时,读数据、并将数据保存下来,以便读卡结束时驱动层可以读到数据。具体读数据的函数代码如下:(一共有三个磁道需要分别读写数据、进行保存,每个磁道的物理特性不同) void ReadDataFromRDD(UINT32 XLLP_GPIO_BIT_RDD) { switch(XLLP_GPIO_BIT_RDD){         case XLLP_GPIO_BIT_CIF_DD5:                                                      if (g_bitIndex1 == MAX_BIT_NUMBER)// MAX_BIT_NUMBER=8               {                             g_bitIndex1 = 0;                             g_byteIndex1 += 1;               }                 if (g_byteIndex1 > MAX_BYTE_NUMBER)// MAX_BYTE_NUMBER=1024               {                              return;               }                 if (g_pGPIORegs->gplr1 & XLLP_GPIO_BIT_RDD)//读数据寄存器的值               {                             g_chBuf1[g_byteIndex1] &= ~(1<                                                                  //三个磁道使用的均是负逻辑               }               else               {                                                                                                               g_chBuf1[g_byteIndex1] |= (1 << g_bitIndex1);               }                           g_bitIndex1++;               break;                 //data type is tract2               case XLLP_GPIO_BIT_CIF_DD3:                                                              ……                             break;                 //data type is tract3               case XLLP_GPIO_BIT_CIF_DD1:                             ……                             break;                 default:                             break;         }         return; } b.使用KernelIoControl ()来完成数据由OAL层向驱动层的传输。 (有些东西具体什么作用不是很清楚,都是是仿照现有BSP中其他使用了KernelIoControl的代码写的) 首先,在XXX/ SRC/INC/ioctl_cfg.h文件中,宏定义一个资源号,该资源号是作为CTL_CODE的第二个参数使用的;宏定义KernelIoControl 中需要的IOControlID。如: #define MAGNETIC_CARD_DATA_TRANS 4003 #define  IOCTL_HAL_MAGNETIC_CARD_TRANS CTL_CODE(FILE_DEVICE_HAL, (MAGNETIC_CARD_DATA_TRANS), METHOD_BUFFERED, FILE_ANY_ACCESS) 其次,在XXX/ SRC/INC/ioctl_tab.h中,添加映射,如: { IOCTL_HAL_MAGNETIC_CARD_TRANS,     0,OALIoCtlHalTransMagneticCardData}, 最后,在XXX/ SRC/INC/ioctl.c中添加OALIoCtlHalTransMagneticCardData ()函数的具体代码 c. 使用DeviceIoControl(对应驱动层的XXX_IOControl)或者XXX_Read函数,把数据传递给用户层。     通过以上的操作,直接使用GPIO控制读取磁卡信息的功能已经实现,并且在用户层的测试程序中得到了正确的数据。我也是第一次接触中断机制、第一次从内核中读取数据,可能理解的还不是很透彻。如果有问题,还请大家指出,呵呵,不过,请不要讲一些过于极端的话(偶会被打击的失去信心的),谢谢^_^