diff --git a/dynamixel_base/include/dynamixel_master.h b/dynamixel_base/include/dynamixel_master.h index 53345e783e670312770579249a82b04ce1571939..6c8c28e81b7843c9f5e6da55ec95038fdbf56269 100644 --- a/dynamixel_base/include/dynamixel_master.h +++ b/dynamixel_base/include/dynamixel_master.h @@ -62,7 +62,7 @@ typedef struct * \brief * */ - unsigned char received_bytes; + unsigned short int received_bytes; /** * \brief * @@ -92,12 +92,7 @@ typedef struct * \brief * */ - unsigned char sync_num_dev_done; - /** - * \brief - * - */ - unsigned char bulk_num_dev_done; + unsigned char packet_bytes; }TDynamixelMaster; /* public functions */ diff --git a/dynamixel_base/src/dynamixel_master.c b/dynamixel_base/src/dynamixel_master.c index bd61ade6dc3df8bd4ead424cbb43e0e3071522f5..2b3e163eb8f75132b0a2d396a05831ddcc72ea34 100644 --- a/dynamixel_base/src/dynamixel_master.c +++ b/dynamixel_base/src/dynamixel_master.c @@ -7,21 +7,26 @@ unsigned char dyn_master_irq_receive_cb(TDynamixelMaster *dyn_master,unsigned ch { if(dyn_master->comm_dev->time!=0x00000000) time_set_timeout(dyn_master->comm_dev->time,dyn_master->rx_timeout_ms*1000); - switch(dyn_master->received_bytes) + switch(dyn_master->packet_bytes) { case 0: if(byte==0xFF) { dyn_master->rx_buffer[dyn_master->received_bytes]=byte; dyn_master->received_bytes++; + dyn_master->packet_bytes++; } break; case 1: if(byte==0xFF) { dyn_master->rx_buffer[dyn_master->received_bytes]=byte; dyn_master->received_bytes++; + dyn_master->packet_bytes++; } else + { dyn_master->received_bytes--; + dyn_master->packet_bytes--; + } break; case 2: if(byte==0xFD)// version 2 header { @@ -29,44 +34,55 @@ unsigned char dyn_master_irq_receive_cb(TDynamixelMaster *dyn_master,unsigned ch { dyn_master->rx_buffer[dyn_master->received_bytes]=byte; dyn_master->received_bytes++; + dyn_master->packet_bytes++; } else - dyn_master->received_bytes=0;// ignore packet and restart synchronization + { + dyn_master->received_bytes-=2;// ignore packet and restart synchronization + dyn_master->packet_bytes=0; + } } else if(byte!=0xFF) { dyn_master->rx_buffer[dyn_master->received_bytes]=byte; dyn_master->received_bytes++; + dyn_master->packet_bytes++; } break; case 3: dyn_master->rx_buffer[dyn_master->received_bytes]=byte; if(dyn_master->version==DYN_VER1) { dyn_master->op_length=byte; - dyn_master->received_bytes=0; /* finish reception by IRQ */ comm_cancel_irq_receive(dyn_master->comm_dev); /* enable dma RX */ - comm_receive_dma(dyn_master->comm_dev,&dyn_master->rx_buffer[4],dyn_master->op_length); + comm_receive_dma(dyn_master->comm_dev,&dyn_master->rx_buffer[dyn_master->received_bytes+1],dyn_master->op_length); + dyn_master->received_bytes+=dyn_master->op_length+1; + dyn_master->packet_bytes=0; } else + { dyn_master->received_bytes++; + dyn_master->packet_bytes++; + } break; case 4: dyn_master->rx_buffer[dyn_master->received_bytes]=byte; dyn_master->received_bytes++; + dyn_master->packet_bytes++; break; case 5: dyn_master->rx_buffer[dyn_master->received_bytes]=byte; dyn_master->received_bytes++; dyn_master->op_length=byte; + dyn_master->packet_bytes++; break; case 6: dyn_master->rx_buffer[dyn_master->received_bytes]=byte; - dyn_master->received_bytes++; dyn_master->op_length+=(byte<<8); - dyn_master->received_bytes=0; /* finish reception by IRQ */ comm_cancel_irq_receive(dyn_master->comm_dev); /* enable dma RX */ - comm_receive_dma(dyn_master->comm_dev,&dyn_master->rx_buffer[7],dyn_master->op_length); + comm_receive_dma(dyn_master->comm_dev,&dyn_master->rx_buffer[dyn_master->received_bytes+1],dyn_master->op_length); + dyn_master->received_bytes+=dyn_master->op_length+1; + dyn_master->packet_bytes=0; break; default: break; } @@ -102,12 +118,13 @@ unsigned char dyn_master_dma_receive_cb(TDynamixelMaster *dyn_master) if(dyn_master->comm_dev->time!=0x00000000) time_cancel_timeout(dyn_master->comm_dev->time); dyn_master->packet_ready=0x01; + dyn_master->received_bytes=0; } else { /* enable RX interrupts */ comm_receive_irq(dyn_master->comm_dev,0); - dyn_master->packet_ready=0x01; +// dyn_master->packet_ready=0x01; } } @@ -219,6 +236,7 @@ unsigned char dyn_master_wait_reception(TDynamixelMaster *master) } } master->packet_ready=0x00; + return DYN_SUCCESS; // check the input packet checksum if(master->version==DYN_VER1) { @@ -502,7 +520,7 @@ unsigned char dyn_master_start_sync_read(TDynamixelMaster *master,unsigned char unsigned char dyn_master_is_sync_read_done(TDynamixelMaster *master,unsigned char num,unsigned char *ids,unsigned short int address, unsigned short int length, unsigned char * const data[]) { - unsigned char error=DYN_COMM_ERROR; + unsigned char error=DYN_COMM_ERROR,i; if(master!=0x00000000) { @@ -514,49 +532,30 @@ unsigned char dyn_master_is_sync_read_done(TDynamixelMaster *master,unsigned cha // wait for the replay within the given timeout if(master->return_level!=no_return) { - if(master->sync_num_dev_done<num) + if((error=dyn_master_is_reception_done(master))==DYN_SUCCESS) { - if((error=dyn_master_is_reception_done(master))==DYN_SUCCESS) + for(i=0;i<num;i++) { - if(dyn2_check_checksum(master->rx_buffer)==0x01) + if(dyn2_check_checksum(&master->rx_buffer[(length+11)*i])==0x01) { - if((error=dyn2_get_status_error(master->rx_buffer))==DYN_SUCCESS) + if((error=dyn2_get_status_error(&master->rx_buffer[(length+11)*i]))==DYN_NO_ERROR) { - while(dyn2_get_read_status_id(master->rx_buffer)!=ids[master->sync_num_dev_done]) master->sync_num_dev_done++; - if(dyn2_get_read_status_data(master->rx_buffer,(unsigned char *)data[master->sync_num_dev_done])!=length)// not enough data + if(dyn2_get_read_status_data(&master->rx_buffer[(length+11)*i],(unsigned char *)data[i])!=length)// not enough data return DYN_INST_ERROR; - else - { - master->sync_num_dev_done++; - return DYN_BUSY; - } } else - { - master->sync_num_dev_done=0; return error; - } } else - { - master->sync_num_dev_done=0; return DYN_CHECKSUM_ERROR; - } } - else - return error; - } - else - { - master->sync_num_dev_done=0; return DYN_SUCCESS; } + else + return error; } else - { - master->sync_num_dev_done=0; return DYN_SUCCESS; - } } else return error; @@ -656,7 +655,8 @@ unsigned char dyn_master_start_bulk_read(TDynamixelMaster *master,unsigned char unsigned char dyn_master_is_bulk_read_done(TDynamixelMaster *master,unsigned char num,unsigned char *ids,unsigned short int *address, unsigned short int *length, unsigned char * const data[]) { - unsigned char error=DYN_COMM_ERROR; + unsigned char error=DYN_COMM_ERROR,i; + unsigned short int start=0; if(master!=0x00000000) { @@ -665,83 +665,51 @@ unsigned char dyn_master_is_bulk_read_done(TDynamixelMaster *master,unsigned cha // wait for the replay within the given timeout if(master->return_level!=no_return) { - if(master->bulk_num_dev_done<num) + if((error=dyn_master_is_reception_done(master))==DYN_SUCCESS) { - if((error=dyn_master_is_reception_done(master))==DYN_SUCCESS) + for(i=0;i<num;i++) { // check the input packet checksum if(master->version==DYN_VER1) { - if(dyn_check_checksum(master->rx_buffer)==0xFF) + if(dyn_check_checksum(&master->rx_buffer[start])==0xFF) { - if((error=dyn_get_status_error(master->rx_buffer))==DYN_SUCCESS) + if((error=dyn_get_status_error(&master->rx_buffer[start]))==DYN_NO_ERROR) { - std::cout << "RX id: " << (int)dyn_get_read_status_id(master->rx_buffer) << " num. dev: " << (int)master->bulk_num_dev_done << std::endl; - while(dyn_get_read_status_id(master->rx_buffer)!=ids[master->bulk_num_dev_done]) master->bulk_num_dev_done++; - if(dyn_get_read_status_data(master->rx_buffer,(unsigned char *)data[master->bulk_num_dev_done])!=length[master->bulk_num_dev_done])// not enough data + if(dyn_get_read_status_data(&master->rx_buffer[start],(unsigned char *)data[i])!=length[i])// not enough data return DYN_INST_ERROR; - else - { - master->bulk_num_dev_done++; - return DYN_BUSY; - } } else - { - std::cout << "error" << std::endl; - master->bulk_num_dev_done=0; return error; - } } else - { - std::cout << "checksum error" << std::endl; - master->bulk_num_dev_done++; - return DYN_BUSY; - } + return DYN_CHECKSUM_ERROR; + start+=length[i]+6; } else { - if(dyn2_check_checksum(master->rx_buffer)==0x01) + if(dyn2_check_checksum(&master->rx_buffer[start])==0x01) { - if((error=dyn2_get_status_error(master->rx_buffer))==DYN_SUCCESS) + if((error=dyn2_get_status_error(&master->rx_buffer[start]))==DYN_NO_ERROR) { - while(dyn2_get_read_status_id(master->rx_buffer)!=ids[master->bulk_num_dev_done]) master->bulk_num_dev_done++; - if(dyn2_get_read_status_data(master->rx_buffer,(unsigned char *)data[master->bulk_num_dev_done])!=length[master->bulk_num_dev_done])// not enough data + if(dyn2_get_read_status_data(&master->rx_buffer[start],(unsigned char *)data[i])!=length[i])// not enough data return DYN_INST_ERROR; - else - { - master->bulk_num_dev_done++; - return DYN_BUSY; - } } else - { - master->bulk_num_dev_done=0; return error; - } } else - { - master->bulk_num_dev_done++; - return DYN_BUSY; - } + return DYN_CHECKSUM_ERROR; + start+=length[i]+11; } } - else - return error; - } - else - { - master->bulk_num_dev_done=0; return DYN_SUCCESS; } + else + return error; } else - { - master->bulk_num_dev_done=0; return DYN_SUCCESS; - } } else return error; @@ -770,8 +738,7 @@ void dyn_master_init(TDynamixelMaster *master,TComm *dev,TDynVersion version) master->rx_no_answer=0x00; master->rx_num_packets=0x00; master->return_level=return_all; - master->sync_num_dev_done=0; - master->bulk_num_dev_done=0; + master->packet_bytes=0; master->set_rx_mode(); } @@ -822,7 +789,23 @@ unsigned char dyn_master_ping(TDynamixelMaster *master,unsigned char id) return error; } // wait for the replay within the given timeout - error=dyn_master_wait_reception(master); + if((error=dyn_master_wait_reception(master))!=DYN_SUCCESS) + return error; + // check the input packet checksum + if(master->version==DYN_VER1) + { + if(dyn_check_checksum(master->rx_buffer)==0xFF) + return dyn_get_status_error(master->rx_buffer); + else + return DYN_CHECKSUM_ERROR; + } + else + { + if(dyn2_check_checksum(master->rx_buffer)==0x01) + return dyn2_get_status_error(master->rx_buffer); + else + return DYN_CHECKSUM_ERROR; + } } return error; @@ -880,15 +863,36 @@ unsigned char dyn_master_read_table(TDynamixelMaster *master,unsigned char id,un { if((error=dyn_master_wait_reception(master))==DYN_SUCCESS) { + // check the input packet checksum if(master->version==DYN_VER1) { - if(dyn_get_read_status_data(master->rx_buffer,data)!=length)// not enough data - error=DYN_INST_ERROR; + if(dyn_check_checksum(master->rx_buffer)==0xFF) + { + if((error=dyn_get_status_error(master->rx_buffer))==DYN_NO_ERROR) + { + if(dyn_get_read_status_data(master->rx_buffer,data)!=length)// not enough data + return DYN_INST_ERROR; + } + else + return error; + } + else + return DYN_CHECKSUM_ERROR; } else { - if(dyn2_get_read_status_data(master->rx_buffer,data)!=length)// not enough data - error=DYN_INST_ERROR; + if(dyn2_check_checksum(master->rx_buffer)==0x01) + { + if((error=dyn2_get_status_error(master->rx_buffer))==DYN_NO_ERROR) + { + if(dyn2_get_read_status_data(master->rx_buffer,data)!=length)// not enough data + return DYN_INST_ERROR; + } + else + return error; + } + else + return DYN_CHECKSUM_ERROR; } } } @@ -943,7 +947,26 @@ unsigned char dyn_master_write_table(TDynamixelMaster *master,unsigned char id, } // wait for the replay within the given timeout if(master->return_level==return_all && id!=DYN_BROADCAST_ID) - error=dyn_master_wait_reception(master); + { + if((error=dyn_master_wait_reception(master))==DYN_SUCCESS) + { + // check the input packet checksum + if(master->version==DYN_VER1) + { + if(dyn_check_checksum(master->rx_buffer)==0xFF) + error=dyn_get_status_error(master->rx_buffer); + else + error=DYN_CHECKSUM_ERROR; + } + else + { + if(dyn2_check_checksum(master->rx_buffer)==0x01) + error=dyn2_get_status_error(master->rx_buffer); + else + error=DYN_CHECKSUM_ERROR; + } + } + } } return error; @@ -981,7 +1004,26 @@ unsigned char dyn_master_reg_write(TDynamixelMaster *master,unsigned char id, un } // wait for the replay within the given timeout if(master->return_level==return_all && id!=DYN_BROADCAST_ID) - error=dyn_master_wait_reception(master); + { + if((error=dyn_master_wait_reception(master))==DYN_SUCCESS) + { + // check the input packet checksum + if(master->version==DYN_VER1) + { + if(dyn_check_checksum(master->rx_buffer)==0xFF) + error=dyn_get_status_error(master->rx_buffer); + else + error=DYN_CHECKSUM_ERROR; + } + else + { + if(dyn2_check_checksum(master->rx_buffer)==0x01) + error=dyn2_get_status_error(master->rx_buffer); + else + error=DYN_CHECKSUM_ERROR; + } + } + } } return error; @@ -1083,13 +1125,22 @@ unsigned char dyn_master_sync_read(TDynamixelMaster *master,unsigned char num,un // wait for the replay within the given timeout if(master->return_level!=no_return) { - for(i=0;i<num;i++) + if((error=dyn_master_wait_reception(master))==DYN_SUCCESS) { - if((error=dyn_master_wait_reception(master))==DYN_SUCCESS) + for(i=0;i<num;i++) { - while(dyn2_get_read_status_id(master->rx_buffer)!=ids[i]) i++; - if(dyn2_get_read_status_data(master->rx_buffer,(unsigned char *)data[i])!=length)// not enough data - error=DYN_INST_ERROR; + if(dyn2_check_checksum(&master->rx_buffer[(length+11)*i])==0x01) + { + if((error=dyn2_get_status_error(&master->rx_buffer[(length+11)*i]))==DYN_NO_ERROR) + { + if(dyn2_get_read_status_data(&master->rx_buffer[(length+11)*i],(unsigned char *)data[i])!=length)// not enough data + return DYN_INST_ERROR; + } + else + return error; + } + else + return DYN_CHECKSUM_ERROR; } } } @@ -1102,6 +1153,7 @@ unsigned char dyn_master_sync_read(TDynamixelMaster *master,unsigned char num,un unsigned char dyn_master_bulk_read(TDynamixelMaster *master,unsigned char num,unsigned char *ids,unsigned short int *address, unsigned short int *length, unsigned char * const data[]) { unsigned char error=DYN_COMM_ERROR,i,ver1_address[255],ver1_length[255]; + unsigned short int start=0; if(master!=0x00000000) { @@ -1139,21 +1191,42 @@ unsigned char dyn_master_bulk_read(TDynamixelMaster *master,unsigned char num,un // wait for the replay within the given timeout if(master->return_level!=no_return) { - for(i=0;i<num;i++) + if((error=dyn_master_wait_reception(master))==DYN_SUCCESS) { - if((error=dyn_master_wait_reception(master))==DYN_SUCCESS) + for(i=0;i<num;i++) { + // check the input packet checksum if(master->version==DYN_VER1) { - while(dyn_get_read_status_id(master->rx_buffer)!=ids[i]) i++; - if(dyn_get_read_status_data(master->rx_buffer,(unsigned char *)data[i])!=length[i])// not enough data - error=DYN_INST_ERROR; + if(dyn_check_checksum(&master->rx_buffer[start])==0xFF) + { + if((error=dyn_get_status_error(&master->rx_buffer[start]))==DYN_NO_ERROR) + { + if(dyn_get_read_status_data(&master->rx_buffer[start],(unsigned char *)data[i])!=length[i])// not enough data + return DYN_INST_ERROR; + } + else + return error; + } + else + return DYN_CHECKSUM_ERROR; + start+=length[i]+6; } else { - while(dyn2_get_read_status_id(master->rx_buffer)!=ids[i]) i++; - if(dyn2_get_read_status_data(master->rx_buffer,(unsigned char *)data[i])!=length[i])// not enough data - error=DYN_INST_ERROR; + if(dyn2_check_checksum(&master->rx_buffer[start])==0x01) + { + if((error=dyn2_get_status_error(&master->rx_buffer[start]))==DYN_NO_ERROR) + { + if(dyn2_get_read_status_data(&master->rx_buffer[start],(unsigned char *)data[i])!=length[i])// not enough data + return DYN_INST_ERROR; + } + else + return error; + } + else + return DYN_CHECKSUM_ERROR; + start+=length[i]+11; } } }