函数定义如下:
section("L1_code") int InitProcessorSpecificConfiguration(ADI_NET2272_DEVICE *pDev) { unsigned short usValue; volatile unsigned int v; #if defined(__ADSPBF533__) /* configure interrupt flag as level sensitive input from NET2272 */ usValue = *pFIO_INEN; *pFIO_INEN = usValue | pDev->PF_Int; usValue = *pFIO_DIR; *pFIO_DIR = usValue & ~(pDev->PF_Int); usValue = *pFIO_EDGE; *pFIO_EDGE = usValue & ~(pDev->PF_Int); usValue = *pFIO_MASKA_D; *pFIO_MASKA_D = usValue | pDev->PF_Int; usValue = *pFIO_POLAR; *pFIO_POLAR = usValue | pDev->PF_Int; /* configure the SET and CLEAR flags as outputs and perform SET or CLEAR */ usValue = *pFIO_DIR; *pFIO_DIR = usValue | pDev->PF_Set | pDev->PF_Clear; *pFIO_FLAG_C = pDev->PF_Clear; *pFIO_FLAG_S = pDev->PF_Set; #elif defined(__ADSPBF537__) /* configure interrupt flag as level sensitive input from NET2272 */ usValue = *pPORTFIO_INEN; *pPORTFIO_INEN = usValue | pDev->PF_Int; usValue = *pPORTFIO_DIR; *pPORTFIO_DIR = usValue & ~(pDev->PF_Int); usValue = *pPORTFIO_EDGE; *pPORTFIO_EDGE = usValue & ~(pDev->PF_Int); usValue = *pPORTFIO_MASKA; *pPORTFIO_MASKA = usValue | pDev->PF_Int; usValue = *pPORTFIO_POLAR; *pPORTFIO_POLAR = usValue | pDev->PF_Int; /* configure the SET and CLEAR flags as outputs and perform SET or CLEAR */ usValue = *pPORTFIO_DIR; *pPORTFIO_DIR = usValue | pDev->PF_Set | pDev->PF_Clear; *pPORTFIO_CLEAR = pDev->PF_Clear; *pPORTFIO_SET = pDev->PF_Set; #elif defined(__ADSPBF561__) /* 将从NET2272的输入中断标记设置为电平触发 */ /* configure interrupt flag as level sensitive input from NET2272 */ usValue = *pFIO0_INEN; /* 读取中断使能寄存器值 */ *pFIO0_INEN = usValue | pDev->PF_Int; /* 根据设备中断值配置FIO0_INEN寄存器 */ usValue = *pFIO0_DIR; *pFIO0_DIR = usValue & ~(pDev->PF_Int); usValue = *pFIO0_EDGE; *pFIO0_EDGE = usValue & ~(pDev->PF_Int); usValue = *pFIO0_MASKA_D; *pFIO0_MASKA_D = usValue | pDev->PF_Int; usValue = *pFIO0_POLAR; *pFIO0_POLAR = usValue | pDev->PF_Int; /* configure the SET and CLEAR flags as outputs and perform SET or CLEAR */ usValue = *pFIO0_DIR; *pFIO0_DIR = usValue | pDev->PF_Set | pDev->PF_Clear; *pFIO0_FLAG_C = pDev->PF_Clear; *pFIO0_FLAG_S = pDev->PF_Set; #else #error *** Processor not supported *** #endif /* delay for a bit */ for (v = 0; v < 0xfffff; v++) ; return 0; }
函数参数数据类型为 ADI_NET2272_DEVICE,其定义如下
/* NET2272的内核设备结构体,是HOST与NET2272驱动的借口 */ /* NET2272 Core Device Structure */ typedef struct Net2272DeviceData { ADI_DEV_DEVICE_HANDLE DeviceHandle; /* 设备句柄 */ ADI_DMA_MANAGER_HANDLE DMAHandle; /* DMA控制句柄 */ ADI_DCB_HANDLE DCBHandle; /* 数据控制块(DCB)句柄 */ ADI_DCB_CALLBACK_FN DMCallback; /* 回调函数 */ ADI_DEV_DIRECTION Direction; /* 设备方向 */ void *pCriticalRegionArg; /* 边界区参数指针 */ bool Started; /* 开始标志 */ DEVICE_STATE State; /* 设备状态 */ PHYSICAL_ENDPOINT_OBJECT PhysicalEndpointObjects[NUM_PHYSICAL_ENDPOINTS]; /* 物理终点对象*/ int NumPhysicalEndpoints; /* 物理中点数量 */ ADI_DMA_STREAM_ID DmaStreamID; /* DMA流的ID */ void* DmaChannelHandle; /* DMA通道句柄 */ ADI_INT_PERIPHERAL_ID PeripheralID; /* 外围设备ID *、 u32 PeripheralIVG; /* 外围设备中断向量表 */ int PF_Reset; /* PF(Programmable Flag)角复位 */ int PF_Int; /* PF角中断 */ int PF_Clear; /* PF角清空 */ int PF_Set; /* PF角设置 */ int DeviceID; /* 设备ID */ DEVICE_OBJECT *pDeviceObj; /* 设备对象指针 */ NET2272_STATS Stats; /* NET2272的状态 */ bool Cache; /* Cache */ void *ConfigMemoryArea; /* 配置内存区指针 */ int ConfigMemorySize; /* 配置内存区大小 */ int BufferPrefix; /* 缓冲区前缀 */ ADI_USB_DEVICE_SPEED Speed; /* USB 设备速度 */ }ADI_NET2272_DEVICE;
因为我用的芯片是ADSPBF561,所以只对ADSPBF561部分进行分析。在分析之前有必要先介绍一下FIOn_XXX寄存器。
1:Flag Input Enable Register (FIOn_INEN)
The Flag Input Enable register is used to enable the input buffers on any flag pin that is being used as an input. Leaving the input buffer disabled eliminates the need for pullups and pulldowns when a particular PFx pin is not used in the system. By default, the input buffers are disabled.
2:Flag Direction Register (FIOn_DIR)
The Flag Direction register is a read-write register. Each bit position corresponds to a PFx pin. A logic 1 configures a PFx pin as an output, driving the state contained in the FIOn_FLAG_D register. A logic 0 configures a PFx pin as an input. The reset value of this register is 0x0000, making all PF pins inputs upon reset.
Note: Note that when using the PFx pin as an input, the corresponding bit should also be set in the Flag Input Enable register.
3:Flag Interrupt Sensitivity Register (FIOn_EDGE)
The Flag Interrupt Sensitivity register is used to configure each of the flags as either a level-sensitive or an edge-sensitive source. When using a edge-sensitive mode, an edge-detection circuit is used to prevent a situation where a short event is missed because of the system clock rate. This register has no effect on PFx pins that are defined as outputs.
The contents of this register are cleared at reset. defaulting to level sensitivity.
4:Flag Mask Interrupt Data register (FIOn_MASKA_D)
The Flag Mask Interrupt registers are implemented as complementary pairs of write-1-to-set, write-1-to-clear, and write-1-to-toggle registers. This implementation provides the ability to enable or disable a PFx pin to act as an interrupt without requiring read-modify-write accesses—or to directly specify the mask value with the data register.
Both Flag Interrupt A and Flag Interrupt B are supported by a set of four dedicated registers:
Each PFx pin is represented by a bit in each of the eight registers. Table 14-5 shows the effect of writing 1 to a bit in a Mask Set, Mask Clear, or Mask Toggle register.
Register
|
Effect of Writing 1 to a Bit in the Register
|
---|---|
Mask Set
|
Enables interrupt generation for that PFx pin
|
Mask Clear
|
Disables interrupt generation for that PFx pin
|
Mask Toggle
|
Changes the state of interrupt generation capability
|
Mask Data
|
Enables interrupt generation for that PFx pin
|
4:FLag Polarity Register (FIOn_POLAR)
The Flag Polarity register is used to configure the polarity of the flag input source. To select active high or rising edge, set the bits in this register to 0.
To select active low or falling edge, set the bits in this register to 1.
This register has no effect on PFx pins that are defined as outputs. The contents of this register are cleared at reset, defaulting to active high polarity.
因为要设置NET2272的输入中断为电平触发,所以先读取输入使能寄存器值
usValue = *pFIO0_INEN;
然后根据设备设置属性PF_Int值修改FIO0_INEN
*pFIO0_INEN = usValue | pDev->PF_Int;
读取PF角方向寄存器值
usValue = *pFIO0_DIR;
将中断使能寄存器对应的使能位设置为输入角
*pFIO0_EDGE = usValue & ~(pDev->PF_Int);
读取数据掩码位
usValue = *pFIO0_MASKA_D
使能对应管脚中断
*pFIO0_MASKA_D = usValue | pDev->PF_Int;
将输入管脚设置为高电平触发,与FIOn_EDGE配合使用
usValue = *pFIO0_POLAR;
*pFIO0_POLAR = usValue | pDev->PF_Int;
因为是通过ADSP是接收端,input from NET2272,所以ADSP要通过FIOn_FLAG_C & FIOn_FLAG_S来控制 NET2272
usValue = *pFIO0_DIR;
*pFIO0_DIR = usValue | pDev->PF_Set | pDev->PF_Clear; /* 方向配置为输出 */
*pFIO0_FLAG_C = pDev->PF_Clear;
*pFIO0_FLAG_S = pDev->PF_Set;
以上语句将SET 和 CLEAR 标记配置为输出来执行SET或CLEAR
根据以上分析可得,本函数功能主要是对相应的PF管脚进行配置,使NET2272与ADSPBF561通过相应的管脚通信。