📄 hal_m5i20.c
字号:
/****************************************************************************** * * 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 + -