Skip to content

Commit

Permalink
Merge pull request #1073 from spark/feature/usb-serial-0.5.x-backport
Browse files Browse the repository at this point in the history
[0.5.x] USB Serial implementation backport
  • Loading branch information
technobly authored Aug 3, 2016
2 parents dff0768 + fd1d86d commit f78536d
Show file tree
Hide file tree
Showing 12 changed files with 1,210 additions and 53 deletions.
26 changes: 26 additions & 0 deletions hal/src/core/usb_settings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
Copyright (c) 2016 Particle Industries, Inc. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
******************************************************************************
*/

#ifndef USB_SETTINGS_H_
#define USB_SETTINGS_H_

#define USB_RX_BUFFER_SIZE 256

//#define USB_SERIAL_USERSPACE_BUFFERS 0

#endif /* USB_SETTINGS_H_ */
121 changes: 78 additions & 43 deletions hal/src/stm32f2xx/usb_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@

/* Includes ------------------------------------------------------------------*/
#include "usb_hal.h"
#include "usbd_cdc_core.h"
#include "usb_settings.h"
#include "usbd_mcdc.h"
#include "usbd_usr.h"
#include "usb_conf.h"
#include "usbd_desc.h"
#include "delay_hal.h"
#include "interrupts_hal.h"
#include "ringbuf_helper.h"
#include <string.h>

/* Private typedef -----------------------------------------------------------*/

Expand All @@ -52,18 +55,10 @@ extern uint32_t USBD_OTG_EP1OUT_ISR_Handler(USB_OTG_CORE_HANDLE *pdev);

/* Extern variables ----------------------------------------------------------*/
#ifdef USB_CDC_ENABLE
extern volatile LINE_CODING linecoding;
extern volatile uint8_t USB_DEVICE_CONFIGURED;
extern volatile uint8_t USB_Rx_Buffer[];
extern volatile uint32_t USB_Rx_Buffer_head;
extern volatile uint32_t USB_Rx_Buffer_tail;
extern volatile uint32_t USB_Rx_Buffer_length;
extern volatile uint8_t USB_Tx_Buffer[];
extern volatile uint32_t USB_Tx_Buffer_head;
extern volatile uint32_t USB_Tx_Buffer_tail;
extern volatile uint8_t USB_Tx_State;
extern volatile uint8_t USB_Rx_State;
extern volatile uint8_t USB_Serial_Open;
static void (*LineCoding_BitRate_Handler)(uint32_t bitRate) = NULL;
USBD_MCDC_Instance_Data USBD_MCDC = {{0}};
__ALIGN_BEGIN static uint8_t USBD_MCDC_Rx_Buffer[USB_RX_BUFFER_SIZE];
__ALIGN_BEGIN static uint8_t USBD_MCDC_Tx_Buffer[USB_TX_BUFFER_SIZE];
#endif

#if defined (USB_CDC_ENABLE) || defined (USB_HID_ENABLE)
Expand All @@ -82,7 +77,7 @@ void SPARK_USB_Setup(void)
USB_OTG_HS_CORE_ID,
#endif
&USR_desc,
&USBD_CDC_cb,
&USBD_MCDC_cb,
NULL);
}

Expand All @@ -100,6 +95,18 @@ void Get_SerialNum(void)
#endif

#ifdef USB_CDC_ENABLE

uint16_t USB_USART_Request_Handler(/*USBD_Composite_Class_Data* cls, */uint32_t cmd, uint8_t* buf, uint32_t len) {
if (cmd == SET_LINE_CODING && LineCoding_BitRate_Handler) {
// USBD_MCDC_Instance_Data* priv = (USBD_MCDC_Instance_Data*)cls->priv;
USBD_MCDC_Instance_Data* priv = &USBD_MCDC;
if (priv)
LineCoding_BitRate_Handler(priv->linecoding.bitrate);
}

return 0;
}

/*******************************************************************************
* Function Name : USB_USART_Init
* Description : Start USB-USART protocol.
Expand All @@ -108,9 +115,9 @@ void Get_SerialNum(void)
*******************************************************************************/
void USB_USART_Init(uint32_t baudRate)
{
if (linecoding.bitrate != baudRate)
if (USBD_MCDC.linecoding.bitrate != baudRate)
{
if (!baudRate && linecoding.bitrate > 0)
if (!baudRate && USBD_MCDC.linecoding.bitrate > 0)
{
// Deconfigure CDC class endpoints
USBD_ClrCfg(&USB_OTG_dev, 0);
Expand All @@ -130,8 +137,18 @@ void USB_USART_Init(uint32_t baudRate)
// Soft reattach
// USB_OTG_dev.regs.DREGS->DCTL |= 0x02;
}
else if (!linecoding.bitrate)
else if (!USBD_MCDC.linecoding.bitrate)
{
memset((void*)&USBD_MCDC, 0, sizeof(USBD_MCDC));
USBD_MCDC.ep_in_data = CDC_IN_EP;
USBD_MCDC.ep_in_int = CDC_CMD_EP;
USBD_MCDC.ep_out_data = CDC_OUT_EP;
USBD_MCDC.rx_buffer = USBD_MCDC_Rx_Buffer;
USBD_MCDC.tx_buffer = USBD_MCDC_Tx_Buffer;
USBD_MCDC.rx_buffer_size = USB_RX_BUFFER_SIZE;
USBD_MCDC.tx_buffer_size = USB_TX_BUFFER_SIZE;
USBD_MCDC.name = "Serial";
USBD_MCDC.req_handler = USB_USART_Request_Handler;
//Initialize USB device
SPARK_USB_Setup();

Expand All @@ -143,26 +160,41 @@ void USB_USART_Init(uint32_t baudRate)
// USB_OTG_dev.regs.DREGS->DCTL |= 0x02;
}
//linecoding.bitrate will be overwritten by USB Host
linecoding.bitrate = baudRate;
USBD_MCDC.linecoding.bitrate = baudRate;
}
}

unsigned USB_USART_Baud_Rate(void)
{
return linecoding.bitrate;
return USBD_MCDC.linecoding.bitrate;
}

static bool USB_WillPreempt()
{
if (HAL_IsISR()) {
#ifdef USE_USB_OTG_FS
int32_t irq = OTG_FS_IRQn;
#else
int32_t irq = OTG_HS_IRQn;
#endif
if (!HAL_WillPreempt(irq, HAL_ServicedIRQn()))
return false;
}

return true;
}


void USB_USART_LineCoding_BitRate_Handler(void (*handler)(uint32_t bitRate))
{
//Init USB Serial first before calling the linecoding handler
USB_USART_Init(9600);

//Set the system defined custom handler
SetLineCodingBitRateHandler(handler);
LineCoding_BitRate_Handler = handler;
}

static inline bool USB_USART_Connected() {
return linecoding.bitrate > 0 && USB_OTG_dev.dev.device_status == USB_OTG_CONFIGURED && USB_Serial_Open;
return USBD_MCDC.linecoding.bitrate > 0 && USB_OTG_dev.dev.device_status == USB_OTG_CONFIGURED && USBD_MCDC.serial_open;
}

/*******************************************************************************
Expand All @@ -175,10 +207,9 @@ uint8_t USB_USART_Available_Data(void)
{
int32_t available = 0;
int state = HAL_disable_irq();
if (USB_Rx_Buffer_head >= USB_Rx_Buffer_tail)
available = USB_Rx_Buffer_head - USB_Rx_Buffer_tail;
else
available = USB_Rx_Buffer_length + USB_Rx_Buffer_head - USB_Rx_Buffer_tail;
available = ring_data_avail(USBD_MCDC.rx_buffer_length,
USBD_MCDC.rx_buffer_head,
USBD_MCDC.rx_buffer_tail);
HAL_enable_irq(state);
return available;
}
Expand All @@ -194,11 +225,9 @@ int32_t USB_USART_Receive_Data(uint8_t peek)
if (USB_USART_Available_Data() > 0)
{
int state = HAL_disable_irq();
uint8_t data = USB_Rx_Buffer[USB_Rx_Buffer_tail];
uint8_t data = USBD_MCDC.rx_buffer[USBD_MCDC.rx_buffer_tail];
if (!peek) {
USB_Rx_Buffer_tail++;
if (USB_Rx_Buffer_tail == USB_Rx_Buffer_length)
USB_Rx_Buffer_tail = 0;
USBD_MCDC.rx_buffer_tail = ring_wrap(USBD_MCDC.rx_buffer_length, USBD_MCDC.rx_buffer_tail + 1);
}
HAL_enable_irq(state);
return data;
Expand All @@ -217,9 +246,11 @@ int32_t USB_USART_Available_Data_For_Write(void)
{
if (USB_USART_Connected())
{
uint32_t tail = USB_Tx_Buffer_tail;
int32_t available = USB_TX_BUFFER_SIZE - (USB_Tx_Buffer_head >= tail ?
USB_Tx_Buffer_head - tail : USB_TX_BUFFER_SIZE + USB_Tx_Buffer_head - tail) - 1;
int state = HAL_disable_irq();
int32_t available = ring_space_avail(USBD_MCDC.tx_buffer_size,
USBD_MCDC.tx_buffer_head,
USBD_MCDC.tx_buffer_tail);
HAL_enable_irq(state);
return available;
}

Expand All @@ -232,22 +263,26 @@ int32_t USB_USART_Available_Data_For_Write(void)
* Input : Data.
* Return : None.
*******************************************************************************/
void USB_USART_Send_Data(uint8_t Data)
void USB_USART_Send_Data(uint8_t data)
{
int32_t ret = -1;
int32_t available = 0;
do {
available = USB_USART_Available_Data_For_Write();
}
while (available < 1 && available != -1);
while (available < 1 && available != -1 && USB_WillPreempt());
// Confirm once again that the Host is connected
if (USB_USART_Connected())
int32_t state = HAL_disable_irq();
if (USB_USART_Connected() && available > 0)
{
uint32_t head = USB_Tx_Buffer_head;

USB_Tx_Buffer[head] = Data;

USB_Tx_Buffer_head = ++head % USB_TX_BUFFER_SIZE;
USBD_MCDC.tx_buffer[USBD_MCDC.tx_buffer_head] = data;
USBD_MCDC.tx_buffer_head = ring_wrap(USBD_MCDC.tx_buffer_size, USBD_MCDC.tx_buffer_head + 1);
ret = 1;
}
HAL_enable_irq(state);

//return ret;
(void)ret;
}

/*******************************************************************************
Expand All @@ -258,9 +293,9 @@ void USB_USART_Send_Data(uint8_t Data)
*******************************************************************************/
void USB_USART_Flush_Data(void)
{
while(USB_USART_Connected() && USB_USART_Available_Data_For_Write() != (USB_TX_BUFFER_SIZE - 1));
while(USB_USART_Connected() && USB_USART_Available_Data_For_Write() != (USBD_MCDC.tx_buffer_size - 1) && USB_WillPreempt());
// We should also wait for USB_Tx_State to become 0, as hardware might still be busy transmitting data
while(USB_Tx_State == 1);
while(USBD_MCDC.tx_state == 1);
}
#endif

Expand Down
28 changes: 28 additions & 0 deletions hal/src/stm32f2xx/usb_settings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
Copyright (c) 2016 Particle Industries, Inc. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
******************************************************************************
*/

#ifndef USB_SETTINGS_H_
#define USB_SETTINGS_H_

#define USB_TX_BUFFER_SIZE 129 /* Total size of IN buffer:
APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */
#define USB_RX_BUFFER_SIZE 256

//#define USB_SERIAL_USERSPACE_BUFFERS 1

#endif /* USB_SETTINGS_H_ */
6 changes: 3 additions & 3 deletions platform/MCU/STM32F2xx/SPARK_Firmware_Driver/inc/usbd_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@
#define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */

#define CDC_IN_FRAME_INTERVAL 1 /* Number of micro-frames between IN transfers */
#define USB_TX_BUFFER_SIZE 128 /* Total size of IN buffer:
APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */
#define USB_RX_BUFFER_SIZE 256
// #define USB_TX_BUFFER_SIZE 128 /* Total size of IN buffer:
// APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */
// #define USB_RX_BUFFER_SIZE 256

#define APP_FOPS APP_fops

Expand Down
Loading

0 comments on commit f78536d

Please sign in to comment.