static void ifaceSetupHook(unsigned hook __attribute__((unused)), void *requestvp) { uint8 request = *(uint8*)requestvp; // Ignore requests we're not interested in. if (request != USB_CDCACM_SET_CONTROL_LINE_STATE) { return; } #ifdef SERIAL_USB // We need to see a negative edge on DTR before we start looking // for the in-band magic reset byte sequence. uint8 dtr = usb_cdcacm_get_dtr(); switch (reset_state) { case DTR_UNSET: reset_state = dtr ? DTR_HIGH : DTR_LOW; break; case DTR_HIGH: reset_state = dtr ? DTR_HIGH : DTR_NEGEDGE; break; case DTR_NEGEDGE: reset_state = dtr ? DTR_HIGH : DTR_LOW; break; case DTR_LOW: reset_state = dtr ? DTR_HIGH : DTR_LOW; break; } #endif #if defined(BOOTLOADER_robotis) uint8 dtr = usb_cdcacm_get_dtr(); uint8 rts = usb_cdcacm_get_rts(); if (rts && !dtr) { reset_state = DTR_NEGEDGE; } #endif if ((usb_cdcacm_get_baud() == 1200) && (reset_state == DTR_NEGEDGE)) { iwdg_init(IWDG_PRE_4, 10); while (1); } }
/** * Ticking */ static void dxl_serial_tick(volatile struct dxl_device *self) { struct serial *serial = (struct serial*)self->data; static int baudrate = DXL_DEFAULT_BAUDRATE; // Timeout on sending packet, this should never happen if (!serial->txComplete && ((millis() - serial->packetSent) > 3)) { serial_received(serial); } /* if (!serial->txComplete) { if (serial->dmaEvent) { // DMA completed serial->dmaEvent = false; serial->txComplete = true; //serial->port->waitDataToBeSent(); receiveMode(serial); serial->syncReadStart = syncReadTimer.getCount(); } } */ if (serial->txComplete) { if (syncReadMode) { bool processed = false; if (syncReadDevices <= 0 && syncReadResponse == &self->packet) { // The process is over, no devices are currently trying to get packet and we // are the device that will respond syncReadResponse->process = true; syncReadMode = false; } else if (serial->syncReadCount) { if (serial->syncReadCurrent == 0xff) { // Sending the first packet serial->syncReadCurrent = 0; syncReadSendPacket(serial); } else { // Reading available data from the port while (serial->port->available() && !serial->syncReadPacket.process) { dxl_packet_push_byte(&serial->syncReadPacket, serial->port->read()); } if (serial->syncReadPacket.process && serial->syncReadPacket.parameter_nb == syncReadLength) { // The packet is OK, copying data to the response at correct offset ui8 i; ui8 off = serial->syncReadOffsets[serial->syncReadCurrent]*(syncReadLength+1); syncReadResponse->parameters[off] = serial->syncReadPacket.error; for (i=0; i<syncReadLength; i++) { syncReadResponse->parameters[off+1+i] = serial->syncReadPacket.parameters[i]; } processed = true; } else if (syncReadTimer.getCount()-serial->syncReadStart > 65) { // The timeout is reached, answer with code 0xff ui8 off = serial->syncReadOffsets[serial->syncReadCurrent]*(syncReadLength+1); syncReadResponse->parameters[off] = 0xff; processed = true; } if (processed) { serial->syncReadCurrent++; if (serial->syncReadCurrent >= serial->syncReadCount) { // The process is over for this bus syncReadDevices--; serial->syncReadCount = 0; } else { // Sending the next packet syncReadSendPacket(serial); } } } } } else { if (self->redirect_packets == NULL && baudrate != usb_cdcacm_get_baud()) { // baudrate = usb_cdcacm_get_baud(); // initSerial(serial, baudrate); } // Reading data that come from the serial bus while (serial->port->available() && !self->packet.process) { dxl_packet_push_byte(&self->packet, serial->port->read()); if (self->packet.process) { // A packet is coming from our bus, noting it in the devices allocation // table devicePorts[self->packet.id] = serial->index; } } } } }