/** * @brief CDC_Itf_DataRx * Data received over USB OUT endpoint are sent over CDC interface * through this function. * @param Buf: Buffer of data to be transmitted * @param Len: Number of data received (in bytes) * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) { /* Write data into Terminal Rx buffer */ TerminalInputBufferWrite(INDEX_USB, (char *)Buf, *Len); USBD_CDC_ReceivePacket(&hUSBDDevice); /* Reset for next packet */ return (USBD_OK); }
// Data received over USB OUT endpoint is processed here. // len: number of bytes received into the buffer we passed to USBD_CDC_ReceivePacket // Returns USBD_OK if all operations are OK else USBD_FAIL int8_t usbd_cdc_receive(usbd_cdc_state_t *cdc_in, size_t len) { usbd_cdc_itf_t *cdc = (usbd_cdc_itf_t*)cdc_in; // copy the incoming data into the circular buffer for (const uint8_t *src = cdc->rx_packet_buf, *top = cdc->rx_packet_buf + len; src < top; ++src) { if (cdc->attached_to_repl && mp_interrupt_char != -1 && *src == mp_interrupt_char) { pendsv_kbd_intr(); } else { uint16_t next_put = (cdc->rx_buf_put + 1) & (USBD_CDC_RX_DATA_SIZE - 1); if (next_put == cdc->rx_buf_get) { // overflow, we just discard the rest of the chars break; } cdc->rx_user_buf[cdc->rx_buf_put] = *src; cdc->rx_buf_put = next_put; } } if ((cdc->flow & USBD_CDC_FLOWCONTROL_RTS) && (usbd_cdc_rx_buffer_full(cdc))) { cdc->rx_buf_full = true; return USBD_BUSY; } else { // initiate next USB packet transfer cdc->rx_buf_full = false; return USBD_CDC_ReceivePacket(&cdc->base, cdc->rx_packet_buf); } }
static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { USBD_CDC_HandleTypeDef *hcdc = context; unsigned index; for (index = 0; index < NUM_OF_CDC_UARTS; index++,hcdc++) { /* Open EP IN */ USBD_LL_OpenEP(pdev, parameters[index].data_in_ep, USBD_EP_TYPE_BULK, USB_FS_MAX_PACKET_SIZE); /* Open EP OUT */ USBD_LL_OpenEP(pdev, parameters[index].data_out_ep, USBD_EP_TYPE_BULK, USB_FS_MAX_PACKET_SIZE); /* Open Command IN EP */ USBD_LL_OpenEP(pdev, parameters[index].command_ep, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE); /* Configure the UART peripheral */ hcdc->InboundBufferReadIndex = 0; hcdc->InboundTransferInProgress = 0; hcdc->OutboundTransferNeedsRenewal = 0; hcdc->UartHandle.Instance = parameters[index].Instance; hcdc->LineCoding = defaultLineCoding; __HAL_LINKDMA(&hcdc->UartHandle, hdmatx, hcdc->hdma_tx); __HAL_LINKDMA(&hcdc->UartHandle, hdmarx, hcdc->hdma_rx); ComPort_Config(hcdc); /* Prepare Out endpoint to receive next packet */ USBD_CDC_ReceivePacket(pdev, index); } return USBD_OK; }
/** * @brief CDC_Receive_FS * Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * untill exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 7 */ /* Transfer data into circular buffer */ uint32_t new_tail_index = AppRxBufferTailIndex + *Len; uint32_t first_copy_len = *Len; uint32_t second_copy_len = 0; uint32_t buffer_bytes_available = APP_HIGHLEVEL_RX_BUFFER_SIZE - CDC_Receive_Available(); /* If more bytes have arrived than are in the buffer, */ /* discard extra bytes at the end of the receive buffer */ if ( first_copy_len > buffer_bytes_available ) { first_copy_len = buffer_bytes_available; } /* Handle wrap */ if ( new_tail_index >= APP_HIGHLEVEL_RX_BUFFER_SIZE ) { first_copy_len = APP_HIGHLEVEL_RX_BUFFER_SIZE - AppRxBufferTailIndex; second_copy_len = *Len - first_copy_len; new_tail_index = second_copy_len; } /* Copy data */ memcpy(&AppHighLevelRxBuffer[AppRxBufferTailIndex],Buf,first_copy_len); AppRxBufferTailIndex += first_copy_len; if ( second_copy_len > 0 ) { memcpy(&AppHighLevelRxBuffer[0],Buf + first_copy_len, second_copy_len); AppRxBufferTailIndex = second_copy_len; } /* Enable reception of next packet */ USBD_CDC_ReceivePacket(hUsbDevice_0); return (USBD_OK); /* USER CODE END 7 */ }
/** * @brief CDC_Init_FS * Initializes the CDC media low layer over the FS USB IP * @param None * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Init_FS(void) { hUsbDevice_0 = &hUsbDeviceFS; USBD_CDC_SetRxBuffer(hUsbDevice_0, ReceiveBuffer); USBD_CDC_ReceivePacket(hUsbDevice_0); return (USBD_OK); }
static int8_t usbReceive(uint8_t* data, uint32_t* len) { doubleBuffer_write(&usbReceiveBuffer, data, *len); USBD_CDC_ReceivePacket(&USBD_Device); return USBD_OK; }
/** * @brief CDC_Itf_DataRx * Data received over USB OUT endpoint * @param Buf: Buffer of data to be transmitted * @param Len: Number of data received (in bytes) * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) { if(get_app_config()->mode == USB_SEND_TEXT) get_USB_text(USBRxBuffer[0]); USBD_CDC_ReceivePacket(&USBD_Device); return (USBD_OK); }
/** * @brief CDC_Receive_FS * Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * untill exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ USBD_CDC_SetRxBuffer(hUsbDevice_0, &Buf[0]); USBD_CDC_ReceivePacket(hUsbDevice_0); return (USBD_OK); /* USER CODE END 6 */ }
/** * @brief CDC_Itf_DataRx * Data received over USB OUT endpoint is processed here. * @param Buf: Buffer of data received * @param Len: Number of data received (in bytes) * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL * @note The buffer we are passed here is just UserRxBuffer, so we are * free to modify it. */ static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) { #if 0 // this sends the data over the UART using DMA HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len); #endif // TODO improve this function to implement a circular buffer // if we have processed all the characters, reset the buffer counters if (UserRxBufCur > 0 && UserRxBufCur >= UserRxBufLen) { memmove(UserRxBuffer, UserRxBuffer + UserRxBufLen, *Len); UserRxBufCur = 0; UserRxBufLen = 0; } uint32_t delta_len; if (user_interrupt_char == -1) { // no special interrupt character delta_len = *Len; } else { // filter out special interrupt character from the buffer bool char_found = false; uint8_t *dest = Buf; uint8_t *src = Buf; uint8_t *buf_top = Buf + *Len; for (; src < buf_top; src++) { if (*src == user_interrupt_char) { char_found = true; // raise exception when interrupts are finished pendsv_nlr_jump(user_interrupt_data); } else { if (char_found) { *dest = *src; } dest++; } } // length of remaining characters delta_len = dest - Buf; } if (UserRxBufLen + delta_len + CDC_DATA_FS_MAX_PACKET_SIZE > APP_RX_DATA_SIZE) { // if we keep this data then the buffer can overflow on the next USB rx // so we don't increment the length, and throw this data away } else { // data fits, leaving room for another CDC_DATA_FS_OUT_PACKET_SIZE UserRxBufLen += delta_len; } // initiate next USB packet transfer, to append to existing data in buffer USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer + UserRxBufLen); USBD_CDC_ReceivePacket(&hUSBDDevice); return USBD_OK; }
/** * @brief CDC_Receive_FS * Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * untill exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); CDC_RX_Data = &Buf[0]; return (USBD_OK); /* USER CODE END 6 */ }
/** * @brief CDC_Receive_FS * Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * untill exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ USBD_CDC_SetRxBuffer(hUsbDevice_0, &Buf[0]); USBD_CDC_ReceivePacket(hUsbDevice_0); HAL_UART_Transmit_IT(&huart2, Buf, *Len); return (USBD_OK); /* USER CODE END 6 */ }
static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { data_received = 1; read_len = (*Len); USBD_CDC_ReceivePacket(hUsbDevice_0); return (USBD_OK); }
void usbd_cdc_rx_check_resume(usbd_cdc_itf_t *cdc) { uint32_t irq_state = disable_irq(); if (cdc->rx_buf_full) { if (!usbd_cdc_rx_buffer_full(cdc)) { cdc->rx_buf_full = false; enable_irq(irq_state); USBD_CDC_ReceivePacket(&cdc->base, cdc->rx_packet_buf); return; } } enable_irq(irq_state); }
uint8_t vcpRead() { uint8_t ch = 0; if( (rxBuffPtr != NULL) && (rxAvailable > 0) ) { ch = rxBuffPtr[0]; rxBuffPtr++; rxAvailable--; } if(rxAvailable < 1) USBD_CDC_ReceivePacket(&USBD_Device); return ch; }
/** * @brief CDC_Itf_DataRx * Data received over USB OUT endpoint are sent over CDC interface * through this function. * @param Buf: Buffer of data to be transmitted * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) { // received data on the USB BUS // pass it to interpretation module application_scrapeUSB(Buf, *Len); /* HAL_UART_Transmit(&UartHandle, (uint8_t *)stm32dev_general_getDec(*Len), strlen(stm32dev_general_getDec(*Len)), 50); char finishNewline[] = " characters\r\n"; HAL_UART_Transmit(&UartHandle, (uint8_t *)finishNewline, strlen(finishNewline), 50); */ USBD_CDC_ReceivePacket(&USBD_Device); return (USBD_OK); }
/** * @brief CDC_Receive_FS * Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * untill exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { uint32_t i; /* USER CODE BEGIN 7 */ for (i = 0; i < *Len; i++) UserTxBufferFS[i] = UserRxBufferFS[i]; USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &UserTxBufferFS[0], *Len); USBD_CDC_TransmitPacket(&hUsbDeviceFS); USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &UserRxBufferFS[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); return (USBD_OK); /* USER CODE END 7 */ }
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { USBD_CDC_HandleTypeDef *hcdc = context; unsigned index; for (index = 0; index < NUM_OF_CDC_UARTS; index++,hcdc++) { if (&hcdc->UartHandle != huart) continue; /* Initiate next USB packet transfer once UART completes transfer (transmitting data over Tx line) */ USBD_CDC_ReceivePacket(&USBD_Device, index); break; } }
/** * @brief CDC_Receive_FS * Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * untill exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 7 */ // uncomment this for you know what //#define CDCecho #ifdef CDCecho for (int i = 0; i < *Len; i++) UserTxBufferFS[i] = UserRxBufferFS[i]; USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &UserTxBufferFS[0], *Len); USBD_CDC_TransmitPacket(&hUsbDeviceFS); USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &UserRxBufferFS[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); #endif return (USBD_OK); /* USER CODE END 7 */ }
static uint8_t USBD_CDC_SOF (struct _USBD_HandleTypeDef *pdev) { uint32_t buffsize, write_index; USBD_CDC_HandleTypeDef *hcdc = context; unsigned index; for (index = 0; index < NUM_OF_CDC_UARTS; index++,hcdc++) { write_index = INBOUND_BUFFER_SIZE - hcdc->hdma_rx.Instance->CNDTR; /* the circular DMA should reset CNDTR when it reaches zero, but just in case it is briefly zero, we fix the value */ if (INBOUND_BUFFER_SIZE == write_index) write_index = 0; if(hcdc->InboundBufferReadIndex != write_index) { if(hcdc->InboundBufferReadIndex > write_index) { /* write index has looped around, so send partial data from the write index to the end of the buffer */ buffsize = INBOUND_BUFFER_SIZE - hcdc->InboundBufferReadIndex; } else { /* send all data between read index and write index */ buffsize = write_index - hcdc->InboundBufferReadIndex; } if(USBD_CDC_TransmitPacket(pdev, index, hcdc->InboundBufferReadIndex, buffsize) == USBD_OK) { hcdc->InboundBufferReadIndex += buffsize; /* if we've reached the end of the buffer, loop around to the beginning */ if (hcdc->InboundBufferReadIndex == INBOUND_BUFFER_SIZE) { hcdc->InboundBufferReadIndex = 0; } } } if (hcdc->OutboundTransferNeedsRenewal) /* if there is a lingering request needed due to a HAL_BUSY, retry it */ USBD_CDC_ReceivePacket(pdev, index); } return USBD_OK; }
/** * @brief USB_ReceiveBuffer * User exposed function to read data over USB CDC Interface * * * @note * This function checks the data_received flag, if set it copies the contents of the receive buffer * to the user buffer and sets the Len field with the number of bytes read. * * * @param usr_buf: user provided buffer to place receive contents into * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ uint8_t USB_ReceiveBuffer(uint8_t* usr_buf, uint8_t *Len){ int i = 0 ; if(data_received == 1){ for(i = 0;i<read_len;i++){ usr_buf[i] = ReceiveBuffer[i]; } (*Len) = read_len; data_received = 0; USBD_CDC_ReceivePacket(hUsbDevice_0); } else { (*Len) = 0; } return USBD_OK; }
/** * @brief CDC_Receive_FS * Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * untill exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ uint8_t result = USBD_OK; static uint8_t buff_RX[512]; static uint8_t buff_TX[512]; int i = 0; for (i = 0; i < *Len; i++) buff_TX[i] = buff_RX[i]; USBD_CDC_SetTxBuffer(hUsbDevice_0, &buff_TX[0], *Len); USBD_CDC_TransmitPacket(hUsbDevice_0); USBD_CDC_SetRxBuffer(hUsbDevice_0, &buff_RX[0]); USBD_CDC_ReceivePacket(hUsbDevice_0); return (result); /* USER CODE END 6 */ }
static int8_t CDC_Itf_Receive(uint8_t* pbuf, uint32_t *Len) { uint32_t n = *Len; uint32_t i; // Write the received buffer to the Rx fifo. for (i = 0; i < n; i ++) { uint32_t rx_wr_inc = (rx_wr == (RX_FIFO_SIZE - 1)) ? 0 : rx_wr + 1; if (rx_wr_inc != rx_rd) { rx_fifo[rx_wr] = pbuf[i]; rx_wr = rx_wr_inc; } else { rx_overflow += 1; } } USBD_CDC_SetRxBuffer(&hUSBDDevice, rx_buffer); USBD_CDC_ReceivePacket(&hUSBDDevice); return USBD_OK; }
/** * @brief VCP_Read * Request a len block of data from host through the OUT Endpoint * and store it into the passed buffer. * * @param pbuf: Buffer of data to be received * @param len: Number of data to be received (in bytes) * @retval The number of received byte avaiable */ int VCP_Read(uint8_t *pbuf, uint16_t len) { if (!s_RxBuffer.ReadDone) return 0; int remaining = s_RxBuffer.Size - s_RxBuffer.Position; int todo = MIN(remaining, len); if (todo <= 0) return 0; memcpy(pbuf, s_RxBuffer.Buffer + s_RxBuffer.Position, todo); s_RxBuffer.Position += todo; if (s_RxBuffer.Position >= s_RxBuffer.Size) { s_RxBuffer.ReadDone = 0; USBD_CDC_ReceivePacket(&hUSBDDevice); } return todo; }
/** * @brief CDC_Receive_FS * Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * untill exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { uint8_t i; for( i = 0; i < *Len; i++ ) { if( IsFifoFull( &UartObj->FifoRx ) == false ) { // Read one byte from the receive data register FifoPush( &UartObj->FifoRx, Buf[i] ); } } if( UartObj->IrqNotify != NULL ) { UartObj->IrqNotify( UART_NOTIFY_RX ); } USBD_CDC_SetRxBuffer(hUsbDevice_0, Buf); USBD_CDC_ReceivePacket(hUsbDevice_0); return (USBD_OK); }
/** * @brief CDC_Itf_DataRx * Data received over USB OUT endpoint are sent over CDC interface * through this function. * @param Buf: Buffer of data to be transmitted * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) { //HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len); //UserRxBuffer[UserRxBufPtrIn] =; /*if(*Len + UserRxBuffCnt >= APP_RX_DATA_SIZE) { memcpy(UserTxBufferFiFo + UserRxBuffCnt, Buf, APP_RX_DATA_SIZE - UserRxBuffCnt); memcpy(UserTxBufferFiFo, Buf + (APP_RX_DATA_SIZE - UserRxBuffCnt), (*Len - (APP_RX_DATA_SIZE - UserRxBuffCnt))); UserRxBuffCnt = *Len - (APP_RX_DATA_SIZE - UserRxBuffCnt); } else { memcpy(UserTxBufferFiFo + UserRxBuffCnt, Buf, *Len); UserRxBuffCnt += *Len; }*/ unsigned int cnt = 0; for(; cnt < *Len; cnt++) fifo_push(usb_cdc_dev_rx_fifo, Buf[cnt]); USBD_CDC_ReceivePacket(&usb_cdc_dev_param); return (USBD_OK); }
/** * @brief CDC_Receive_FS * Callback. Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * untill exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS (uint8_t* buf, uint32_t *len) { if(len == 0) return USBD_OK; /* not sure if this ever happens but it might */ /* Push the buffer we just received into the HAL UART TX quee */ HAL_StatusTypeDef r; while((r = HAL_UART_Transmit_IT(&huart2, buf, *len)) == HAL_BUSY) { // We could go into STOP mode here, but USB is connected so who cares about power? // UART, transmit timer are both higher priority interrupts so will interrupt us here } /* Swap the buffer that we'll receive next CDC packet into */ if(buf == cdc2usart_buf_a) USBD_CDC_SetRxBuffer(husb, cdc2usart_buf_b); else USBD_CDC_SetRxBuffer(husb, cdc2usart_buf_a); USBD_CDC_ReceivePacket(husb); return r == HAL_OK ? USBD_OK : USBD_FAIL; }
/** * @brief CDC_Receive_FS * Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * untill exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ memcpy(User_Data, Buf, *Len); // if(User_Data[1] == 0) { // temp = atoi(&User_Data[0]); // } // else { // UiData[temp - 1] = atoi(&User_Data[0]); // memset(User_Data, 0, sizeof(User_Data)); // } if(temp == 0) { temp = atoi(&User_Data[0]); } else { UiData[temp - 1] = atoi(&User_Data[0]); temp = 0; memset(User_Data, 0, sizeof(User_Data)); } //a = atoi((const char *) User_Data[0]); //UiData[a] = //UiData[atoi(User_Data[0])] = atoi(User_Data[1]); USBD_CDC_SetRxBuffer(hUsbDevice_0, &Buf[0]); USBD_CDC_ReceivePacket(hUsbDevice_0); return (USBD_OK); /* USER CODE END 6 */ }
int __start(void) { const volatile uint32_t *src; volatile uint32_t *dest; /* Set up BSS and copy data from flash */ for (src = &_eronly, dest = &_sdata; dest < &_edata;) { *dest++ = *src++; } for (dest = &_sbss; dest < &_ebss;) { *dest++ = 0; } SystemInit(); HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Make sure the flash option bytes are set such that we don't re-enter bootloader mode */ set_dfu_option_bytes(0u); MX_USB_DEVICE_Init(); /* Configure GPIO for the CAN_SILENT signal */ GPIO_InitTypeDef GPIO_InitStruct; /* GPIO Ports Clock Enable */ __GPIOA_CLK_ENABLE(); __GPIOB_CLK_ENABLE(); __CRS_CLK_ENABLE(); /*Configure GPIO pin : PB7 */ GPIO_InitStruct.Pin = GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /**CAN GPIO Configuration PB8 ------> CAN_RX PB9 ------> CAN_TX */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_CAN; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Configure the bxCAN transceiver */ CAN_HandleTypeDef hcan; __CAN_CLK_ENABLE(); hcan.Instance = CAN; hcan.Init.Mode = CAN_MODE_SILENT; hcan.Init.TTCM = DISABLE; hcan.Init.ABOM = ENABLE; hcan.Init.AWUM = ENABLE; hcan.Init.NART = DISABLE; hcan.Init.RFLM = DISABLE; hcan.Init.TXFP = DISABLE; /* Set the bitrate and init */ set_can_bitrate(&hcan, 1000000u); CanRxMsgTypeDef rx_msg; hcan.pRxMsg = &rx_msg; CanTxMsgTypeDef tx_msg; hcan.pTxMsg = &tx_msg; CAN_FilterConfTypeDef filter; filter.FilterNumber = 0; filter.FilterMode = CAN_FILTERMODE_IDMASK; filter.FilterScale = CAN_FILTERSCALE_32BIT; filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; filter.FilterActivation = ENABLE; filter.BankNumber = 0; filter.FilterMaskIdLow = filter.FilterIdLow = filter.FilterMaskIdHigh = filter.FilterIdHigh = 0; HAL_CAN_ConfigFilter(&hcan, &filter); __HAL_UNLOCK(&hcan); /* Now that USB is active, we need to sync with the 1 kHz SOF packets to tune the HSI48 so it's accurate enough not to disrupt the CAN bus. */ RCC_CRSInitTypeDef crs_config; crs_config.Prescaler = RCC_CRS_SYNC_DIV1; crs_config.Source = RCC_CRS_SYNC_SOURCE_USB; crs_config.Polarity = RCC_CRS_SYNC_POLARITY_RISING; crs_config.ReloadValue = RCC_CRS_RELOADVALUE_DEFAULT; crs_config.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT; crs_config.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT; HAL_RCCEx_CRSConfig(&crs_config); /* Don't continue unless we're synced */ while (!(HAL_RCCEx_CRSWaitSynchronization(1000000u) & RCC_CRS_SYNCOK)); while (1) { /* Set up the command record */ size_t i; uint8_t current_cmd; uint8_t current_cmd_data[32]; uint8_t current_cmd_data_length; uint8_t channel_open; current_cmd = current_cmd_data_length = i = 0; channel_open = 0; rx_buffer_length = 0; while (hUsbDevice_0 && hUsbDevice_0->pClassData) { /* If the RX buffer is non-empty, process any commands/messages in it and then acknowledge the transfer to the USB stack */ if (rx_buffer_length) { /* Exit if we've read the entire buffer, or if transmit mailboxes are full and the current command is a transmit. */ for (; i < rx_buffer_length && ((current_cmd != 't' && current_cmd != 'T') || __HAL_CAN_GET_FLAG(&hcan, CAN_FLAG_TME0)); i++) { if (rx_buffer[i] == '\r') { uint8_t *buf = active_buffer ? tx_buffer_1 : tx_buffer_0; /* End of command -- process and reset state */ switch (current_cmd) { case 'S': /* Setup bitrate -- data should be a number from 0 to 8. */ if (current_cmd_data[0] < '0' || current_cmd_data[0] > '8') { buf[active_buffer_length++] = '\a'; } else if (set_can_bitrate( &hcan, bitrate_lookup[current_cmd_data[0] - '0'])) { buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'O': /* Open channel -- take CAN out of silent mode and start receiving. */ if (!channel_open) { channel_open = 1; set_can_silent(&hcan, 0); buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'L': /* Open in listen-only -- CAN should already be in silent mode but just make sure. */ if (!channel_open) { channel_open = 1; set_can_silent(&hcan, 1); buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'C': /* Close channel -- put CAN back in silent mode. */ if (channel_open) { channel_open = 0; set_can_silent(&hcan, 1); buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'V': /* Hardware version */ buf[active_buffer_length++] = 'V'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '1'; buf[active_buffer_length++] = '\r'; break; case 'v': /* Major/minor version */ buf[active_buffer_length++] = 'v'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '0'; buf[active_buffer_length++] = '1'; buf[active_buffer_length++] = '\r'; break; case 'N': /* Serial number */ buf[active_buffer_length++] = 'N'; buf[active_buffer_length++] = 'F'; buf[active_buffer_length++] = 'F'; buf[active_buffer_length++] = 'F'; buf[active_buffer_length++] = 'F'; buf[active_buffer_length++] = '\r'; break; case 'T': /* Extended message */ if (read_ext_message(&tx_msg, current_cmd_data, current_cmd_data_length) && HAL_CAN_Transmit(&hcan, 0) == HAL_OK) { buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 't': /* Standard message */ if (read_std_message(&tx_msg, current_cmd_data, current_cmd_data_length) && HAL_CAN_Transmit(&hcan, 0) == HAL_OK) { buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'R': /* Extended RTR */ if (read_ext_rtr(&tx_msg, current_cmd_data, current_cmd_data_length) && HAL_CAN_Transmit(&hcan, 0) == HAL_OK) { buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case 'r': /* Standard RTR */ if (read_std_rtr(&tx_msg, current_cmd_data, current_cmd_data_length) && HAL_CAN_Transmit(&hcan, 0) == HAL_OK) { buf[active_buffer_length++] = '\r'; } else { buf[active_buffer_length++] = '\a'; } break; case '_': /* Bootloader request */ if (current_cmd_data[0] == '_' && current_cmd_data[1] == 'd' && current_cmd_data[2] == 'f' && current_cmd_data[3] == 'u') { /* Set option bytes to force bootloader entry */ set_dfu_option_bytes(1u); NVIC_SystemReset(); } else { buf[active_buffer_length++] = '\a'; } break; case 'F': /* Read status flags -- return 4 hex digits */ case 'Z': /* Timestamp on/off -- 0=off, 1=on */ case 'M': /* Acceptance mask -- 8 hex digits */ case 'm': /* Acceptance value -- 8 hex digits */ case 's': /* Set bitrate register -- 6 hex digits */ default: /* NACK */ buf[active_buffer_length++] = '\a'; break; } current_cmd = current_cmd_data_length = 0; } else if (current_cmd) { /* Command data -- save it */ current_cmd_data[current_cmd_data_length++] = rx_buffer[i]; /* Reset command state if the data is too long */ if (current_cmd_data_length == 32u) { current_cmd = current_cmd_data_length = 0; } } else { /* The first letter of a line is the command type -- don't bother validating as we can't NACK until the data has been received. */ current_cmd = rx_buffer[i]; } } if (i == rx_buffer_length) { /* Mark last packet as received */ rx_buffer_length = i = 0; USBD_CDC_ReceivePacket(hUsbDevice_0); } } /* Check the CAN controller for messages and process them if the channel is open */ if (HAL_CAN_Receive(&hcan, CAN_FIFO0, 0) == HAL_OK && hUsbDevice_0 && channel_open) { /* Format the message and send it to the host. The data format for a standard ID message is: tiiildddddddddddddddd\r The data format for a standard ID RTR is: riii\r The data format for an extended ID message is: Tiiiiiiiildddddddddddddddd\r The data format for an extended ID RTR is: Riiiiiiii\r */ uint8_t *write_location; if (active_buffer_length + EXT_MESSAGE_LEN > TX_BUFFER_SIZE) { /* Reset buffer if we're too far behind -- use worst-case message length for calculation */ active_buffer_length = 0; } write_location = &((active_buffer ? tx_buffer_1 : tx_buffer_0)[active_buffer_length]); if (rx_msg.IDE == CAN_ID_EXT && rx_msg.RTR) { active_buffer_length += write_ext_rtr( write_location, &rx_msg); } else if (rx_msg.IDE == CAN_ID_EXT && !rx_msg.RTR) { active_buffer_length += write_ext_message( write_location, &rx_msg); } else if (rx_msg.IDE == CAN_ID_STD && rx_msg.RTR) { active_buffer_length += write_std_rtr( write_location, &rx_msg); } else if (rx_msg.IDE == CAN_ID_STD && !rx_msg.RTR) { active_buffer_length += write_std_message( write_location, &rx_msg); } } if (!hUsbDevice_0 || !hUsbDevice_0->pClassData) { /* Reset TX buffer if USB is not connected */ active_buffer_length = 0; } else if (active_buffer_length && ((USBD_CDC_HandleTypeDef*)hUsbDevice_0->pClassData)->TxState == 0) { /* Transmit the next buffer if one is available */ CDC_Transmit_FS(active_buffer ? tx_buffer_1 : tx_buffer_0, active_buffer_length); active_buffer_length = 0; active_buffer = active_buffer ? 0 : 1; } } } }
/** * @brief Tx Transfer completed callback * @param huart: UART handle * @retval None */ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { /* Initiate next USB packet transfer once UART completes transfer (transmitting data over Tx line) */ USBD_CDC_ReceivePacket(&USBD_Device); }
uint8_t CDC_StartReceiveData(void) { return USBD_CDC_ReceivePacket(&hUsbDeviceFS); }