📄 librtd-dm6430.c
字号:
/* FILE NAME: librtd-dm6430.c FILE DESCRIPTION: DM6430 user level library source code PROJECT NAME: Linux DM6430 Driver, Library, and Example Programs PROJECT VERSION: (Defined in README.TXT) Copyright 2004 RTD Embedded Technologies, Inc. All Rights Reserved.*/#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <unistd.h>#include <signal.h>#include <stdlib.h>#include <errno.h>#include <dm6430lib.h>/*=============================================================================Non-exported library data =============================================================================*/static char basename[] = DM6430HR_DEVICE_BASENAME;static int signalno = SIGUSR2;static unsigned long magic_signature = 0xB9DAFE8D;struct DM6430HR_cbd { unsigned long signature; void (*isr)(void); struct sigaction sa; sigset_t mask;};/*=============================================================================End of non-exported library data =============================================================================*//*=============================================================================Non-exported library functions =============================================================================*//******************************************************************************DM6430HR_signal_handler() Purpose: Internal library signal handler. Used whenever an application calls InstallCallbackIRQHandler6430(). Parameters: signal_num => Signal number that was delivered. siginfo_p ==> Pointer to signal info structure containing details about the signal. dummy_p ====> Pointer to implementation defined argument passed from kernel to signal handler. Unused. Return Value: None. ******************************************************************************/static voidDM6430HR_signal_handler(int signal_num, siginfo_t *siginfo_p, void *dummy_p) { if ( (signal_num == signalno) && (siginfo_p->si_signo == signalno) && (siginfo_p->si_code == DM6430HR_SI_CODE) && (siginfo_p->si_pid == 0) ) { struct DM6430HR_cbd *cbd_p = (struct DM6430HR_cbd *) siginfo_p->si_ptr; if ((cbd_p->signature == magic_signature) && (cbd_p->isr != NULL)) (*cbd_p->isr)(); }}/******************************************************************************inb6430() Purpose: Read one byte from the specified register within a board's I/O space. Parameters: descriptor ====> File descriptor from OpenBoard6430() call. from_register => The board register to read, given as the offset from the base I/O address. byte_value_p ==> The address where the value read should be stored. Return Value: 0 Success. -1 Failure with errno set as follows: EACCES descriptor refers to a file which is open but not for read access. EINVAL from_register specifies an offset which lies outside the board's I/O space. ******************************************************************************/static inline intinb6430(int descriptor, int from_register, u_int8_t *byte_value_p) { int status; struct DM6430HR_IO8 io_request = {(enum DM6430HR_Regs) from_register, 0}; status = ioctl(descriptor, DM6430HR_IOCTL_INB, &io_request); if (status != -1) { *byte_value_p = io_request.value; } return status;}/******************************************************************************outb6430() Purpose: Write one byte to the specified register within a board's I/O space. Parameters: descriptor ==> File descriptor from OpenBoard6430() call. to_register => The board register to write, given as the offset from the base I/O address. byte_value ==> The data to write. Return Value: 0 Success. -1 Failure with errno set as follows: EACCES descriptor refers to a file which is open but not for write access. EINVAL to_register specifies an offset which lies outside the board's I/O space. ******************************************************************************/static inline intoutb6430(int descriptor, int to_register, u_int8_t byte_value) { struct DM6430HR_IO8 io_request = {(enum DM6430HR_Regs) to_register, byte_value}; return (ioctl(descriptor, DM6430HR_IOCTL_OUTB, &io_request));}/******************************************************************************moutb6430() Purpose: Write one byte to the specified register within a board's I/O space, using a bit mask to indicate which bits in the register should not be disturbed. Parameters: descriptor ==> File descriptor from OpenBoard6430() call. to_register => The board register to write, given as the offset from the base I/O address. mask ========> Mask that controls which bits can be changed. A 1 bit in the mask indicates that the register bit at that bit position should not be disturbed. A 0 bit in the mask indicates that the register bit at that bit position can be overwritten. data ========> The data to write. Return Value: 0 Success. -1 Failure with errno set as follows: EACCES descriptor refers to a file which is open but not for write access. EINVAL to_register specifies an offset which lies outside the board's I/O space. ******************************************************************************/static inline intmoutb6430(int descriptor, int to_register, u_int8_t mask, u_int8_t data) { struct DM6430HR_MIO8 io_request = {(enum DM6430HR_Regs) to_register, mask, data}; return (ioctl(descriptor, DM6430HR_IOCTL_MOUTB, &io_request));}/******************************************************************************inw6430() Purpose: Read two bytes (one word) from the specified register within a board's I/O space. Parameters: descriptor ====> File descriptor from OpenBoard6430() call. from_register => The board register to read, given as the offset from the base I/O address. word_value_p ==> The address where the value read should be stored. Return Value: 0 Success. -1 Failure with errno set as follows: EACCES descriptor refers to a file which is open but not for read access. EINVAL from_register specifies an offset which lies outside the board's I/O space. EINVAL from_register is not even. ******************************************************************************/static inline intinw6430(int descriptor, int from_register, u_int16_t *word_value_p) { int status; struct DM6430HR_IO16 io_request = {(enum DM6430HR_Regs) from_register, 0}; status = ioctl(descriptor, DM6430HR_IOCTL_INW, &io_request); if (status != -1) { *word_value_p = io_request.value; } return status;}/******************************************************************************outw6430() Purpose: Write two bytes (one word) to the specified register within a board's I/O space. Parameters: descriptor ==> File descriptor from OpenBoard6430() call. to_register => The board register to write, given as the offset from the base I/O address. data ========> The data to write. Return Value: 0 Success. -1 Failure with errno set as follows: EACCES descriptor refers to a file which is open but not for write access. EINVAL to_register specifies an offset which lies outside the board's I/O space. EINVAL to_register is not even. ******************************************************************************/static inline intoutw6430(int descriptor, int to_register, u_int16_t data) { struct DM6430HR_IO16 io_request = {(enum DM6430HR_Regs) to_register, data}; return (ioctl(descriptor, DM6430HR_IOCTL_OUTW, &io_request));}/******************************************************************************moutw6430() Purpose: Write two bytes (one word) to the specified register within a board's I/O space, using a bit mask to indicate which bits in the register should not be disturbed. Parameters: descriptor ==> File descriptor from OpenBoard6430() call. to_register => The board register to write, given as the offset from the base I/O address. mask ========> Mask that controls which bits can be changed. A 1 bit in the mask indicates that the register bit at that bit position should not be disturbed. A 0 bit in the mask indicates that the register bit at that bit position can be overwritten. data ========> The data to write. Return Value: 0 Success. -1 Failure with errno set as follows: EACCES descriptor refers to a file which is open but not for write access. EINVAL to_register specifies an offset which lies outside the board's I/O space. EINVAL to_register is not even. ******************************************************************************/static inline intmoutw6430(int descriptor, int to_register, u_int16_t mask, u_int16_t data) { struct DM6430HR_MIO16 io_request = {(enum DM6430HR_Regs) to_register, mask, data}; return (ioctl(descriptor, DM6430HR_IOCTL_MOUTW, &io_request));}/******************************************************************************validate_interrupt_source() Purpose: Determine if an interrupt source passed to certain library functions is valid. Parameters: source => Interrupt source to validate. Return Value: 0 Success. -1 Failure with errno set as follows: EINVAL source is not valid. ******************************************************************************/static intvalidate_interrupt_source(int source) { switch (source) { case IRQS_AD_SAMPLE_CNT_6430: case IRQS_AD_START_CONVERT_6430: case IRQS_AD_END_CONVERT_6430: case IRQS_AD_WRITE_FIFO_6430: case IRQS_AD_FIFO_HALF_6430: case IRQS_AD_DMA_DONE_6430: case IRQS_RESET_GAIN_TABLE_6430: case IRQS_PAUSE_GAIN_TABLE_6430: case IRQS_EXT_PACER_CLOCK_6430: case IRQS_EXT_TRIGGER_6430: case IRQS_DIGITAL_6430: case IRQS_TC_COUNTER0_6430: case IRQS_TC_COUNTER0_INVERTED_6430: case IRQS_TC_COUNTER1_6430: case IRQS_DIO_FIFO_HALF_6430: case IRQS_DIO_WRITE_FIFO_6430: return 0; break; default: errno = EINVAL; return -1; break; }}/******************************************************************************validate_clock_timer() Purpose: Determine if an clock/timer passed to certain library functions is valid. Parameters: clock_timer => Clock/timer to validate. Return Value: 0 Success. -1 Failure with errno set as follows: EINVAL clock_timer is not valid. ******************************************************************************/static intvalidate_clock_timer(int clock_timer) { switch (clock_timer) { case DM6430HR_CLK0: case DM6430HR_CLK1: case DM6430HR_CLK2: return 0; break; default: errno = EINVAL; return -1; break; }}/******************************************************************************validate_clock_select() Purpose: Determine if an clock/timer select passed to certain library functions is valid. Parameters: clock_select => Clock/timer select to validate. Return Value: 0 Success. -1 Failure with errno set as follows: EINVAL clock_select is not valid. ******************************************************************************/static intvalidate_clock_select(int clock_select) { switch (clock_select) { case DM6430HR_CLOCK_TC: case DM6430HR_USER_TC: return 0; break; default: errno = EINVAL; return -1; break; }}/******************************************************************************validate_dio_port() Purpose: Determine if a digital I/O port passed to certain library functions is valid. Parameters: dio_port => Digital I/O port to validate. Return Value: 0 Success. -1 Failure with errno set as follows: EINVAL dio_port is not valid. ******************************************************************************/static intvalidate_dio_port(int dio_port) { switch (dio_port) { case DM6430HR_DIO0: case DM6430HR_DIO1: return 0; break; default: errno = EINVAL; return -1; break; }}/*=============================================================================End of non-exported library functions =============================================================================*/intOpenBoard6430(int DeviceNumber) { char devname[4096]; int descriptor; snprintf(devname, sizeof(devname), "%s-%u", basename, DeviceNumber); descriptor = open(devname, O_RDWR | O_NOCTTY); return descriptor;}intCloseBoard6430(int descriptor) { if (descriptor == -1) return -1; /* * Ignore any errors while removing interrupt handlers. It's possible to * have one installed but not the other, which leads to wanting to special * case this in the driver; this would be a very bad idea. */ (void) RemoveIRQHandler6430(descriptor, DM6430HR_INT1); (void) RemoveIRQHandler6430(descriptor, DM6430HR_INT2); return close(descriptor);}intInstallCallbackIRQHandler6430( int descriptor, void (*callback)(void), enum DM6430HR_INT IRQChannel) { struct DM6430HR_CallBack cb = {IRQChannel, 0, signalno, 1}; struct sigaction sigact; sigset_t sigmask; struct DM6430HR_cbd *cbd_p; if (!callback) { errno = EINVAL; return -1; } (void) RemoveIRQHandler6430(descriptor, IRQChannel); cbd_p = (struct DM6430HR_cbd *) malloc(sizeof(*cbd_p)); if (cbd_p == NULL) { errno = ENOMEM; return -1; } sigemptyset(&sigact.sa_mask); sigact.sa_flags = SA_RESTART | SA_NOMASK | SA_SIGINFO; sigact.sa_sigaction = DM6430HR_signal_handler; if (sigaction(signalno, &sigact, &cbd_p->sa)) { free(cbd_p); return -1; } sigemptyset(&sigmask); sigaddset(&sigmask, signalno); if (sigprocmask(SIG_UNBLOCK, &sigmask, &cbd_p->mask)) { sigaction(signalno, &cbd_p->sa, NULL); free(cbd_p); return -1; } cbd_p->signature = magic_signature; cbd_p->isr = callback; cb.context = cbd_p; if (ioctl(descriptor, DM6430HR_IOCTL_IRQ_INSTALL, &cb)) { (void) sigprocmask(SIG_SETMASK, &cbd_p->mask, NULL); (void) sigaction(signalno, &cbd_p->sa, NULL); free(cbd_p); return -1; } return 0;}intRemoveIRQHandler6430(int descriptor, enum DM6430HR_INT IRQChannel) { int rv; struct DM6430HR_CallBack cb = {IRQChannel, 0, signalno, 0}; rv = ioctl(descriptor, DM6430HR_IOCTL_IRQ_INSTALL, &cb); if ((rv == 0) && (cb.context != 0)) { struct DM6430HR_cbd *cbd_p = (struct DM6430HR_cbd *) cb.context; sigprocmask(SIG_SETMASK, &cbd_p->mask, NULL); sigaction(signalno, &cbd_p->sa, NULL); free(cbd_p); } return rv;}intClearRegister6430(int descriptor, u_int16_t ClearValue) { return (ioctl(descriptor, DM6430HR_IOCTL_CLEAR, ClearValue));}intClearBoard6430(int descriptor) { return ClearRegister6430(descriptor, DM6430_CL_BOARD);}intClearADFIFO6430(int descriptor) { return ClearRegister6430(descriptor, DM6430_CL_AD_FIFO);}intClearADDMADone6430(int descriptor) { return ClearRegister6430(descriptor, DM6430_CL_AD_DMA_DONE);}intClearChannelGainTable6430(int descriptor) { return ClearRegister6430(descriptor, DM6430_CL_CLEAR_GAIN);}intResetChannelGainTable6430(int descriptor) { return ClearRegister6430(descriptor, DM6430_CL_RESET_GAIN);}intClearDINFIFO6430(int descriptor) { return ClearRegister6430(descriptor, DM6430_CL_DIO_FIFO);}intClearIRQ06430(int descriptor) { return ClearRegister6430(descriptor, DM6430_CL_IRQ1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -