基于STM32F407-LAN9252的EtherCAT从站协议移植过程,代码部分

关于从站协议栈移植过程,请参考我前一篇文章,有详细的解析,本章只用于代码细节的补充。

目录

main.h

main.c

gpio.h

gpio.c

spi.h

spi.c

tim.h

tim.c

usart.h

usart.c

lan9252.h

lan9252.c

APPlication.h

Application.c

中断


main.h

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.h
  * @brief          : Header for main.c file.
  *                   This file contains the common defines of the application.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */

/* USER CODE END ET */

/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */

/* USER CODE END EC */

/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */

/* USER CODE END EM */

/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);

/* USER CODE BEGIN EFP */

/* USER CODE END EFP */

/* Private defines -----------------------------------------------------------*/
#define SPI1_CS_Pin GPIO_PIN_4
#define SPI1_CS_GPIO_Port GPIOA
#define SPI1_SCK_Pin GPIO_PIN_5
#define SPI1_SCK_GPIO_Port GPIOA
#define SPI1_MISO_Pin GPIO_PIN_6
#define SPI1_MISO_GPIO_Port GPIOA
#define SPI1_MOSI_Pin GPIO_PIN_7
#define SPI1_MOSI_GPIO_Port GPIOA
#define LAN9253_ESC_Pin GPIO_PIN_8
#define LAN9253_ESC_GPIO_Port GPIOE
#define LAN9253_ESC_EXTI_IRQn EXTI9_5_IRQn
#define LAN9253_SCY0_Pin GPIO_PIN_9
#define LAN9253_SCY0_GPIO_Port GPIOE
#define LAN9253_SCY0_EXTI_IRQn EXTI9_5_IRQn
#define LAN9253_SCY1_Pin GPIO_PIN_10
#define LAN9253_SCY1_GPIO_Port GPIOE
#define LAN9253_SCY1_EXTI_IRQn EXTI15_10_IRQn
#define LED0_Pin GPIO_PIN_8
#define LED0_GPIO_Port GPIOD
#define LED1_Pin GPIO_PIN_9
#define LED1_GPIO_Port GPIOD
#define LED2_Pin GPIO_PIN_10
#define LED2_GPIO_Port GPIOD
#define LED3_Pin GPIO_PIN_11
#define LED3_GPIO_Port GPIOD
#define LED4_Pin GPIO_PIN_12
#define LED4_GPIO_Port GPIOD
#define LED5_Pin GPIO_PIN_13
#define LED5_GPIO_Port GPIOD
#define LED6_Pin GPIO_PIN_14
#define LED6_GPIO_Port GPIOD
#define LED7_Pin GPIO_PIN_15
#define LED7_GPIO_Port GPIOD
#define KEY0_Pin GPIO_PIN_0
#define KEY0_GPIO_Port GPIOD
#define KEY1_Pin GPIO_PIN_1
#define KEY1_GPIO_Port GPIOD
#define KEY2_Pin GPIO_PIN_2
#define KEY2_GPIO_Port GPIOD
#define KEY3_Pin GPIO_PIN_3
#define KEY3_GPIO_Port GPIOD
#define KEY4_Pin GPIO_PIN_4
#define KEY4_GPIO_Port GPIOD
#define KEY5_Pin GPIO_PIN_5
#define KEY5_GPIO_Port GPIOD
#define KEY6_Pin GPIO_PIN_6
#define KEY6_GPIO_Port GPIOD
#define KEY7_Pin GPIO_PIN_7
#define KEY7_GPIO_Port GPIOD
/* USER CODE BEGIN Private defines */

/* USER CODE END Private defines */

#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

main.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "applInterface.h"
#include "RT2000.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
//  MX_SPI1_Init();//放至HW_Init()
//  TIM7_Init();//放至HW_Init()
//  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	
  HW_Init();
  MainInit();
	APPL_GenerateMapping(&nPdInputSize,&nPdOutputSize);
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

        MainLoop();
		
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 168;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

gpio.h

/**
  ******************************************************************************
  * @file    gpio.h
  * @brief   This file contains all the function prototypes for
  *          the gpio.c file
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __GPIO_H__
#define __GPIO_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* USER CODE BEGIN Private defines */

/* USER CODE END Private defines */

void MX_GPIO_Init(void);

/* USER CODE BEGIN Prototypes */
void Init_ESC(void);	
void Init_SYNC0(void);
void Init_SYNC1(void);
void Disable_all_int(void );
void Enable_all_int(void);
/* USER CODE END Prototypes */

#ifdef __cplusplus
}
#endif
#endif /*__ GPIO_H__ */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

gpio.c

/**
  ******************************************************************************
  * @file    gpio.c
  * @brief   This file provides code for the configuration
  *          of all used GPIO pins.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "gpio.h"
/* USER CODE BEGIN 0 */
#include "ecatappl.h"
#include "lan9252.h"

/* USER CODE END 0 */

/*----------------------------------------------------------------------------*/
/* Configure GPIO                                                             */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/** Configure pins as
        * Analog
        * Input
        * Output
        * EVENT_OUT
        * EXTI
*/
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, LED0_Pin|LED1_Pin|LED2_Pin|LED3_Pin
                          |LED4_Pin|LED5_Pin|LED6_Pin|LED7_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin = SPI1_CS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(SPI1_CS_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : PEPin PEPin PEPin */
//  GPIO_InitStruct.Pin = LAN9253_ESC_Pin|LAN9253_SCY0_Pin|LAN9253_SCY1_Pin;
//  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
//  GPIO_InitStruct.Pull = GPIO_NOPULL;
//  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /*Configure GPIO pins : PDPin PDPin PDPin PDPin
                           PDPin PDPin PDPin PDPin */
  GPIO_InitStruct.Pin = LED0_Pin|LED1_Pin|LED2_Pin|LED3_Pin
                          |LED4_Pin|LED5_Pin|LED6_Pin|LED7_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /*Configure GPIO pins : PDPin PDPin PDPin PDPin
                           PDPin PDPin PDPin PDPin */
  GPIO_InitStruct.Pin = KEY0_Pin|KEY1_Pin|KEY2_Pin|KEY3_Pin
                          |KEY4_Pin|KEY5_Pin|KEY6_Pin|KEY7_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /* EXTI interrupt init*/
//  HAL_NVIC_SetPriority(EXTI9_5_IRQn, 1, 1);
//  HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

//  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 1, 2);
//  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

}

/* USER CODE BEGIN 2 */

void Init_ESC(void)	
{
    GPIO_InitTypeDef GPIO_InitStruct;
	
	  __HAL_RCC_GPIOE_CLK_ENABLE();
	
	  GPIO_InitStruct.Pin = GPIO_PIN_8;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT|GPIO_MODE_IT_FALLING; 
  	GPIO_InitStruct.Pull = GPIO_NOPULL;    
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
	
    HAL_NVIC_SetPriority(EXTI9_5_IRQn,1, 1);
    HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
}


void Init_SYNC0(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

		__HAL_RCC_GPIOE_CLK_ENABLE();
	
		GPIO_InitStruct.Pin = GPIO_PIN_9;
	  GPIO_InitStruct.Mode = GPIO_MODE_INPUT|GPIO_MODE_IT_FALLING;
		GPIO_InitStruct.Pull = GPIO_NOPULL; 
		HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
	
    HAL_NVIC_SetPriority(EXTI9_5_IRQn,1, 1);
    HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);

}


void Init_SYNC1(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

		__HAL_RCC_GPIOE_CLK_ENABLE();
	
		GPIO_InitStruct.Pin = GPIO_PIN_10;
	  GPIO_InitStruct.Mode = GPIO_MODE_INPUT|GPIO_MODE_IT_FALLING;
		GPIO_InitStruct.Pull = GPIO_NOPULL;      
		HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
	
    HAL_NVIC_SetPriority(EXTI15_10_IRQn,1, 2);
    HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
}



void EXTI9_5_IRQHandler(void)
{

  if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_8) != RESET)
  {
	  HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
		PDI_Isr();
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_8);
    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
		
#if defined (INTERRUPTS_SUPPORTED) && defined(DC_SUPPORTED)
		if(IS_SYNC0_INT_ACTIVE)
    {
        Sync0_Isr();
        /* reset the interrupt flag */
        ACK_SYNC0_INT;
    }
#endif
		
#if defined (INTERRUPTS_SUPPORTED) && defined(DC_SUPPORTED)
		if(IS_SYNC1_INT_ACTIVE)
    {
        Sync1_Isr();
        /* reset the interrupt flag */
        ACK_SYNC1_INT;
    }
#endif
  }
	
	 if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_9) != RESET)
  {
	  HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
		Sync0_Isr();
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_9);
    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
		
#ifdef INTERRUPTS_SUPPORTED
    if(IS_ESC_INT_ACTIVE)
    {
        DISABLE_ESC_INT();
        PDI_Isr();
        /* reset the interrupt flag */
        ACK_ESC_INT;
    }
#endif
		
#if defined(INTERRUPTS_SUPPORTED) && defined(DC_SUPPORTED)
if(IS_SYNC1_INT_ACTIVE)
    {
        Sync1_Isr();
       /* reset the interrupt flag */
       ACK_SYNC1_INT;
    }
#endif	
  }	
} 


void EXTI15_10_IRQHandler(void)
{
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_10) != RESET)
  {
	  HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
		Sync1_Isr();
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_10);
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
		
#ifdef INTERRUPTS_SUPPORTED
    if(IS_ESC_INT_ACTIVE)
    {
        DISABLE_ESC_INT();
        PDI_Isr();
        /* reset the interrupt flag */
        ACK_ESC_INT;
    }
#endif
		
#if defined(INTERRUPTS_SUPPORTED) && defined(DC_SUPPORTED)
if(IS_SYNC0_INT_ACTIVE)
    {
        Sync0_Isr();
       /* reset the interrupt flag */
       ACK_SYNC0_INT;
    }
#endif	
  }	
}

void Disable_all_int(void )
{
	HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
	
	HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
	HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
	
	HAL_NVIC_DisableIRQ(TIM7_IRQn);

}


void Enable_all_int(void)
{
	HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
	
	HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
	HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
	
	HAL_NVIC_EnableIRQ(TIM7_IRQn);
}



/* USER CODE END 2 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

spi.h

/**
  ******************************************************************************
  * @file    spi.h
  * @brief   This file contains all the function prototypes for
  *          the spi.c file
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPI_H__
#define __SPI_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "ecat_def.h"
#include "lan9252.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

extern SPI_HandleTypeDef hspi1;

/* USER CODE BEGIN Private defines */

#define CSLOW()      HAL_GPIO_WritePin(SPI1_CS_GPIO_Port,SPI1_CS_Pin,GPIO_PIN_RESET)
#define CSHIGH()     HAL_GPIO_WritePin(SPI1_CS_GPIO_Port,SPI1_CS_Pin,GPIO_PIN_SET)

#define CMD_SERIAL_READ 0x03
#define CMD_FAST_READ 0x0B
#define CMD_DUAL_OP_READ 0x3B
#define CMD_DUAL_IO_READ 0xBB
#define CMD_QUAD_OP_READ 0x6B
#define CMD_QUAD_IO_READ 0xEB
#define CMD_SERIAL_WRITE 0x02
#define CMD_DUAL_DATA_WRITE 0x32
#define CMD_DUAL_ADDR_DATA_WRITE 0xB2
#define CMD_QUAD_DATA_WRITE 0x62
#define CMD_QUAD_ADDR_DARA_WRITE 0xE2

#define CMD_SERIAL_READ_DUMMY 0
#define CMD_FAST_READ_DUMMY 1
#define CMD_DUAL_OP_READ_DUMMY 1
#define CMD_DUAL_IO_READ_DUMMY 2
#define CMD_QUAD_OP_READ_DUMMY 1
#define CMD_QUAD_IO_READ_DUMMY 4
#define CMD_SERIAL_WRITE_DUMMY 0
#define CMD_DUAL_DATA_WRITE_DUMMY 0
#define CMD_DUAL_ADDR_DATA_WRITE_DUMMY 0
#define CMD_QUAD_DATA_WRITE_DUMMY 0
#define CMD_QUAD_ADDR_DARA_WRITE_DUMMY 0

#define ESC_CSR_CMD_REG		0x304
#define ESC_CSR_DATA_REG	0x300
#define ESC_WRITE_BYTE 		0x80
#define ESC_READ_BYTE 		0xC0
#define ESC_CSR_BUSY		0x80

			#define SYS_FREQ_MHZ     80

#define SPI_CLK_DIV(MHz) ((SYS_FREQ_MHZ/(2*MHz))-1)

#define SPI_MODE0 0
#define SPI_MODE1 1
#define SPI_MODE2 2
#define SPI_MODE3 3

#define SPIWriteByte(UINT8) SPIWrite(UINT8)
#define SPIReadByte() SPIRead()


typedef union 
{
		UINT8           byte[2];
		UINT16          Val;
}UINT16_VAL;

typedef union 
{
		UINT8           byte[4];
		UINT16					w[2];
		UINT32          Val;
}UINT32_VAL;


/* USER CODE END Private defines */

void MX_SPI1_Init(void);

/* USER CODE BEGIN Prototypes */

void SPIWrite(uint8_t data);
uint8_t SPIRead(void);
void SPIWritePDRamRegister(UINT8 *WriteBuffer, UINT16 Address, UINT16 Count);
void SPIReadPDRamRegister(UINT8 *ReadBuffer, UINT16 Address, UINT16 Count);
void SPIWriteRegister( UINT8 *WriteBuffer, UINT16 Address, UINT16 Count);
void SPIReadDRegister(UINT8 *ReadBuffer, UINT16 Address, UINT16 Count);
void SPIReadRegUsingCSR(UINT8 *ReadBuffer, UINT16 Address, UINT8 Count);
void SPIWriteRegUsingCSR( UINT8 *WriteBuffer, UINT16 Address, UINT8 Count);
void SPIWriteDWord (UINT16 Address, UINT32 Val);
UINT32 SPIReadDWord (UINT16 Address);


void SPIWriteBurstMode (UINT32 Val);
UINT32 SPIReadBurstMode (void);
void SPISendAddr (UINT16 Address);
/* USER CODE END Prototypes */

#ifdef __cplusplus
}
#endif

#endif /* __SPI_H__ */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

spi.c

/**
  ******************************************************************************
  * @file    spi.c
  * @brief   This file provides code for the configuration
  *          of the SPI instances.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "spi.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

SPI_HandleTypeDef hspi1;

/* SPI1 init function */
void MX_SPI1_Init(void)
{

  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }

}

void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(spiHandle->Instance==SPI1)
  {
  /* USER CODE BEGIN SPI1_MspInit 0 */

  /* USER CODE END SPI1_MspInit 0 */
    /* SPI1 clock enable */
    __HAL_RCC_SPI1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**SPI1 GPIO Configuration
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI
    */
    GPIO_InitStruct.Pin = SPI1_SCK_Pin|SPI1_MISO_Pin|SPI1_MOSI_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USER CODE BEGIN SPI1_MspInit 1 */

  /* USER CODE END SPI1_MspInit 1 */
  }
}

void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{

  if(spiHandle->Instance==SPI1)
  {
  /* USER CODE BEGIN SPI1_MspDeInit 0 */

  /* USER CODE END SPI1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_SPI1_CLK_DISABLE();

    /**SPI1 GPIO Configuration
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI
    */
    HAL_GPIO_DeInit(GPIOA, SPI1_SCK_Pin|SPI1_MISO_Pin|SPI1_MOSI_Pin);

  /* USER CODE BEGIN SPI1_MspDeInit 1 */

  /* USER CODE END SPI1_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */
void SPIWrite(uint8_t data){
	HAL_SPI_Transmit(&hspi1,&data,1,2000);
	
}

uint8_t SPIRead(void){
	uint8_t data;
	HAL_SPI_Receive(&hspi1,&data,1,2000);
	return  data;
}


UINT32 SPIReadDWord (UINT16 Address)
{
    UINT32_VAL dwResult;
    UINT16_VAL wAddr;

    wAddr.Val  = Address;
    //Assert CS line
    CSLOW();
    //Write Command
    SPIWriteByte(CMD_FAST_READ);
    //Write Address
    SPIWriteByte(wAddr.byte[1]);
    SPIWriteByte(wAddr.byte[0]);
    
    //Dummy Byte
    SPIWriteByte(CMD_FAST_READ_DUMMY);
    SPIWriteByte(0x00);
    //Read Bytes
    dwResult.byte[0] = SPIReadByte();
    dwResult.byte[1] = SPIReadByte();
    dwResult.byte[2] = SPIReadByte();
    dwResult.byte[3] = SPIReadByte();
    //De-Assert CS line
    CSHIGH();
   
    return dwResult.Val;
}
void SPISendAddr (UINT16 Address)
{
    UINT16_VAL wAddr;

    wAddr.Val  = Address;
    //Write Address
    SPIWriteByte(wAddr.byte[1]);
    SPIWriteByte(wAddr.byte[0]);
}                         
UINT32 SPIReadBurstMode (void)
{
    UINT32_VAL dwResult;
    //Read Bytes
    dwResult.byte[0] = SPIReadByte();
    dwResult.byte[1] = SPIReadByte();
    dwResult.byte[2] = SPIReadByte();
    dwResult.byte[3] = SPIReadByte();
    
    return dwResult.Val;
}
void SPIWriteBurstMode (UINT32 Val)
{
    UINT32_VAL dwData;
    dwData.Val = Val;
    
    //Write Bytes
    SPIWriteByte(dwData.byte[0]);
    SPIWriteByte(dwData.byte[1]);
    SPIWriteByte(dwData.byte[2]);
    SPIWriteByte(dwData.byte[3]);
}

void SPIWriteDWord (UINT16 Address, UINT32 Val)
{
    UINT32_VAL dwData;
    UINT16_VAL wAddr;

    wAddr.Val  = Address;
    dwData.Val = Val;
    //Assert CS line
    CSLOW();
    //Write Command
    SPIWriteByte(CMD_SERIAL_WRITE);
    //Write Address
    SPIWriteByte(wAddr.byte[1]);
    SPIWriteByte(wAddr.byte[0]);
    //Write Bytes
    SPIWriteByte(dwData.byte[0]);
    SPIWriteByte(dwData.byte[1]);
    SPIWriteByte(dwData.byte[2]);
    SPIWriteByte(dwData.byte[3]);

    //De-Assert CS line
    CSHIGH();
}
void SPIReadRegUsingCSR(UINT8 *ReadBuffer, UINT16 Address, UINT8 Count)
{
    UINT32_VAL param32_1 = {0};
    UINT8 i = 0;
    UINT16_VAL wAddr;
    wAddr.Val = Address;

    param32_1.byte[0] = wAddr.byte[0];
    param32_1.byte[1] = wAddr.byte[1];
    param32_1.byte[2] = Count;
    param32_1.byte[3] = ESC_READ_BYTE;

    SPIWriteDWord (ESC_CSR_CMD_REG, param32_1.Val);

    do
    {
        param32_1.Val = SPIReadDWord (ESC_CSR_CMD_REG);
		
    }while(param32_1.byte[3] & ESC_CSR_BUSY);

    param32_1.Val = SPIReadDWord (ESC_CSR_DATA_REG);

    
    for(i=0;i<Count;i++)
         ReadBuffer[i] = param32_1.byte[i];
   
    return;
}
void SPIWriteRegUsingCSR( UINT8 *WriteBuffer, UINT16 Address, UINT8 Count)
{
    UINT32_VAL param32_1 = {0};
    UINT8 i = 0;
    UINT16_VAL wAddr;

    for(i=0;i<Count;i++)
         param32_1.byte[i] = WriteBuffer[i];

    SPIWriteDWord (ESC_CSR_DATA_REG, param32_1.Val);


    wAddr.Val = Address;

    param32_1.byte[0] = wAddr.byte[0];
    param32_1.byte[1] = wAddr.byte[1];
    param32_1.byte[2] = Count;
    param32_1.byte[3] = ESC_WRITE_BYTE;

    SPIWriteDWord (0x304, param32_1.Val);
    do
    {
        param32_1.Val = SPIReadDWord (0x304);

    }while(param32_1.byte[3] & ESC_CSR_BUSY);

    return;
}

void SPIReadPDRamRegister(UINT8 *ReadBuffer, UINT16 Address, UINT16 Count)
{
    UINT32_VAL param32_1 = {0};
    UINT8 i = 0,nlength, nBytePosition;
    UINT8 nReadSpaceAvblCount;
//    UINT16 RefAddr = Address;


    /*Reset/Abort any previous commands.*/
    param32_1.Val = PRAM_RW_ABORT_MASK;                                                 

    SPIWriteDWord (PRAM_READ_CMD_REG, param32_1.Val);

    /*The host should not modify this field unless the PRAM Read Busy
    (PRAM_READ_BUSY) bit is a 0.*/
    do
    {
        param32_1.Val = SPIReadDWord (PRAM_READ_CMD_REG);

    }while((param32_1.byte[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;

    SPIWriteDWord (PRAM_READ_ADDR_LEN_REG, param32_1.Val);


    /*Set PRAM Read Busy (PRAM_READ_BUSY) bit(-EtherCAT Process RAM Read Command Register)
     *  to start read operatrion*/

    param32_1.Val = PRAM_RW_BUSY_32B; /*TODO:replace with #defines*/

    SPIWriteDWord (PRAM_READ_CMD_REG, param32_1.Val);

    /*Read PRAM Read Data Available (PRAM_READ_AVAIL) bit is set*/
    do
    {
        param32_1.Val = SPIReadDWord (PRAM_READ_CMD_REG);

    }while(!(param32_1.byte[0] & IS_PRAM_SPACE_AVBL_MASK));

    nReadSpaceAvblCount = param32_1.byte[1] & PRAM_SPACE_AVBL_COUNT_MASK;

    /*Fifo registers are aliased address. In indexed it will read indexed data reg 0x04, but it will point to reg 0
     In other modes read 0x04 FIFO register since all registers are aliased*/

    /*get the UINT8 lenth for first read*/
    //Auto increment is supported in SPIO
    param32_1.Val = SPIReadDWord (PRAM_READ_FIFO_REG);
    nReadSpaceAvblCount--;
    nBytePosition = (Address & 0x03);
    nlength = (4-nBytePosition) > Count ? Count:(4-nBytePosition);
    memcpy(ReadBuffer+i ,&param32_1.byte[nBytePosition],nlength);
    Count-=nlength;
    i+=nlength;

    //Lets do it in auto increment mode
    CSLOW();

    //Write Command
    SPIWriteByte(CMD_FAST_READ);

    SPISendAddr(PRAM_READ_FIFO_REG);
    
    //Dummy Byte
    SPIWriteByte(CMD_FAST_READ_DUMMY);

    while(Count)
    {
        param32_1.Val = SPIReadBurstMode ();

        nlength = Count > 4 ? 4: Count;
        memcpy((ReadBuffer+i) ,&param32_1,nlength);

        i+=nlength;
        Count-=nlength;
        nReadSpaceAvblCount --;
    }

    CSHIGH();

    return;
}

void SPIWritePDRamRegister(UINT8 *WriteBuffer, UINT16 Address, UINT16 Count)
{
    UINT32_VAL param32_1 = {0};
    UINT8 i = 0,nlength, nBytePosition,nWrtSpcAvlCount;

    /*Reset or Abort any previous commands.*/
    param32_1.Val = PRAM_RW_ABORT_MASK;                                                

    SPIWriteDWord (PRAM_WRITE_CMD_REG, param32_1.Val);

    /*Make sure there is no previous write is pending
    (PRAM Write Busy) bit is a 0 */
    do
    {
        param32_1.Val = SPIReadDWord (PRAM_WRITE_CMD_REG);

    }while((param32_1.byte[3] & PRAM_RW_BUSY_8B));

    /*Write Address and Length Register (ECAT_PRAM_WR_ADDR_LEN) with the
    starting UINT8 address and length)*/
    param32_1.w[0] = Address;
    param32_1.w[1] = Count;

    SPIWriteDWord (PRAM_WRITE_ADDR_LEN_REG, param32_1.Val);

    /*write to the EtherCAT Process RAM Write Command Register (ECAT_PRAM_WR_CMD) with the  PRAM Write Busy
    (PRAM_WRITE_BUSY) bit set*/

    param32_1.Val = PRAM_RW_BUSY_32B; /*TODO:replace with #defines*/

    SPIWriteDWord (PRAM_WRITE_CMD_REG, param32_1.Val);

    /*Read PRAM write Data Available (PRAM_READ_AVAIL) bit is set*/
    do
    {
       param32_1.Val = SPIReadDWord (PRAM_WRITE_CMD_REG);

    }while(!(param32_1.byte[0] & IS_PRAM_SPACE_AVBL_MASK));

    /*Check write data available count*/
    nWrtSpcAvlCount = param32_1.byte[1] & PRAM_SPACE_AVBL_COUNT_MASK;

    /*Write data to Write FIFO) */ 
    /*get the byte lenth for first read*/
    nBytePosition = (Address & 0x03);

    nlength = (4-nBytePosition) > Count ? Count:(4-nBytePosition);

    param32_1.Val = 0;
    memcpy(&param32_1.byte[nBytePosition],WriteBuffer+i, nlength);

    SPIWriteDWord (PRAM_WRITE_FIFO_REG,param32_1.Val);

    nWrtSpcAvlCount--;
    Count-=nlength;
    i+=nlength;

    //Auto increment mode
    CSLOW();

    //Write Command
    SPIWriteByte(CMD_SERIAL_WRITE);

    SPISendAddr(PRAM_WRITE_FIFO_REG);

    while(Count)
    {
        nlength = Count > 4 ? 4: Count;
        param32_1.Val = 0;
        memcpy(&param32_1, (WriteBuffer+i), nlength);

        SPIWriteBurstMode (param32_1.Val);
        i+=nlength;
        Count-=nlength;
        nWrtSpcAvlCount--;
    }

    CSHIGH();
    return;
}
void SPIReadDRegister(UINT8 *ReadBuffer, UINT16 Address, UINT16 Count)
{
    if (Address >= 0x1000)
    {
         SPIReadPDRamRegister(ReadBuffer, Address,Count);
    }
    else
    {
         SPIReadRegUsingCSR(ReadBuffer, Address,Count);
    }
}
void SPIWriteRegister( UINT8 *WriteBuffer, UINT16 Address, UINT16 Count)
{
   
   if (Address >= 0x1000)
   {
		SPIWritePDRamRegister(WriteBuffer, Address,Count);
   }
   else
   {
		SPIWriteRegUsingCSR(WriteBuffer, Address,Count);
   }
    
}


/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

tim.h

#ifndef __TIMERSET__H
#define __TIMERSET__H

#include  "stm32f4xx_hal.h"
#include  "ecatappl.h"

extern TIM_HandleTypeDef  TimHandle;

void TIM7_Init(void);
void TIM7_Start(void);
void TIM7_Stop(void);

#endif

tim.c


#include "tim.h"
#include "stm32f4xx_hal_tim.h"

TIM_HandleTypeDef  TimHandle;

void TIM7_Init(void)
{
  uint32_t uwPrescalerValue = 0;

  TimHandle.Instance = TIM7;

  TimHandle.Init.Period            = 1000;
  TimHandle.Init.Prescaler         = 42-1;
  TimHandle.Init.ClockDivision     = 0;
  TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP | TIM_CR1_ARPE; //递增计数 ,自动重载
	TimHandle.Init.RepetitionCounter = 0;
  HAL_TIM_Base_Init(&TimHandle);                                      
	
  HAL_NVIC_SetPriority(TIM7_IRQn, 6, 1);
	HAL_NVIC_EnableIRQ(TIM7_IRQn);

  HAL_TIM_Base_Start_IT(&TimHandle);                                     //开始计时
}

void TIM7_Start(void)
{
	  HAL_TIM_Base_Start_IT(&TimHandle);
}

void TIM7_Stop(void)
{
	  HAL_TIM_Base_Stop_IT(&TimHandle);
}

usart.h

/**
  ******************************************************************************
  * @file    usart.h
  * @brief   This file contains all the function prototypes for
  *          the usart.c file
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_H__
#define __USART_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

extern UART_HandleTypeDef huart1;

/* USER CODE BEGIN Private defines */

/* USER CODE END Private defines */

void MX_USART1_UART_Init(void);

/* USER CODE BEGIN Prototypes */

/* USER CODE END Prototypes */

#ifdef __cplusplus
}
#endif

#endif /* __USART_H__ */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

usart.c

/**
  ******************************************************************************
  * @file    usart.c
  * @brief   This file provides code for the configuration
  *          of the USART instances.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "usart.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

UART_HandleTypeDef huart1;

/* USART1 init function */

void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }

}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */

  /* USER CODE END USART1_MspInit 0 */
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspInit 1 */

  /* USER CODE END USART1_MspInit 1 */
  }
}

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{

  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspDeInit 0 */

  /* USER CODE END USART1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART1_CLK_DISABLE();

    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);

    /* USART1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspDeInit 1 */

  /* USER CODE END USART1_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

lan9252.h

/*******************************************************************************
 LAN9252 - Hardware Abtraction Layer header file.

  Company:
    Microchip Technology Inc.

  File Name:
    9252_HW.h

  Description:
    This file contains the defines, function protypes for LAN9252 Hardware Abtraction Layer

  Change History:
    Version		Changes
	0.1			Initial version.
	0.2			-
	0.3			-
	0.4			-
	1.0			-
*******************************************************************************/

/*******************************************************************************
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.
 *******************************************************************************/

#ifndef _9252_HW_H_
#define _9252_HW_H_

///
// Includes

#include  "esc.h"

#include "stm32f4xx_hal.h"
#include "tim.h"

///
// Defines, types

#define ESC_RD                    0x02 /**< \brief Indicates a read access to ESC or EEPROM*/
#define ESC_WR                    0x04 /**< \brief Indicates a write access to ESC or EEPROM.*/


// Microcontroller definitions


#define PORT_CFG            //{TRISD = 0xFFFF; TRISB = 0x0008; TRISF = 0xFFCC; TRISG = 0x210C; PORTB = 0x00F4; PORTF = 0x0030; PORTG = 0x1243;}
#define SWITCH_1            //PORTDbits.RD7 /**< \brief Access to switch 1 input*/
#define SWITCH_2            //PORTDbits.RD6 /**< \brief Access to switch 2 input*/
#define SWITCH_3            //PORTDbits.RD5 /**< \brief Access to switch 3 input*/
#define SWITCH_4            //PORTDbits.RD4 /**< \brief Access to switch 4 input*/
#define SWITCH_5            //PORTDbits.RD3 /**< \brief Access to switch 5 input*/
#define SWITCH_6            //PORTDbits.RD2 /**< \brief Access to switch 6 input*/
#define SWITCH_7            //PORTDbits.RD1 /**< \brief Access to switch 7 input*/
#define SWITCH_8            //PORTDbits.RD0 /**< \brief Access to switch 8 input*/

#define LED_1               //LATBbits.LATB8 /**< \brief Access to led 1 output*/
#define LED_2               //LATBbits.LATB9 /**< \brief Access to led 2 output*/
#define LED_3               //LATBbits.LATB10 /**< \brief Access to led 3 output*/
#define LED_4               //LATBbits.LATB11 /**< \brief Access to led 4 output*/
#define LED_5               //LATBbits.LATB12 /**< \brief Access to led 5 output*/
#define LED_6               //LATBbits.LATB13 /**< \brief Access to led 6 output*/
#define LED_7               //LATBbits.LATB14 /**< \brief Access to led 7 output*/
#define LED_8              // LATBbits.LATB15 /**< \brief Access to led 8 output*/

///
//9252 HW DEFINES
#define ECAT_REG_BASE_ADDR              0x0300

#define CSR_DATA_REG_OFFSET             0x00
#define CSR_CMD_REG_OFFSET              0x04
#define PRAM_READ_ADDR_LEN_OFFSET       0x08
#define PRAM_READ_CMD_OFFSET            0x0c
#define PRAM_WRITE_ADDR_LEN_OFFSET      0x10
#define PRAM_WRITE_CMD_OFFSET           0x14

#define PRAM_SPACE_AVBL_COUNT_MASK      0x1f
#define IS_PRAM_SPACE_AVBL_MASK         0x01


#define CSR_DATA_REG                    ECAT_REG_BASE_ADDR+CSR_DATA_REG_OFFSET
#define CSR_CMD_REG                     ECAT_REG_BASE_ADDR+CSR_CMD_REG_OFFSET
#define PRAM_READ_ADDR_LEN_REG          ECAT_REG_BASE_ADDR+PRAM_READ_ADDR_LEN_OFFSET
#define PRAM_READ_CMD_REG               ECAT_REG_BASE_ADDR+PRAM_READ_CMD_OFFSET
#define PRAM_WRITE_ADDR_LEN_REG         ECAT_REG_BASE_ADDR+PRAM_WRITE_ADDR_LEN_OFFSET
#define PRAM_WRITE_CMD_REG              ECAT_REG_BASE_ADDR+PRAM_WRITE_CMD_OFFSET

#define PRAM_READ_FIFO_REG              0x04
#define PRAM_WRITE_FIFO_REG             0x20

#define HBI_INDEXED_DATA0_REG           0x04
#define HBI_INDEXED_DATA1_REG           0x0c
#define HBI_INDEXED_DATA2_REG           0x14

#define HBI_INDEXED_INDEX0_REG          0x00
#define HBI_INDEXED_INDEX1_REG          0x08
#define HBI_INDEXED_INDEX2_REG          0x10

#define HBI_INDEXED_PRAM_READ_WRITE_FIFO    0x18

#define PRAM_RW_ABORT_MASK      (1UL << 30)
#define PRAM_RW_BUSY_32B        (1UL << 31)
#define PRAM_RW_BUSY_8B         (1 << 7)
#define PRAM_SET_READ           (1 << 6)
#define PRAM_SET_WRITE          0

/********************************************** 总中断 **************************************************************/
#define DISABLE_GLOBAL_INT          __disable_irq()//HAL_NVIC_DisableIRQ(EXTI9_5_IRQn)
#define ENABLE_GLOBAL_INT           __enable_irq()//HAL_NVIC_EnableIRQ(EXTI9_5_IRQn)
#define DISABLE_AL_EVENT_INT        DISABLE_GLOBAL_INT
#define ENABLE_AL_EVENT_INT         ENABLE_GLOBAL_INT
/********************************************** ESC主中断 **************************************************************/

#define    INIT_ESC_INT           	Init_ESC()
#define    ACK_ESC_INT            	__HAL_GPIO_EXTI_CLEAR_IT(LAN9253_ESC_Pin)
#define    IS_ESC_INT_ACTIVE     		HAL_GPIO_ReadPin(LAN9253_ESC_GPIO_Port, LAN9253_ESC_Pin)==RESET

/********************************************** ESC-DC中断 **************************************************************/
#ifndef RUN_FROM_SVB_FPGA

    #define    INIT_SYNC0_INT                Init_SYNC0()
    #define    DISABLE_SYNC0_INT             HAL_NVIC_DisableIRQ(EXTI9_5_IRQn)
    #define    ENABLE_SYNC0_INT              HAL_NVIC_EnableIRQ(EXTI9_5_IRQn)
    #define    ACK_SYNC0_INT                 __HAL_GPIO_EXTI_CLEAR_IT(LAN9253_SCY0_Pin)
    #define    IS_SYNC0_INT_ACTIVE           HAL_GPIO_ReadPin(LAN9253_SCY0_GPIO_Port, LAN9253_SCY0_Pin)==RESET
		
    #define    INIT_SYNC1_INT               Init_SYNC1()
    #define    DISABLE_SYNC1_INT            HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
    #define    ENABLE_SYNC1_INT             HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
    #define    ACK_SYNC1_INT                __HAL_GPIO_EXTI_CLEAR_IT(LAN9253_SCY1_Pin)
    #define    IS_SYNC1_INT_ACTIVE          HAL_GPIO_ReadPin(LAN9253_SCY1_GPIO_Port, LAN9253_SCY1_Pin)==RESET
#else
#endif

/********************************************** ESC定时器 **************************************************************/
#define STOP_ECAT_TIMER         						TIM7_Stop();
#define INIT_ECAT_TIMER         						TIM7_Init();
#define START_ECAT_TIMER        						TIM7_Start(); 

#define ECAT_TIMER_INC_P_MS              		1000 /**< \brief 312 ticks per ms*/

#ifndef DISABLE_ESC_INT
    #define    DISABLE_ESC_INT()           HAL_NVIC_DisableIRQ(EXTI9_5_IRQn) /**< \brief Disable interrupt source INT1*/
#endif
#ifndef ENABLE_ESC_INT
    #define    ENABLE_ESC_INT()            HAL_NVIC_EnableIRQ(EXTI9_5_IRQn) /**< \brief Enable interrupt source INT1*/
#endif
extern TIM_HandleTypeDef  TimHandle;


#ifndef HW_GetTimer
    #define HW_GetTimer()                  __HAL_TIM_GET_COUNTER(&TimHandle) /**< \brief Access to the hardware timer*/
#endif

#ifndef HW_ClearTimer
    #define HW_ClearTimer()                __HAL_TIM_GET_COUNTER(&TimHandle) /**< \brief Clear the hardware timer*/
#endif


void HW_EscRead( MEM_ADDR *pData, UINT16 Address, UINT16 Len );

#define HW_EscReadWord(WordValue, Address)       HW_EscRead(((MEM_ADDR *)&(WordValue)),((UINT16)(Address)),2) /**< \brief 16Bit ESC read access*/
#define HW_EscReadDWord(DWordValue, Address)     HW_EscRead(((MEM_ADDR *)&(DWordValue)),((UINT16)(Address)),4) /**< \brief 32Bit ESC read access*/
#define HW_EscReadByte(ByteValue, Address)       HW_EscRead(((MEM_ADDR *)&(ByteValue)),((UINT16)(Address)),1) /**< \brief 8Bit ESC read access*/
#define HW_EscReadMbxMem(pData,Address,Len)      HW_EscRead(((MEM_ADDR *)(pData)),((UINT16)(Address)),(Len)) /**< \brief The mailbox data is stored in the local uC memory therefore the default read function is used.*/

#define HW_EscReadWordIsr(WordValue, Address)    HW_EscReadIsr(((MEM_ADDR *)&(WordValue)),((UINT16)(Address)),2) /**< \brief Interrupt specific 16Bit ESC read access*/
#define HW_EscReadDWordIsr(DWordValue, Address)  HW_EscReadIsr(((MEM_ADDR *)&(DWordValue)),((UINT16)(Address)),4) /**< \brief Interrupt specific 32Bit ESC read access*/
#define HW_EscReadByteIsr(ByteValue, Address)    HW_EscReadIsr(((MEM_ADDR *)&(ByteValue)),((UINT16)(Address)),1) /**< \brief Interrupt specific 8Bit ESC read access*/


#define HW_EscWriteWord(WordValue, Address)      HW_EscWrite(((MEM_ADDR *)&(WordValue)),((UINT16)(Address)),2) /**< \brief 16Bit ESC write access*/
#define HW_EscWriteDWord(DWordValue, Address)    HW_EscWrite(((MEM_ADDR *)&(DWordValue)),((UINT16)(Address)),4) /**< \brief 32Bit ESC write access*/
#define HW_EscWriteByte(ByteValue, Address)      HW_EscWrite(((MEM_ADDR *)&(ByteValue)),((UINT16)(Address)),1) /**< \brief 8Bit ESC write access*/
#define HW_EscWriteMbxMem(pData,Address,Len)     HW_EscWrite(((MEM_ADDR *)(pData)),((UINT16)(Address)),(Len)) /**< \brief The mailbox data is stored in the local uC memory therefore the default write function is used.*/

#define HW_EscWriteWordIsr(WordValue, Address)   HW_EscWriteIsr(((MEM_ADDR *)&(WordValue)),((UINT16)(Address)),2) /**< \brief Interrupt specific 16Bit ESC write access*/
#define HW_EscWriteDWordIsr(DWordValue, Address) HW_EscWriteIsr(((MEM_ADDR *)&(DWordValue)),((UINT16)(Address)),4) /**< \brief Interrupt specific 32Bit ESC write access*/
#define HW_EscWriteByteIsr(ByteValue, Address)   HW_EscWriteIsr(((MEM_ADDR *)&(ByteValue)),((UINT16)(Address)),1) /**< \brief Interrupt specific 8Bit ESC write access*/

#endif // end of _9252_PIC32HW_H_


#if _9252_HW_
    #define PROTO
#else
    #define PROTO extern
#endif

	///
	// Global variables extern

	///
	// Global functions prototype

	PROTO UINT8 HW_Init(void);
	PROTO void HW_Release(void);
	PROTO UINT16 HW_GetALEventRegister(void);

	PROTO UINT16 HW_GetALEventRegister_Isr(void);

//	PROTO void HW_ResetALEventMask(UINT16 intMask);
//	PROTO void HW_SetALEventMask(UINT16 intMask);

	PROTO void HW_EscRead( MEM_ADDR * pData, UINT16 Address, UINT16 Len );
	PROTO void HW_EscReadIsr( MEM_ADDR *pData, UINT16 Address, UINT16 Len );

	PROTO void HW_EscWrite( MEM_ADDR *pData, UINT16 Address, UINT16 Len );

	PROTO void HW_EscWriteIsr( MEM_ADDR *pData, UINT16 Address, UINT16 Len );

//	PROTO void HW_DisableSyncManChannel(UINT8 channel);
//	PROTO void HW_EnableSyncManChannel(UINT8 channel);
//	PROTO TSYNCMAN ESCMEM *HW_GetSyncMan(UINT8 channel);
//    PROTO void HW_SetLed(UINT8 RunLed,UINT8 ErrLed);

	///
	// ESC Access macros

	#if _9252_PIC32HW_
		// Place-holder
	#endif //#if _9252_PIC32HW_

#undef    PROTO

lan9252.c

/*******************************************************************************
 LAN9252 Hardware Abtraction Layer - Implementation file

  Company:
    Microchip Technology Inc.

  File Name:
    9252_HW.c

  Description:
    This file  cContains the functional implementation of LAN9252 Hardware Abtraction Layer
	
  Change History:
    Version		Changes
	0.1			Initial version.
	0.2			-
	0.3			-
	0.4			*Disabled Sync Manager & Application Layer Event Requests.
				*Commented out the ISR call backs related to Sync Manager & AL Event Request.
	1.0			*Enabled Sync Manager & Application Layer Event Requests.
				*Added ISR call backs related to Sync Manager & AL Event Request.
*******************************************************************************/

/*******************************************************************************
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.
 *******************************************************************************/

///
// Included files

#include "ecat_def.h"

#include "ecatslv.h"

#define  _9252_HW_ 1
#include "lan9252.h"

#undef    _9252_HW_
#define    _9252_HW_ 0

#include "ecatappl.h"

#ifndef    PIC32_HW
    #define PIC32_HW	// Use PIC32MX board
#endif

#include "stm32f4xx_hal.h"
#include "tim.h"
#include "spi.h"
#include "gpio.h"

///
// Internal Type Defines

typedef union
{
    unsigned short    Word;
    unsigned char    Byte[2];
} UBYTETOWORD;

typedef union 
{
    UINT8           Byte[2];
    UINT16          Word;
}
UALEVENT;

void HW_ResetALEventMask(UINT16 intMask);

/*-----------------------------------------------------------------------------------------
------
------    LED defines
------
-----------------------------------------------------------------------------------------*/

//#define LED_ECATRED                    LATDbits.LATD1


#ifdef PIC32_HW
BOOL bEscInterrupt = 0;
BOOL bSync0Interrupt = 0;
BOOL bSync1Interrupt = 0;
BOOL bTimer5Interrupt = 0;
///
// Global Interrupt setting


#endif // end of PIC32_HW

///
// Internal Variables

UALEVENT      EscALEvent;     // contains the content of the ALEvent register (0x220), this variable is updated on each Access to the Esc
UINT16        nAlEventMask;   // current ALEventMask (content of register 0x204:0x205)
//TSYNCMAN      TmpSyncMan;

///
// Internal functions

/*******************************************************************************
  Function:
    void GetInterruptRegister(void)

  Summary:
    The function operates a SPI access without addressing.

  Description:
    The first two bytes of an access to the EtherCAT ASIC always deliver the AL_Event register (0x220).
    It will be saved in the global "EscALEvent"
  *****************************************************************************/

static void GetInterruptRegister(void)
{
      DISABLE_AL_EVENT_INT;
      HW_EscReadIsr((MEM_ADDR *)&EscALEvent.Word, 0x220, 2);
      ENABLE_AL_EVENT_INT;

}


/*******************************************************************************
  Function:
    void ISR_GetInterruptRegister(void)

  Summary:
    The function operates a SPI access without addressing.
        Shall be implemented if interrupts are supported else this function is equal to "GetInterruptRegsiter()"

  Description:
    The first two bytes of an access to the EtherCAT ASIC always deliver the AL_Event register (0x220).
        It will be saved in the global "EscALEvent"
  *****************************************************************************/

static void ISR_GetInterruptRegister(void)
{
     HW_EscReadIsr((MEM_ADDR *)&EscALEvent.Word, 0x220, 2);
}


///
// Exported HW Access functions


/*******************************************************************************
  Function:
    UINT8 HW_Init(void)

  Summary:
    This function intialize the Process Data Interface (PDI) and the host controller.

  Description:
    
  *****************************************************************************/

UINT8 HW_Init(void)
{

    UINT16 intMask;
    UINT32 data;
//		UINT8 ready = 0;
	
	  MX_SPI1_Init(); //SQI/SPI初始化
//		HW_EscReadByte(ready, 0x0);
    //应用层中断事件屏蔽
	  do
    {
        intMask = 0x93;
        HW_EscWriteWord(intMask, ESC_AL_EVENTMASK_OFFSET);       
        intMask = 0;
        HW_EscReadWord(intMask, ESC_AL_EVENTMASK_OFFSET);
    } while (intMask != 0x93);

    
    //IRQ enable,IRQ polarity, IRQ buffer type in Interrupt Configuration register.
    //Wrte 0x54 - 0x00000101
    data = 0x00000101;
	  SPIWriteDWord(0x54, data); //配置LAN9252中断配置寄存器
    //Write in Interrupt Enable register -->
    //Write 0x5c - 0x00000001
    data = 0x00000001;
    SPIWriteDWord(0x5C, data);//配置LAN9251中断允许寄存器
    //Read Interrupt Status register
    //Read 0x58.
    SPIReadDWord(0x58);      //读LAN9252中断状态寄存器
		
//时钟同步模式
#ifdef DC_SUPPORTED
#ifndef RUN_FROM_SVB_FPGA
    INIT_SYNC0_INT;  
    INIT_SYNC1_INT;
    ENABLE_SYNC0_INT;
    ENABLE_SYNC1_INT;
#endif

#endif
    INIT_ECAT_TIMER;
    START_ECAT_TIMER;	
		
    INIT_ESC_INT;		
    HW_ResetALEventMask(0x0);		
    ENABLE_ESC_INT();    
		return 1;
}





/*******************************************************************************
  Function:
    void HW_Release(void)

  Summary:
    This function shall be implemented if hardware resources need to be release
        when the sample application stops

  Description:
  *****************************************************************************/

void HW_Release(void)
{

}


/*******************************************************************************
  Function:
    UINT16 HW_GetALEventRegister(void)

  Summary:
    This function gets the current content of ALEvent register.

  Description:
    Returns first two Bytes of ALEvent register (0x220)
  *****************************************************************************/

UINT16 HW_GetALEventRegister(void)
{
    GetInterruptRegister();
    return EscALEvent.Word;
}


/*******************************************************************************
  Function:
    UINT16 HW_GetALEventRegister_Isr(void)

  Summary:
    The SPI PDI requires an extra ESC read access functions from interrupts service routines.
        The behaviour is equal to "HW_GetALEventRegister()"

  Description:
    Returns  first two Bytes of ALEvent register (0x220)
  *****************************************************************************/

UINT16 HW_GetALEventRegister_Isr(void)
{
     ISR_GetInterruptRegister();
    return EscALEvent.Word;
}


/*******************************************************************************
  Function:
    void HW_ResetALEventMask(UINT16 intMask)

  Summary:
    This function makes an logical and with the AL Event Mask register (0x204)

  Description:
    Input param: intMask - interrupt mask (disabled interrupt shall be zero)
  *****************************************************************************/

void HW_ResetALEventMask(UINT16 intMask)
{
    UINT16 mask;

    HW_EscReadWord(mask, ESC_AL_EVENTMASK_OFFSET);

    mask &= intMask;
    DISABLE_AL_EVENT_INT;
    HW_EscWriteWord(mask, ESC_AL_EVENTMASK_OFFSET);
    HW_EscReadWord(nAlEventMask, ESC_AL_EVENTMASK_OFFSET);
    ENABLE_AL_EVENT_INT;
}


/*******************************************************************************
  Function:
    void HW_SetALEventMask(UINT16 intMask)

  Summary:
    This function makes an logical or with the AL Event Mask register (0x204)

  Description:
    Input param: intMask - interrupt mask (disabled interrupt shall be zero)
  *****************************************************************************/

void HW_SetALEventMask(UINT16 intMask)
{
    UINT16 mask;

    HW_EscReadWord(mask, ESC_AL_EVENTMASK_OFFSET);

    mask |= intMask;
    DISABLE_AL_EVENT_INT;
    HW_EscWriteWord(mask, ESC_AL_EVENTMASK_OFFSET);
    HW_EscReadWord(nAlEventMask, ESC_AL_EVENTMASK_OFFSET);
    ENABLE_AL_EVENT_INT;
}


/*******************************************************************************
  Function:
    void HW_EscRead( MEM_ADDR *pData, UINT16 Address, UINT16 Len )

  Summary:
    This function operates the SPI read access to the EtherCAT ASIC.

  Description:
    Input param:
     pData    - Pointer to a byte array which holds data to write or saves read data.
     Address  - EtherCAT ASIC address ( upper limit is 0x1FFF )    for access.
     Len      - Access size in Bytes.
  *****************************************************************************/

void HW_EscRead( MEM_ADDR *pData, UINT16 Address, UINT16 Len )
{
    UINT16 i;
    UINT8 *pTmpData = (UINT8 *)pData;

    /* loop for all bytes to be read */
    while ( Len > 0 )
    {
        if (Address >= 0x1000)
        {
            i = Len;
        }
        else
        {
            i= (Len > 4) ? 4 : Len;

            if(Address & 01)
            {
               i=1;
            }
            else if (Address & 02)
            {
               i= (i&1) ? 1:2;
            }
            else if (i == 03)
            {
                i=1;
            }
        }

       DISABLE_AL_EVENT_INT;
				
       SPIReadDRegister(pTmpData,Address,i);
       ENABLE_AL_EVENT_INT;

        Len -= i;
        pTmpData += i;
        Address += i;
    }

#ifdef INTERRUPTS_SUPPORTED
    if(IS_ESC_INT_ACTIVE)
    {
        DISABLE_ESC_INT();
        PDI_Isr();
        ACK_ESC_INT;
    }
#endif
#if defined (INTERRUPTS_SUPPORTED) && defined(DC_SUPPORTED)
if(IS_SYNC0_INT_ACTIVE)
    {
        Sync0_Isr();

       ACK_SYNC0_INT;
    }
#endif
#if defined (INTERRUPTS_SUPPORTED) && defined(DC_SUPPORTED)
if(IS_SYNC1_INT_ACTIVE)
    {
        Sync1_Isr();

        ACK_SYNC1_INT;
    }
#endif
}

/
/**
 \param pData        Pointer to a byte array which holds data to write or saves read data.
 \param Address     EtherCAT ASIC address ( upper limit is 0x1FFF )    for access.
 \param Len            Access size in Bytes.

\brief  The SPI PDI requires an extra ESC read access functions from interrupts service routines.
        The behaviour is equal to "HW_EscRead()"
*

/*******************************************************************************
  Function:
    void HW_EscReadIsr( MEM_ADDR *pData, UINT16 Address, UINT16 Len )

  Summary:
    The SPI PDI requires an extra ESC read access functions from interrupts service routines.
        The behaviour is equal to "HW_EscRead()"

  Description:
    Input param:
    pData          - Pointer to a byte array which holds data to write or saves read data.
    param Address  - EtherCAT ASIC address ( upper limit is 0x1FFF ) for access.
    param Len      - Access size in Bytes.
  *****************************************************************************/

void HW_EscReadIsr( MEM_ADDR *pData, UINT16 Address, UINT16 Len )
{

   UINT16 i;
   UINT8 *pTmpData = (UINT8 *)pData;

    /* send the address and command to the ESC */

    /* loop for all bytes to be read */
   while ( Len > 0 )
   {

        if (Address >= 0x1000)
        {
            i = Len;
        }
        else
        {
            i= (Len > 4) ? 4 : Len;

            if(Address & 01)
            {
               i=1;
            }
            else if (Address & 02)
            {
               i= (i&1) ? 1:2;
            }
            else if (i == 03)
            {
                i=1;
            }
        }
        SPIReadDRegister(pTmpData, Address,i);
        Len -= i;
        pTmpData += i;
        Address += i;
    }
   
}


/*******************************************************************************
  Function:
    void HW_EscWrite( MEM_ADDR *pData, UINT16 Address, UINT16 Len )

  Summary:
    This function operates the SPI write access to the EtherCAT ASIC.

  Description:
    Input param:
    pData          - Pointer to a byte array which holds data to write or saves write data.
    param Address  - EtherCAT ASIC address ( upper limit is 0x1FFF ) for access.
    param Len      - Access size in Bytes.
  *****************************************************************************/

void HW_EscWrite( MEM_ADDR *pData, UINT16 Address, UINT16 Len )
{

    UINT16 i;
    UINT8 *pTmpData = (UINT8 *)pData;

    /* loop for all bytes to be written */
    while ( Len )
    {

        if (Address >= 0x1000)
        {
            i = Len;
        }
        else
        {
            i= (Len > 4) ? 4 : Len;

            if(Address & 01)
            {
               i=1;
            }
            else if (Address & 02)
            {
               i= (i&1) ? 1:2;
            }
            else if (i == 03)
            {
                i=1;
            }
        }

        DISABLE_AL_EVENT_INT;
       
        /* start transmission */
        SPIWriteRegister(pTmpData, Address, i);
        ENABLE_AL_EVENT_INT;

       
   
        /* next address */
        Len -= i;
        pTmpData += i;
        Address += i;

    }

#ifdef INTERRUPTS_SUPPORTED
    if(IS_ESC_INT_ACTIVE)
    {
        DISABLE_ESC_INT();
        PDI_Isr();
        ACK_ESC_INT;
    }
#endif
#if defined (INTERRUPTS_SUPPORTED) && defined(DC_SUPPORTED)
if(IS_SYNC0_INT_ACTIVE)
    {
        Sync0_Isr();

       ACK_SYNC0_INT;
    }
#endif
#if defined (INTERRUPTS_SUPPORTED) && defined(DC_SUPPORTED)
if(IS_SYNC1_INT_ACTIVE)
    {
        Sync1_Isr();

        ACK_SYNC1_INT;
    }
#endif
}


/*******************************************************************************
  Function:
    void HW_EscWriteIsr( MEM_ADDR *pData, UINT16 Address, UINT16 Len )

  Summary:
    The SPI PDI requires an extra ESC write access functions from interrupts service routines.
        The behaviour is equal to "HW_EscWrite()"

  Description:
    Input param:
    pData          - Pointer to a byte array which holds data to write or saves write data.
    param Address  - EtherCAT ASIC address ( upper limit is 0x1FFF ) for access.
    param Len      - Access size in Bytes.
  *****************************************************************************/

void HW_EscWriteIsr( MEM_ADDR *pData, UINT16 Address, UINT16 Len )
{

    UINT16 i ;
    UINT8 *pTmpData = (UINT8 *)pData;

  
    /* loop for all bytes to be written */
    while ( Len )
    {

        if (Address >= 0x1000)
        {
            i = Len;
        }
        else
        {
            i= (Len > 4) ? 4 : Len;

            if(Address & 01)
            {
               i=1;
            }
            else if (Address & 02)
            {
               i= (i&1) ? 1:2;
            }
            else if (i == 03)
            {
                i=1;
            }
        }
        
       /* start transmission */
       SPIWriteRegister(pTmpData, Address, i);
       /* next address */
        Len -= i;
        pTmpData += i;
        Address += i;
    }

}
/*******************************************************************************

 \param RunLed            desired EtherCAT Run led state
 \param ErrLed            desired EtherCAT Error led state

  \brief    This function updates the EtherCAT run and error led
  *****************************************************************************/
void HW_SetLed(UINT8 RunLed,UINT8 ErrLed)
{
    /* Here RunLed is not used. Because on chip supported RUN Led is available*/    
//    LED_ECATRED   = ErrLed;
}

#ifdef PIC32_HW

/*******************************************************************************
  Function:
    void __ISR(_EXTERNAL_0_VECTOR, ipl7srs) ExtInterruptHandler(void)

  Summary:
    Interrupt service routine for the PDI interrupt from the EtherCAT Slave Controller

  *****************************************************************************/
#ifdef DC_SUPPORTED
#ifndef RUN_FROM_SVB_FPGA

/*******************************************************************************
  Function:
    void __ISR(_EXTERNAL_1_VECTOR, ipl5) Sync0Isr(void)

  Summary:
    Interrupt service routine for the interrupts from SYNC0
  *****************************************************************************/



/*******************************************************************************
  Function:
    void __ISR(_EXTERNAL_2_VECTOR, ipl4) Sync1Isr(void)


  Summary:
    Interrupt service routine for the interrupts from SYNC1
  *****************************************************************************/


#endif

#endif //DC_SUPPORTED

#endif // PIC32_HW

APPlication.h

/**
 * \addtogroup RT2000 RT2000
 * @{
 */

/**
\file RT2000.h
\brief RT2000 function prototypes and defines

\version 1.0.0.11
 */

 
 #ifndef _RT2000_H_
#define _RT2000_H_


/*-----------------------------------------------------------------------------------------
------
------    Includes
------
-----------------------------------------------------------------------------------------*/
#include "ecat_def.h"

#include "ecatappl.h"

/*-----------------------------------------------------------------------------------------
------
------    Defines and Types
------
-----------------------------------------------------------------------------------------*/

#endif //_RT2000_H_

//include custom application object dictionary 
#include "RT2000Objects.h"


#if defined(_RT2000_) && (_RT2000_ == 1)
    #define PROTO
#else
    #define PROTO extern
#endif


PROTO void APPL_Application(void);
#if EXPLICIT_DEVICE_ID
PROTO UINT16 APPL_GetDeviceID(void);
#endif

PROTO void   APPL_AckErrorInd(UINT16 stateTrans);
PROTO UINT16 APPL_StartMailboxHandler(void);
PROTO UINT16 APPL_StopMailboxHandler(void);
PROTO UINT16 APPL_StartInputHandler(UINT16 *pIntMask);
PROTO UINT16 APPL_StopInputHandler(void);
PROTO UINT16 APPL_StartOutputHandler(void);
PROTO UINT16 APPL_StopOutputHandler(void);

PROTO UINT16 APPL_GenerateMapping(UINT16 *pInputSize,UINT16 *pOutputSize);
PROTO void APPL_InputMapping(UINT16* pData);
PROTO void APPL_OutputMapping(UINT16* pData);

#undef PROTO
/** @}*/

Application.c

/**
\addtogroup RT2000 RT2000
@{
*/

/**
\file RT2000.c
\brief Implementation

\version 1.0.0.11
*/


/*-----------------------------------------------------------------------------------------
------
------    Includes
------
-----------------------------------------------------------------------------------------*/
#include "ecat_def.h"
#include "main.h"
#include "applInterface.h"

#define _RT2000_ 1
#include "RT2000.h"
#undef _RT2000_
/*--------------------------------------------------------------------------------------
------
------    local types and defines
------
--------------------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------------------
------
------    local variables and constants
------
-----------------------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------------------
------
------    application specific functions
------
-----------------------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------------------
------
------    generic functions
------
-----------------------------------------------------------------------------------------*/

/
/**
 \brief    The function is called when an error state was acknowledged by the master

*

void    APPL_AckErrorInd(UINT16 stateTrans)
{

}

/
/**
 \return    AL Status Code (see ecatslv.h ALSTATUSCODE_....)

 \brief    The function is called in the state transition from INIT to PREOP when
             all general settings were checked to start the mailbox handler. This function
             informs the application about the state transition, the application can refuse
             the state transition when returning an AL Status error code.
            The return code NOERROR_INWORK can be used, if the application cannot confirm
            the state transition immediately, in that case this function will be called cyclically
            until a value unequal NOERROR_INWORK is returned

*

UINT16 APPL_StartMailboxHandler(void)
{
    return ALSTATUSCODE_NOERROR;
}

/
/**
 \return     0, NOERROR_INWORK

 \brief    The function is called in the state transition from PREEOP to INIT
             to stop the mailbox handler. This functions informs the application
             about the state transition, the application cannot refuse
             the state transition.

*

UINT16 APPL_StopMailboxHandler(void)
{
    return ALSTATUSCODE_NOERROR;
}

/
/**
 \param    pIntMask    pointer to the AL Event Mask which will be written to the AL event Mask
                        register (0x204) when this function is succeeded. The event mask can be adapted
                        in this function
 \return    AL Status Code (see ecatslv.h ALSTATUSCODE_....)

 \brief    The function is called in the state transition from PREOP to SAFEOP when
           all general settings were checked to start the input handler. This function
           informs the application about the state transition, the application can refuse
           the state transition when returning an AL Status error code.
           The return code NOERROR_INWORK can be used, if the application cannot confirm
           the state transition immediately, in that case the application need to be complete 
           the transition by calling ECAT_StateChange.
*

UINT16 APPL_StartInputHandler(UINT16 *pIntMask)
{
    return ALSTATUSCODE_NOERROR;
}

/
/**
 \return     0, NOERROR_INWORK

 \brief    The function is called in the state transition from SAFEOP to PREEOP
             to stop the input handler. This functions informs the application
             about the state transition, the application cannot refuse
             the state transition.

*

UINT16 APPL_StopInputHandler(void)
{
    return ALSTATUSCODE_NOERROR;
}

/
/**
 \return    AL Status Code (see ecatslv.h ALSTATUSCODE_....)

 \brief    The function is called in the state transition from SAFEOP to OP when
             all general settings were checked to start the output handler. This function
             informs the application about the state transition, the application can refuse
             the state transition when returning an AL Status error code.
           The return code NOERROR_INWORK can be used, if the application cannot confirm
           the state transition immediately, in that case the application need to be complete 
           the transition by calling ECAT_StateChange.
*

UINT16 APPL_StartOutputHandler(void)
{
    return ALSTATUSCODE_NOERROR;
}

/
/**
 \return     0, NOERROR_INWORK

 \brief    The function is called in the state transition from OP to SAFEOP
             to stop the output handler. This functions informs the application
             about the state transition, the application cannot refuse
             the state transition.

*

UINT16 APPL_StopOutputHandler(void)
{
		DigitalOut0x7000.DO0 = 0;
		DigitalOut0x7000.DO1 = 0;
		DigitalOut0x7000.DO2 = 0;
		DigitalOut0x7000.DO3 = 0;
		DigitalOut0x7000.DO4 = 0;
		DigitalOut0x7000.DO5 = 0;
		DigitalOut0x7000.DO6 = 0;
		DigitalOut0x7000.DO7 = 0;
	
    return ALSTATUSCODE_NOERROR;
}

/
/**
\return     0(ALSTATUSCODE_NOERROR), NOERROR_INWORK
\param      pInputSize  pointer to save the input process data length
\param      pOutputSize  pointer to save the output process data length

\brief    This function calculates the process data sizes from the actual SM-PDO-Assign
            and PDO mapping
*
UINT16 APPL_GenerateMapping(UINT16 *pInputSize,UINT16 *pOutputSize)
{
    UINT16 result = ALSTATUSCODE_NOERROR;
    UINT16 InputSize = 0;
    UINT16 OutputSize = 0;

#if COE_SUPPORTED
    UINT16 PDOAssignEntryCnt = 0;
    OBJCONST TOBJECT OBJMEM * pPDO = NULL;
    UINT16 PDOSubindex0 = 0;
    UINT32 *pPDOEntry = NULL;
    UINT16 PDOEntryCnt = 0;
   
    /*Scan object 0x1C12 RXPDO assign*/
    for(PDOAssignEntryCnt = 0; PDOAssignEntryCnt < sRxPDOassign.u16SubIndex0; PDOAssignEntryCnt++)
    {
        pPDO = OBJ_GetObjectHandle(sRxPDOassign.aEntries[PDOAssignEntryCnt]);
        if(pPDO != NULL)
        {
            PDOSubindex0 = *((UINT16 *)pPDO->pVarPtr);
            for(PDOEntryCnt = 0; PDOEntryCnt < PDOSubindex0; PDOEntryCnt++)
            {
                pPDOEntry = (UINT32 *)((UINT8 *)pPDO->pVarPtr + (OBJ_GetEntryOffset((PDOEntryCnt+1),pPDO)>>3));    //goto PDO entry
                // we increment the expected output size depending on the mapped Entry
                OutputSize += (UINT16) ((*pPDOEntry) & 0xFF);
            }
        }
        else
        {
            /*assigned PDO was not found in object dictionary. return invalid mapping*/
            OutputSize = 0;
            result = ALSTATUSCODE_INVALIDOUTPUTMAPPING;
            break;
        }
    }

    OutputSize = (OutputSize + 7) >> 3;

    if(result == 0)
    {
        /*Scan Object 0x1C13 TXPDO assign*/
        for(PDOAssignEntryCnt = 0; PDOAssignEntryCnt < sTxPDOassign.u16SubIndex0; PDOAssignEntryCnt++)
        {
            pPDO = OBJ_GetObjectHandle(sTxPDOassign.aEntries[PDOAssignEntryCnt]);
            if(pPDO != NULL)
            {
                PDOSubindex0 = *((UINT16 *)pPDO->pVarPtr);
                for(PDOEntryCnt = 0; PDOEntryCnt < PDOSubindex0; PDOEntryCnt++)
                {
                    pPDOEntry = (UINT32 *)((UINT8 *)pPDO->pVarPtr + (OBJ_GetEntryOffset((PDOEntryCnt+1),pPDO)>>3));    //goto PDO entry
                    // we increment the expected output size depending on the mapped Entry
                    InputSize += (UINT16) ((*pPDOEntry) & 0xFF);
                }
            }
            else
            {
                /*assigned PDO was not found in object dictionary. return invalid mapping*/
                InputSize = 0;
                result = ALSTATUSCODE_INVALIDINPUTMAPPING;
                break;
            }
        }
    }
    InputSize = (InputSize + 7) >> 3;

#else
#if _WIN32
   #pragma message ("Warning: Define 'InputSize' and 'OutputSize'.")
#else
    #warning "Define 'InputSize' and 'OutputSize'."
#endif
#endif

    *pInputSize = InputSize;
    *pOutputSize = OutputSize;
    return result;
}

/
/**
\param      pData  pointer to input process data

\brief      This function will copies the inputs from the local memory to the ESC memory
            to the hardware
*
void APPL_InputMapping(UINT16* pData)
{
		*pData++ = (((UINT16 *) &DigitalIn0x6000)[1]);
}

/
/**
\param      pData  pointer to output process data

\brief    This function will copies the outputs from the ESC memory to the local memory
            to the hardware
*
void APPL_OutputMapping(UINT16* pData)
{
	 ((UINT16 *) &DigitalOut0x7000)[1] = (*pData++);	
}

/
/**
\brief    This function will called from the synchronisation ISR 
            or from the mainloop if no synchronisation is supported
*
void APPL_Application(void)
{
	DigitalIn0x6000.DI0 = HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin);
	DigitalIn0x6000.DI1 = HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin);
	DigitalIn0x6000.DI2 = HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin);
	DigitalIn0x6000.DI3 = HAL_GPIO_ReadPin(KEY3_GPIO_Port,KEY3_Pin);
	DigitalIn0x6000.DI4 = HAL_GPIO_ReadPin(KEY4_GPIO_Port,KEY4_Pin);
	DigitalIn0x6000.DI5 = HAL_GPIO_ReadPin(KEY5_GPIO_Port,KEY5_Pin);
	DigitalIn0x6000.DI6 = HAL_GPIO_ReadPin(KEY6_GPIO_Port,KEY6_Pin);
	DigitalIn0x6000.DI7 = HAL_GPIO_ReadPin(KEY7_GPIO_Port,KEY7_Pin);
	
	DigitalOut0x7000.DO0 ?( HAL_GPIO_WritePin( LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET) ) : ( HAL_GPIO_WritePin( LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET) );
	DigitalOut0x7000.DO1 ?( HAL_GPIO_WritePin( LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET) ) : ( HAL_GPIO_WritePin( LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET) );
	DigitalOut0x7000.DO2 ?( HAL_GPIO_WritePin( LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET) ) : ( HAL_GPIO_WritePin( LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET) );
	DigitalOut0x7000.DO3 ?( HAL_GPIO_WritePin( LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET) ) : ( HAL_GPIO_WritePin( LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET) );
	DigitalOut0x7000.DO4 ?( HAL_GPIO_WritePin( LED4_GPIO_Port, LED4_Pin, GPIO_PIN_RESET) ) : ( HAL_GPIO_WritePin( LED4_GPIO_Port, LED4_Pin, GPIO_PIN_SET) );
	DigitalOut0x7000.DO5 ?( HAL_GPIO_WritePin( LED5_GPIO_Port, LED5_Pin, GPIO_PIN_RESET) ) : ( HAL_GPIO_WritePin( LED5_GPIO_Port, LED5_Pin, GPIO_PIN_SET) );
	DigitalOut0x7000.DO6 ?( HAL_GPIO_WritePin( LED6_GPIO_Port, LED6_Pin, GPIO_PIN_RESET) ) : ( HAL_GPIO_WritePin( LED6_GPIO_Port, LED6_Pin, GPIO_PIN_SET) );
	DigitalOut0x7000.DO7 ?( HAL_GPIO_WritePin( LED7_GPIO_Port, LED7_Pin, GPIO_PIN_RESET) ) : ( HAL_GPIO_WritePin( LED7_GPIO_Port, LED7_Pin, GPIO_PIN_SET) );
	
}

#if EXPLICIT_DEVICE_ID
/
/**
 \return    The Explicit Device ID of the EtherCAT slave

 \brief     Calculate the Explicit Device ID
*/eID()
{///
UINT16 APPL_GetDevic
#if _WIN32
   #pragma message ("Warning: Implement explicit Device ID latching")
#else
    #warning "Implement explicit Device ID latching"
#endif
    /* Explicit Device 5 is expected by Explicit Device ID conformance tests*/
    return 0x5;
}
#endif



#if USE_DEFAULT_MAIN
/
/**

 \brief    This is the main function

*
#if _PIC24
int main(void)
#else
void main(void)
#endif
{
    /* initialize the Hardware and the EtherCAT Slave Controller */
#if FC1100_HW
    if(HW_Init())
    {
        HW_Release();
        return;
    }
#else
    HW_Init();
#endif
    MainInit();

    bRunApplication = TRUE;
    do
    {
        MainLoop();
        
    } while (bRunApplication == TRUE);

    HW_Release();
#if _PIC24
    return 0;
#endif
}
#endif //#if USE_DEFAULT_MAIN
/** @} */


中断

根据自己的需要加中断,TIM7中断时必须的,其他中断看自己的应用逻辑添加。

/**
  ******************************************************************************
  * @file    GPIO/GPIO_EXTI/Src/stm32f4xx_it.c
  * @author  MCD Application Team
  * @brief   Main Interrupt Service Routines.
  *          This file provides template for all exceptions handler and
  *          peripherals interrupt service routine.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "bsp.h"
#include "stm32f4xx_it.h"

/** @addtogroup STM32F4xx_HAL_Examples
  * @{
  */

/** @addtogroup GPIO_EXTI
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/******************************************************************************/
/*            Cortex-M4 Processor Exceptions Handlers                         */
/******************************************************************************/

/**
  * @brief  This function handles NMI exception.
  * @param  None
  * @retval None
  */
void NMI_Handler(void)
{
}

/**
  * @brief  This function handles Hard Fault exception.
  * @param  None
  * @retval None
  */
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Memory Manage exception.
  * @param  None
  * @retval None
  */
void MemManage_Handler(void)
{
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Bus Fault exception.
  * @param  None
  * @retval None
  */
void BusFault_Handler(void)
{
  /* Go to infinite loop when Bus Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Usage Fault exception.
  * @param  None
  * @retval None
  */
void UsageFault_Handler(void)
{
  /* Go to infinite loop when Usage Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles SVCall exception.
  * @param  None
  * @retval None
  */
void SVC_Handler(void)
{
}

/**
  * @brief  This function handles Debug Monitor exception.
  * @param  None
  * @retval None
  */
void DebugMon_Handler(void)
{
}

/**
  * @brief  This function handles PendSVC exception.
  * @param  None
  * @retval None
  */
void PendSV_Handler(void)
{
}

/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
	  OS_CPU_SR  cpu_sr;
	
		HAL_IncTick();
	
    OS_ENTER_CRITICAL();                         /* Tell uC/OS-II that we are starting an ISR          */
    OSIntNesting++;
    OS_EXIT_CRITICAL();
	
    OSTimeTick();                                /* Call uC/OS-II's OSTimeTick()                       */
    OSIntExit(); 	
}

/******************************************************************************/
/*                 STM32F4xx Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f4xx.s).                                               */
/******************************************************************************/

uint32_t count=0;
uint8_t stated=0;

void TIM7_IRQHandler(void)
{
  if(__HAL_TIM_GET_FLAG(&TimHandle, TIM_FLAG_UPDATE) != RESET)
  {
    if(__HAL_TIM_GET_IT_SOURCE(&TimHandle, TIM_IT_UPDATE) !=RESET)
    {		
				if(count++ > n_Count.Word)
				{
						if(stated)
						{
								CpuRunled(0);
								stated = 0;
						}
						else
						{
								CpuRunled(1);
								stated = 1;
						}
						count = 0;
				}			
				
				 ECAT_CheckTimer();	
				 __HAL_TIM_CLEAR_IT(&TimHandle, TIM_IT_UPDATE);
		}
  }
}

void USART2_IRQHandler(void)
{		
		uint8_t RecvByte = 0;
		if( (USARTx->SR & USART_SR_RXNE)||(USARTx->SR & USART_SR_ORE) )//接收数据寄存器不为空中断,硬件自动清零
		{
			 RecvByte = USARTx->DR;//取接受的数据
			 //USARTx_SendData(RecvByte);
			 FifoWriteOneByte(RecvByte);//存进缓存区
		}
}


//PWM0 定时器更新中断
volatile uint8_t Puls0_Level=0;
void TIM1_UP_TIM10_IRQHandler(void)
{
		uint16_t M0_TmpARR = 0;
	
		if(TIM1->SR & TIM_SR_UIF)
		{
				if(Puls0_Level)//周期结束
				{
						PWM_PORT_0->ODR &= ~PWM_ODR_0;
						Puls0_Level=0;
					
						//更新数据
						if((M0_Flag==1)&&(M0_Buffer != 0)&&(M0_Cycle>0))//缓冲区有新的数据
						{
								M0_Target += M0_Buffer;//更新目标值	
								if(M0_Target>0)
								{
										//DIR0(0);//正向
										M0_TmpARR = (uint16_t)(M0_Cycle*1000/M0_Target);
								}
								else
								{
										//DIR0(1);//反向
										M0_TmpARR = (uint16_t)(M0_Cycle*1000/(-M0_Target));
								}
								M0_Buffer = 0;//清楚缓存器
								M0_Cycle = 0;
								if(M0_TmpARR<1)
								{
										PWM0_Stop();
										return;
								}
								else
								{
										TIM1->ARR = M0_TmpARR; 
										TIM1->EGR |= TIM_EGR_UG;
								}	
						}
						//监控脉冲输出
						if(M0_Target>0)
						{
								M0_Target--;
						}
						else if(M0_Target<0)
						{
								M0_Target++;
						}	
						else
						{
								TIM1->BDTR &= ~TIM_BDTR_MOE;
								TIM1->CR1 &= ~TIM_CR1_CEN;
								M0_Flag = 0;
						}
				}
				else//周期一半
				{
						PWM_PORT_0->ODR |= PWM_ODR_0;
						Puls0_Level = 1;
				}
				
				TIM1->SR &= ~TIM_SR_UIF;
		}
}

//PWM1 定时器更新中断
volatile uint8_t Puls1_Level=0;
void TIM2_IRQHandler(void)
{
	  uint16_t M1_TmpARR = 0;

		if(TIM2->SR & TIM_SR_UIF)
		{
				if(Puls1_Level)
				{
						PWM_PORT_1->ODR &= ~PWM_ODR_1;
						Puls1_Level=0;
						PulsNum++;

						//更新数据
						if((M1_Flag==1)&&(M1_Buffer != 0)&&(M1_Cycle>0))//运行过程中,缓冲区有新的数据
						{
								Sum += M1_Buffer;
								M1_Target += M1_Buffer;//更新目标值
								if(M1_Target>0)
								{
										//DIR1(0);//正向
										M1_TmpARR = (uint16_t)(M1_Cycle*1000/M1_Target);
								}
								else
								{
										//DIR1(1);//反向
										M1_TmpARR = (uint16_t)(M1_Cycle*1000/(-M1_Target));
								}
								M1_Buffer = 0;//清楚缓存器
								M1_Cycle=0;
								if(M1_TmpARR<1)
								{
										PWM1_Stop();
										return;
								}
								else
								{
										TIM2->ARR = M1_TmpARR;
										TIM2->EGR |= TIM_EGR_UG;
								}
						}
						
						//监控脉冲输出
						if(M1_Target>0)
						{
								M1_Target--;
						}
						else if(M1_Target<0)
						{
								M1_Target++;
						}	
						else
						{
								TIM2->CR1 &= ~TIM_CR1_CEN;
								M1_Flag = 0;
						}
				}
				else
				{
						PWM_PORT_1->ODR |= PWM_ODR_1;
						Puls1_Level = 1;
				}
				
				TIM2->SR &= ~TIM_SR_UIF;
		}
}

//PWM2 定时器更新中断
volatile uint8_t Puls2_Level = 0;
void TIM3_IRQHandler (void)
{
    uint16_t M2_TmpARR = 0;
	
		if(TIM3->SR & TIM_SR_UIF)
		{
				if(Puls2_Level)
				{
						PWM_PORT_2->ODR &= ~PWM_ODR_2;
						Puls2_Level=0;
					
						//更新数据
						if((M2_Flag==1)&&(M2_Buffer != 0)&&(M2_Cycle>0))//缓冲区有新的数据
						{
								M2_Target += M2_Buffer;//更新目标值	
								if(M2_Target>0)
								{
										//DIR2(0);//正向
										M2_TmpARR = (uint16_t)(M2_Cycle*1000/M2_Target);
								}
								else
								{
										//DIR2(1);//反向
										M2_TmpARR = (uint16_t)(M2_Cycle*1000/(-M2_Target));
								}
								M2_Buffer = 0;//清楚缓存器
								M2_Cycle = 0;
								if(M2_TmpARR<1)
								{
										PWM2_Stop();
										return;
								}
								else
								{
										TIM3->ARR = M2_TmpARR;
										TIM3->EGR |= TIM_EGR_UG;
								}
						}
						
						//监控脉冲输出
						if(M2_Target>0)
						{
								M2_Target--;
						}
						else if(M2_Target<0)
						{
								M2_Target++;
						}	
						else
						{
								TIM3->CR1 &= ~TIM_CR1_CEN;
								M2_Flag = 0;
						}					
				}
				else
				{
						PWM_PORT_2->ODR |= PWM_ODR_2;
						Puls2_Level = 1;
				}
				
				TIM3->SR &= ~TIM_SR_UIF;
		}
}

//PWM3 定时器更新中断
volatile uint8_t Puls3_Level = 0;
void TIM4_IRQHandler(void)
{
	  uint16_t M3_TmpARR = 0;
	
		if(TIM4->SR & TIM_SR_UIF)
		{
				if(Puls3_Level)
				{
						PWM_PORT_3->ODR &= ~PWM_ODR_3;
						Puls3_Level=0;
					
						//更新数据
						if((M3_Flag==1)&&(M3_Buffer != 0)&&(M3_Cycle>0))//缓冲区有新的数据
						{
								M3_Target += M3_Buffer;//更新目标值
								if(M3_Target>0)
								{
										//DIR3(0);//正向
										M3_TmpARR = (uint16_t)(M3_Cycle*1000/M3_Target);
								}
								else
								{
										//DIR3(1);//反向
										M3_TmpARR = (uint16_t)(M3_Cycle*1000/(-M3_Target));
								}
								M3_Buffer = 0;//清楚缓存器
								M3_Cycle = 0;
								if(M3_TmpARR<1)
								{
										PWM3_Stop();
										return;
								}
								else
								{
										TIM4->ARR = M3_TmpARR;
										TIM4->EGR |= TIM_EGR_UG;
								}
						}

						//监控脉冲输出
						if(M3_Target>0)
						{
								M3_Target--;
						}
						else if(M3_Target<0)
						{
								M3_Target++;
						}	
						else
						{
								TIM4->CR1 &= ~TIM_CR1_CEN;
								M3_Flag = 0;
						}
				}
				else
				{
						PWM_PORT_3->ODR |= PWM_ODR_3;
						Puls3_Level = 1;
				}
				
				TIM4->SR &= ~TIM_SR_UIF;
		}
}

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

  • 12
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 基于STM32LAN9252是一种用于工业自动化和物联网应用的网络控制器。该设备使用现场总线通信协议,通过以太网进行数据传输。LAN9252具有丰富的功能和灵活的配置选项,使其成为一种理想的选择。 首先,LAN9252具有高度集成的特点,包括以太网MAC和PHY、CAN和SPI接口等。它能够与STM32微控制器进行无缝集成,提供稳定可靠的通信能力。 其次,LAN9252支持多种网络协议,包括以太网/IP、TCP和UDP等,能够满足不同应用场景的需求。它支持连接到各种网络设备和主机,实现数据的快速传输和处理。 此外,LAN9252还支持多种工业标准,如EtherCAT(以太网控制自动化技术)、Modbus TCP和CANOpen等。这些标准使得它可以广泛应用于工业自动化领域,如机器人控制、工厂自动化和过程监控等。 同时,LAN9252具有低功耗和高速传输的特点,适用于低功耗和实时性要求较高的应用。它还具有丰富的故障检测和诊断功能,提高了系统的可靠性和稳定性。 总的来说,基于STM32LAN9252是一种功能强大的网络控制器,适用于工业自动化和物联网应用。它的高度集成、多协议支持和灵活性使得它成为一种理想的选择,能够满足各种应用需求。 ### 回答2: 基于STM32LAN9252是一种以太网控制器,它可以与STM32微控制器配合使用,实现网络通信功能。LAN9252提供了以太网物理层接口和TCP/IP协议栈,可以实现高速的数据传输和网络连接。 LAN9252采用SPI接口与STM32微控制器进行连接,通过SPI总线进行数据传输。它支持10/100Mbps的以太网速率,并且符合IEEE 802.3标准。LAN9252还支持自动协商功能,可以根据网络环境自动适应通信速率。 使用基于STM32LAN9252可以实现多种应用,例如工业自动化控制系统、机器人控制系统、家庭自动化系统等。它可以与其他设备进行数据交换,实现设备之间的互联互通。 基于STM32LAN9252具有低功耗的特点,可以在嵌入式系统中长时间稳定工作。它还具有多种保护功能,如过压保护、过温保护等,可以保证系统的安全性和可靠性。 此外,基于STM32LAN9252还提供了丰富的软件开发工具和驱动程序,可以方便开发者进行软件开发和调试。开发者可以使用STM32提供的开发环境和编程语言进行开发,快速实现网络通信功能。 总之,基于STM32LAN9252是一种可靠、高效的以太网控制器,适用于各种嵌入式系统中,为系统提供了稳定的网络通信能力。 ### 回答3: 基于STM32LAN9252是一款高性能以太网通信控制器。STM32是意法半导体推出的一款32位单片机系列,具有强大的处理能力和丰富的外设资源。而LAN9252是一款由Microchip公司提供的以太网通信控制器,用于实现高速以太网通信。 基于STM32LAN9252具有许多优点。首先,它支持高速以太网通信,具备高达100 Mbps的通信速度,可以满足高带宽需求。其次,它提供了丰富的外设资源,包括多个串行接口、通用输入输出口、定时器等,可以方便地与其他外设进行连接和通信。此外,它还具有低功耗特性,能够在工作时尽量减少能耗,提高整体系统效率。 基于STM32LAN9252适用于许多应用场景。比如,它可以应用于工业自动化领域,用于实现机器人、自动输送线、智能仓储系统等设备之间的高速通信。此外,它还可用于智能家居领域,用于实现家庭设备之间的联网和通信,如智能音响、智能灯具等。同时,基于STM32LAN9252还可以应用于智能交通领域,用于实现车辆之间的通信和数据传输,提高交通安全性和效率。 综上所述,基于STM32LAN9252是一款强大的以太网通信控制器,具有高性能、丰富的外设资源和低功耗特性。它能够广泛应用于多个领域,提供高速、稳定的通信支持,为各种设备之间的连接和数据传输提供便利。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值