Sigmatel37xx GPIO的使用

//========================================================================
//TITLE:
//    Sigmatel37xx GPIO的使用
//AUTHOR:
//    norains
//DATE:
//    Thursday 21-August-2008
//Environment:
//    NONE
//========================================================================
    在文章开篇之前,先小小抱怨一下。Sigmatel的硬件部分做得不错,这个是必须承认的;但WinCE的软件部分,却不能不让人抓狂。用一句

黑话来说,就是见过烂的,没有见过这么烂的:条理杂乱无章,结构模糊不清,更不用说那些莫名其妙的BUG了。以GPIO为例子,其实在

Sigmatel 37xx BSP包已经有驱动,但实际上只是一些代码而已,没有注册表,没有PB选项,换句话说,你根本无法通过简单的设置来使用GPIO

驱动。
   
    如果想控制GPIO,那么唯一的办法就是直接对寄存器进行读写。
   
    首先我们必须要做的就是,包含头文件:regspinctrl.h。不过这个可得小心了,因为这文件有两个,一个位于:/SRC/INC/37xxRegs,另

一个则是在/SRC/SOCFirmware/include/37xx/registers。并且这不同位置的文件的开头描述都是一样的,但实际上在宏定义方面区别还挺大,

从而导致包含不同的regspinctrl.h,程序代码就有不同的写法。弱弱地感叹一下,不能不拜服sigmatel的方式。
   
    在这里为了简便起见,我们用的是/SRC/INC/37xxRegs/regspinctrl.h。
   
    首先,在使用之前,我们必须映射一下内存地址:
    static PVOID pv_HwRegPinCtrl;
   static PHYSICAL_ADDRESS PhysAddr;
    PhysAddr.QuadPart = _PA_REGS_PINCTRL_BASE;
    pv_HwRegPinCtrl = (PVOID) MmMapIoSpace(PhysAddr, 0x1000, FALSE);

    if ( pv_HwRegPinCtrl == NULL)
    {
       RETAILMSG(1, (TEXT("Failed to map device registers /r/n")));
       return FALSE;
    }
   
    如果提示找不到PHYSICAL_ADDRESS的声明,请先包含ceddk.h。在这里还有一点需要提醒一下的是,pv_HwRegPinCtrl变量只能用该名字,

并且作用域是全局的,否则在接下来的宏使用中会编译无法通过。
   
    在对GPIO进行操作之前,我们先了解如下几个宏:
    REG_HW_PINCTRL_MUXSELx_SET : 设置pin的功能。
    BF_PINCTRL_MUXSELx_BANKx_PINxx :将相应的pin功能转化为写入寄存器的数值。
    REG_HW_PINCTRL_DOUTx_SET :输出high
    REG_HW_PINCTRL_DOUTx_CLR :输出low
    REG_HW_PINCTRL_DOEx_SET :输出使能
    REG_HW_PINCTRL_DOEx_CLR :输入使能
    REG_HW_PINCTRL_DINx_RD :如果PIN为输入,则该宏用来读取相应寄存器的数值。
   
    宏中的x代表数字,对应相应的PIN。
   
   
    现在以实际例子对pin做一次操作。
   
    如果我们在datasheet中看到某个PIN有如下描述:
    HW_PINCTRL_MUXSEL0 BANK0_PIN08
    GPMI_D08 Pin Function Selection.
   00 = GPMI_D8.
   01 = EMI_ADDR15.
   10 = Reserved.
   11 = GPIO.
   
  如果我们想令该PIN作为GPIO并输出high,那么代码如下:
  REG_HW_PINCTRL_MUXSEL0_SET(BF_PINCTRL_MUXSEL0_BANK0_PIN08(3)); 
  REG_HW_PINCTRL_DOUT0_CLR(1 << 8);  
  REG_HW_PINCTRL_DOE0_SET(1 << 8); 
  
  对应datasheet,我们就不难发现以上三个宏的x如何选择相应的数字,如图:
  
  
  若是想将该pin作为输入,也是比较简单,样例代码如下:
  REG_HW_PINCTRL_MUXSEL0_SET(BF_PINCTRL_MUXSEL0_BANK0_PIN08(3));
  REG_HW_PINCTRL_DOE0_CLR(1 << 8); //设置为输入  
  if((REG_HW_PINCTRL_DIN0_RD() & (1 << 8)) != 0)
  {
   //Input high
  }
  else
  {
   //Input low
  }
  
  代码宏中数字的选择,可参考之前图片的解释,在此就不再详表。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明
BOOL status = 0; DWORD accessMode = 0, shareMode = 0; HANDLE fileHandle = NULL; //PUCHAR dataBuffer = NULL; SCSI_PASS_THROUGH_WITH_BUFFERS sptwb; SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb; UCHAR buffer[ 2048 ]; UCHAR string[ 25 ]; ULONG length = 0, errorCode = 0; DWORD returned = 0; strcpy(string, "\\\\.\\"); strcat(string, "I:"); shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;//default accessMode = GENERIC_WRITE | GENERIC_READ;//default fileHandle = CreateFile( string, accessMode, shareMode, NULL, OPEN_EXISTING, 0, NULL ); if (fileHandle == INVALID_HANDLE_VALUE) { MessageBox(NULL, "Create file fail", "tester", MB_OK); return false; } ZeroMemory(&sptwb, sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS)); sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH); sptwb.spt.PathId = 0; sptwb.spt.TargetId = 1; sptwb.spt.Lun = 0; sptwb.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb.spt.SenseInfoLength = 24; sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN; sptwb.spt.DataTransferLength = 192; sptwb.spt.TimeOutValue = 2; sptwb.spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf); sptwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf); sptwb.spt.Cdb[0] = SCSI_OPCODE_HWTEST_COMMAND; //SCSI_OPCODE_SIGMATEL_WRITE_COMMAND;// sptwb.spt.Cdb[1] = HWTEST_DISPLAY_ID;//ALLOCATE_MEDIA; sptwb.spt.Cdb[4] = 192; length = offsetof( SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf ) + sptwb.spt.DataTransferLength; status = DeviceIoControl( fileHandle, IOCTL_SCSI_PASS_THROUGH, &sptwb, sizeof(SCSI_PASS_THROUGH), &sptwb, length, &returned, FALSE ); if (!status) { MessageBox(NULL, "Device I/0 control fail!", "tester", MB_OK); errorCode = GetLastError(); ShowMessage(IntToStr(errorCode)); PrintError(errorCode); CloseHandle(fileHandle); return false; } CloseHandle( fileHandle ); return true;
03-22

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值