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

📄 hal_m5i20.c

📁 Source code for an Numeric Cmputer
💻 C
📖 第 1 页 / 共 3 页
字号:
	    rtapi_print_msg(RTAPI_MSG_ERR, "M5I20: ERROR: hal_create_thread() failed\n");	    hal_exit(driver.componentId);	    return(-1);	} else {	    rtapi_print_msg(RTAPI_MSG_INFO, "M5I20: created %d uS thread\n", period / 1000);	}    }    return(0);}voidrtapi_app_exit(void){    int					i;    Device				*pDevice;    hal_exit(driver.componentId);    for(i = 0; i < MAX_DEVICES; i++){	if((pDevice = driver.deviceTable[i]) != NULL){	    // Unmap card.	    iounmap((void *)(pDevice->pCard16));	    iounmap((void *)(pDevice->pCard32));	    iounmap((void *)(pDevice->pBridgeIc));	    // TODO: Free device object when HAL supports free.//	    hal_free(pDevice);	}    }}/****************************************************************************** * DEVICE OBJECT FUNCTION DEFINITIONS ******************************************************************************//* * LOCAL FUNCTIONS */static intDevice_Init(Device *this, M5i20HostMotRegMap *pCard16, M5i20HostMotRegMap *pCard32,		Plx9030LocalRegMap *pBridgeIc){    int					i;    this->pCard16 = pCard16;    this->pCard32 = pCard32;    this->pBridgeIc = pBridgeIc;    // Download FPGA configuration.    if(loadFpga && ((i = Device_LoadFpga(this)) != 0)){	return(i);    }    // Initialize hardware.    pCard16->mode = 0;    pCard16->ledView = 0;    pCard16->pwmRate = dacRate * 65536 / 1000 * 1024 / 33000;    pCard16->wdTimeout = 16000;    pCard16->control = M5I20_CONTROL_RESET_WDT | M5I20_CONTROL_CLEAR_IRQ	    | M5I20_CONTROL_CLEAR_PWMS | M5I20_CONTROL_CLEAR_ENCODERS;    // Initialize PWM channels.    for(i = 0; i < M5I20_NUM_PWM_CHANNELS; i++){	this->lastDacInterlaced[i] = 1;	pCard16->pwmControl[i] = M5I20_PWM_CTL_SIGNED | M5I20_PWM_CTL_INTERLACED;    }    // Initialize primary encoders.    for(i = 0; i < M5I20_NUM_PRIMARY_ENCODERS; i++){	pCard16->encoderControl[i] = M5I20_ENC_CTL_COUNT_QUADRATURE	    | M5I20_ENC_CTL_INDEX_ACTIVE_HI | M5I20_ENC_CTL_QUAD_FILTER_4MHZ	    | M5I20_ENC_CTL_LATCH_ON_READ | M5I20_ENC_CTL_LOCAL_CLEAR;    }    // Initialize secondary encoders.    for(i = M5I20_MAX_PRIMARY_ENCODERS;	i < M5I20_MAX_PRIMARY_ENCODERS + M5I20_NUM_SECONDARY_ENCODERS; i++){	pCard16->encoderControl[i] = M5I20_ENC_CTL_COUNT_QUADRATURE	    | M5I20_ENC_CTL_INDEX_ACTIVE_HI | M5I20_ENC_CTL_QUAD_FILTER_4MHZ	    | M5I20_ENC_CTL_LATCH_ON_READ | M5I20_ENC_CTL_LOCAL_CLEAR;    }    // Initialize digital I/O.    for(i = 0; i < M5I20_NUM_DIGITAL_IO_PORTS; i++){	pCard32->digitalIo[i].data = M5I20_DIGITAL_OUT;	pCard32->digitalIo[i].direction = M5I20_DIGITAL_OUT;    }    pCard16->mode = M5I20_MODE_PWM_ENABLE | M5I20_MODE_COUNTER_ENABLE;        return(0);}// FPGA configuration.#include "m5i20_HM5-4E.h"/* * Function: Device_LoadFpga * Purpose: Initialize the FPGA with the contents from compiled in array. * Used by: Local functions. * Returns: Error code. * Notes: *   If DONE never goes high, but INIT goes low - this means the FPGA got a valid  *   synchonization word (5599AA66) but encounterd a CRC error later in the stream. * *   If DONE never goes high and INIT stays high, most likely the FPGA never saw  *   the syncronization word. * */static intDevice_LoadFpga(Device *this){    M5i20HostMotRegMap			*pCard16 = this->pCard16;    Plx9030LocalRegMap			*pBridgeIc = this->pBridgeIc;    hal_u32_t				i;    // Configure the GPIO.    pBridgeIc->gpioc &= M5I20_PLX_GPIOC_AND_MASK;    pBridgeIc->gpioc |= M5I20_PLX_GPIOC_OR_MASK;    // Turn on LED.    pBridgeIc->gpioc &= ~M5I20_PLX_GPIOC_LED_OFF;    // Reset the FPGA    pBridgeIc->gpioc &= ~M5I20_PLX_GPIOC_CFG_NPROGRAM;    pBridgeIc->gpioc |= M5I20_PLX_GPIOC_CFG_NWRITE;    if(pBridgeIc->gpioc & M5I20_PLX_GPIOC_CFG_DONE){	// Note that if we see DONE at the start of programming, it's most likely due	// to an attempt to access the FPGA at the wrong I/O location.	rtapi_print_msg(RTAPI_MSG_ERR, "M5I20: ERROR: FPGA busy at start of programming\n");	return(1);    }    // Enable programming.    pBridgeIc->gpioc |= M5I20_PLX_GPIOC_CFG_NPROGRAM;    pBridgeIc->gpioc &= ~M5I20_PLX_GPIOC_CFG_NWRITE;    // Delay for at least 100 uS. to allow the FPGA to finish its reset sequencing.    Device_Delay100us();    // Program the fpga.    for(i = 0; i < sizeof(fpgaConfig); i++){	// Write byte to FPGA.	pCard16->fpgaCfgData = fpgaConfig[i];    }    // Wait for completion of programming.    Device_Delay100us();    // Check for completion.    if(!(pBridgeIc->gpioc & M5I20_PLX_GPIOC_CFG_DONE)){	rtapi_print_msg(RTAPI_MSG_ERR, "M5I20: ERROR: FPGA programming not completed\n");	return(2);    }    // Send configuration completion clocks (6 should be enough, but we send    // lots for good measure).    pBridgeIc->gpioc |= M5I20_PLX_GPIOC_CFG_NWRITE;    for(i = 0; i < 24 ; i++){	pCard16->fpgaCfgData = 0xFF;    }    // Turn off LED.    pBridgeIc->gpioc |= M5I20_PLX_GPIOC_LED_OFF;    return(0);}static voidDevice_Delay100us(void){    long int				maxDelay = rtapi_delay_max();    long int				ns = 100000;    long int				delay;    while(ns){	delay = (ns > maxDelay)? maxDelay: ns;	ns -= delay;	rtapi_delay(delay);    }}static intDevice_ExportPinsParametersFunctions(Device *this, int componentId, int boardId){    int					msgLevel, error;    // This function exports a lot of stuff, which results in a lot of    // logging if msg_level is at INFO or ALL. So we save the current value    // of msg_level and restore it later.  If you actually need to log this    // function's actions, change the second line below.    msgLevel = rtapi_get_msg_level();    rtapi_set_msg_level(RTAPI_MSG_WARN);    // Export encoders.    error = Device_ExportEncoderPinsParametersFunctions(this, componentId, boardId);    // Export DACs.    if(!error) error = Device_ExportDacPinsParametersFunctions(this, componentId, boardId);    // Export digital I/O.    if(!error) error = Device_ExportDigitalInPinsParametersFunctions(this, componentId, boardId);    if(!error) error = Device_ExportDigitalOutPinsParametersFunctions(this, componentId, boardId);    // Export miscellaneous.    if(!error) error = Device_ExportMiscPinsParametersFunctions(this, componentId, boardId);    // Restore saved message level.    rtapi_set_msg_level(msgLevel);    return(error);}static intDevice_ExportEncoderPinsParametersFunctions(Device *this, int componentId, int boardId){    int					halError=0, channel;    char				name[HAL_NAME_LEN + 2];    // Export pins and parameters.    for(channel = 0; channel < M5I20_NUM_ENCODER_CHANNELS; channel++){	// Pins.	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.enc-%02d-count", boardId, channel);	if((halError = hal_pin_s32_new(name, HAL_WR, &(this->encoder[channel].pCount), componentId)) != 0)	    break;	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.enc-%02d-cnt-latch", boardId, channel);	if((halError = hal_pin_s32_new(name, HAL_WR, &(this->encoder[channel].pCountLatch), componentId)) != 0)	    break;	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.enc-%02d-position", boardId, channel);	if((halError = hal_pin_float_new(name, HAL_WR, &(this->encoder[channel].pPosition), componentId)) != 0)	    break;	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.enc-%02d-pos-latch", boardId, channel);	if((halError = hal_pin_float_new(name, HAL_WR, &(this->encoder[channel].pPositionLatch), componentId)) != 0)	    break;	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.enc-%02d-index", boardId, channel);	if((halError = hal_pin_bit_new(name, HAL_WR, &(this->encoder[channel].pIndex), componentId)) != 0)	    break;	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.enc-%02d-idx-latch", boardId, channel);	if((halError = hal_pin_bit_new(name, HAL_WR, &(this->encoder[channel].pIndexLatch), componentId)) != 0)	    break;	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.enc-%02d-latch-index", boardId, channel);	if((halError = hal_pin_bit_new(name, HAL_RD_WR, &(this->encoder[channel].pLatchIndex), componentId)) != 0)	    break;	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.enc-%02d-reset-count", boardId, channel);	if((halError = hal_pin_bit_new(name, HAL_RD_WR, &(this->encoder[channel].pResetCount), componentId)) != 0)	    break;	// Parameters.	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.enc-%02d-scale", boardId, channel);	if((halError = hal_param_float_new(name, HAL_WR, &(this->encoder[channel].scale), componentId)) != 0)	    break;	// Init encoder.	*(this->encoder[channel].pCount) = 0;	*(this->encoder[channel].pCountLatch) = 0;	*(this->encoder[channel].pPosition) = 0.0;	*(this->encoder[channel].pPositionLatch) = 0.0;	*(this->encoder[channel].pIndex) = 0;	*(this->encoder[channel].pIndexLatch) = 0;	*(this->encoder[channel].pLatchIndex) = 0;	*(this->encoder[channel].pResetCount) = 0;	this->encoder[channel].scale = 1.0;    }    // Export functions.    if(!halError){	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.encoder-read", boardId);	halError = hal_export_funct(name, Device_EncoderRead, this, 1, 0, componentId);    }    if(halError){	rtapi_print_msg(RTAPI_MSG_ERR, "M5I20: ERROR: export encoder failed\n");	return(-1);    }    return(0);}static intDevice_ExportDacPinsParametersFunctions(Device *this, int componentId, int boardId){    int					halError=0, channel;    char				name[HAL_NAME_LEN + 2];    // Export pins and parameters.    for(channel = 0; channel < M5I20_NUM_PWM_CHANNELS; channel++){	// Pins.	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.dac-%02d-enable", boardId, channel);	if((halError = hal_pin_bit_new(name, HAL_RD, &(this->dac[channel].pEnable), componentId)) != 0)	    break;	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.dac-%02d-value", boardId, channel);	if((halError = hal_pin_float_new(name, HAL_RD, &(this->dac[channel].pValue), componentId)) != 0)	    break;	// Parameters.	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.dac-%02d-offset", boardId, channel);	if((halError = hal_param_float_new(name, HAL_WR, &(this->dac[channel].offset), componentId)) != 0)	    break;	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.dac-%02d-gain", boardId, channel);	if((halError = hal_param_float_new(name, HAL_WR, &(this->dac[channel].gain), componentId)) != 0)	    break;	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.dac-%02d-interlaced", boardId, channel);	if((halError = hal_param_bit_new(name, HAL_WR, &(this->dac[channel].interlaced), componentId)) != 0)	    break;	// Init DAC.	*(this->dac[channel].pEnable) = 0;	*(this->dac[channel].pValue) = 0.0;	this->dac[channel].offset = 0.0;	this->dac[channel].gain = 1.0;	this->dac[channel].interlaced = 1;    }    // Export functions.    if(!halError){	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.dac-write", boardId);	halError = hal_export_funct(name, Device_DacWrite, this, 1, 0, componentId);    }    if(halError){	rtapi_print_msg(RTAPI_MSG_ERR, "M5I20: ERROR: export DAC failed\n");	return(-1);    }    return(0);}static intDevice_ExportDigitalInPinsParametersFunctions(Device *this, int componentId, int boardId){    int					halError=0, channel;    char				name[HAL_NAME_LEN + 2];    // Export pins and parameters.    for(channel = 0; channel < M5I20_NUM_DIGITAL_INPUTS; channel++){	// Pins.	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.in-%02d", boardId, channel);	if((halError = hal_pin_bit_new(name, HAL_WR, &(this->in[channel].pValue), componentId)) != 0)	    break;	rtapi_snprintf(name, HAL_NAME_LEN, "m5i20.%d.in-%02d-not", boardId, channel);	if((halError = hal_pin_bit_new(name, HAL_WR, &(this->in[channel].pValueNot), componentId)) != 0)	    break;

⌨️ 快捷键说明

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