4LAN9252
端口配置由硬件引脚决定
PDI接口模式由寄存器决定
寄存器的配置从EEPROM中读取,EEPROM的配置由XML文件配置
该配置的值由文档《》可得
设置为16位变址模式
去MicroChip官网下载 LAN9252-PIC32_SDK_V1.1 文件,里面有与LAN9252的通讯代码,基于该代码文件修改
pmpdrive.c
/*******************************************************************************
PIC32 Host Bus Interface Driver
Company:
Microchip Technology Inc.
File Name:
PMPDriver.c
Summary:
Contains the functional implementation of PIC32 Host Bus Interface Driver
Description:
This file contains the functional implementation of PIC32 Host Bus Interface Driver
Change History:
Version Changes
0.1 Initial version.
1.3 Re-arranged the functions.
*******************************************************************************/
/*******************************************************************************
Copyright (c) 2015 released Microchip Technology Inc. All rights reserved.
Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital signal
controller that is integrated into your product or third party product
(pursuant to the sublicense terms in the accompanying license agreement).
You should refer to the license agreement accompanying this Software for
additional information regarding your rights and obligations.
SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
*******************************************************************************/
// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************
#include "stm32f4xx.h"
#include "pmpdriver.h"
#include "string.h"
#define Bank1_SRAM1_ADDR ((uint32_t)0x60000000)
/*******************************************************************************
Function:
void PMPOpen(PMPMode pmpmode, RWType rwtype, Polarity pl)
Summary:
This function configures the PMP(Host Bus Interface) module of SOC.
Description:
This function configures the PMP(Host bus Interface) module of SOC. Refer HBI section of LAN9252 datasheet for more information.
Parameters:
pmpmode- Different modes(INDEXED_8BIT, INDEXED_16BIT, MDP_8BIT, MDP_16BIT, MSP_8BIT, MSP_16BIT)
rwtype - Read and Write on separate pins(MM2) or same pin(MM1)
pl - Different polarities.
*****************************************************************************/
void PMPOpen(void)
{
// FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
// FSMC_NORSRAMTimingInitTypeDef p;
// GPIO_InitTypeDef GPIO_InitStructure;
//
// /* Enable GPIOs clock */
// RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF |
// RCC_AHB1Periph_GPIOG, ENABLE);
// /* Enable FSMC clock */
// RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
/*-- GPIOs Configuration -----------------------------------------------------*/
/*
+-------------------+--------------------+------------------+------------------+
| PD0 <-> FSMC_D2 | | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 |
| PD1 <-> FSMC_D3 | | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 |
| PD4 <-> FSMC_NOE | | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 |
| PD5 <-> FSMC_NWE | | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 |
| PD8 <-> FSMC_D13 | | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 |
| PD9 <-> FSMC_D14 | | PF5 <-> FSMC_A5 | |
| PD10 <-> FSMC_D15 | | PF12 <-> FSMC_A6 | |
| | PE7 <-> FSMC_D4 | PF13 <-> FSMC_A7 |------------------+
| | PE8 <-> FSMC_D5 | PF14 <-> FSMC_A8 |
| | PE9 <-> FSMC_D6 | PF15 <-> FSMC_A9 |
| PD14 <-> FSMC_D0 | PE10 <-> FSMC_D7 |------------------+
| PD15 <-> FSMC_D1 | PE11 <-> FSMC_D8 |
+-------------------| PE12 <-> FSMC_D9 |
PD6-> FSMC_NWAIT | PE13 <-> FSMC_D10 |
PD7 <-> FSMC_NE1 | PE14 <-> FSMC_D11 |
| PE15 <-> FSMC_D12 |
+--------------------+
*/
/* GPIOD configuration */
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
// GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 |
// GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
//
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
// GPIO_Init(GPIOD, &GPIO_InitStructure);
// /* GPIOE configuration */
// GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FSMC);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 |
// GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11|
// GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
// GPIO_Init(GPIOE, &GPIO_InitStructure);
// /* GPIOF configuration */
// GPIO_PinAFConfig(GPIOF, GPIO_PinSource0 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOF, GPIO_PinSource1 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOF, GPIO_PinSource2 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOF, GPIO_PinSource3 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOF, GPIO_PinSource4 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOF, GPIO_PinSource5 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOF, GPIO_PinSource12 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOF, GPIO_PinSource13 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOF, GPIO_PinSource14 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOF, GPIO_PinSource15 , GPIO_AF_FSMC);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
// GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 |
// GPIO_Pin_14 | GPIO_Pin_15;
// GPIO_Init(GPIOF, &GPIO_InitStructure);
// /* GPIOG configuration */
// GPIO_PinAFConfig(GPIOG, GPIO_PinSource0 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOG, GPIO_PinSource1 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOG, GPIO_PinSource2 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOG, GPIO_PinSource3 , GPIO_AF_FSMC);
// GPIO_PinAFConfig(GPIOG, GPIO_PinSource4 , GPIO_AF_FSMC);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
// GPIO_Pin_4 ;
// GPIO_Init(GPIOG, &GPIO_InitStructure);
///*-- FSMC Configuration ------------------------------------------------------*/
// p.FSMC_AddressSetupTime = 2;//
// p.FSMC_AddressHoldTime = 4;//
// p.FSMC_DataSetupTime = 60;
// p.FSMC_BusTurnAroundDuration = 1;
// p.FSMC_CLKDivision = 1;
// p.FSMC_DataLatency = 0;
// p.FSMC_AccessMode = FSMC_AccessMode_A;
// FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
// FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
// FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
// FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
// FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
// FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
// FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
// FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
// FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
// FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
// FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
// FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
// FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
// FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
// FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
// FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
// /*!< Enable FSMC Bank1_SRAM2 Bank */
// FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1/*FSMC_Bank1_NORSRAM2*/, ENABLE);
}
/*******************************************************************************
Function:
uint32_t PMPReadDWord (uint16_t Address)
Summary:
This function readS 4 bytes of data from LAN9252 CSR register
Description:
This function readS 4 bytes of data from LAN9252 CSR register( not ESC register).
Refer HBI section of LAN9252 datasheet for more information.
Parameters:
Address - Address of LAN9252 CSR register( not ESC register).
*****************************************************************************/
uint32_t PMPReadDWord (uint16_t Address)
{
UINT32_VAL res;
res.w[0] = *(uint16_t *) (Bank1_SRAM1_ADDR + Address);
res.w[1] = *(uint16_t *) (Bank1_SRAM1_ADDR + Address + 0x02);
return res.Val;
}
/*******************************************************************************
Function:
void PMPWriteDWord (uint16_t Address, uint32_t Val)
Summary:
This function writes 4 bytes of data to the corresponding address of LAN9252 CSR register
Description:
This function writes 4 bytes of data to the corresponding address of LAN9252 CSR register ( not ESC register). Refer HBI section of LAN9252 datasheet for more information.
Parameters:
Address - Address of LAN9252 CSR register( not ESC register).
Val - 4 byte value.
*****************************************************************************/
void PMPWriteDWord (uint16_t Address, uint32_t Val) /****Enter****/
{
UINT32_VAL data;
data.Val=Val;
*(uint16_t *) (Bank1_SRAM1_ADDR + Address) = data.w[0];
*(uint16_t *) (Bank1_SRAM1_ADDR + Address + 0x02) = data.w[1];
}
/*******************************************************************************
Function:
void PMPReadRegUsingCSR(uint8_t *ReadBuffer, uint16_t Address, uint8_t Count)
Summary:
This function reads the EtherCAT core registers using LAN9252 CSR registers.
*****************************************************************************/
void PMPReadRegUsingCSR(uint8_t *ReadBuffer, uint16_t Address, uint8_t Count)
{
UINT32_VAL param32_1 = {0};
uint8_t i = 0;
param32_1.w[0] = Address;
param32_1.v[2] = Count;
param32_1.v[3] = PRAM_RW_BUSY_8B | PRAM_SET_READ;
#ifdef HBI_INDEXED_MODE
PMPWriteDWord (HBI_INDEXED_INDEX0_REG,CSR_CMD_REG);
PMPWriteDWord (HBI_INDEXED_DATA0_REG,param32_1.Val);
#else
PMPWriteDWord (CSR_CMD_REG, param32_1.Val);
#endif
do
{
#ifdef HBI_INDEXED_MODE
param32_1.Val = PMPReadDWord (HBI_INDEXED_DATA0_REG);
#else
param32_1.Val = PMPReadDWord (CSR_CMD_REG);
#endif
}while(param32_1.v[3] & PRAM_RW_BUSY_8B);
#ifdef HBI_INDEXED_MODE
PMPWriteDWord (HBI_INDEXED_INDEX0_REG,CSR_DATA_REG);
param32_1.Val = PMPReadDWord (HBI_INDEXED_DATA0_REG);
#else
param32_1.Val = PMPReadDWord (CSR_DATA_REG);
#endif
for(i=0;i<Count;i++)
ReadBuffer[i] = param32_1.v[i];
return;
}
/*******************************************************************************
Function:
void PMPWriteRegUsingCSR( uint8_t *WriteBuffer, uint16_t Address, uint8_t Count)
Summary:
This function writes the EtherCAT core registers using LAN9252 CSR registers.
*****************************************************************************/
void PMPWriteRegUsingCSR( uint8_t *WriteBuffer, uint16_t Address, uint8_t Count) /****Enter****/
{
UINT32_VAL param32_1 = {0};
uint8_t i = 0;
for(i=0;i<Count;i++)
param32_1.v[i] = WriteBuffer[i];
#ifdef HBI_INDEXED_MODE /****Enter****/
PMPWriteDWord (HBI_INDEXED_INDEX0_REG,CSR_DATA_REG);
PMPWriteDWord (HBI_INDEXED_DATA0_REG,param32_1.Val);
#else
PMPWriteDWord (CSR_DATA_REG, param32_1.Val);
#endif
param32_1.w[0] = Address;
param32_1.v[2] = Count;
param32_1.v[3] = PRAM_RW_BUSY_8B | PRAM_SET_WRITE;
#ifdef HBI_INDEXED_MODE /****Enter****/
PMPWriteDWord (HBI_INDEXED_INDEX0_REG,CSR_CMD_REG);
PMPWriteDWord (HBI_INDEXED_DATA0_REG,param32_1.Val);
#else
PMPWriteDWord (CSR_CMD_REG, param32_1.Val);
#endif
do /****Enter****/
{
#ifdef HBI_INDEXED_MODE /****Enter****/
param32_1.Val = PMPReadDWord (HBI_INDEXED_DATA0_REG);
#else
param32_1.Val = PMPReadDWord (CSR_CMD_REG);
#endif
}while(param32_1.v[3] & PRAM_RW_BUSY_8B);
return;
}
/*******************************************************************************
Function:
void PMPReadPDRamRegister(uint8_t *ReadBuffer, uint16_t Address, uint16_t Count)
Summary:
This function reads the PDRAM using LAN9252 FIFO.
*****************************************************************************/
void PMPReadPDRamRegister(uint8_t *ReadBuffer, uint16_t Address, uint16_t Count)
{
UINT32_VAL param32_1 = {0};
uint8_t i = 0,nlength, nBytePosition;
uint8_t nReadSpaceAvblCount;
// uint16_t RefAddr = Address;
/*Reset/Abort any previous commands.*/
param32_1.Val = PRAM_RW_ABORT_MASK;
/*Set index register 8 for PRAM_READ_CMD_REG.*/
PMPWriteDWord (HBI_INDEXED_INDEX1_REG,PRAM_READ_CMD_REG);
PMPWriteDWord (HBI_INDEXED_DATA1_REG,param32_1.Val);
/*The host should not modify this field unless the PRAM Read Busy
(PRAM_READ_BUSY) bit is a 0.*/
do
{
#ifdef HBI_INDEXED_MODE
param32_1.Val = PMPReadDWord (HBI_INDEXED_DATA1_REG);
#else
param32_1.Val = PMPReadDWord (PRAM_READ_CMD_REG);
#endif
}while((param32_1.v[3] & PRAM_RW_BUSY_8B));
/*Write address and length in the EtherCAT Process RAM Read Address and
* Length Register (ECAT_PRAM_RD_ADDR_LEN)*/
param32_1.w[0] = Address;
param32_1.w[1] = Count;
#ifdef HBI_INDEXED_MODE
/*Set index register 0x10 for PRAM_READ_ADDR_LEN_OFFSET*/
PMPWriteDWord (HBI_INDEXED_INDEX2_REG,PRAM_READ_ADDR_LEN_REG);