#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "util.h" #include "../mavlink/c_library/ardupilotmega/mavlink.h" #include "../mavlink/c_library/common/mavlink.h" #include #include #include #include #include using namespace std; /*********************************************************************** Serial port name ***********************************************************************/ string serialPortName; /*********************************************************************** File descriptors ***********************************************************************/ int serial_fd; /*********************************************************************** Threading variables ***********************************************************************/ pthread_mutex_t mutex_msg; pthread_mutex_t mutex_msgtype; mavlink_message_t latest_msg; sem_t sem_msg; int msg_type = 0; /*********************************************************************** Serial tx/rx buffer size ***********************************************************************/ #define BUFSIZE 256 /*********************************************************************** Function: int serial_setup(int baud) Description: The serial port initialization function. This function initializes the serial port over which DSM data is sent to the pixhawk. A return of 0 indicates an error. ***********************************************************************/ int serial_setup(int baud) { struct termios options; serial_fd = open(serialPortName.c_str(), O_RDWR | O_NOCTTY); if(serial_fd < 0) { cerr << "Unable to open serial port " << serialPortName.c_str() << endl; return 0; } tcflush(serial_fd, TCIOFLUSH); //Configure port for 8N1 transmission tcgetattr(serial_fd, &options); //Gets the current options for the port //Set the output baud rate switch(baud) { case 57600: cfsetspeed(&options, B57600); break; case 115200: cfsetspeed(&options, B115200); break; case 1500000: cfsetspeed(&options, B1500000); break; default: cerr << "Unsupported baud rate" << endl; return 0; } options.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP | IXON); options.c_oflag &= ~(OCRNL | ONLCR | ONLRET | ONOCR | OFILL | OPOST); options.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); options.c_cflag &= ~(CSIZE | PARENB); options.c_cflag |= CS8; options.c_cflag |= CRTSCTS; options.c_cc[VMIN] = 17; options.c_cc[VTIME] = 0; tcsetattr(serial_fd, TCSANOW, &options); //Set the new options for the port "NOW" //sleep(1); tcflush(serial_fd, TCIOFLUSH); cout << "Opened serial port " << serialPortName.c_str() << endl; return 1; } void connectUSB(void) { system("echo 19 >> /sys/class/gpio/export"); system("echo 21 >> /sys/class/gpio/export"); system("echo out >> /sys/class/gpio/gpio19/direction"); system("echo out >> /sys/class/gpio/gpio21/direction"); system("echo 1 >> /sys/class/gpio/gpio21/value"); system("echo 0 >> /sys/class/gpio/gpio19/value"); } void disconnectUSB(void) { system("echo 0 >> /sys/class/gpio/gpio21/value"); system("echo 0 >> /sys/class/gpio/gpio19/value"); system("echo 19 >> /sys/class/gpio/unexport"); system("echo 21 >> /sys/class/gpio/unexport"); } /*********************************************************************** Function: int mavlink_task() Description: Thread task to pull mavlink data from the serial port and dump it into a mutex-protected mavlink message. When log data begins streaming, dumps log data into the log file on the filesystem. ***********************************************************************/ void *mavlink_task(void*) { mavlink_message_t _msg; mavlink_status_t mavlink_status; int read_len; int i; char buf[BUFSIZE]; int msgtolookfor; while(1) { read_len = read(serial_fd, buf, BUFSIZE); if (read_len < 0) { if (errno != EAGAIN) cerr << "Read err: " << errno << endl; } if(read_len > 0) { for(i=0; id_name, usbdev_string, 23)) { foundDevice = true; strcpy(usbdev_string,direntry->d_name); break; } } if(!foundDevice) { cerr << "Unable to find USB device" << endl; return -1; } closedir(dir); //Serial port setup serialPortName = "/dev/serial/by-id/"; serialPortName.append(usbdev_string); if(!serial_setup(115200)) { cerr << "Unable to initialize the USB serial port" << endl; return -1; } return 0; } /*********************************************************************** Function: void request_baudrate() Description: Request a particular log file from the pixhawk. ***********************************************************************/ void request_baudrate(void) { char buf[BUFSIZE]; mavlink_message_t msg; int msg_len; float baud; int tries; bool gotParam=false; mavlink_msg_param_request_read_pack(1, 1, &msg, 1, 1, "SERIAL1_BAUD", -1); msg_len = mavlink_msg_to_send_buffer((uint8_t*)buf,&msg); if(write(serial_fd, buf, msg_len) != msg_len) { cerr << "Serial port write error." << endl; disconnectUSB(); exit(1); } for(tries=0; tries<3; ++tries) { cout << "Requesting SERIAL1_BAUD..." << endl; if(wait_for_message(MAVLINK_MSG_ID_PARAM_VALUE, &msg, 3) >= 0) { baud = mavlink_msg_param_value_get_param_value(&msg); cout << "Got param value " << baud << endl; disconnectUSB(); exit(0); } } if(!gotParam) { cout << "Unable to get SERIAL1_BAUD_VALUE" << endl; disconnectUSB(); exit(1); } } /********************************************************************** Function: int main(void) Description: The main function. Initializes and runs the serial and UDP threads. ***********************************************************************/ int main(int argc, char *argv[]) { int baudrate; pthread_t mavlink_ctx; mavlink_message_t msg; //Cout cleanup std::cout.precision(2); std::cout.setf( ios::fixed, ios::floatfield ); cout << "Pixhawk baudrate checker" << endl; //Serial port setup serialPortName = "/dev/ttymxc1"; baudrate=115200;//57600; if(!serial_setup(baudrate)) { cerr << "Unable to initialize the serial send" << endl; return -1; } //Threading initialization pthread_mutex_init(&mutex_msg, NULL); sem_init(&sem_msg, 0, 0); //Start the mavlink rx thread pthread_create(&mavlink_ctx, NULL, mavlink_task, NULL); cout << "Waiting for a hearbeat..." << endl; //Wait for a heartbeat on the telem port if(wait_for_message(MAVLINK_MSG_ID_HEARTBEAT, &msg, 5) < 0) { cout << "No heartbeat received, requesting baudrate from USB" << endl; pthread_cancel(mavlink_ctx); close(serial_fd); if (open_USB_serial() < 0) return -1; } else { cout << "Got a heartbeat, exiting" << endl; return 0; } pthread_create(&mavlink_ctx, NULL, mavlink_task, NULL); //Send a param request to the pixhawk request_baudrate(); //Wait for the mavlink thread to end pthread_join(mavlink_ctx, NULL); return 0; }