get rid of OUT queue, caused missed frames

retry
Ondřej Hruška 7 years ago
parent 8efe91c8ed
commit 78137628ba
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 1
      Inc/gex_gateway.h
  2. 125
      Src/gex_gateway.c
  3. 16
      Src/usbd_cdc_if.c

@ -7,5 +7,6 @@
#include "main.h" #include "main.h"
void gw_process(void); void gw_process(void);
void gw_handle_usb_out(uint8_t *buffer);
#endif //GEX_NRF_GEX_GATEWAY_H #endif //GEX_NRF_GEX_GATEWAY_H

@ -42,74 +42,79 @@ void start_slave_cmd(uint8_t slave_addr, uint16_t frame_len, uint8_t cksum)
msg4slave_cksum = cksum; msg4slave_cksum = cksum;
} }
/** called from the main loop, periodically */ void gw_handle_usb_out(uint8_t *buffer)
void gw_process(void)
{ {
static uint8_t buffer[MQ_SLOT_LEN]; dbg("Handling frame.");
while (mq_read(&usb_rxq, buffer)) { // greedy - handle as many as possible if (urx_state == URXS_IDLE) {
dbg("Handling frame."); PayloadParser pp = pp_start(buffer, MQ_SLOT_LEN, NULL);
if (urx_state == URXS_IDLE) {
PayloadParser pp = pp_start(buffer, MQ_SLOT_LEN, NULL); // handle binary commands for the gateway
// handle binary commands for the gateway // magic twice, one inverted - denotes a gateway command
uint16_t magic1 = pp_u8(&pp);
// magic twice, one inverted - denotes a gateway command uint16_t magic2 = pp_u8(&pp);
uint16_t magic1 = pp_u8(&pp); if (magic1 == MAGIC_GW_COMMAND && magic2 == (0xFFU & (~MAGIC_GW_COMMAND))) {
uint16_t magic2 = pp_u8(&pp); // third byte is the command code
if (magic1 == MAGIC_GW_COMMAND && magic2 == (0xFFU & (~MAGIC_GW_COMMAND))) { switch (pp_u8(&pp)) {
// third byte is the command code case CMD_GET_ID:
switch (pp_u8(&pp)) { respond_gw_id();
case CMD_GET_ID: break;
respond_gw_id();
case CMD_MSG4SLAVE:;
uint8_t slave_addr = pp_u8(&pp);
uint16_t frame_len = pp_u16(&pp);
uint8_t cksum = pp_u8(&pp);
if (frame_len == 0 || frame_len > MAX_FRAME_LEN) {
dbg("Frame too big!");
break; break;
}
case CMD_MSG4SLAVE:; start_slave_cmd(slave_addr, frame_len, cksum);
uint8_t slave_addr = pp_u8(&pp); dbg("Collecting frame for slave %02x: %d bytes", (int)slave_addr, (int)frame_len);
uint16_t frame_len = pp_u16(&pp); urx_state = URXS_MSG4SLAVE;
uint8_t cksum = pp_u8(&pp); break;
if (frame_len == 0 || frame_len > MAX_FRAME_LEN) {
dbg("Frame too big!");
break;
}
start_slave_cmd(slave_addr, frame_len, cksum);
dbg("Collecting frame for slave %02x: %d bytes", (int)slave_addr, (int)frame_len);
urx_state = URXS_MSG4SLAVE;
break;
default: default:
dbg("Bad cmd"); dbg("Bad cmd");
}
} else {
// Bad frame??
dbg("Bad USB frame, starts %x,%x", buffer[0],buffer[1]);
} }
} else {
// Bad frame??
dbg("Bad USB frame, starts %x,%x", buffer[0],buffer[1]);
} }
else if (urx_state == URXS_MSG4SLAVE) { }
uint32_t wanted = MIN(msg4slave_len-msg4slave_already, MQ_SLOT_LEN); else if (urx_state == URXS_MSG4SLAVE) {
memcpy(&msg4slave[msg4slave_already], buffer, wanted); uint32_t wanted = MIN(msg4slave_len-msg4slave_already, MQ_SLOT_LEN);
msg4slave_already += wanted; memcpy(&msg4slave[msg4slave_already], buffer, wanted);
msg4slave_already += wanted;
if (wanted < MQ_SLOT_LEN) {
// this was the end if (wanted < MQ_SLOT_LEN) {
uint8_t ck = 0; // this was the end
for (int i = 0; i < msg4slave_len; i++) { uint8_t ck = 0;
ck ^= msg4slave[i]; for (int i = 0; i < msg4slave_len; i++) {
} ck ^= msg4slave[i];
ck = ~ck; }
ck = ~ck;
if (ck != msg4slave_cksum) {
dbg("Checksum mismatch!"); if (ck != msg4slave_cksum) {
} dbg("Checksum mismatch!");
else {
dbg("Verified, sending a %d B frame to slave.", (int) msg4slave_len);
// TODO send to slave
}
urx_state = URXS_IDLE;
} }
else {
dbg("Verified, sending a %d B frame to slave.", (int) msg4slave_len);
// TODO send to slave
}
urx_state = URXS_IDLE;
} }
} }
} }
/** called from the main loop, periodically */
void gw_process(void)
{
// static uint8_t buffer[MQ_SLOT_LEN];
// while (mq_read(&usb_rxq, buffer)) { // greedy - handle as many as possible
// gw_handle_usb_out(buffer);
// }
}

@ -50,6 +50,7 @@
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include <debug.h> #include <debug.h>
#include <msg_queue.h> #include <msg_queue.h>
#include <gex_gateway.h>
#include "usbd_cdc_if.h" #include "usbd_cdc_if.h"
/* USER CODE BEGIN INCLUDE */ /* USER CODE BEGIN INCLUDE */
@ -298,10 +299,15 @@ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
// queue the frame // queue the frame
dbg("USB rx frame"); dbg("USB rx frame");
bool suc = mq_post(&usb_rxq, Buf, *Len); gw_handle_usb_out(Buf); // this expects full 64byte frames always starting with magic or useful data
if (!suc) {
dbg("USB rxq overrun!"); // handled immediately in the interrupt to block USB (NAK)
}
//
// bool suc = mq_post(&usb_rxq, Buf, *Len);
// if (!suc) {
// dbg("USB rxq overrun!");
// }
return (USBD_OK); return (USBD_OK);
/* USER CODE END 6 */ /* USER CODE END 6 */
@ -336,6 +342,8 @@ uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */ /* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
// TODO add Tx Done notify
/** /**
* @} * @}
*/ */

Loading…
Cancel
Save