⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal_m5i20.c

📁 Source code for an Numeric Cmputer
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************** * * Copyright (C) 2005 Peter G. Vavaroutsos <pete AT vavaroutsos DOT com> * * $RCSfile: hal_m5i20.c,v $ * $Author: jmkasunich $ * $Locker:  $ * $Revision: 1.3 $ * $State: Exp $ * $Date: 2005/11/25 19:38:57 $ * * This is the driver for the Mesa Electronics 5i20 board. * The board includes a user programable FPGA. This driver * is written for the 4 axis host based motion control FPGA * configuration. It includes 8 quadrature decoder channels, 4 * PWM output channels, and 48 I/O channels. * * Installation of the driver (realtime only): * * insmod hal_m5i20 loadFpga=<1|0> dacRate=<Hz> * * * The following items are exported to the HAL. <boardId> is * the PCI board number and is formated as "%d". <channel> is * formated as "%02d". * * Encoders: *   Parameters: *	float	m5i20.<boardId>.enc-<channel>-scale * *   Pins: *	s32	m5i20.<boardId>.enc-<channel>-count *	s32	m5i20.<boardId>.enc-<channel>-cnt-latch *	float	m5i20.<boardId>.enc-<channel>-position *	float	m5i20.<boardId>.enc-<channel>-pos-latch *	bit	m5i20.<boardId>.enc-<channel>-index *	bit	m5i20.<boardId>.enc-<channel>-idx-latch *	bit	m5i20.<boardId>.enc-<channel>-latch-index *	bit	m5i20.<boardId>.enc-<channel>-reset-count * *   Functions: *	void    m5i20.<boardId>.encoder-read * * * DACs: *   Parameters: *	float	m5i20.<boardId>.dac-<channel>-offset *	float	m5i20.<boardId>.dac-<channel>-gain *	bit	m5i20.<boardId>.dac-<channel>-interlaced * *   Pins: *	bit	m5i20.<boardId>.dac-<channel>-enable *	float	m5i20.<boardId>.dac-<channel>-value * *   Functions: *	void    m5i20.<boardId>.dac-write * * * Digital In: *   Pins: *	bit	m5i20.<boardId>.in-<channel> *	bit	m5i20.<boardId>.in-<channel>-not * *   Functions: *	void    m5i20.<boardId>.digital-in-read * * * Digital Out: *   Parameters: *	bit	m5i20.<boardId>.out-<channel>-invert * *   Pins: *	bit	m5i20.<boardId>.out-<channel> * *   Functions: *	void    m5i20.<boardId>.digital-out-write * * * Miscellaneous: *   Parameters: *	u16	m5i20.<boardId>.watchdog-control *		    0x0001				// 1 = enabled. *		    0x0002				// Reset by DAC writes. *	u16	m5i20.<boardId>.watchdog-timeout	// In micro-seconds. *	u16	m5i20.<boardId>.led-view * *   Pins: *	bit	m5i20.<boardId>.estop-in *	bit	m5i20.<boardId>.estop-in-not *	bit	m5i20.<boardId>.watchdog-reset * *   Functions: *	void    m5i20.<boardId>.misc-update * ****************************************************************************** * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2.1 of the GNU General * Public License as published by the Free Software Foundation. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111 USA * * THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR * ANY HARM OR LOSS RESULTING FROM ITS USE.  IT IS _EXTREMELY_ UNWISE * TO RELY ON SOFTWARE ALONE FOR SAFETY.  Any machinery capable of * harming persons must have provisions for completely removing power * from all motors, etc, before persons enter any danger area.  All * machinery must be designed to comply with local and national safety * codes, and the authors of this software can not, and do not, take * any responsibility for such compliance. * * This code was written as part of the EMC HAL project.  For more * information, go to www.linuxcnc.org. * ******************************************************************************/#ifndef RTAPI#error This is a realtime component only!#endif#include <linux/pci.h>#include "rtapi.h"			// RTAPI realtime OS API.#include "rtapi_app.h"			// RTAPI realtime module decls.#include "hal.h"			// HAL public API decls.#include "plx9030.h"			// Hardware dependent defines.#include "m5i20.h"			// Hardware dependent defines.#ifndef MODULE#define MODULE#endif#ifdef MODULE// Module information.MODULE_AUTHOR("Pete Vavaroutsos");MODULE_DESCRIPTION("Driver for Mesa Electronics 5i20 for EMC HAL");#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endif // MODULE_LICENSEstatic unsigned long			period = 0;	// Thread period (0 = no thread).MODULE_PARM(period, "l");MODULE_PARM_DESC(period, "thread period (nsecs)");static unsigned long			loadFpga = 1;MODULE_PARM(loadFpga, "l");MODULE_PARM_DESC(loadFpga, "Set to have FPGA configuration loaded");static unsigned long			dacRate = 32000;// PWM rate in Hz. 1 Hz to 32 KHz.MODULE_PARM(dacRate, "l");MODULE_PARM_DESC(dacRate, "DAC PWM rate");#endif // MODULE/****************************************************************************** * DEVICE OBJECT * * This object contains all the data for one card. A device object is * dynamically allocated in shmem for each card during initialization. * ******************************************************************************/typedef struct {    // Pins.    hal_s32_t				*pCount;	// Captured binary count value.    hal_s32_t				*pCountLatch;    hal_float_t				*pPosition;	// Scaled position (floating point).    hal_float_t				*pPositionLatch;    hal_bit_t				*pIndex;	// Current state of index.    hal_bit_t				*pIndexLatch;    hal_bit_t				*pLatchIndex;	// Setting this pin enables the index							// latch and clears IndexLatch. When the							// next index pulse is seen, CountLatch							// is updated and IndexLatch is set. This							// pin is self clearing.    hal_bit_t				*pResetCount;	// Setting this pin causes Count to be reset.							// This pin is self clearing.    // Parameters.    hal_float_t				scale;		// Scaling factor for position.} EncoderPinsParams;typedef struct {    // Pins.    hal_bit_t				*pEnable;	// Controls HW ENA pin too.    hal_float_t				*pValue;	// Desired value.    // Parameters.    hal_float_t				offset;    hal_float_t				gain;    hal_bit_t				interlaced;	// For analog out.} DacPinsParams;typedef struct {    // Pins.    hal_bit_t				*pValue;    hal_bit_t				*pValueNot;} DigitalInPinsParams;typedef struct {    // Pins.    hal_bit_t				*pValue;    // Parameters.    hal_bit_t				invert;} DigitalOutPinsParams;typedef struct {    // Pins.    hal_bit_t				*pEstopIn;    hal_bit_t				*pEstopInNot;    hal_bit_t				*pWatchdogReset;// This pin is self clearing.    // Parameters.    hal_u16_t				watchdogControl;    hal_u16_t				watchdogTimeout;    hal_u16_t				ledView;} MiscPinsParams;#define WDT_CONTROL_ENABLE		0x0001#define WDT_CONTROL_AUTO_RESET		0x0002typedef struct {    M5i20HostMotRegMap			*pCard16;    M5i20HostMotRegMap			*pCard32;    Plx9030LocalRegMap			*pBridgeIc;    hal_bit_t				lastDacInterlaced[M5I20_NUM_PWM_CHANNELS];    // Exported to HAL.    EncoderPinsParams			encoder[M5I20_NUM_ENCODER_CHANNELS];    DacPinsParams			dac[M5I20_NUM_PWM_CHANNELS];    DigitalInPinsParams			in[M5I20_NUM_DIGITAL_INPUTS];    DigitalOutPinsParams		out[M5I20_NUM_DIGITAL_OUTPUTS];    MiscPinsParams			misc;} Device;// These methods are used for initialization.static int Device_Init(Device *this, M5i20HostMotRegMap *pCard16, M5i20HostMotRegMap *pCard32,			Plx9030LocalRegMap *pBridgeIc);static int Device_LoadFpga(Device *this);static void Device_Delay100us(void);static int Device_ExportPinsParametersFunctions(Device *this, int componentId, int boardId);static int Device_ExportEncoderPinsParametersFunctions(Device *this, int componentId, int boardId);static int Device_ExportDacPinsParametersFunctions(Device *this, int componentId, int boardId);static int Device_ExportDigitalInPinsParametersFunctions(Device *this, int componentId, int boardId);static int Device_ExportDigitalOutPinsParametersFunctions(Device *this, int componentId, int boardId);static int Device_ExportMiscPinsParametersFunctions(Device *this, int componentId, int boardId);// These methods are exported to the HAL.static void Device_EncoderRead(void *this, long period);static void Device_DacWrite(void *this, long period);static void Device_DigitalInRead(void *this, long period);static void Device_DigitalOutWrite(void *this, long period);static void Device_MiscUpdate(void *this, long period);// Private helper methods.static void Device_WdtReset(Device *this);/****************************************************************************** * DRIVER OBJECT * * This object contains all the data for this HAL component. * ******************************************************************************/#define MAX_DEVICES			4		// Would be nice to have board id bits.typedef struct {    int					componentId;	// HAL component ID.    Device				*deviceTable[MAX_DEVICES];} Driver;static Driver				driver;/****************************************************************************** * INIT AND EXIT CODE ******************************************************************************/intrtapi_app_main(void){    int					i;    struct pci_dev			*pDev = NULL;    M5i20HostMotRegMap			*pCard16 = NULL;    M5i20HostMotRegMap			*pCard32;    Plx9030LocalRegMap			*pBridgeIc;    Device				*pDevice;    // Connect to the HAL.    driver.componentId = hal_init("hal_m5i20");    if (driver.componentId < 0) {	rtapi_print_msg(RTAPI_MSG_ERR, "M5I20: ERROR: hal_init() failed\n");	return(-1);    }    for(i = 0; i < MAX_DEVICES; i++){	driver.deviceTable[i] = NULL;    }    i = 0;    // TODO: check subsys values after programming into serial prom.    // Find a M5I20 card.#if 0    while((i < MAX_DEVICES) && ((pDev = pci_find_subsys(M5I20_VENDOR_ID, M5I20_DEVICE_ID,			M5I20_SUBSYS_VENDOR_ID, M5I20_SUBSYS_DEVICE_ID, pDev)) != NULL)){#else    while((i < MAX_DEVICES) && ((pDev = pci_find_device(M5I20_VENDOR_ID, M5I20_DEVICE_ID, pDev)) != NULL)){#endif	// Allocate memory for device object.	pDevice = hal_malloc(sizeof(Device));	if (pDevice == NULL) {	    rtapi_print_msg(RTAPI_MSG_ERR, "M5I20: ERROR: hal_malloc() failed\n");	    hal_exit(driver.componentId);	    return(-1);	}	// Save pointer to device object.	driver.deviceTable[i] = pDevice;	// Map card into memory.	rtapi_print_msg(RTAPI_MSG_INFO, "M5I20: Card detected in Slot: %2x\n", PCI_SLOT(pDev->devfn));	pCard16 = (M5i20HostMotRegMap *)ioremap_nocache(pci_resource_start(pDev, 4), pci_resource_len(pDev, 4));	rtapi_print_msg(RTAPI_MSG_INFO, "M5I20: Card address @ %lx, Len = %ld\n", (long)pCard16, (long)pci_resource_len(pDev, 4));	pCard32 = (M5i20HostMotRegMap *)ioremap_nocache(pci_resource_start(pDev, 5), pci_resource_len(pDev, 5));	rtapi_print_msg(RTAPI_MSG_INFO, "M5I20: Card address @ %lx, Len = %ld\n", (long)pCard32, (long)pci_resource_len(pDev, 5));	pBridgeIc = (Plx9030LocalRegMap *)ioremap_nocache(pci_resource_start(pDev, 0), pci_resource_len(pDev, 0));	rtapi_print_msg(RTAPI_MSG_INFO, "M5I20: Card address @ %lx, Len = %ld\n", (long)pBridgeIc, (long)pci_resource_len(pDev, 0));	// Initialize device.	if(Device_Init(pDevice, pCard16, pCard32, pBridgeIc)){	    hal_exit(driver.componentId);	    return(-1);	}	// Export pins, parameters, and functions.	if(Device_ExportPinsParametersFunctions(pDevice, driver.componentId, i++)){	    hal_exit(driver.componentId);	    return(-1);	}    }    if(pCard16 == NULL){	// No card present.	rtapi_print_msg(RTAPI_MSG_WARN, "M5I20: **** No M5I20 card detected ****\n");	hal_exit(driver.componentId);	return(-1);    }    // Was 'period' specified in the insmod command?    if (period > 0) {	// Create a thread.	if (hal_create_thread("m5i20.thread", period, 1) < 0){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -