int net_probe(void) { void * pkt; int ret; /* drain the transmmit queue */ pkt = rs485_pkt_drain(&net.link); if (pkt != NULL) pktbuf_free(pkt); /* set the probe pin low */ net.probe_mode = true; stm32_gpio_clr(RS485_MODE); DCC_LOG(LOG_TRACE, "Probe mode."); if ((pkt = pktbuf_alloc()) != NULL) { uint32_t seq; while ((seq = rand()) == 0); /* send a probe packet */ sprintf((char *)pkt, "PRB=%08x", seq); DCC_LOG1(LOG_TRACE, "seq=0x%08x", seq); rs485_pkt_enqueue(&net.link, pkt, 12); net.stat.tx.pkt_cnt++; net.stat.tx.octet_cnt += 12; /* wait for the end of transmission */ pkt = rs485_pkt_drain(&net.link); pktbuf_free(pkt); if ((ret = thinkos_flag_timedtake(net.probe_flag, 10)) == 0) { if (seq != net.probe_seq) { DCC_LOG(LOG_WARNING, "probe sequence mismatch!"); ret = -1; } } else if (ret == THINKOS_ETIMEDOUT) { DCC_LOG(LOG_WARNING, "probe sequence timedout!"); } DCC_LOG1(LOG_TRACE, "seq=0x%08x", seq); } else { DCC_LOG(LOG_ERROR, "pktbuf_alloc() failed!"); ret = -1; } /* set the probe pin high */ net.probe_mode = false; stm32_gpio_set(RS485_MODE); DCC_LOG(LOG_TRACE, "Probe mode."); return ret; }
int stm32f_serial_read(struct stm32f_serial_drv * drv, void * buf, unsigned int len, unsigned int tmo) { uint8_t * cp = (uint8_t *)buf; unsigned int tail; int ret; int cnt; int n; int i; DCC_LOG2(LOG_INFO, "1. len=%d tmo=%d", len, tmo); again: if ((ret = thinkos_flag_timedtake(drv->rx_flag, tmo)) < 0) { DCC_LOG1(LOG_INFO, "cnt=%d, timeout!", (int32_t)(drv->rx_fifo.head - drv->rx_fifo.tail)); return ret; } tail = drv->rx_fifo.tail; cnt = (int32_t)(drv->rx_fifo.head - tail); if (cnt == 0) { DCC_LOG(LOG_WARNING, "RX FIFO empty!"); goto again; } n = MIN(len, cnt); for (i = 0; i < n; ++i) cp[i] = drv->rx_fifo.buf[tail++ & (SERIAL_RX_FIFO_LEN - 1)]; drv->rx_fifo.tail = tail; if (cnt > n) { DCC_LOG3(LOG_INFO, "len=%d cnt=%d n=%d", len, cnt, n); thinkos_flag_give(drv->rx_flag); } else { DCC_LOG1(LOG_INFO, "2. n=%d", n); } // DCC_LOG1(LOG_TRACE, "len=%d", n); DCC_LOG2(LOG_INFO, "len=%d '%c'...", n, cp[0]); return n; }
int serdrv_recv(struct serdrv * dev, void * buf, int len, unsigned int tmo) { uint8_t * cp = (uint8_t *)buf; unsigned int tail; int ret; int cnt; int n; int i; DCC_LOG2(LOG_INFO, "1. len=%d tmo=%d", len, tmo); again: if ((ret = thinkos_flag_timedtake(SERDRV_RX_FLAG, tmo)) < 0) { DCC_LOG1(LOG_INFO, "cnt=%d, timeout!", (int8_t)(dev->rx_fifo.head - dev->rx_fifo.tail)); return ret; } tail = dev->rx_fifo.tail; cnt = (int8_t)(dev->rx_fifo.head - tail); if (cnt == 0) { DCC_LOG(LOG_WARNING, "RX FIFO empty!"); goto again; } n = MIN(len, cnt); for (i = 0; i < n; ++i) cp[i] = dev->rx_fifo.buf[tail++ & (UART_RX_FIFO_BUF_LEN - 1)]; dev->rx_fifo.tail = tail; if (cnt > n) { DCC_LOG3(LOG_TRACE, "len=%d cnt=%d n=%d", len, cnt, n); thinkos_flag_give(SERDRV_RX_FLAG); } else { DCC_LOG1(LOG_INFO, "2. n=%d", n); } return n; }