vt100: include pgmspace.h as we use PROGMEM macro
[aversive.git] / modules / devices / servo / ax12 / ax12.h
1 /*  
2  *  Copyright Droids Corporation, Microb Technology, Eirbot (2008)
3  *  JD Brossillon <jean.damien.brossillon@gmail.com>  (main job)
4  *  Olivier Matz <zer0@droids-corp.org>               (clean-up, fixes)
5  * 
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  Revision : $Id: ax12.h,v 1.1.4.4 2009-04-07 20:00:57 zer0 Exp $
21  *
22  */
23
24 /** 
25  * @file ax12.h
26  *
27  * @brief This module provides functions for using a Robotis Dynamixel
28  *  AX-12 numeric actuator
29  *
30  * @todo
31  * - Manage the "Status Return Level"
32  *
33  * AX12 servos uses a half duplex uart. This means that there is only
34  * one line that is used for both transmitting and receiving. Refer to
35  * the AX12 documentation for more informations.
36  * 
37  * This module doesn't need ATmega's uart, user have to provide
38  * 3 functions to control the half duplex uart:
39  *  - send char.
40  *  - write char.
41  *  - switch direction
42  *
43  * These functions may use (or not) the AVR uart. Have a look to the
44  * test program in test/ directory for an example.
45  */
46
47 #ifndef _AX12_H_
48 #define _AX12_H_
49
50 #include <aversive.h>
51 #include <stdlib.h> 
52
53 #include "ax12_address.h"
54 #include "ax12_config.h"
55
56 /*__________________________________________*/
57
58 /* Half duplex uart switch */
59 #define AX12_STATE_READ  0
60 #define AX12_STATE_WRITE 1
61
62 /* Error bits */
63 #define AX12_ERROR_BIT_VOLTAGE      0
64 #define AX12_ERROR_BIT_ANGLE_LIMIT  1
65 #define AX12_ERROR_BIT_OVERHEAT     2
66 #define AX12_ERROR_BIT_RANGE        3
67 #define AX12_ERROR_BIT_CHECKSUM     4
68 #define AX12_ERROR_BIT_OVERLOAD     5
69 #define AX12_ERROR_BIT_INSTRUCTION  6
70
71 /* Other error types when bit 7 id 1 */
72 #define AX12_ERROR_TYPE_NO_ANSWER       0xff 
73 #define AX12_ERROR_TYPE_TIMEOUT         0xfe 
74 #define AX12_ERROR_TYPE_INVALID_PACKET  0xfd 
75 #define AX12_ERROR_TYPE_XMIT_FAILED     0xfc
76 #define AX12_ERROR_TYPE_BAD_CKSUM       0xfb
77
78 /* Address (see ax12_address.h) */
79 #define AX12_BROADCAST_ID 0xFE
80
81 /* AX-12 instruction set */
82 #define AX12_PING       0x01
83 #define AX12_READ       0x02
84 #define AX12_WRITE      0x03
85 #define AX12_REG_WRITE  0x04
86 #define AX12_ACTION     0x05
87 #define AX12_RESET      0x06
88 #define AX12_SYNC_WRITE 0x83
89
90 /*__________________________________________*/
91
92 typedef struct AX12
93 {
94         /* function to send a byte to the serial line. Return 0 on
95          * success. */
96         int8_t (*hardware_send)(uint8_t);
97
98         /* synchronously receive a byte from ax12. Return -1 on
99          * timeout, or the received byte. */
100         int16_t (*hardware_recv)(void);
101
102         /* switch the line state (read or write) */
103         void (*hardware_switch)(uint8_t);
104 } AX12;
105
106 typedef struct AX12_Packet
107 {
108         uint8_t id;
109         uint8_t instruction;
110
111         /* Size of AX12_Packet.params */
112         uint8_t nparams;
113         uint8_t params[AX12_MAX_PARAMS];
114
115         /* Used in status packet */
116         uint8_t error;
117
118 } AX12_Packet;
119
120 /*___________ Interface ____________*/
121
122 void AX12_init(AX12 *ax12);
123
124 /*___________ Hardware layer _____________*/
125
126 /** @brief Set the function called when writing a character. */
127 void AX12_set_hardware_send(AX12 *ax12, int8_t(*)(uint8_t));
128
129 /** @brief Set the function called when reading a character. */
130 void AX12_set_hardware_recv(AX12 *ax12, int16_t(*)(void));
131
132 /** @brief Set the function called when switching line direction */
133 void AX12_set_hardware_switch(AX12 *ax12, void(*)(uint8_t));
134
135 /*___________ Low level layer ____________*/
136
137 /** @brief Compute AX12 packet checksum */
138 uint8_t AX12_checksum(AX12_Packet *packet);
139
140 /** @brief Send a formated AX12 instruction packet. Return 0 on
141  *  on success. */
142 uint8_t AX12_send(AX12 *ax12, AX12_Packet *packet);
143
144 /* @brief Receive a formated AX12 status packet. Return 0 on
145  *  on success. */
146 uint8_t AX12_recv(AX12 *ax12, AX12_Packet *packet);
147
148 /*___________ Medium level layer _________*/
149
150 /*
151  * ////////////////// WARNING /////////////////////////
152  *   The following functions assume that AX12 always 
153  *    answer with a status packet
154  *  (Status Return Level = 0x02 in AX12 EEPROM area)
155  * ////////////////// WARNING /////////////////////////
156  */
157
158 /** @brief Write byte in AX-12 memory 
159  * @return Error code from AX-12 (0 means okay) */
160 uint8_t AX12_write_byte(AX12 *ax12, uint8_t id, AX12_ADDRESS address,
161                         uint8_t data);
162
163 /** @brief Write integer (2 bytes) in AX-12 memory 
164  * @return Error code from AX-12 (0 means okay)
165  *
166  * address   : data low
167  * address+1 : data high
168  */
169 uint8_t AX12_write_int(AX12 *ax12, uint8_t id, AX12_ADDRESS address,
170                        uint16_t data);
171
172 /** @brief Read byte from AX-12 memory 
173  * @return Error code from AX-12 (0 means okay) */
174 uint8_t AX12_read_byte(AX12 *ax12, uint8_t id, AX12_ADDRESS address,
175                        uint8_t *val);
176
177 /** @brief Write integer (2 bytes) from AX-12 memory
178  * @return Error code from AX-12 (0 means okay) */
179 uint8_t AX12_read_int(AX12 *ax12, uint8_t id, AX12_ADDRESS address,
180                       uint16_t *val);
181
182 /*___________ High level layer _________*/
183
184 /** @brief Set AX12 position */
185 uint8_t AX12_set_position(AX12 *ax12,uint8_t id, uint16_t position);
186
187 /** @brief Set AX12 position and moving speed */
188 uint8_t AX12_set_position2(AX12 *ax12, uint8_t id, uint16_t position,
189                            uint16_t speed);
190
191 /** @brief Set AX12 position, moving speed and torque */
192 uint8_t AX12_set_position3(AX12 *ax12, uint8_t id, uint16_t position,
193                            uint16_t speed, uint16_t torque);
194
195 /** @brief Read AX12 position */
196 uint8_t AX12_get_position(AX12 *ax12, uint8_t id, uint16_t *pos);
197
198 /** @brief Read AX12 speed */
199 uint8_t AX12_get_speed(AX12 *ax12, uint8_t id, uint16_t *speed);
200
201 /** @brief Read AX12 load */
202 uint8_t AX12_get_load(AX12 *ax12, uint8_t id, uint16_t *load);
203
204
205 /** @brief Ping an AX12 and return error register */
206 uint8_t AX12_ping(AX12 *ax12, uint8_t id);
207
208 /** @brief Reset AX12 back to factory settings */
209 uint8_t AX12_reset(AX12 *ax12, uint8_t id);
210
211 #endif/*_AX12_H */