📄 lib.cpp
字号:
----------------------------------------------
INTERRUPT PROCESSING
----------------------------------------------
*/
long set_intrpt_mask(long the_value)
{
WORD mask, scratch;
mask = the_value & 0xffffL;
send_chipset_cmd(SET_INTRPT_MASK, CHIPSET_SET, 1, &mask, &scratch);
return(0L);
}
long get_intrpt(void)
{
WORD axis_status, scratch;
send_chipset_cmd(GET_INTRPT, CHIPSET_REQUEST, 1, &scratch, &axis_status);
return((long) axis_status);
}
long rst_intrpt(long the_value)
{
WORD mask, scratch;
mask = the_value & 0xffffL;
send_chipset_cmd(RST_INTRPT, CHIPSET_SET, 1, &mask, &scratch);
return(0L);
}
long get_intrpt_mask(void)
{
WORD interrupt_mask, scratch;
send_chipset_cmd(GET_INTRPT_MASK, CHIPSET_REQUEST, 1, &scratch, &interrupt_mask);
return((long) interrupt_mask);
}
/*
----------------------------------------------
STATUS/MODE PROCESSING
----------------------------------------------
*/
long clr_status(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(CLR_STATUS, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long rst_status(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(RST_STATUS, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long get_status(void)
{
WORD axis_status, scratch;
send_chipset_cmd(GET_STATUS, CHIPSET_REQUEST, 1, &scratch, &axis_status);
return((long) axis_status);
}
long get_mode(void)
{
WORD misc_mode_info, scratch;
send_chipset_cmd(GET_MODE, CHIPSET_REQUEST, 1, &scratch, &misc_mode_info);
return((long) misc_mode_info);
}
long set_capt_index(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(SET_CAPT_INDEX, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long set_capt_home(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(SET_CAPT_HOME, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long get_capt(void)
{
WORD data[2], scratch;
long index;
send_chipset_cmd(GET_CAPT, CHIPSET_REQUEST, 2, &scratch, data);
index = ((data[HIGH] & 0xffffL) << 16) | (data[LOW] & 0xffffL);
return((long) index);
}
/*
----------------------------------------
MOTOR
----------------------------------------
*/
long set_output_pwm(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(SET_OUTPUT_PWM, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long set_output_dac16(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(SET_OUTPUT_DAC16, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long mtr_on(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(MTR_ON, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long mtr_off(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(MTR_OFF, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long set_mtr_cmd(long the_value)
{
WORD mtr_cmd, scratch;
mtr_cmd = the_value & 0xffffL;
send_chipset_cmd(SET_MTR_CMD, CHIPSET_SET, 1, &mtr_cmd, &scratch);
return(0L);
}
long get_output_mode(void)
{
WORD output_mode, scratch;
send_chipset_cmd(GET_OUTPUT_MODE, CHIPSET_REQUEST, 1, &scratch, &output_mode);
return((long) output_mode);
}
/*
----------------------------------------
MISCELLANEOUS
----------------------------------------
*/
long axis_on(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(AXIS_ON, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long axis_off(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(AXIS_OFF, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long get_actl_pos(void)
{
WORD data[2], scratch;
long actual_position;
send_chipset_cmd(GET_ACTL_POS, CHIPSET_REQUEST, 2, &scratch, data);
actual_position = ((data[HIGH] & 0xffffL) << 16) | (data[LOW] & 0xffffL);
return(actual_position);
}
long set_lmt_sense(long the_value)
{
WORD limit_sense, scratch;
limit_sense = the_value & 0xffffL;
send_chipset_cmd(SET_LMT_SENSE, CHIPSET_SET, 1, &limit_sense, &scratch);
return(0L);
}
long get_lmt_swtch(void)
{
WORD limit_switch, scratch;
send_chipset_cmd(GET_LMT_SWTCH, CHIPSET_REQUEST, 1, &scratch, &limit_switch);
return((long) limit_switch);
}
long lmts_on(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(LMTS_ON, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long lmts_off(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(LMTS_OFF, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long get_home(void)
{
WORD home_switch, scratch;
send_chipset_cmd(GET_HOME, CHIPSET_REQUEST, 1, &scratch, &home_switch);
return((long) home_switch);
}
long set_smpl_time(long the_value)
{
WORD sample_time, scratch;
sample_time = the_value & 0xffffL;
send_chipset_cmd(SET_SMPL_TIME, CHIPSET_SET, 1, &sample_time, &scratch);
return(0L);
}
long get_smpl_time(void)
{
WORD sample_time, scratch;
send_chipset_cmd(GET_SMPL_TIME, CHIPSET_REQUEST, 1, &scratch, &sample_time);
return((long) sample_time);
}
long reset(void)
{
WORD scratch1, scratch2;
send_chipset_cmd(RESET, CHIPSET_SET, 0, &scratch1, &scratch2);
return(0L);
}
long get_time(void)
{
WORD data[5], scratch;
long chip_time;
send_chipset_cmd(GET_TIME, CHIPSET_REQUEST, 2, &scratch, data);
chip_time = ((data[HIGH] & 0xffffL) << 16) | (data[LOW] & 0xffffL);
return(chip_time);
}
/*
--------------------------------------------------------------------------
Routine: send_chipset_cmd
Function: This is the main routine used to send a command to the chipset.
It accepts read or write commands, with any # of data words.
It uses the command checksum for both read and write operations.
In case of a checksum error, it will not re-try the command
automatically, although it does report the checksum status of
the operation, so that the calling routine can (if desired),
perform a special recovery sequence upon I/O checksum error.
Arguments:
command is the hex command code
cmd_type is the type of the command, the values are CHIPSET_SET
and CHIPSET_REQUEST
length is the length of the read or write data stream in words
send_data is a pointer to an array of words where the data to send
is stored
rcv_data is a pointer to an array of words where the data to receive
is stored
Return Arguments: CHECKSUM_BAD if the command checksum is bad, CHECKSUM_GOOD if
the command checksum is OK
--------------------------------------------------------------------------
*/
checksum_error send_chipset_cmd(
short int command,
command_type cmd_type,
short int length,
WORD *send_data,
WORD *rcv_data)
{
BYTE high_byte, low_byte;
WORD checksum, got;
short int i;
/* write the command to the chipset */
write_a_cmd(command, &checksum);
for (i = 0; i < length; i++)
{
if (cmd_type == CHIPSET_SET)
write_a_word(send_data[i], &checksum);
else
read_a_word(&rcv_data[i], &checksum);
}
/* we've read or written the requested # of bytes.
finish up by getting & checking the checksum */
if ((read_n_check_checksum(checksum, &got) == CHECKSUM_BAD) && (command != RESET))
{
// if (CHECKSUM_DIAG)
printf("<I/O CHECKSUM ERROR OCCURRED>\n\r");
check_sum_err = TRUE;
return(CHECKSUM_ERROR);
}
return(NO_CHECKSUM_ERROR);
}
/*
--------------------------------------------------------------------------
Routine: read_n_check_checksum
Function: This routine is called at the end of a command sequence. It
reads a data word from the chipset (the checksum), and compares
it with the expected checksum provided as a calling argument.
It returns an error condition if the checksums do not compare
correctly.
Arguments:
checksum is the expected checksum, based on the previous I/O operations
actual_checksum is a pointer to the actual checksum, read from the chipset
Return Arguments: CHECKSUM_BAD if the command checksum is bad, CHECKSUM_GOOD if
the command checksum is OK
--------------------------------------------------------------------------
*/
checksum_result read_n_check_checksum(WORD checksum, WORD *actual_checksum)
{
WORD asic_checksum, scratch;
WORD good_count, bad_count;
WORD i;
read_a_word(&asic_checksum, &scratch);
if (asic_checksum == checksum)
return(CHECKSUM_GOOD);
else
{
*actual_checksum = asic_checksum;
return(CHECKSUM_BAD);
}
}
/*
--------------------------------------------------------------------------
Routine: write_a_cmd
Function: This routine writes a single command byte to the chipset, and
maintains the checksum word.
Arguments:
the_cmd is the command to write to the chipset.
the_checksum is a pointer to the running checksum. After this routine
executes the running checksum is set equal to the command
byte.
Return Arguments: none
--------------------------------------------------------------------------
*/
void write_a_cmd(BYTE the_cmd, WORD *the_checksum)
{
wait_until_not_busy();
write_cmd(the_cmd);
*the_checksum = the_cmd;
}
/*
--------------------------------------------------------------------------
Routine: write_a_word
Function: This routine writes a 2-byte data word to the chipset, and
maintains the checksum word.
Arguments: the_word is the data word to write to the chipset.
the_checksum is a pointer to the running checksum.
Return Arguments: none
--------------------------------------------------------------------------
*/
void write_a_word(WORD the_word, WORD *the_checksum)
{
wait_until_not_busy();
write_byte((BYTE) ((the_word & 0xff00) >> 8));
wait_until_not_busy();
write_byte((BYTE) (the_word & 0xff));
*the_checksum += the_word;
}
/*
--------------------------------------------------------------------------
Routine: read_a_word
Function: This routine reads a 2-byte data word from the chipset, and
maintains the checksum word.
Arguments: the_word is a pointer to the data word to read from the chipset.
the_checksum is a pointer to the running checksum.
Return Arguments: none
--------------------------------------------------------------------------
*/
void read_a_word(WORD *the_word, WORD *the_checksum)
{
BYTE lo_byte, hi_byte;
wait_until_not_busy();
hi_byte = read_byte();
wait_until_not_busy();
lo_byte = read_byte();
*the_word = ((hi_byte & 0xff) << 8) | (lo_byte & 0xff);
*the_checksum += *the_word;
}
/*
--------------------------------------------------------------------------
Routine: write_cmd
Function: This is the low-level routine that writes a single byte command
to the chipset.
Arguments: the_cmd is the command byte to write to the chipset.
Return Arguments: none
--------------------------------------------------------------------------
*/
void write_cmd(BYTE the_cmd)
{
outp(COMMAND_PORT_ADDRESS, the_cmd);
}
/*
--------------------------------------------------------------------------
Routine: write_byte
Function: This is the low-level routine that writes a single byte of data
to the chipset.
Arguments: the_byte is the data byte to write to the chipset.
Return Arguments: none
--------------------------------------------------------------------------
*/
void write_byte(BYTE the_byte)
{
outp(DATA_PORT_ADDRESS, the_byte);
}
/*
--------------------------------------------------------------------------
Routine: read_byte
Function: This is the low-level routine that reads a single byte of
data from the chipset.
Arguments: none
Return Arguments: the byte read from the chipset
--------------------------------------------------------------------------
*/
BYTE read_byte(void)
{
BYTE the_byte;
the_byte = inp(DATA_PORT_ADDRESS);
return(the_byte);
}
/*
--------------------------------------------------------------------------
Routine: wait_until_not_busy
Function: This routine polls the ready/busy host bit and returns
when it is ready. Note that this routine has no
waiting period timeout. If the chipset is not receiving
power, or if there is some other hardware I/O problem,
this routine many wait in an "infinite loop"
Arguments: none
Return Arguments: none
--------------------------------------------------------------------------
*/
void wait_until_not_busy(void)
{
short int in_val;
while (TRUE)
{
/* poll ready port, if not ready, loop */
in_val =inp(STATUS_PORT_ADDRESS);
if (in_val&0x80)
return;
}
}
/*
--------------------------------------------------------------------------
Routine: wait_for_interrupt
Function:This routine polls the host interrupt bit of the status port
and returns when an interrupt is active (the motion chipset
is asserting the host_interrupt signal). Depending on the
IRQ selection setting of the board, a chipset host signal
may or may not generate a DOS interrupt. In any case this
routine only looks at the 'polled' mode bit in the status
word. Note that this routine has no waiting period timeout. If
the chipset is not receiving power, or if there is some other
hardware I/O problem, this routine many wait in an "infinite loop".
Arguments: none
Return Arguments:none
--------------------------------------------------------------------------
*/
void wait_for_interrupt(void)
{
BYTE the_byte;
while (TRUE)
{
the_byte = inp(INTERRUPT_PORT_ADDRESS);
if ((the_byte & HOST_INTERRUPT_BIT_MASK) == INTERRUPT_BIT_SENSE)
return;
}
}
/*
--------------------------------------------------------------------------
Routine: hardware_reset
Function: This routine sends a hardware reset command to the chipset.
Arguments: none
Return Arguments:none
--------------------------------------------------------------------------
*/
void hardware_reset(void)
{
outp(RESET_PORT_ADDRESS, 0x00);
}
long get_io_input(void)
{
return inportb(DATA_PORT_ADDRESS+9);
}
long set_io_output(long output_value)
{
outportb(DATA_PORT_ADDRESS+8,output_value);
return 0;
}
long get_mtr_cmd(void)
{
WORD mtr_cmd, scratch;
send_chipset_cmd(GET_MTR_CMD, CHIPSET_REQUEST, 1, &scratch, &mtr_cmd);
return((long) mtr_cmd);
}
long set_actl_pos(long the_value)
{
WORD data[2], scratch;
data[HIGH] = (the_value >> 16) & 0xffffL;
data[LOW] = the_value & 0xffffL;
send_chipset_cmd(SET_ACTL_POS, CHIPSET_SET, 2, data, &scratch);
return(0L);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -