Commit from zer0 on branch b_zer0 (2008-10-26 22:59 CET) =================================
Add the ax12 module from b_eirbot in b_zer0 Signed-off: JDaM Add a new test program that uses a cmdline interface to control the ax12 actuator. aversive config/config.in 1.42.4.20 aversive config/generate_aversive_config 1.23.4.11 + aversive modules/devices/servo/ax12/Makefile 1.1.4.2 + aversive modules/devices/servo/ax12/ax12.c 1.1.4.2 + aversive modules/devices/servo/ax12/ax12.h 1.1.4.2 + aversive modules/devices/servo/ax12/ax12_address.h 1.1.4.2 + aversive modules/devices/servo/ax12/config/ax12_config.h 1.1.4.2 + aversive modules/devices/servo/ax12/test/.config 1.1.4.2 + aversive modules/devices/servo/ax12/test/Makefile 1.1.4.2 + aversive modules/devices/servo/ax12/test/ax12_config.h 1.1.4.2 + aversive modules/devices/servo/ax12/test/commands.c 1.1.2.1 + aversive modules/devices/servo/ax12/test/error_config.h 1.1.4.2 + aversive modules/devices/servo/ax12/test/main.c 1.1.4.2 + aversive modules/devices/servo/ax12/test/rdline_config.h 1.1.2.1 + aversive modules/devices/servo/ax12/test/uart_config.h 1.1.4.2 ========================= aversive/config/config.in (1.42.4.19 -> 1.42.4.20) ========================= @@ -275,6 +275,11 @@ dep_bool ' |-- Create Default servo config' CONFIG_MODULE_MULTISERVO_CREATE_CONFIG \ $CONFIG_MODULE_MULTISERVO +bool 'AX-12' CONFIG_MODULE_AX12 + +dep_bool ' |-- Create Default AX-12 config' CONFIG_MODULE_AX12_CREATE_CONFIG\ + $CONFIG_MODULE_AX12 + mainmenu_option next_comment comment 'Brushless motor drivers (you should enable pwm modules to see all)' ======================================== aversive/config/generate_aversive_config (1.23.4.10 -> 1.23.4.11) ======================================== @@ -21,6 +21,7 @@ CONFIG_MODULE_VT100,ihm/vt100 CONFIG_MODULE_LCD,devices/ihm/lcd CONFIG_MODULE_MULTISERVO,devices/servo/multiservo + CONFIG_MODULE_AX12,devices/servo/ax12 CONFIG_MODULE_ENCODERS_MICROB,devices/encoders/encoders_microb CONFIG_MODULE_ENCODERS_EIRBOT,devices/encoders/encoders_eirbot CONFIG_MODULE_TRAJECTORY_MANAGER,devices/robot/trajectory_manager ============================================ aversive/modules/devices/servo/ax12/Makefile (1.1.4.2) ============================================ @@ -0,0 +1,6 @@ +TARGET = ax12 + +# List C source files here. (C dependencies are automatically generated.) +SRC = ax12.c + +include $(AVERSIVE_DIR)/mk/aversive_module.mk ========================================== aversive/modules/devices/servo/ax12/ax12.c (1.1.4.2) ========================================== @@ -0,0 +1,376 @@ +/* + * Copyright Droids Corporation, Microb Technology, Eirbot (2008) + * JD Brossillon <[EMAIL PROTECTED]> (main job) + * Olivier Matz <[EMAIL PROTECTED]> (clean-up, fixes) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Revision : $Id: ax12.c,v 1.1.4.2 2008-10-26 21:59:28 zer0 Exp $ + * + */ + +/* See some help in ax12.h */ + +#include "ax12.h" + +void AX12_init(AX12 *s) +{ + s->hardware_send = NULL; + s->hardware_recv = NULL; + s->hardware_switch = NULL; +} + +/*_________________________________________________________*/ +/*_________________________________________________________*/ + +void AX12_set_hardware_send(AX12 *s, void(*pf)(uint8_t)) +{ + s->hardware_send = pf; +} + +void AX12_set_hardware_recv(AX12 *s, uint8_t(*pf)(void)) +{ + s->hardware_recv = pf; +} + +void AX12_set_hardware_switch(AX12 *s, void(*pf)(uint8_t)) +{ + s->hardware_switch = pf; +} + +/*_________________________________________________________*/ +/*_________________________________________________________*/ + +uint8_t AX12_checksum(AX12_Packet *packet) +{ + uint8_t i; + uint8_t checksum=0; + + checksum += packet->id; + checksum += packet->instruction; + + /* Packet also contain length = number of params + 2 */ + checksum += packet->nparams + 2; + + for (i=0; i<packet->nparams; i++) + checksum += packet->params[i]; + + return ~checksum; +} + +int8_t AX12_send(AX12 *s, AX12_Packet *packet) +{ + uint8_t i; + + /* Switch line to write */ + s->hardware_switch(AX12_STATE_WRITE); + + /* Header */ + s->hardware_send(0xFF); + s->hardware_send(0xFF); + + /* AX12 ID */ + s->hardware_send( packet->id ); + + /* Packet length */ + s->hardware_send( packet->nparams + 2 ); + + /* Instruction */ + s->hardware_send( packet->instruction ); + + /* Params */ + for (i=0; i<(packet->nparams); i++) + s->hardware_send( packet->params[i] ); + + /* Checksum */ + s->hardware_send( AX12_checksum(packet) ); + + /* Switch line back to read */ + s->hardware_switch(AX12_STATE_READ); + + return 0; +} + +int8_t AX12_recv(AX12 *s, AX12_Packet *packet) +{ + uint8_t c; + int length; + int i; + + /* Switch line to read */ + s->hardware_switch(AX12_STATE_READ); + + c = s->hardware_recv(); + if (c != 0xFF) + return -1; + + c = s->hardware_recv(); + if (c != 0xFF) + return -1; + + packet->id = s->hardware_recv(); + + length = s->hardware_recv(); + packet->nparams = length - 2; + + packet->error = s->hardware_recv(); + + for (i=0; i<(length-2) ;i++) + packet->params[i] = s->hardware_recv(); + + /* Checksum */ + c = s->hardware_recv(); + + if (c != AX12_checksum(packet)) + return -2; + + return 0; +} + +/*_________________________________________________________*/ +/*_________________________________________________________*/ + +uint8_t AX12_write_byte(AX12 *s, uint8_t id, AX12_ADDRESS address, uint8_t data) +{ + AX12_Packet p, rp; + + p.id = id; + p.instruction = AX12_WRITE; + p.nparams = 2; + + /* memory address */ + p.params[0] = (uint8_t)address; + + /* value */ + p.params[1] = data; + + /* send packet */ + AX12_send(s, &p); + + /* We talk broadcast, no reply */ + if(p.id == AX12_BROADCAST_ID) + return 0; + + /* recv packet */ + AX12_recv(s, &rp); + + return rp.error; +} + +uint8_t AX12_write_int(AX12 *s, uint8_t id, AX12_ADDRESS address, uint16_t data) +{ + AX12_Packet p, rp; + + p.id = id; + p.instruction = AX12_WRITE; + p.nparams = 3; + + /* memory address */ + p.params[0] = (uint8_t)address; + + /* value (low) */ + p.params[1] = 0xFF & data; + + /* value (high) */ + p.params[2] = data>>8; + + /* send packet */ + AX12_send(s, &p); + + /* We talk broadcast, no reply */ + if(p.id == AX12_BROADCAST_ID) + return 0; + + /* receive status packet */ + AX12_recv(s, &rp); + + return rp.error; +} + +uint8_t AX12_read_byte(AX12 *s, uint8_t id, AX12_ADDRESS address) +{ + AX12_Packet p, rp; + + p.id = id; + p.instruction = AX12_READ; + p.nparams = 2; + + /* memory address */ + p.params[0] = (uint8_t)address; + + /* data length */ + p.params[1] = 1; + + /* send packet */ + AX12_send(s, &p); + + /* wait for reply packet */ + AX12_recv(s, &rp); + + return rp.params[0]; +} + +uint16_t AX12_read_int(AX12 *s, uint8_t id, AX12_ADDRESS address) +{ + AX12_Packet p, rp; + + p.id = id; + p.instruction = AX12_READ; + p.nparams = 2; + + /* memory address */ + p.params[0] = (uint8_t)address; + + /* data length */ + p.params[1] = 2; + + /* send packet */ + AX12_send(s, &p); + + /* wait for reply packet */ + AX12_recv(s, &rp); + + return rp.params[0] + ((rp.params[1])<<8); +} + +/*_________________________________________________________*/ +/*_________________________________________________________*/ + +uint8_t AX12_set_position(AX12 *s,uint8_t id, uint16_t position) +{ + return AX12_write_int(s, id, AA_GOAL_POSITION_L, position); +} + +uint8_t AX12_set_position2(AX12 *s, uint8_t id, uint16_t position, + uint16_t speed) +{ + AX12_Packet p, rp; + + p.id = id; + p.instruction = AX12_WRITE; + p.nparams = 5; + + /* memory address */ + p.params[0] = AA_GOAL_POSITION_L; + /* position */ + p.params[1] = 0xFF & position; + p.params[2] = position>>8; + /* speed */ + p.params[3] = 0xFF & speed; + p.params[4] = speed>>8; + + /* send packet */ + AX12_send(s, &p); + + /* We talk broadcast, no reply */ + if(p.id == AX12_BROADCAST_ID) + return 0; + + /* receive status packet */ + AX12_recv(s, &rp); + + return rp.error; +} + +uint8_t AX12_set_position3(AX12*s ,uint8_t id, uint16_t position, + uint16_t speed, uint16_t torque) +{ + AX12_Packet p, rp; + + p.id = id; + p.instruction = AX12_WRITE; + p.nparams = 7; + + /* memory address */ + p.params[0] = AA_GOAL_POSITION_L; + /* position */ + p.params[1] = 0xFF & position; + p.params[2] = position>>8; + /* speed */ + p.params[3] = 0xFF & speed; + p.params[4] = speed>>8; + /* torque */ + p.params[5] = 0xFF & torque; + p.params[6] = torque>>8; + + /* send packet */ + AX12_send(s, &p); + + /* We talk broadcast, no reply */ + if(p.id == AX12_BROADCAST_ID) + return 0; + + /* receive status packet */ + AX12_recv(s, &rp); + + return rp.error; +} + +uint16_t AX12_get_position(AX12 *s, uint8_t id) +{ + return AX12_read_int(s, id, AA_PRESENT_POSITION_L); +} + +uint16_t AX12_get_speed(AX12 *s, uint8_t id) +{ + return AX12_read_int(s, id, AA_PRESENT_SPEED_L); +} + +uint16_t AX12_get_load(AX12 *s, uint8_t id) +{ + return AX12_read_int(s, id, AA_PRESENT_LOAD_L); +} + +uint8_t AX12_ping(AX12 *s, uint8_t id) +{ + AX12_Packet p, rp; + + p.id = id; + p.instruction = AX12_PING; + p.nparams = 0; + + /* send packet */ + AX12_send(s,&p); + + /* We talk broadcast, no reply */ + if(p.id == AX12_BROADCAST_ID) + return 0; + + /* recv packet */ + AX12_recv(s, &rp); + + return rp.error; +} + +uint8_t AX12_reset(AX12 *s, uint8_t id) +{ + AX12_Packet p, rp; + + p.id = id; + p.instruction = AX12_RESET; + p.nparams = 0; + + /* send packet */ + AX12_send(s, &p); + + /* We talk broadcast, no reply */ + if(p.id == AX12_BROADCAST_ID) + return 0; + + /* recv packet */ + AX12_recv(s, &rp); + + return rp.error; +} ========================================== aversive/modules/devices/servo/ax12/ax12.h (1.1.4.2) ========================================== @@ -0,0 +1,196 @@ +/* + * Copyright Droids Corporation, Microb Technology, Eirbot (2008) + * JD Brossillon <[EMAIL PROTECTED]> (main job) + * Olivier Matz <[EMAIL PROTECTED]> (clean-up, fixes) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Revision : $Id: ax12.h,v 1.1.4.2 2008-10-26 21:59:28 zer0 Exp $ + * + */ + +/** + * @file ax12.h + * + * @brief This module provides functions for using a Robotis Dynamixel + * AX-12 numeric actuator + * + * @todo + * - Manage the "Status Return Level" + * + * AX12 servos uses a half duplex uart. This means that there is only + * one line that is used for both transmitting and receiving. Refer to + * the AX12 documentation for more informations. + * + * This module DOESN'T use ATmega's uart, user have to provide + * 3 functions to control the full duplex uart : + * - send char. + * - write char. + * - switch direction + * + * These functions may use (or not) the AVR uart. Have a look to the + * test program in test/ directory for an example. + */ + +#ifndef _AX12_H_ +#define _AX12_H_ + +#include <aversive.h> +#include <stdlib.h> + +#include "ax12_address.h" +#include "ax12_config.h" + +/*__________________________________________*/ + +/* Half duplex uart switch */ +#define AX12_STATE_READ 0 +#define AX12_STATE_WRITE 1 + +/* Error bits */ +#define AX12_ERROR_VOLTAGE 0 +#define AX12_ERROR_ANGLE_LIMIT 1 +#define AX12_ERROR_OVERHEAT 2 +#define AX12_ERROR_RANGE 3 +#define AX12_ERROR_CHECKSUM 4 +#define AX12_ERROR_OVERLOAD 5 +#define AX12_ERROR_INSTRUCTION 6 + +/* Address (see ax12_address.h) */ +#define AX12_BROADCAST_ID 0xFE + +/* AX-12 instruction set */ +#define AX12_PING 0x01 +#define AX12_READ 0x02 +#define AX12_WRITE 0x03 +#define AX12_REG_WRITE 0x04 +#define AX12_ACTION 0x05 +#define AX12_RESET 0x06 +#define AX12_SYNC_WRITE 0x83 + +/*__________________________________________*/ + +typedef struct AX12 +{ + void (*hardware_send)(uint8_t); + uint8_t (*hardware_recv)(void); + void (*hardware_switch)(uint8_t); + +} AX12; + +typedef struct AX12_Packet +{ + uint8_t id; + uint8_t instruction; + + /* Size of AX12_Packet.params */ + uint8_t nparams; + uint8_t params[MAX_PARAMS]; + + /* Used in status packet */ + uint8_t error; + +} AX12_Packet; + +/*___________ Interface ____________*/ + +void AX12_init(AX12 *); + +/*___________ Hardware layer _____________*/ + +/** @brief Set the function called when writing a character. */ +void AX12_set_hardware_send(AX12 *, void(*)(uint8_t)); + +/** @brief Set the function called when reading a character. */ +void AX12_set_hardware_recv(AX12 *, uint8_t(*)(void)); + +/** @brief Set the function called when switching line direction */ +void AX12_set_hardware_switch(AX12 *, void(*)(uint8_t)); + +/*___________ Low level layer ____________*/ + +/** @brief Compute AX12 packet checksum */ +uint8_t AX12_checksum(AX12_Packet *packet); + +/** @brief Send a formated AX12 instruction packet. Return 0 on + * on success. */ +int8_t AX12_send(AX12 *, AX12_Packet *packet); + +/* @brief Receive a formated AX12 status packet. Return 0 on + * on success. */ +int8_t AX12_recv(AX12 *, AX12_Packet *packet); + +/*___________ Medium level layer _________*/ + +/* + * ////////////////// WARNING ///////////////////////// + * The following functions assume that AX12 always + * answer with a status packet + * (Status Return Level = 0x02 in AX12 EEPROM area) + * ////////////////// WARNING ///////////////////////// + */ + +/** @brief Write byte in AX-12 memory + * @return Error code from AX-12 (0 means okay) */ +uint8_t AX12_write_byte(AX12 *, + uint8_t id, + AX12_ADDRESS address, + uint8_t data); + +/** @brief Write integer (2 bytes) in AX-12 memory + * @return Error code from AX-12 (0 means okay) + * + * address : data low + * address+1 : data high + */ +uint8_t AX12_write_int(AX12 *, uint8_t id, AX12_ADDRESS address, + uint16_t data); + +/** @brief Read byte from AX-12 memory */ +uint8_t AX12_read_byte(AX12 *, uint8_t id, AX12_ADDRESS address); + +/** @brief Write integer (2 bytes) from AX-12 memory */ +uint16_t AX12_read_int(AX12 *, uint8_t id, AX12_ADDRESS address); + +/*___________ High level layer _________*/ + +/** @brief Set AX12 position */ +uint8_t AX12_set_position(AX12 *,uint8_t id, uint16_t position); + +/** @brief Set AX12 position and moving speed */ +uint8_t AX12_set_position2(AX12 *, uint8_t id, uint16_t position, + uint16_t speed); + +/** @brief Set AX12 position, moving speed and torque */ +uint8_t AX12_set_position3(AX12 *, uint8_t id, uint16_t position, + uint16_t speed, uint16_t torque); + +/** @brief Read AX12 position */ +uint16_t AX12_get_position(AX12 *, uint8_t id); + +/** @brief Read AX12 speed */ +uint16_t AX12_get_speed(AX12 *, uint8_t id); + +/** @brief Read AX12 load */ +uint16_t AX12_get_load(AX12 *, uint8_t id); + + +/** @brief Ping an AX12 and return error register */ +uint8_t AX12_ping(AX12 *, uint8_t id); + +/** @brief Reset AX12 back to factory settings */ +uint8_t AX12_reset(AX12 *, uint8_t id); + +#endif/*_AX12_H */ ================================================== aversive/modules/devices/servo/ax12/ax12_address.h (1.1.4.2) ================================================== @@ -0,0 +1,60 @@ +#ifndef _AX12_INSTRUCTIONS_H_ +#define _AX12_INSTRUCTIONS_H_ + +/** @brief AX-12 control table */ +typedef enum _AX12_ADDRESS +{ + AA_MODEL_NUMBER_L = 0x00, + AA_MODEL_NUMBER_H, + AA_FIRMWARE, + AA_ID, + AA_BAUD_RATE, + AA_DELAY_TIME, + AA_CW_ANGLE_LIMIT_L, + AA_CW_ANGLE_LIMIT_H, + AA_CCW_ANGLE_LIMIT_L, + AA_CCW_ANGLE_LIMIT_H, + AA_RESERVED_1, + AA_HIGHEST_LIMIT_TEMP, + AA_LOWEST_LIMIT_VOLTAGE, + AA_HIGHEST_LIMIT_VOLTAGE, + AA_MAX_TORQUE_L, + AA_MAX_TORQUE_H, + AA_STATUS_RETURN_LEVEL, + AA_ALARM_LED, + AA_ALARM_SHUTDOWN, + AA_RESERVED_2, + AA_DOWN_CALIBRATION_L, + AA_DOWN_CALIBRATION_H, + AA_UP_CALIBRATION_L, + AA_UP_CALIBRATION_H, + AA_TORQUE_ENABLE, + AA_LED, + AA_CW_COMPLIANCE_MARGIN, + AA_CCW_COMPLIANCE_MARGIN, + AA_CW_COMPLIANCE_SLOPE, + AA_CCW_COMPLIANCE_SLOPE, + AA_GOAL_POSITION_L, + AA_GOAL_POSITION_H, + AA_MOVING_SPEED_L, + AA_MOVING_SPEED_H, + AA_TORQUE_LIMIT_L, + AA_TORQUE_LIMIT_H, + AA_PRESENT_POSITION_L, + AA_PRESENT_POSITION_H, + AA_PRESENT_SPEED_L, + AA_PRESENT_SPEED_H, + AA_PRESENT_LOAD_L, + AA_PRESENT_LOAD_H, + AA_PRESENT_VOLTAGE, + AA_PRESENT_TEMP, + AA_PRESENT_REGINST, + AA_RESERVED_3, + AA_MOVING, + AA_LOCK, + AA_PUNCH_L, + AA_PUNCH_H + +}AX12_ADDRESS; + +#endif/*_AX12_INSTRUCTIONS_H_*/ ======================================================== aversive/modules/devices/servo/ax12/config/ax12_config.h (1.1.4.2) ======================================================== @@ -0,0 +1,7 @@ +#ifndef _AX12_CONFIG_H_ +#define _AX12_CONFIG_H_ + +#define MAX_PARAMS 32 + + +#endif/*_AX12_CONFIG_H_*/ ================================================ aversive/modules/devices/servo/ax12/test/.config (1.1.4.2) ================================================ @@ -0,0 +1,226 @@ +# +# Automatically generated by make menuconfig: don't edit +# + +# +# Hardware +# +# CONFIG_MCU_AT90S2313 is not set +# CONFIG_MCU_AT90S2323 is not set +# CONFIG_MCU_AT90S3333 is not set +# CONFIG_MCU_AT90S2343 is not set +# CONFIG_MCU_ATTINY22 is not set +# CONFIG_MCU_ATTINY26 is not set +# CONFIG_MCU_AT90S4414 is not set +# CONFIG_MCU_AT90S4433 is not set +# CONFIG_MCU_AT90S4434 is not set +# CONFIG_MCU_AT90S8515 is not set +# CONFIG_MCU_AT90S8534 is not set +# CONFIG_MCU_AT90S8535 is not set +# CONFIG_MCU_AT86RF401 is not set +# CONFIG_MCU_ATMEGA103 is not set +# CONFIG_MCU_ATMEGA603 is not set +# CONFIG_MCU_AT43USB320 is not set +# CONFIG_MCU_AT43USB355 is not set +# CONFIG_MCU_AT76C711 is not set +# CONFIG_MCU_ATMEGA8 is not set +# CONFIG_MCU_ATMEGA48 is not set +# CONFIG_MCU_ATMEGA88 is not set +# CONFIG_MCU_ATMEGA8515 is not set +# CONFIG_MCU_ATMEGA8535 is not set +# CONFIG_MCU_ATTINY13 is not set +# CONFIG_MCU_ATTINY2313 is not set +# CONFIG_MCU_ATMEGA16 is not set +# CONFIG_MCU_ATMEGA161 is not set +# CONFIG_MCU_ATMEGA162 is not set +# CONFIG_MCU_ATMEGA163 is not set +# CONFIG_MCU_ATMEGA165 is not set +# CONFIG_MCU_ATMEGA168 is not set +# CONFIG_MCU_ATMEGA169 is not set +# CONFIG_MCU_ATMEGA32 is not set +# CONFIG_MCU_ATMEGA323 is not set +# CONFIG_MCU_ATMEGA325 is not set +# CONFIG_MCU_ATMEGA3250 is not set +# CONFIG_MCU_ATMEGA64 is not set +# CONFIG_MCU_ATMEGA645 is not set +# CONFIG_MCU_ATMEGA6450 is not set +CONFIG_MCU_ATMEGA128=y +# CONFIG_MCU_AT90CAN128 is not set +# CONFIG_MCU_AT94K is not set +# CONFIG_MCU_AT90S1200 is not set +CONFIG_QUARTZ=16000000 + +# +# Generation options +# +# CONFIG_OPTM_0 is not set +# CONFIG_OPTM_1 is not set +# CONFIG_OPTM_2 is not set +# CONFIG_OPTM_3 is not set +CONFIG_OPTM_S=y +CONFIG_MATH_LIB=y +# CONFIG_FDEVOPEN_COMPAT is not set +# CONFIG_MINIMAL_PRINTF is not set +CONFIG_STANDARD_PRINTF=y +# CONFIG_ADVANCED_PRINTF is not set +CONFIG_FORMAT_IHEX=y +# CONFIG_FORMAT_SREC is not set +# CONFIG_FORMAT_BINARY is not set + +# +# Base modules +# +CONFIG_MODULE_CIRBUF=y +# CONFIG_MODULE_CIRBUF_LARGE is not set +# CONFIG_MODULE_FIXED_POINT is not set +# CONFIG_MODULE_VECT2 is not set +# CONFIG_MODULE_SCHEDULER is not set +# CONFIG_MODULE_SCHEDULER_CREATE_CONFIG is not set +# CONFIG_MODULE_SCHEDULER_USE_TIMERS is not set +CONFIG_MODULE_SCHEDULER_TIMER0=y +# CONFIG_MODULE_SCHEDULER_MANUAL is not set +# CONFIG_MODULE_TIME is not set +# CONFIG_MODULE_TIME_CREATE_CONFIG is not set + +# +# Communication modules +# +CONFIG_MODULE_UART=y +CONFIG_MODULE_UART_CREATE_CONFIG=y +# CONFIG_MODULE_I2C is not set +# CONFIG_MODULE_I2C_MASTER is not set +# CONFIG_MODULE_I2C_MULTIMASTER is not set +# CONFIG_MODULE_I2C_CREATE_CONFIG is not set +# CONFIG_MODULE_MF2_CLIENT is not set +# CONFIG_MODULE_MF2_CLIENT_USE_SCHEDULER is not set +# CONFIG_MODULE_MF2_CLIENT_CREATE_CONFIG is not set +# CONFIG_MODULE_MF2_SERVER is not set +# CONFIG_MODULE_MF2_SERVER_CREATE_CONFIG is not set + +# +# Hardware modules +# +# CONFIG_MODULE_TIMER is not set +# CONFIG_MODULE_TIMER_CREATE_CONFIG is not set +# CONFIG_MODULE_TIMER_DYNAMIC is not set +# CONFIG_MODULE_PWM is not set +# CONFIG_MODULE_PWM_CREATE_CONFIG is not set +# CONFIG_MODULE_ADC is not set +# CONFIG_MODULE_ADC_CREATE_CONFIG is not set + +# +# IHM modules +# +# CONFIG_MODULE_MENU is not set +CONFIG_MODULE_VT100=y +CONFIG_MODULE_RDLINE=y +CONFIG_MODULE_RDLINE_CREATE_CONFIG=y +CONFIG_MODULE_RDLINE_KILL_BUF=y +CONFIG_MODULE_RDLINE_HISTORY=y +CONFIG_MODULE_PARSE=y + +# +# External devices modules +# +# CONFIG_MODULE_LCD is not set +# CONFIG_MODULE_LCD_CREATE_CONFIG is not set +# CONFIG_MODULE_MULTISERVO is not set +# CONFIG_MODULE_MULTISERVO_CREATE_CONFIG is not set +CONFIG_MODULE_AX12=y +CONFIG_MODULE_AX12_CREATE_CONFIG=y + +# +# Brushless motor drivers (you should enable pwm modules to see all) +# +# CONFIG_MODULE_BRUSHLESS_3PHASE_DIGITAL_HALL is not set +# CONFIG_MODULE_BRUSHLESS_3PHASE_DIGITAL_HALL_CREATE_CONFIG is not set +# CONFIG_MODULE_BRUSHLESS_3PHASE_DIGITAL_HALL_DOUBLE is not set +# CONFIG_MODULE_BRUSHLESS_3PHASE_DIGITAL_HALL_DOUBLE_CREATE_CONFIG is not set + +# +# Encoders +# +# CONFIG_MODULE_ENCODERS_MICROB is not set +# CONFIG_MODULE_ENCODERS_MICROB_CREATE_CONFIG is not set +# CONFIG_MODULE_ENCODERS_EIRBOT is not set +# CONFIG_MODULE_ENCODERS_EIRBOT_CREATE_CONFIG is not set + +# +# Robot specific modules +# +# CONFIG_MODULE_ROBOT_SYSTEM is not set +# CONFIG_MODULE_ROBOT_SYSTEM_MOT_AND_EXT is not set +# CONFIG_MODULE_POSITION_MANAGER is not set +# CONFIG_MODULE_TRAJECTORY_MANAGER is not set +# CONFIG_MODULE_BLOCKING_DETECTION_MANAGER is not set +# CONFIG_MODULE_OBSTACLE_AVOIDANCE is not set + +# +# Control system modules +# +# CONFIG_MODULE_CONTROL_SYSTEM_MANAGER is not set +# CONFIG_MODULE_PID is not set +# CONFIG_MODULE_PID_CREATE_CONFIG is not set +# CONFIG_MODULE_RAMP is not set +# CONFIG_MODULE_QUADRAMP is not set +# CONFIG_MODULE_QUADRAMP_DERIVATE is not set +# CONFIG_MODULE_BIQUAD is not set + +# +# Crypto modules +# +# CONFIG_MODULE_AES is not set +# CONFIG_MODULE_AES_CTR is not set +# CONFIG_MODULE_MD5 is not set +# CONFIG_MODULE_MD5_HMAC is not set +# CONFIG_MODULE_RC4 is not set + +# +# Encodings modules +# +# CONFIG_MODULE_BASE64 is not set +# CONFIG_MODULE_HAMMING is not set + +# +# Debug modules +# +# CONFIG_MODULE_DIAGNOSTIC is not set +# CONFIG_MODULE_DIAGNOSTIC_CREATE_CONFIG is not set +CONFIG_MODULE_ERROR=y +CONFIG_MODULE_ERROR_CREATE_CONFIG=y + +# +# Programmer options +# +CONFIG_AVRDUDE=y +# CONFIG_AVARICE is not set + +# +# Avrdude +# +# CONFIG_AVRDUDE_PROG_FUTURELEC is not set +# CONFIG_AVRDUDE_PROG_ABCMINI is not set +# CONFIG_AVRDUDE_PROG_PICOWEB is not set +# CONFIG_AVRDUDE_PROG_SP12 is not set +# CONFIG_AVRDUDE_PROG_ALF is not set +# CONFIG_AVRDUDE_PROG_BASCOM is not set +# CONFIG_AVRDUDE_PROG_DT006 is not set +# CONFIG_AVRDUDE_PROG_PONY_STK200 is not set +CONFIG_AVRDUDE_PROG_STK200=y +# CONFIG_AVRDUDE_PROG_PAVR is not set +# CONFIG_AVRDUDE_PROG_BUTTERFLY is not set +# CONFIG_AVRDUDE_PROG_AVR910 is not set +# CONFIG_AVRDUDE_PROG_STK500 is not set +# CONFIG_AVRDUDE_PROG_AVRISP is not set +# CONFIG_AVRDUDE_PROG_BSD is not set +# CONFIG_AVRDUDE_PROG_DAPA is not set +# CONFIG_AVRDUDE_PROG_JTAG1 is not set +CONFIG_AVRDUDE_PORT="/dev/.static/dev/parport0" + +# +# Avarice +# +CONFIG_AVARICE_PORT="/dev/ttyS0" +CONFIG_AVARICE_DEBUG_PORT=1234 +CONFIG_AVARICE_PROG_MKI=y +# CONFIG_AVARICE_PROG_MKII is not set ================================================= aversive/modules/devices/servo/ax12/test/Makefile (1.1.4.2) ================================================= @@ -0,0 +1,22 @@ +TARGET = main + +# repertoire des modules +AVERSIVE_DIR = ../../../../.. +# VALUE, absolute or relative path : example ../.. # + +# List C source files here. (C dependencies are automatically generated.) +SRC = commands.c $(TARGET).c + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + +######################################## + +-include .aversive_conf +include $(AVERSIVE_DIR)/mk/aversive_project.mk ====================================================== aversive/modules/devices/servo/ax12/test/ax12_config.h (1.1.4.2) ====================================================== @@ -0,0 +1,7 @@ +#ifndef _AX12_CONFIG_H_ +#define _AX12_CONFIG_H_ + +#define MAX_PARAMS 32 + + +#endif/*_AX12_CONFIG_H_*/ =================================================== aversive/modules/devices/servo/ax12/test/commands.c (1.1.2.1) =================================================== @@ -0,0 +1,345 @@ +/* + * Copyright Droids Corporation (2008) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Revision : $Id: commands.c,v 1.1.2.1 2008-10-26 21:59:28 zer0 Exp $ + * + * Olivier MATZ <[EMAIL PROTECTED]> + */ + +#include <stdio.h> +#include <string.h> + +#include <aversive/pgmspace.h> +#include <aversive/wait.h> + +#include <ax12.h> +#include <parse.h> +#include <parse_num.h> +#include <parse_string.h> + +extern AX12 ax12; + +uint8_t addr_from_string(const char *s) +{ + /* 16 bits */ + if (!strcmp_P(s, PSTR("cw_angle_limit"))) + return AA_CW_ANGLE_LIMIT_L; + if (!strcmp_P(s, PSTR("ccw_angle_limit"))) + return AA_CCW_ANGLE_LIMIT_L; + if (!strcmp_P(s, PSTR("max_torque"))) + return AA_MAX_TORQUE_L; + if (!strcmp_P(s, PSTR("down_calibration"))) + return AA_DOWN_CALIBRATION_L; + if (!strcmp_P(s, PSTR("up_calibration"))) + return AA_UP_CALIBRATION_L; + if (!strcmp_P(s, PSTR("torque_limit"))) + return AA_TORQUE_LIMIT_L; + if (!strcmp_P(s, PSTR("position"))) + return AA_PRESENT_POSITION_L; + if (!strcmp_P(s, PSTR("speed"))) + return AA_PRESENT_SPEED_L; + if (!strcmp_P(s, PSTR("load"))) + return AA_PRESENT_LOAD_L; + if (!strcmp_P(s, PSTR("moving_speed"))) + return AA_MOVING_SPEED_L; + if (!strcmp_P(s, PSTR("model"))) + return AA_MODEL_NUMBER_L; + if (!strcmp_P(s, PSTR("goal_pos"))) + return AA_GOAL_POSITION_L; + if (!strcmp_P(s, PSTR("punch"))) + return AA_PUNCH_L; + + /* 8 bits */ + if (!strcmp_P(s, PSTR("firmware"))) + return AA_MOVING_SPEED_L; + if (!strcmp_P(s, PSTR("id"))) + return AA_MOVING_SPEED_L; + if (!strcmp_P(s, PSTR("baudrate"))) + return AA_BAUD_RATE; + if (!strcmp_P(s, PSTR("delay"))) + return AA_DELAY_TIME; + if (!strcmp_P(s, PSTR("high_lim_temp"))) + return AA_HIGHEST_LIMIT_TEMP; + if (!strcmp_P(s, PSTR("low_lim_volt"))) + return AA_LOWEST_LIMIT_VOLTAGE; + if (!strcmp_P(s, PSTR("high_lim_volt"))) + return AA_HIGHEST_LIMIT_VOLTAGE; + if (!strcmp_P(s, PSTR("status_return"))) + return AA_STATUS_RETURN_LEVEL; + if (!strcmp_P(s, PSTR("alarm_led"))) + return AA_ALARM_LED; + if (!strcmp_P(s, PSTR("alarm_shutdown"))) + return AA_ALARM_SHUTDOWN; + if (!strcmp_P(s, PSTR("torque_enable"))) + return AA_TORQUE_ENABLE; + if (!strcmp_P(s, PSTR("led"))) + return AA_LED; + if (!strcmp_P(s, PSTR("cw_comp_margin"))) + return AA_CW_COMPLIANCE_MARGIN; + if (!strcmp_P(s, PSTR("ccw_comp_margin"))) + return AA_CCW_COMPLIANCE_MARGIN; + if (!strcmp_P(s, PSTR("cw_comp_slope"))) + return AA_CW_COMPLIANCE_SLOPE; + if (!strcmp_P(s, PSTR("ccw_comp_slope"))) + return AA_CCW_COMPLIANCE_SLOPE; + if (!strcmp_P(s, PSTR("voltage"))) + return AA_PRESENT_VOLTAGE; + if (!strcmp_P(s, PSTR("temp"))) + return AA_PRESENT_TEMP; + if (!strcmp_P(s, PSTR("reginst"))) + return AA_PRESENT_REGINST; + if (!strcmp_P(s, PSTR("moving"))) + return AA_MOVING; + if (!strcmp_P(s, PSTR("lock"))) + return AA_LOCK; + + return 0; +} + + + +/**********************************************************/ +/* Reset */ + +/* this structure is filled when cmd_reset is parsed successfully */ +struct cmd_reset_result { + fixed_string_t arg0; +}; + +/* function called when cmd_reset is parsed successfully */ +static void cmd_reset_parsed(void * parsed_result, void * data) +{ + reset(); +} + +prog_char str_reset_arg0[] = "reset"; +parse_pgm_token_string_t cmd_reset_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_reset_result, arg0, str_reset_arg0); + +prog_char help_reset[] = "Reset the board"; +parse_pgm_inst_t cmd_reset = { + .f = cmd_reset_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_reset, + .tokens = { /* token list, NULL terminated */ + (prog_void *)&cmd_reset_arg0, + NULL, + }, +}; + +/**********************************************************/ +/* Test */ + +/* this structure is filled when cmd_test is parsed successfully */ +struct cmd_test_result { + fixed_string_t arg0; +}; + +/* function called when cmd_test is parsed successfully */ +static void cmd_test_parsed(void * parsed_result, void * data) +{ + /* Set some AX12 parameters */ + AX12_write_int(&ax12,0xFE,AA_PUNCH_L,0x20); + AX12_write_int(&ax12,0xFE,AA_TORQUE_LIMIT_L,0x3FF); + AX12_write_int(&ax12,0xFE,AA_MOVING_SPEED_L,0x2FF); + AX12_write_byte(&ax12,0xFE,AA_ALARM_LED,0xEF); + + AX12_set_position(&ax12,0xFE,0x1FF - 0x130); + wait_ms(800); + AX12_set_position(&ax12,0xFE,0x1FF + 0x130); + wait_ms(800); +} + +prog_char str_test_arg0[] = "test"; +parse_pgm_token_string_t cmd_test_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_test_result, arg0, str_test_arg0); + +prog_char help_test[] = "Test func"; +parse_pgm_inst_t cmd_test = { + .f = cmd_test_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_test, + .tokens = { /* token list, NULL terminated */ + (prog_void *)&cmd_test_arg0, + NULL, + }, +}; + +/**********************************************************/ +/* Uint16 */ + + +/* this structure is filled when cmd_uint16_read is parsed successfully */ +struct cmd_uint16_result { + fixed_string_t arg0; + fixed_string_t arg1; + uint8_t num; + uint16_t val; +}; + +/* function called when cmd_uint16_read is parsed successfully */ +static void cmd_uint16_read_parsed(void * parsed_result, void * data) +{ + struct cmd_uint16_result *res = parsed_result; + uint16_t val; + uint8_t addr = addr_from_string(res->arg1); + val = AX12_read_int(&ax12, res->num, addr); + printf_P(PSTR("%s: %d [0x%.4x]\r\n"), res->arg1, val, val); +} + +prog_char str_uint16_arg0[] = "read"; +parse_pgm_token_string_t cmd_uint16_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_uint16_result, arg0, str_uint16_arg0); +prog_char str_uint16_arg1[] = "moving_speed#model#goal_pos#cw_angle_limit#ccw_angle_limit#" + "max_torque#down_calibration#up_calibration#torque_limit#" + "position#speed#load#punch"; +parse_pgm_token_string_t cmd_uint16_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_uint16_result, arg1, str_uint16_arg1); +parse_pgm_token_num_t cmd_uint16_num = TOKEN_NUM_INITIALIZER(struct cmd_uint16_result, num, UINT8); + +prog_char help_uint16_read[] = "Read uint16 value (type, num)"; +parse_pgm_inst_t cmd_uint16_read = { + .f = cmd_uint16_read_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_uint16_read, + .tokens = { /* token list, NULL terminated */ + (prog_void *)&cmd_uint16_arg0, + (prog_void *)&cmd_uint16_arg1, + (prog_void *)&cmd_uint16_num, + NULL, + }, +}; + +/* function called when cmd_uint16_write is parsed successfully */ +static void cmd_uint16_write_parsed(void * parsed_result, void * data) +{ + struct cmd_uint16_result *res = parsed_result; + uint8_t addr = addr_from_string(res->arg1); + printf_P(PSTR("writing %s: %d [0x%.4x]\r\n"), res->arg1, + res->val, res->val); + AX12_write_int(&ax12, res->num, addr, res->val); + /* XXX check error ? */ +} + +prog_char str_uint16_arg0_w[] = "write"; +parse_pgm_token_string_t cmd_uint16_arg0_w = TOKEN_STRING_INITIALIZER(struct cmd_uint16_result, arg0, str_uint16_arg0_w); +prog_char str_uint16_arg1_w[] = "moving_speed#goal_pos#cw_angle_limit#ccw_angle_limit#" + "max_torque#torque_limit#punch"; +parse_pgm_token_string_t cmd_uint16_arg1_w = TOKEN_STRING_INITIALIZER(struct cmd_uint16_result, arg1, str_uint16_arg1_w); +parse_pgm_token_num_t cmd_uint16_val = TOKEN_NUM_INITIALIZER(struct cmd_uint16_result, val, UINT16); + +prog_char help_uint16_write[] = "Write uint16 value (write, num, val)"; +parse_pgm_inst_t cmd_uint16_write = { + .f = cmd_uint16_write_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_uint16_write, + .tokens = { /* token list, NULL terminated */ + (prog_void *)&cmd_uint16_arg0_w, + (prog_void *)&cmd_uint16_arg1_w, + (prog_void *)&cmd_uint16_num, + (prog_void *)&cmd_uint16_val, + NULL, + }, +}; + +/**********************************************************/ +/* Uint8 */ + + +/* this structure is filled when cmd_uint8_read is parsed successfully */ +struct cmd_uint8_result { + fixed_string_t arg0; + fixed_string_t arg1; + uint8_t num; + uint8_t val; +}; + +/* function called when cmd_uint8_read is parsed successfully */ +static void cmd_uint8_read_parsed(void * parsed_result, void * data) +{ + struct cmd_uint8_result *res = parsed_result; + uint8_t val; + uint8_t addr = addr_from_string(res->arg1); + val = AX12_read_int(&ax12, res->num, addr); + printf_P(PSTR("%s: %s [0x%.2x]\r\n"), res->arg1, val, val); +} + +prog_char str_uint8_arg0[] = "read"; +parse_pgm_token_string_t cmd_uint8_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_uint8_result, arg0, str_uint8_arg0); +prog_char str_uint8_arg1[] = "id#firmware#baudrate#delay#high_lim_temp#" + "low_lim_volt#high_lim_volt#status_return#alarm_led#" + "alarm_shutdown#torque_enable#led#cw_comp_margin#" + "ccw_comp_margin#cw_comp_slope#ccw_comp_slope#" + "voltage#temp#reginst#moving#lock"; +parse_pgm_token_string_t cmd_uint8_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_uint8_result, arg1, str_uint8_arg1); +parse_pgm_token_num_t cmd_uint8_num = TOKEN_NUM_INITIALIZER(struct cmd_uint8_result, num, UINT8); + +prog_char help_uint8_read[] = "Read uint8 value (type, num)"; +parse_pgm_inst_t cmd_uint8_read = { + .f = cmd_uint8_read_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_uint8_read, + .tokens = { /* token list, NULL terminated */ + (prog_void *)&cmd_uint8_arg0, + (prog_void *)&cmd_uint8_arg1, + (prog_void *)&cmd_uint8_num, + NULL, + }, +}; + +/* function called when cmd_uint8_write is parsed successfully */ +static void cmd_uint8_write_parsed(void * parsed_result, void * data) +{ + struct cmd_uint8_result *res = parsed_result; + uint8_t addr = addr_from_string(res->arg1); + printf_P(PSTR("writing %s: %d [0x%.2x]\r\n"), res->arg1, + res->val, res->val); + AX12_write_int(&ax12, res->num, addr, res->val); + /* XXX check error ? */ +} + +prog_char str_uint8_arg0_w[] = "write"; +parse_pgm_token_string_t cmd_uint8_arg0_w = TOKEN_STRING_INITIALIZER(struct cmd_uint8_result, arg0, str_uint8_arg0_w); +prog_char str_uint8_arg1_w[] = "id#baudrate#delay#high_lim_temp#" + "low_lim_volt#high_lim_volt#status_return#alarm_led#" + "alarm_shutdown#torque_enable#led#cw_comp_margin#" + "ccw_comp_margin#cw_comp_slope#ccw_comp_slope#" + "reginst#lock"; +parse_pgm_token_string_t cmd_uint8_arg1_w = TOKEN_STRING_INITIALIZER(struct cmd_uint8_result, arg1, str_uint8_arg1_w); +parse_pgm_token_num_t cmd_uint8_val = TOKEN_NUM_INITIALIZER(struct cmd_uint8_result, val, UINT8); + +prog_char help_uint8_write[] = "Write uint8 value (write, num, val)"; +parse_pgm_inst_t cmd_uint8_write = { + .f = cmd_uint8_write_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_uint8_write, + .tokens = { /* token list, NULL terminated */ + (prog_void *)&cmd_uint8_arg0_w, + (prog_void *)&cmd_uint8_arg1_w, + (prog_void *)&cmd_uint8_num, + (prog_void *)&cmd_uint8_val, + NULL, + }, +}; + + +/* in progmem */ +parse_pgm_ctx_t main_ctx[] = { + (parse_pgm_inst_t *)&cmd_reset, + (parse_pgm_inst_t *)&cmd_test, + (parse_pgm_inst_t *)&cmd_uint16_read, + (parse_pgm_inst_t *)&cmd_uint16_write, + (parse_pgm_inst_t *)&cmd_uint8_read, + (parse_pgm_inst_t *)&cmd_uint8_write, + NULL, +}; ======================================================= aversive/modules/devices/servo/ax12/test/error_config.h (1.1.4.2) ======================================================= @@ -0,0 +1,31 @@ +/* + * Copyright Droids Corporation, Microb Technology, Eirbot (2005) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Revision : $Id: error_config.h,v 1.1.4.2 2008-10-26 21:59:28 zer0 Exp $ + * + */ + +#ifndef _ERROR_CONFIG_ +#define _ERROR_CONFIG_ + +/** enable the dump of the comment */ +#define ERROR_DUMP_TEXTLOG + +/** enable the dump of filename and line number */ +#define ERROR_DUMP_FILE_LINE + +#endif =============================================== aversive/modules/devices/servo/ax12/test/main.c (1.1.4.2) =============================================== @@ -0,0 +1,190 @@ +/* + * Copyright Droids Corporation + * Olivier Matz <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Revision : $Id: main.c,v 1.1.4.2 2008-10-26 21:59:28 zer0 Exp $ + * + */ + +/* + * Cmdline interface for AX12. Use the PC to command a daisy-chain of + * AX12 actuators with a nice command line interface. + * + * The circuit should be as following: + * + * |----------| + * | uart1|------->--- PC (baudrate=57600) + * | |-------<--- + * | atmega128| + * | | + * | uart0|---->---+-- AX12 (baudrate 1000000) + * | |----<---| + * |----------| + * + * Note that RX and TX pins of UART0 are connected together to provide + * a half-duplex UART emulation. + * + */ + +#include <stdio.h> +#include <string.h> + +#include <aversive.h> +#include <aversive/pgmspace.h> +#include <aversive/wait.h> + +#include <uart.h> +#include <ax12.h> +#include <parse.h> +#include <rdline.h> + +/* for cmdline interface */ +struct rdline rdl; +char prompt[RDLINE_PROMPT_SIZE]; +extern parse_pgm_ctx_t main_ctx[]; + +/* structure defining the AX12 servo */ +AX12 ax12; + +/******** For cmdline. See in commands.c for the list of commands. */ +static void write_char(char c) +{ + uart1_send(c); +} + +static void +valid_buffer(const char * buf, uint8_t size) +{ + int8_t ret; + ret = parse(main_ctx, buf); + if (ret == PARSE_AMBIGUOUS) + printf_P(PSTR("Ambiguous command\r\n")); + else if (ret == PARSE_NOMATCH) + printf_P(PSTR("Command not found\r\n")); + else if (ret == PARSE_BAD_ARGS) + printf_P(PSTR("Bad arguments\r\n")); +} + +static int8_t +complete_buffer(const char * buf, char * dstbuf, uint8_t dstsize, + int16_t * state) +{ + return complete(main_ctx, buf, state, dstbuf, dstsize); +} + +/********************************* AX12 commands */ + +/* + * --- use uart0 + * + * We use synchronous access (not interrupt driven) to the hardware + * UART, because we have to be sure that the transmission/reception is + * really finished when we return from the functions. + * + * We don't use the CM-5 circuit as described in the AX12 + * documentation, we simply connect TX and RX and use TXEN + RXEN + + * DDR to manage the port directions. + */ + +#define UCSRnA UCSR0A +#define UCSRnB UCSR0B +#define UDRn UDR0 +#define UDREn UDRE0 +#define TXCn TXC0 +#define RXCn RXC0 + +static void ax12_send_char(uint8_t c) +{ + sbi(UCSRnA,TXCn); + while(!(UCSRnA & (1<<UDREn))) nop(); + UDRn = c; + while((UCSRnA & (1<<TXCn)) == 0) nop(); +} + +static uint8_t ax12_recv_char(void) +{ + while((UCSRnA & (1<<RXCn)) == 0) nop(); + return UDRn; +} + +static void ax12_switch_uart(uint8_t state) +{ + if (state == AX12_STATE_WRITE) { + UCSRnB &= ~(1<<RXEN); + UCSRnB |= (1<<TXEN); + } + else { + UCSRnB &= ~(1<<TXEN); + UCSRnB |= (1<<RXEN); + } +} + +/***********************/ + +/* TODO: + * - uart rx interrupt must be disabled manually... :( + * - use the Wundef option + * - rx timeout ? + * - provide a miniuart ? + * - check errors and display them + */ + +int main(void) +{ + int c; + const char * history; + int8_t ret; + + wait_ms(1000); + + uart_init(); + /* disable rx intr, needed !! */ + UCSRnB &= ~(1 << RXCIE); + + AX12_init(&ax12); + AX12_set_hardware_send(&ax12, ax12_send_char); + AX12_set_hardware_recv(&ax12, ax12_recv_char); + AX12_set_hardware_switch(&ax12, ax12_switch_uart); + + fdevopen(uart1_dev_send, uart1_dev_recv); + + sei(); + + /* set status return level to 2 */ + AX12_write_byte(&ax12, 0xFE, AA_STATUS_RETURN_LEVEL, 2); + + rdline_init(&rdl, write_char, valid_buffer, complete_buffer); + snprintf(prompt, sizeof(prompt), "ax12 > "); + rdline_newline(&rdl, prompt); + + /* waiting for commands now... */ + + while (1) { + c = uart1_recv_nowait(); + if (c == -1) + continue; + ret = rdline_char_in(&rdl, c); + if (ret != 2 && ret != 0) { + history = rdline_get_buffer(&rdl); + if (strlen(history)>1) + rdline_add_history(&rdl, history); + rdline_newline(&rdl, prompt); + } + } + + return 0; +} ======================================================== aversive/modules/devices/servo/ax12/test/rdline_config.h (1.1.2.1) ======================================================== ====================================================== aversive/modules/devices/servo/ax12/test/uart_config.h (1.1.4.2) ====================================================== @@ -0,0 +1,102 @@ +/* + * Copyright Droids Corporation, Microb Technology, Eirbot (2005) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Revision : $Id: uart_config.h,v 1.1.4.2 2008-10-26 21:59:28 zer0 Exp $ + * + */ + +/* Droids-corp 2004 - Zer0 + * config for uart module + */ + +#ifndef UART_CONFIG_H +#define UART_CONFIG_H + +/* compile uart0 fonctions, undefine it to pass compilation */ +#define UART0_COMPILE + +/* enable uart0 if == 1, disable if == 0 */ +#define UART0_ENABLED 1 + +/* enable uart0 interrupts if == 1, disable if == 0 */ +#define UART0_INTERRUPT_ENABLED 1 + +#define UART0_BAUDRATE 1000000 + +/* + * if you enable this, the maximum baudrate you can reach is + * higher, but the precision is lower. + */ +#define UART0_USE_DOUBLE_SPEED 0 +//#define UART0_USE_DOUBLE_SPEED 1 + +#define UART0_RX_FIFO_SIZE 32 +#define UART0_TX_FIFO_SIZE 16 +//#define UART0_NBITS 5 +//#define UART0_NBITS 6 +//#define UART0_NBITS 7 +#define UART0_NBITS 8 +//#define UART0_NBITS 9 + +#define UART0_PARITY UART_PARTITY_NONE +//#define UART0_PARITY UART_PARTITY_ODD +//#define UART0_PARITY UART_PARTITY_EVEN + +#define UART0_STOP_BIT UART_STOP_BITS_1 +//#define UART0_STOP_BIT UART_STOP_BITS_2 + + +/* + * UART1 definitions + */ + +/* compile uart1 fonctions, undefine it to pass compilation */ +#define UART1_COMPILE + +/* enable uart1 if == 1, disable if == 0 */ +#define UART1_ENABLED 1 + +/* enable uart1 interrupts if == 1, disable if == 0 */ +#define UART1_INTERRUPT_ENABLED 1 + +#define UART1_BAUDRATE 57600 + +/* + * if you enable this, the maximum baudrate you can reach is + * higher, but the precision is lower. + */ +#define UART1_USE_DOUBLE_SPEED 0 +//#define UART1_USE_DOUBLE_SPEED 1 + +#define UART1_RX_FIFO_SIZE 4 +#define UART1_TX_FIFO_SIZE 4 +//#define UART1_NBITS 5 +//#define UART1_NBITS 6 +//#define UART1_NBITS 7 +#define UART1_NBITS 8 +//#define UART1_NBITS 9 + +#define UART1_PARITY UART_PARTITY_NONE +//#define UART1_PARITY UART_PARTITY_ODD +//#define UART1_PARITY UART_PARTITY_EVEN + +#define UART1_STOP_BIT UART_STOP_BITS_1 +//#define UART1_STOP_BIT UART_STOP_BITS_2 + + +#endif + _______________________________________________ Avr-list mailing list Avr-list@droids-corp.org CVSWEB : http://cvsweb.droids-corp.org/cgi-bin/viewcvs.cgi/aversive WIKI : http://wiki.droids-corp.org/index.php/Aversive DOXYGEN : http://zer0.droids-corp.org/doxygen_aversive/html/ BUGZILLA : http://bugzilla.droids-corp.org COMMIT LOGS : http://zer0.droids-corp.org/aversive_commitlog