mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-18 03:52:11 +01:00
com: Move buffering out of USART/HID layer and into COM layer
This allows the spektrum and sbus receiver drivers to bind directly to the usart layer using a properly exported API rather than overriding the interrupt handler. Bytes are now pushed directly from the usart layer into the com layer without any buffering. The com layer performs all of the buffering. A further benefit from this approach is that we can put all blocking/non-blocking behaviour into the COM layer and not in the underlying drivers. Misc related changes: - Remove obsolete .handler field from irq configs - Adapt all users of PIOS_COM_* functions to new API - Fixup callers of PIOS_USB_HID_Init()
This commit is contained in:
parent
c7cf52be39
commit
5f8760a55c
@ -54,7 +54,6 @@ static const struct pios_spi_cfg pios_spi_op_cfg = {
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags =
|
||||
(DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 |
|
||||
DMA1_FLAG_GL4),
|
||||
@ -157,7 +156,6 @@ static const struct pios_adc_cfg pios_adc_cfg = {
|
||||
.dma = {
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA1_Channel1_IRQn,
|
||||
@ -217,7 +215,6 @@ static const struct pios_usart_cfg pios_usart_aux_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART3_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
|
||||
@ -294,7 +291,6 @@ static const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
|
||||
},
|
||||
},
|
||||
.event = {
|
||||
.handler = NULL,
|
||||
.flags = 0, /* FIXME: check this */
|
||||
.init = {
|
||||
.NVIC_IRQChannel = I2C1_EV_IRQn,
|
||||
@ -304,7 +300,6 @@ static const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
|
||||
},
|
||||
},
|
||||
.error = {
|
||||
.handler = NULL,
|
||||
.flags = 0, /* FIXME: check this */
|
||||
.init = {
|
||||
.NVIC_IRQChannel = I2C1_ER_IRQn,
|
||||
|
@ -55,7 +55,6 @@ static const struct pios_spi_cfg
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA1_Channel4_IRQn,
|
||||
@ -133,11 +132,18 @@ void PIOS_SPI_op_irq_handler(void) {
|
||||
|
||||
#include "bl_fsm.h" /* lfsm_* */
|
||||
|
||||
static bool board_init_complete = false;
|
||||
void PIOS_Board_Init() {
|
||||
if (board_init_complete) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set up the SPI interface to the OP board */
|
||||
if (PIOS_SPI_Init(&pios_spi_op_id, &pios_spi_op_cfg)) {
|
||||
PIOS_DEBUG_Assert(0);
|
||||
}
|
||||
lfsm_attach(pios_spi_op_id);
|
||||
lfsm_init();
|
||||
|
||||
board_init_complete = true;
|
||||
}
|
||||
|
@ -195,11 +195,10 @@ uint32_t LedPWM(uint32_t pwm_period, uint32_t pwm_sweep_steps, uint32_t count) {
|
||||
|
||||
uint8_t processRX() {
|
||||
while (PIOS_COM_ReceiveBufferUsed(PIOS_COM_TELEM_USB) >= 63) {
|
||||
for (int32_t x = 0; x < 63; ++x) {
|
||||
mReceive_Buffer[x] = PIOS_COM_ReceiveBuffer(PIOS_COM_TELEM_USB);
|
||||
}
|
||||
if (PIOS_COM_ReceiveBuffer(PIOS_COM_TELEM_USB, mReceive_Buffer, 63, 0) == 63) {
|
||||
processComand(mReceive_Buffer);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,21 @@
|
||||
|
||||
// ***********************************************************************************
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
#include "pios_usb_hid_priv.h"
|
||||
|
||||
static const struct pios_usb_hid_cfg pios_usb_hid_main_cfg = {
|
||||
.irq = {
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
.NVIC_IRQChannelCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
};
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
||||
extern const struct pios_com_driver pios_usb_com_driver;
|
||||
|
||||
uint32_t pios_com_telem_usb_id;
|
||||
@ -44,7 +59,12 @@ uint32_t pios_com_telem_usb_id;
|
||||
* initializes all the core subsystems on this specific hardware
|
||||
* called from System/openpilot.c
|
||||
*/
|
||||
static bool board_init_complete = false;
|
||||
void PIOS_Board_Init(void) {
|
||||
if (board_init_complete) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable Prefetch Buffer */
|
||||
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
|
||||
|
||||
@ -58,13 +78,18 @@ void PIOS_Board_Init(void) {
|
||||
PIOS_GPIO_Init();
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
PIOS_USB_HID_Init(0);
|
||||
uint32_t pios_usb_hid_id;
|
||||
if (PIOS_USB_HID_Init(&pios_usb_hid_id, &pios_usb_hid_main_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
#if defined(PIOS_INCLUDE_COM)
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, 0)) {
|
||||
PIOS_DEBUG_Assert(0);
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, pios_usb_hid_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);//TODO Tirar
|
||||
|
||||
board_init_complete = true;
|
||||
}
|
||||
|
@ -250,11 +250,10 @@ uint32_t LedPWM(uint32_t pwm_period, uint32_t pwm_sweep_steps, uint32_t count) {
|
||||
uint8_t processRX() {
|
||||
if (ProgPort == Usb) {
|
||||
while (PIOS_COM_ReceiveBufferUsed(PIOS_COM_TELEM_USB) >= 63) {
|
||||
for (int32_t x = 0; x < 63; ++x) {
|
||||
mReceive_Buffer[x] = PIOS_COM_ReceiveBuffer(PIOS_COM_TELEM_USB);
|
||||
}
|
||||
if (PIOS_COM_ReceiveBuffer(PIOS_COM_TELEM_USB, mReceive_Buffer, 63, 0) == 63) {
|
||||
processComand(mReceive_Buffer);
|
||||
}
|
||||
}
|
||||
} else if (ProgPort == Serial) {
|
||||
|
||||
if (fifoBuf_getUsed(&ssp_buffer) >= 63) {
|
||||
@ -279,7 +278,12 @@ void SSP_CallBack(uint8_t *buf, uint16_t len) {
|
||||
}
|
||||
int16_t SSP_SerialRead(void) {
|
||||
if (PIOS_COM_ReceiveBufferUsed(PIOS_COM_TELEM_RF) > 0) {
|
||||
return PIOS_COM_ReceiveBuffer(PIOS_COM_TELEM_RF);
|
||||
uint8_t byte;
|
||||
if (PIOS_COM_ReceiveBuffer(PIOS_COM_TELEM_RF, &byte, 1, 0) == 1) {
|
||||
return byte;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
|
@ -60,7 +60,6 @@ const struct pios_spi_cfg
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA1_Channel4_IRQn,
|
||||
@ -157,7 +156,6 @@ const struct pios_usart_cfg pios_usart_telem_cfg = {
|
||||
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
|
||||
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
|
||||
}, .irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART2_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
|
||||
@ -188,6 +186,21 @@ const struct pios_usart_cfg pios_usart_telem_cfg = {
|
||||
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
#include "pios_usb_hid_priv.h"
|
||||
|
||||
static const struct pios_usb_hid_cfg pios_usb_hid_main_cfg = {
|
||||
.irq = {
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
.NVIC_IRQChannelCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
};
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
||||
extern const struct pios_com_driver pios_usb_com_driver;
|
||||
|
||||
uint32_t pios_com_telem_rf_id;
|
||||
@ -200,7 +213,11 @@ uint32_t pios_com_telem_usb_id;
|
||||
* initializes all the core subsystems on this specific hardware
|
||||
* called from System/openpilot.c
|
||||
*/
|
||||
static bool board_init_complete = false;
|
||||
void PIOS_Board_Init(void) {
|
||||
if (board_init_complete) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable Prefetch Buffer */
|
||||
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
|
||||
@ -226,10 +243,11 @@ void PIOS_Board_Init(void) {
|
||||
PIOS_GPIO_Init();
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
PIOS_USB_HID_Init(0);
|
||||
uint32_t pios_usb_hid_id;
|
||||
PIOS_USB_HID_Init(&pios_usb_hid_id, &pios_usb_hid_main_cfg);
|
||||
#if defined(PIOS_INCLUDE_COM)
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, 0)) {
|
||||
PIOS_DEBUG_Assert(0);
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, pios_usb_hid_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
@ -243,6 +261,8 @@ void PIOS_Board_Init(void) {
|
||||
|
||||
/* Bind the AHRS comms layer to the AHRS SPI link */
|
||||
PIOS_OPAHRS_Attach(pios_spi_ahrs_id);
|
||||
|
||||
board_init_complete = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -203,11 +203,10 @@ uint32_t LedPWM(uint32_t pwm_period, uint32_t pwm_sweep_steps, uint32_t count) {
|
||||
|
||||
uint8_t processRX() {
|
||||
while (PIOS_COM_ReceiveBufferUsed(PIOS_COM_TELEM_USB) >= 63) {
|
||||
for (int32_t x = 0; x < 63; ++x) {
|
||||
mReceive_Buffer[x] = PIOS_COM_ReceiveBuffer(PIOS_COM_TELEM_USB);
|
||||
}
|
||||
if (PIOS_COM_ReceiveBuffer(PIOS_COM_TELEM_USB, mReceive_Buffer, 63, 0) == 63) {
|
||||
processComand(mReceive_Buffer);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,21 @@
|
||||
|
||||
// ***********************************************************************************
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
#include "pios_usb_hid_priv.h"
|
||||
|
||||
static const struct pios_usb_hid_cfg pios_usb_hid_main_cfg = {
|
||||
.irq = {
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
.NVIC_IRQChannelCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
};
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
||||
extern const struct pios_com_driver pios_usb_com_driver;
|
||||
|
||||
uint32_t pios_com_telem_usb_id;
|
||||
@ -44,7 +59,12 @@ uint32_t pios_com_telem_usb_id;
|
||||
* initializes all the core subsystems on this specific hardware
|
||||
* called from System/openpilot.c
|
||||
*/
|
||||
static bool board_init_complete = false;
|
||||
void PIOS_Board_Init(void) {
|
||||
if (board_init_complete) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable Prefetch Buffer */
|
||||
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
|
||||
|
||||
@ -58,13 +78,16 @@ void PIOS_Board_Init(void) {
|
||||
PIOS_GPIO_Init();
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
PIOS_USB_HID_Init(0);
|
||||
uint32_t pios_usb_hid_id;
|
||||
PIOS_USB_HID_Init(&pios_usb_hid_id, &pios_usb_hid_main_cfg);
|
||||
#if defined(PIOS_INCLUDE_COM)
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, 0)) {
|
||||
PIOS_DEBUG_Assert(0);
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, pios_usb_hid_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);//TODO Tirar
|
||||
|
||||
board_init_complete = true;
|
||||
}
|
||||
|
@ -63,7 +63,6 @@ static const struct pios_spi_cfg pios_spi_flash_accel_cfg = {
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA1_Channel4_IRQn,
|
||||
@ -156,7 +155,6 @@ static const struct pios_adc_cfg pios_adc_cfg = {
|
||||
.dma = {
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA1_Channel1_IRQn,
|
||||
@ -216,7 +214,6 @@ static const struct pios_usart_cfg pios_usart_telem_main_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART1_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
@ -253,7 +250,6 @@ static const struct pios_usart_cfg pios_usart_telem_flexi_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART3_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
@ -295,7 +291,6 @@ static const struct pios_usart_cfg pios_usart_gps_main_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART1_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
@ -332,7 +327,6 @@ static const struct pios_usart_cfg pios_usart_gps_flexi_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART3_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
@ -376,7 +370,6 @@ static const struct pios_usart_cfg pios_usart_spektrum_main_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = PIOS_SPEKTRUM_irq_handler,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART1_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
|
||||
@ -425,7 +418,6 @@ static const struct pios_usart_cfg pios_usart_spektrum_flexi_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = PIOS_SPEKTRUM_irq_handler,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART3_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
|
||||
@ -482,7 +474,6 @@ static const struct pios_usart_cfg pios_usart_sbus_main_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = PIOS_SBUS_irq_handler,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART1_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
|
||||
@ -545,7 +536,6 @@ static const struct pios_rtc_cfg pios_rtc_main_cfg = {
|
||||
.clksrc = RCC_RTCCLKSource_HSE_Div128,
|
||||
.prescaler = 100,
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = RTC_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
@ -666,7 +656,6 @@ const struct pios_ppm_cfg pios_ppm_cfg = {
|
||||
},
|
||||
.remap = 0,
|
||||
.irq = {
|
||||
.handler = TIM4_IRQHandler,
|
||||
.init = {
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
@ -761,7 +750,6 @@ const struct pios_pwm_cfg pios_pwm_cfg = {
|
||||
},
|
||||
.remap = 0,
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
@ -826,7 +814,6 @@ static const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
|
||||
},
|
||||
},
|
||||
.event = {
|
||||
.handler = NULL,
|
||||
.flags = 0, /* FIXME: check this */
|
||||
.init = {
|
||||
.NVIC_IRQChannel = I2C2_EV_IRQn,
|
||||
@ -836,7 +823,6 @@ static const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
|
||||
},
|
||||
},
|
||||
.error = {
|
||||
.handler = NULL,
|
||||
.flags = 0, /* FIXME: check this */
|
||||
.init = {
|
||||
.NVIC_IRQChannel = I2C2_ER_IRQn,
|
||||
@ -869,6 +855,21 @@ struct pios_rcvr_channel_map pios_rcvr_channel_to_id_map[PIOS_RCVR_MAX_CHANNELS]
|
||||
uint32_t pios_rcvr_max_channel;
|
||||
#endif /* PIOS_INCLUDE_RCVR */
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
#include "pios_usb_hid_priv.h"
|
||||
|
||||
static const struct pios_usb_hid_cfg pios_usb_hid_main_cfg = {
|
||||
.irq = {
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
.NVIC_IRQChannelCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
};
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
||||
extern const struct pios_com_driver pios_usb_com_driver;
|
||||
|
||||
uint32_t pios_com_telem_rf_id;
|
||||
@ -934,12 +935,20 @@ void PIOS_Board_Init(void) {
|
||||
case HWSETTINGS_CC_MAINPORT_SBUS:
|
||||
#if defined(PIOS_INCLUDE_SBUS)
|
||||
{
|
||||
PIOS_SBUS_Init(&pios_sbus_cfg);
|
||||
|
||||
uint32_t pios_usart_sbus_id;
|
||||
if (PIOS_USART_Init(&pios_usart_sbus_id, &pios_usart_sbus_main_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
uint32_t pios_sbus_id;
|
||||
if (PIOS_SBUS_Init(&pios_sbus_id, &pios_sbus_cfg, &pios_usart_com_driver, pios_usart_sbus_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
uint32_t pios_rcvr_id;
|
||||
if (PIOS_RCVR_Init(&pios_rcvr_id, &pios_sbus_rcvr_driver, pios_sbus_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_SBUS */
|
||||
break;
|
||||
@ -959,13 +968,20 @@ void PIOS_Board_Init(void) {
|
||||
case HWSETTINGS_CC_MAINPORT_SPEKTRUM:
|
||||
#if defined(PIOS_INCLUDE_SPEKTRUM)
|
||||
{
|
||||
/* SPEKTRUM init must come before usart init since it may use Rx pin for bind */
|
||||
PIOS_SPEKTRUM_Init(&pios_spektrum_main_cfg, false);
|
||||
|
||||
uint32_t pios_usart_spektrum_id;
|
||||
if (PIOS_USART_Init(&pios_usart_spektrum_id, &pios_usart_spektrum_main_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
uint32_t pios_spektrum_id;
|
||||
if (PIOS_SPEKTRUM_Init(&pios_spektrum_id, &pios_spektrum_main_cfg, &pios_usart_com_driver, pios_usart_spektrum_id, false)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
uint32_t pios_rcvr_id;
|
||||
if (PIOS_RCVR_Init(&pios_rcvr_id, &pios_spektrum_rcvr_driver, pios_spektrum_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_SPEKTRUM */
|
||||
break;
|
||||
@ -1009,13 +1025,20 @@ void PIOS_Board_Init(void) {
|
||||
case HWSETTINGS_CC_FLEXIPORT_SPEKTRUM:
|
||||
#if defined(PIOS_INCLUDE_SPEKTRUM)
|
||||
{
|
||||
/* SPEKTRUM init must come before usart init since it may use Rx pin for bind */
|
||||
PIOS_SPEKTRUM_Init(&pios_spektrum_flexi_cfg, false);
|
||||
|
||||
uint32_t pios_usart_spektrum_id;
|
||||
if (PIOS_USART_Init(&pios_usart_spektrum_id, &pios_usart_spektrum_flexi_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
uint32_t pios_spektrum_id;
|
||||
if (PIOS_SPEKTRUM_Init(&pios_spektrum_id, &pios_spektrum_flexi_cfg, &pios_usart_com_driver, pios_usart_spektrum_id, false)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
uint32_t pios_rcvr_id;
|
||||
if (PIOS_RCVR_Init(&pios_rcvr_id, &pios_spektrum_rcvr_driver, pios_spektrum_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_SPEKTRUM */
|
||||
break;
|
||||
@ -1114,9 +1137,10 @@ void PIOS_Board_Init(void) {
|
||||
PIOS_GPIO_Init();
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
PIOS_USB_HID_Init(0);
|
||||
uint32_t pios_usb_hid_id;
|
||||
PIOS_USB_HID_Init(&pios_usb_hid_id, &pios_usb_hid_main_cfg);
|
||||
#if defined(PIOS_INCLUDE_COM)
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, 0)) {
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, pios_usb_hid_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
|
@ -61,7 +61,6 @@ static const struct pios_spi_cfg pios_spi_op_mag_cfg = {
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags =
|
||||
(DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 |
|
||||
DMA1_FLAG_GL4),
|
||||
@ -175,7 +174,6 @@ static const struct pios_spi_cfg pios_spi_accel_cfg = {
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags = (DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA1_Channel2_IRQn,
|
||||
@ -277,7 +275,6 @@ static const struct pios_usart_cfg pios_usart_gps_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART1_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
@ -321,7 +318,6 @@ static const struct pios_usart_cfg pios_usart_aux_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART4_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
|
||||
@ -393,7 +389,6 @@ static const struct pios_i2c_adapter_cfg pios_i2c_pres_mag_adapter_cfg = {
|
||||
},
|
||||
},
|
||||
.event = {
|
||||
.handler = NULL,
|
||||
.flags = 0, /* FIXME: check this */
|
||||
.init = {
|
||||
.NVIC_IRQChannel = I2C1_EV_IRQn,
|
||||
@ -403,7 +398,6 @@ static const struct pios_i2c_adapter_cfg pios_i2c_pres_mag_adapter_cfg = {
|
||||
},
|
||||
},
|
||||
.error = {
|
||||
.handler = NULL,
|
||||
.flags = 0, /* FIXME: check this */
|
||||
.init = {
|
||||
.NVIC_IRQChannel = I2C1_ER_IRQn,
|
||||
@ -461,7 +455,6 @@ static const struct pios_i2c_adapter_cfg pios_i2c_gyro_adapter_cfg = {
|
||||
},
|
||||
},
|
||||
.event = {
|
||||
.handler = NULL,
|
||||
.flags = 0, /* FIXME: check this */
|
||||
.init = {
|
||||
.NVIC_IRQChannel = I2C2_EV_IRQn,
|
||||
@ -471,7 +464,6 @@ static const struct pios_i2c_adapter_cfg pios_i2c_gyro_adapter_cfg = {
|
||||
},
|
||||
},
|
||||
.error = {
|
||||
.handler = NULL,
|
||||
.flags = 0, /* FIXME: check this */
|
||||
.init = {
|
||||
.NVIC_IRQChannel = I2C2_ER_IRQn,
|
||||
|
@ -196,8 +196,10 @@ static void gpsTask(void *parameters)
|
||||
|
||||
while (PIOS_COM_ReceiveBufferUsed(gpsPort) > 0)
|
||||
{
|
||||
int res = GTOP_BIN_update_position(PIOS_COM_ReceiveBuffer(gpsPort), &numChecksumErrors, &numParsingErrors);
|
||||
if (res >= 0)
|
||||
uint8_t c;
|
||||
PIOS_COM_ReceiveBuffer(gpsPort, &c, 1, 0);
|
||||
|
||||
if (GTOP_BIN_update_position(c, &numChecksumErrors, &numParsingErrors) >= 0)
|
||||
{
|
||||
numUpdates++;
|
||||
|
||||
@ -213,7 +215,8 @@ static void gpsTask(void *parameters)
|
||||
// This blocks the task until there is something on the buffer
|
||||
while (PIOS_COM_ReceiveBufferUsed(gpsPort) > 0)
|
||||
{
|
||||
char c = PIOS_COM_ReceiveBuffer(gpsPort);
|
||||
uint8_t c;
|
||||
PIOS_COM_ReceiveBuffer(gpsPort, &c, 1, 0);
|
||||
|
||||
// detect start while acquiring stream
|
||||
if (!start_flag && (c == '$'))
|
||||
|
@ -305,7 +305,6 @@ static void telemetryTxPriTask(void *parameters)
|
||||
static void telemetryRxTask(void *parameters)
|
||||
{
|
||||
uint32_t inputPort;
|
||||
int32_t len;
|
||||
|
||||
// Task loop
|
||||
while (1) {
|
||||
@ -320,13 +319,15 @@ static void telemetryRxTask(void *parameters)
|
||||
}
|
||||
|
||||
// Block until data are available
|
||||
// TODO: Currently we periodically check the buffer for data, update once the PIOS_COM is made blocking
|
||||
len = PIOS_COM_ReceiveBufferUsed(inputPort);
|
||||
for (int32_t n = 0; n < len; ++n) {
|
||||
UAVTalkProcessInputStream(PIOS_COM_ReceiveBuffer(inputPort));
|
||||
}
|
||||
vTaskDelay(5); // <- remove when blocking calls are implemented
|
||||
uint8_t serial_data[1];
|
||||
uint16_t bytes_to_process;
|
||||
|
||||
bytes_to_process = PIOS_COM_ReceiveBuffer(inputPort, serial_data, sizeof(serial_data), 500);
|
||||
if (bytes_to_process > 0) {
|
||||
for (uint8_t i = 0; i < bytes_to_process; i++) {
|
||||
UAVTalkProcessInputStream(serial_data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,6 @@ static const struct pios_spi_cfg pios_spi_sdcard_cfg = {
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags = (DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA1_Channel2_IRQn,
|
||||
@ -163,7 +162,6 @@ static const struct pios_spi_cfg pios_spi_ahrs_cfg = {
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA1_Channel4_IRQn,
|
||||
@ -263,7 +261,6 @@ static const struct pios_adc_cfg pios_adc_cfg = {
|
||||
.dma = {
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA1_Channel1_IRQn,
|
||||
@ -322,7 +319,6 @@ static const struct pios_usart_cfg pios_usart_telem_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART2_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
@ -363,7 +359,6 @@ static const struct pios_usart_cfg pios_usart_gps_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART3_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
@ -404,7 +399,6 @@ static const struct pios_usart_cfg pios_usart_aux_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART1_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
@ -444,7 +438,6 @@ static const struct pios_rtc_cfg pios_rtc_main_cfg = {
|
||||
.clksrc = RCC_RTCCLKSource_HSE_Div128,
|
||||
.prescaler = 100,
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = RTC_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
@ -478,7 +471,6 @@ static const struct pios_usart_cfg pios_usart_spektrum_cfg = {
|
||||
.USART_Mode = USART_Mode_Rx,
|
||||
},
|
||||
.irq = {
|
||||
.handler = PIOS_SPEKTRUM_irq_handler,
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USART1_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
|
||||
@ -505,12 +497,6 @@ static const struct pios_usart_cfg pios_usart_spektrum_cfg = {
|
||||
};
|
||||
|
||||
#include <pios_spektrum_priv.h>
|
||||
static uint32_t pios_usart_spektrum_id;
|
||||
void PIOS_USART_spektrum_irq_handler(void)
|
||||
{
|
||||
PIOS_SPEKTRUM_irq_handler(pios_usart_spektrum_id);
|
||||
}
|
||||
|
||||
static const struct pios_spektrum_cfg pios_spektrum_cfg = {
|
||||
.bind = {
|
||||
.gpio = GPIOA,
|
||||
@ -710,7 +696,6 @@ const struct pios_pwm_cfg pios_pwm_cfg = {
|
||||
},
|
||||
.remap = GPIO_PartialRemap_TIM3,
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
@ -750,7 +735,6 @@ static const struct pios_ppmsv_cfg pios_ppmsv_cfg = {
|
||||
.TIM_RepetitionCounter = 0x0000,
|
||||
},
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
@ -790,7 +774,6 @@ static const struct pios_ppm_cfg pios_ppm_cfg = {
|
||||
},
|
||||
.remap = 0,
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.init = {
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
@ -851,7 +834,6 @@ static const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
|
||||
},
|
||||
},
|
||||
.event = {
|
||||
.handler = NULL,
|
||||
.flags = 0, /* FIXME: check this */
|
||||
.init = {
|
||||
.NVIC_IRQChannel = I2C2_EV_IRQn,
|
||||
@ -861,7 +843,6 @@ static const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
|
||||
},
|
||||
},
|
||||
.error = {
|
||||
.handler = NULL,
|
||||
.flags = 0, /* FIXME: check this */
|
||||
.init = {
|
||||
.NVIC_IRQChannel = I2C2_ER_IRQn,
|
||||
@ -979,6 +960,21 @@ struct pios_rcvr_channel_map pios_rcvr_channel_to_id_map[PIOS_RCVR_MAX_CHANNELS]
|
||||
uint32_t pios_rcvr_max_channel;
|
||||
#endif /* PIOS_INCLUDE_RCVR */
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
#include "pios_usb_hid_priv.h"
|
||||
|
||||
static const struct pios_usb_hid_cfg pios_usb_hid_main_cfg = {
|
||||
.irq = {
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
.NVIC_IRQChannelCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
};
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
||||
extern const struct pios_com_driver pios_usb_com_driver;
|
||||
|
||||
uint32_t pios_com_telem_rf_id;
|
||||
@ -1118,13 +1114,17 @@ void PIOS_Board_Init(void) {
|
||||
#if (PIOS_SPEKTRUM_NUM_INPUTS > PIOS_RCVR_MAX_CHANNELS)
|
||||
#error More receiver inputs than available devices
|
||||
#endif
|
||||
/* SPEKTRUM init must come before comms */
|
||||
PIOS_SPEKTRUM_Init(&pios_spektrum_cfg, false);
|
||||
|
||||
{
|
||||
uint32_t pios_usart_spektrum_id;
|
||||
if (PIOS_USART_Init(&pios_usart_spektrum_id, &pios_usart_spektrum_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
uint32_t pios_spektrum_id;
|
||||
if (PIOS_SPEKTRUM_Init(&pios_spektrum_id, &pios_spektrum_cfg, &pios_usart_com_driver, pios_usart_spektrum_id, false)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
uint32_t pios_spektrum_rcvr_id;
|
||||
if (PIOS_RCVR_Init(&pios_spektrum_rcvr_id, &pios_spektrum_rcvr_driver, 0)) {
|
||||
PIOS_Assert(0);
|
||||
@ -1136,6 +1136,7 @@ void PIOS_Board_Init(void) {
|
||||
pios_rcvr_channel_to_id_map[pios_rcvr_max_channel].channel = i;
|
||||
pios_rcvr_max_channel++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case MANUALCONTROLSETTINGS_INPUTMODE_SBUS:
|
||||
@ -1145,11 +1146,11 @@ void PIOS_Board_Init(void) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
PIOS_USB_HID_Init(0);
|
||||
uint32_t pios_usb_hid_id;
|
||||
PIOS_USB_HID_Init(&pios_usb_hid_id, &pios_usb_hid_main_cfg);
|
||||
#if defined(PIOS_INCLUDE_COM)
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, 0)) {
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, pios_usb_hid_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
|
@ -112,8 +112,6 @@ extern uint32_t pios_i2c_main_adapter_id;
|
||||
// PIOS_USART
|
||||
//-------------------------
|
||||
#define PIOS_USART_MAX_DEVS 2
|
||||
#define PIOS_USART_RX_BUFFER_SIZE 256
|
||||
#define PIOS_USART_TX_BUFFER_SIZE 256
|
||||
|
||||
//-------------------------
|
||||
// PIOS_COM
|
||||
@ -121,6 +119,9 @@ extern uint32_t pios_i2c_main_adapter_id;
|
||||
// See also pios_board.c
|
||||
//-------------------------
|
||||
#define PIOS_COM_MAX_DEVS 2
|
||||
#define PIOS_COM_RX_BUFFER_SIZE 256
|
||||
#define PIOS_COM_TX_BUFFER_SIZE 256
|
||||
|
||||
extern uint32_t pios_com_aux_id;
|
||||
#define PIOS_COM_AUX (pios_com_aux_id)
|
||||
#define PIOS_COM_DEBUG PIOS_COM_AUX
|
||||
|
@ -125,15 +125,14 @@ extern uint32_t pios_i2c_main_adapter_id;
|
||||
//-------------------------
|
||||
#define PIOS_USART_MAX_DEVS 2
|
||||
|
||||
#define PIOS_USART_RX_BUFFER_SIZE 256
|
||||
#define PIOS_USART_TX_BUFFER_SIZE 256
|
||||
|
||||
//-------------------------
|
||||
// PIOS_COM
|
||||
//
|
||||
// See also pios_board.c
|
||||
//-------------------------
|
||||
#define PIOS_COM_MAX_DEVS 4
|
||||
#define PIOS_COM_MAX_DEVS 3
|
||||
#define PIOS_COM_RX_BUFFER_SIZE 192
|
||||
#define PIOS_COM_TX_BUFFER_SIZE 192
|
||||
|
||||
extern uint32_t pios_com_telem_rf_id;
|
||||
#define PIOS_COM_TELEM_RF (pios_com_telem_rf_id)
|
||||
@ -265,10 +264,9 @@ extern uint32_t pios_com_sbus_id;
|
||||
// USB
|
||||
//-------------------------
|
||||
#define PIOS_USB_ENABLED 1
|
||||
#define PIOS_USB_HID_MAX_DEVS 1
|
||||
#define PIOS_USB_DETECT_GPIO_PORT GPIOC
|
||||
#define PIOS_USB_DETECT_GPIO_PIN GPIO_Pin_15
|
||||
#define PIOS_USB_DETECT_EXTI_LINE EXTI_Line15
|
||||
#define PIOS_IRQ_USB_PRIORITY PIOS_IRQ_PRIO_MID
|
||||
#define PIOS_USB_RX_BUFFER_SIZE 128
|
||||
#define PIOS_USB_TX_BUFFER_SIZE 256
|
||||
#endif /* STM32103CB_AHRS_H_ */
|
||||
|
@ -144,15 +144,14 @@ extern uint32_t pios_spi_port_id;
|
||||
//-------------------------
|
||||
#define PIOS_USART_MAX_DEVS 1
|
||||
|
||||
#define PIOS_USART_RX_BUFFER_SIZE 512
|
||||
#define PIOS_USART_TX_BUFFER_SIZE 512
|
||||
|
||||
//-------------------------
|
||||
// PIOS_COM
|
||||
//
|
||||
// See also pios_board.c
|
||||
//-------------------------
|
||||
#define PIOS_COM_MAX_DEVS 2
|
||||
#define PIOS_COM_RX_BUFFER_SIZE 512
|
||||
#define PIOS_COM_TX_BUFFER_SIZE 512
|
||||
|
||||
extern uint32_t pios_com_serial_id;
|
||||
#define PIOS_COM_SERIAL (pios_com_serial_id)
|
||||
@ -396,12 +395,11 @@ extern uint32_t pios_com_telem_usb_id;
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
#define PIOS_USB_ENABLED 1
|
||||
#define PIOS_USB_HID_MAX_DEVS 1
|
||||
#define PIOS_USB_DETECT_GPIO_PORT GPIO_IN_2_PORT
|
||||
#define PIOS_USB_DETECT_GPIO_PIN GPIO_IN_2_PIN
|
||||
#define PIOS_USB_DETECT_EXTI_LINE EXTI_Line4
|
||||
#define PIOS_IRQ_USB_PRIORITY 8
|
||||
#define PIOS_USB_RX_BUFFER_SIZE 512
|
||||
#define PIOS_USB_TX_BUFFER_SIZE 512
|
||||
#endif
|
||||
|
||||
// *****************************************************************
|
||||
|
@ -125,15 +125,14 @@ extern uint32_t pios_i2c_gyro_adapter_id;
|
||||
//-------------------------
|
||||
#define PIOS_USART_MAX_DEVS 2
|
||||
|
||||
#define PIOS_USART_RX_BUFFER_SIZE 256
|
||||
#define PIOS_USART_TX_BUFFER_SIZE 256
|
||||
|
||||
//-------------------------
|
||||
// PIOS_COM
|
||||
//
|
||||
// See also pios_board.c
|
||||
//-------------------------
|
||||
#define PIOS_COM_MAX_DEVS 2
|
||||
#define PIOS_COM_RX_BUFFER_SIZE 256
|
||||
#define PIOS_COM_TX_BUFFER_SIZE 256
|
||||
|
||||
extern uint32_t pios_com_gps_id;
|
||||
#define PIOS_COM_GPS (pios_com_gps_id)
|
||||
|
@ -139,15 +139,14 @@ extern uint32_t pios_i2c_main_adapter_id;
|
||||
//-------------------------
|
||||
#define PIOS_USART_MAX_DEVS 3
|
||||
|
||||
#define PIOS_USART_RX_BUFFER_SIZE 512
|
||||
#define PIOS_USART_TX_BUFFER_SIZE 512
|
||||
|
||||
//-------------------------
|
||||
// PIOS_COM
|
||||
//
|
||||
// See also pios_board.c
|
||||
//-------------------------
|
||||
#define PIOS_COM_MAX_DEVS 4
|
||||
#define PIOS_COM_RX_BUFFER_SIZE 512
|
||||
#define PIOS_COM_TX_BUFFER_SIZE 512
|
||||
|
||||
extern uint32_t pios_com_telem_rf_id;
|
||||
#define PIOS_COM_TELEM_RF (pios_com_telem_rf_id)
|
||||
@ -309,12 +308,11 @@ extern uint32_t pios_com_sbus_id;
|
||||
// USB
|
||||
//-------------------------
|
||||
#define PIOS_USB_ENABLED 1
|
||||
#define PIOS_USB_HID_MAX_DEVS 1
|
||||
#define PIOS_USB_DETECT_GPIO_PORT GPIOC
|
||||
#define PIOS_USB_DETECT_GPIO_PIN GPIO_Pin_4
|
||||
#define PIOS_USB_DETECT_EXTI_LINE EXTI_Line4
|
||||
#define PIOS_IRQ_USB_PRIORITY PIOS_IRQ_PRIO_MID
|
||||
#define PIOS_USB_RX_BUFFER_SIZE 512
|
||||
#define PIOS_USB_TX_BUFFER_SIZE 512
|
||||
|
||||
/**
|
||||
* glue macros for file IO
|
||||
|
@ -34,8 +34,36 @@
|
||||
|
||||
#if defined(PIOS_INCLUDE_COM)
|
||||
|
||||
#include "fifo_buffer.h"
|
||||
#include <pios_com_priv.h>
|
||||
|
||||
#if !defined(PIOS_INCLUDE_FREERTOS)
|
||||
#include "pios_delay.h" /* PIOS_DELAY_WaitmS */
|
||||
#endif
|
||||
|
||||
enum pios_com_dev_magic {
|
||||
PIOS_COM_DEV_MAGIC = 0xaa55aa55,
|
||||
};
|
||||
|
||||
struct pios_com_dev {
|
||||
enum pios_com_dev_magic magic;
|
||||
uint32_t lower_id;
|
||||
const struct pios_com_driver * driver;
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreHandle tx_sem;
|
||||
xSemaphoreHandle rx_sem;
|
||||
#endif
|
||||
|
||||
// align to 32-bit to try and provide speed improvement;
|
||||
uint8_t rx_buffer[PIOS_COM_RX_BUFFER_SIZE] __attribute__ ((aligned(4)));
|
||||
t_fifo_buffer rx;
|
||||
|
||||
// align to 32-bit to try and provide speed improvement;
|
||||
uint8_t tx_buffer[PIOS_COM_TX_BUFFER_SIZE] __attribute__ ((aligned(4)));
|
||||
t_fifo_buffer tx;
|
||||
};
|
||||
|
||||
static bool PIOS_COM_validate(struct pios_com_dev * com_dev)
|
||||
{
|
||||
return (com_dev && (com_dev->magic == PIOS_COM_DEV_MAGIC));
|
||||
@ -70,6 +98,11 @@ static struct pios_com_dev * PIOS_COM_alloc(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint16_t PIOS_COM_TxOutCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield);
|
||||
static uint16_t PIOS_COM_RxInCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield);
|
||||
static void PIOS_COM_UnblockRx(struct pios_com_dev * com_dev, bool * need_yield);
|
||||
static void PIOS_COM_UnblockTx(struct pios_com_dev * com_dev, bool * need_yield);
|
||||
|
||||
/**
|
||||
* Initialises COM layer
|
||||
* \param[out] handle
|
||||
@ -77,10 +110,12 @@ static struct pios_com_dev * PIOS_COM_alloc(void)
|
||||
* \param[in] id
|
||||
* \return < 0 if initialisation failed
|
||||
*/
|
||||
int32_t PIOS_COM_Init(uint32_t * com_id, const struct pios_com_driver * driver, const uint32_t lower_id)
|
||||
int32_t PIOS_COM_Init(uint32_t * com_id, const struct pios_com_driver * driver, uint32_t lower_id)
|
||||
{
|
||||
PIOS_DEBUG_Assert(com_id);
|
||||
PIOS_DEBUG_Assert(driver);
|
||||
PIOS_Assert(com_id);
|
||||
PIOS_Assert(driver);
|
||||
PIOS_Assert(driver->bind_tx_cb);
|
||||
PIOS_Assert(driver->bind_rx_cb);
|
||||
|
||||
struct pios_com_dev * com_dev;
|
||||
|
||||
@ -88,8 +123,26 @@ int32_t PIOS_COM_Init(uint32_t * com_id, const struct pios_com_driver * driver,
|
||||
if (!com_dev) goto out_fail;
|
||||
|
||||
com_dev->driver = driver;
|
||||
com_dev->id = lower_id;
|
||||
com_dev->lower_id = lower_id;
|
||||
|
||||
/* Clear buffer counters */
|
||||
fifoBuf_init(&com_dev->rx, com_dev->rx_buffer, sizeof(com_dev->rx_buffer));
|
||||
fifoBuf_init(&com_dev->tx, com_dev->tx_buffer, sizeof(com_dev->tx_buffer));
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
/* Create semaphores before binding callbacks */
|
||||
vSemaphoreCreateBinary(com_dev->rx_sem);
|
||||
vSemaphoreCreateBinary(com_dev->tx_sem);
|
||||
#endif
|
||||
/* Bind our callbacks into the lower layer */
|
||||
(com_dev->driver->bind_rx_cb)(lower_id, PIOS_COM_RxInCallback, (uint32_t)com_dev);
|
||||
(com_dev->driver->bind_tx_cb)(lower_id, PIOS_COM_TxOutCallback, (uint32_t)com_dev);
|
||||
|
||||
if (com_dev->driver->rx_start) {
|
||||
/* Start the receiver */
|
||||
(com_dev->driver->rx_start)(com_dev->lower_id,
|
||||
fifoBuf_getFree(&com_dev->rx));
|
||||
}
|
||||
*com_id = (uint32_t)com_dev;
|
||||
return(0);
|
||||
|
||||
@ -97,6 +150,86 @@ out_fail:
|
||||
return(-1);
|
||||
}
|
||||
|
||||
static void PIOS_COM_UnblockRx(struct pios_com_dev * com_dev, bool * need_yield)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
static signed portBASE_TYPE xHigherPriorityTaskWoken;
|
||||
xSemaphoreGiveFromISR(com_dev->rx_sem, &xHigherPriorityTaskWoken);
|
||||
|
||||
if (xHigherPriorityTaskWoken != pdFALSE) {
|
||||
*need_yield = true;
|
||||
} else {
|
||||
*need_yield = false;
|
||||
}
|
||||
#else
|
||||
*need_yield = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void PIOS_COM_UnblockTx(struct pios_com_dev * com_dev, bool * need_yield)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
static signed portBASE_TYPE xHigherPriorityTaskWoken;
|
||||
xSemaphoreGiveFromISR(com_dev->tx_sem, &xHigherPriorityTaskWoken);
|
||||
|
||||
if (xHigherPriorityTaskWoken != pdFALSE) {
|
||||
*need_yield = true;
|
||||
} else {
|
||||
*need_yield = false;
|
||||
}
|
||||
#else
|
||||
*need_yield = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint16_t PIOS_COM_RxInCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield)
|
||||
{
|
||||
struct pios_com_dev * com_dev = (struct pios_com_dev *)context;
|
||||
|
||||
bool valid = PIOS_COM_validate(com_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
PIOS_IRQ_Disable();
|
||||
uint16_t bytes_into_fifo = fifoBuf_putData(&com_dev->rx, buf, buf_len);
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
if (bytes_into_fifo > 0) {
|
||||
/* Data has been added to the buffer */
|
||||
PIOS_COM_UnblockRx(com_dev, need_yield);
|
||||
}
|
||||
|
||||
if (headroom) {
|
||||
*headroom = fifoBuf_getFree(&com_dev->rx);
|
||||
}
|
||||
|
||||
return (bytes_into_fifo);
|
||||
}
|
||||
|
||||
static uint16_t PIOS_COM_TxOutCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield)
|
||||
{
|
||||
struct pios_com_dev * com_dev = (struct pios_com_dev *)context;
|
||||
|
||||
bool valid = PIOS_COM_validate(com_dev);
|
||||
PIOS_Assert(valid);
|
||||
PIOS_Assert(buf);
|
||||
PIOS_Assert(buf_len);
|
||||
|
||||
PIOS_IRQ_Disable();
|
||||
uint16_t bytes_from_fifo = fifoBuf_getData(&com_dev->tx, buf, buf_len);
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
if (bytes_from_fifo > 0) {
|
||||
/* More space has been made in the buffer */
|
||||
PIOS_COM_UnblockTx(com_dev, need_yield);
|
||||
}
|
||||
|
||||
if (headroom) {
|
||||
*headroom = fifoBuf_getUsed(&com_dev->tx);
|
||||
}
|
||||
|
||||
return (bytes_from_fifo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the port speed without re-initializing
|
||||
* \param[in] port COM port
|
||||
@ -115,7 +248,7 @@ int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud)
|
||||
|
||||
/* Invoke the driver function if it exists */
|
||||
if (com_dev->driver->set_baud) {
|
||||
com_dev->driver->set_baud(com_dev->id, baud);
|
||||
com_dev->driver->set_baud(com_dev->lower_id, baud);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -140,12 +273,24 @@ int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, u
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Invoke the driver function if it exists */
|
||||
if (com_dev->driver->tx_nb) {
|
||||
return com_dev->driver->tx_nb(com_dev->id, buffer, len);
|
||||
if (len >= fifoBuf_getFree(&com_dev->tx)) {
|
||||
/* Buffer cannot accept all requested bytes (retry) */
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
PIOS_IRQ_Disable();
|
||||
uint16_t bytes_into_fifo = fifoBuf_putData(&com_dev->tx, buffer, len);
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
if (bytes_into_fifo > 0) {
|
||||
/* More data has been put in the tx buffer, make sure the tx is started */
|
||||
if (com_dev->driver->tx_start) {
|
||||
com_dev->driver->tx_start(com_dev->lower_id,
|
||||
fifoBuf_getUsed(&com_dev->tx));
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,12 +311,25 @@ int32_t PIOS_COM_SendBuffer(uint32_t com_id, const uint8_t *buffer, uint16_t len
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Invoke the driver function if it exists */
|
||||
if (com_dev->driver->tx) {
|
||||
return com_dev->driver->tx(com_dev->id, buffer, len);
|
||||
}
|
||||
int32_t rc;
|
||||
do {
|
||||
rc = PIOS_COM_SendBufferNonBlocking(com_id, buffer, len);
|
||||
|
||||
return 0;
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (rc == -2) {
|
||||
/* Make sure the transmitter is running while we wait */
|
||||
if (com_dev->driver->tx_start) {
|
||||
(com_dev->driver->tx_start)(com_dev->lower_id,
|
||||
fifoBuf_getUsed(&com_dev->tx));
|
||||
}
|
||||
if (xSemaphoreTake(com_dev->tx_sem, portMAX_DELAY) != pdTRUE) {
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} while (rc == -2);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -273,18 +431,46 @@ int32_t PIOS_COM_SendFormattedString(uint32_t com_id, const char *format, ...)
|
||||
* \param[in] port COM port
|
||||
* \returns Byte from buffer
|
||||
*/
|
||||
uint8_t PIOS_COM_ReceiveBuffer(uint32_t com_id)
|
||||
uint16_t PIOS_COM_ReceiveBuffer(uint32_t com_id, uint8_t * buf, uint16_t buf_len, uint32_t timeout_ms)
|
||||
{
|
||||
PIOS_Assert(buf);
|
||||
PIOS_Assert(buf_len);
|
||||
|
||||
struct pios_com_dev * com_dev = (struct pios_com_dev *)com_id;
|
||||
|
||||
if (!PIOS_COM_validate(com_dev)) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
PIOS_DEBUG_Assert(0);
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
PIOS_DEBUG_Assert(com_dev->driver->rx);
|
||||
check_again:
|
||||
PIOS_IRQ_Disable();
|
||||
uint16_t bytes_from_fifo = fifoBuf_getData(&com_dev->rx, buf, buf_len);
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
return com_dev->driver->rx(com_dev->id);
|
||||
if (bytes_from_fifo == 0 && timeout_ms > 0) {
|
||||
/* No more bytes in receive buffer */
|
||||
/* Make sure the receiver is running while we wait */
|
||||
if (com_dev->driver->rx_start) {
|
||||
/* Notify the lower layer that there is now room in the rx buffer */
|
||||
(com_dev->driver->rx_start)(com_dev->lower_id,
|
||||
fifoBuf_getFree(&com_dev->rx));
|
||||
}
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (xSemaphoreTake(com_dev->rx_sem, timeout_ms / portTICK_RATE_MS) == pdTRUE) {
|
||||
/* Make sure we don't come back here again */
|
||||
timeout_ms = 0;
|
||||
goto check_again;
|
||||
}
|
||||
#else
|
||||
PIOS_DELAY_WaitmS(1);
|
||||
timeout_ms--;
|
||||
goto check_again;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return received byte */
|
||||
return (bytes_from_fifo);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -298,16 +484,10 @@ int32_t PIOS_COM_ReceiveBufferUsed(uint32_t com_id)
|
||||
|
||||
if (!PIOS_COM_validate(com_dev)) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
/* This is commented out so com_id=NULL can be used to disable telemetry */
|
||||
//PIOS_DEBUG_Assert(0);
|
||||
return 0;
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
if (!com_dev->driver->rx_avail) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return com_dev->driver->rx_avail(com_dev->id);
|
||||
return (fifoBuf_getUsed(&com_dev->rx));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -56,7 +56,7 @@ static struct pios_rcvr_dev * PIOS_RCVR_alloc(void)
|
||||
* \param[in] id
|
||||
* \return < 0 if initialisation failed
|
||||
*/
|
||||
int32_t PIOS_RCVR_Init(uint32_t * rcvr_id, const struct pios_rcvr_driver * driver, const uint32_t lower_id)
|
||||
int32_t PIOS_RCVR_Init(uint32_t * rcvr_id, const struct pios_rcvr_driver * driver, uint32_t lower_id)
|
||||
{
|
||||
PIOS_DEBUG_Assert(rcvr_id);
|
||||
PIOS_DEBUG_Assert(driver);
|
||||
@ -82,7 +82,7 @@ int32_t PIOS_RCVR_Read(uint32_t rcvr_id, uint8_t channel)
|
||||
|
||||
if (!PIOS_RCVR_validate(rcvr_dev)) {
|
||||
/* Undefined RCVR port for this board (see pios_board.c) */
|
||||
PIOS_DEBUG_Assert(0);
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
PIOS_DEBUG_Assert(rcvr_dev->driver->read);
|
||||
|
@ -35,7 +35,7 @@
|
||||
#if defined(PIOS_INCLUDE_PWM)
|
||||
|
||||
/* Provide a RCVR driver */
|
||||
static int32_t PIOS_PWM_Get(uint32_t rcvr_id, uint8_t chan_id);
|
||||
static int32_t PIOS_PWM_Get(uint32_t rcvr_id, uint8_t channel);
|
||||
|
||||
const struct pios_rcvr_driver pios_pwm_rcvr_driver = {
|
||||
.read = PIOS_PWM_Get,
|
||||
|
@ -132,10 +132,30 @@ static void process_byte(uint8_t b)
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t PIOS_SBUS_RxInCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield)
|
||||
{
|
||||
/* process byte(s) and clear receive timer */
|
||||
for (uint8_t i = 0; i < buf_len; i++) {
|
||||
process_byte(buf[i]);
|
||||
receive_timer = 0;
|
||||
}
|
||||
|
||||
/* Always signal that we can accept another byte */
|
||||
if (headroom) {
|
||||
*headroom = SBUS_FRAME_LENGTH;
|
||||
}
|
||||
|
||||
/* We never need a yield */
|
||||
*need_yield = false;
|
||||
|
||||
/* Always indicate that all bytes were consumed */
|
||||
return (buf_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise S.Bus receiver interface
|
||||
*/
|
||||
void PIOS_SBUS_Init(const struct pios_sbus_cfg *cfg)
|
||||
int32_t PIOS_SBUS_Init(uint32_t * sbus_id, const struct pios_sbus_cfg *cfg, const struct pios_com_driver * driver, uint32_t lower_id)
|
||||
{
|
||||
/* Enable inverter clock and enable the inverter */
|
||||
(*cfg->gpio_clk_func)(cfg->gpio_clk_periph, ENABLE);
|
||||
@ -144,9 +164,13 @@ void PIOS_SBUS_Init(const struct pios_sbus_cfg *cfg)
|
||||
cfg->inv.init.GPIO_Pin,
|
||||
cfg->gpio_inv_enable);
|
||||
|
||||
(driver->bind_rx_cb)(lower_id, PIOS_SBUS_RxInCallback, 0);
|
||||
|
||||
if (!PIOS_RTC_RegisterTickCallback(PIOS_SBUS_Supervisor, 0)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,34 +188,6 @@ static int32_t PIOS_SBUS_Get(uint32_t rcvr_id, uint8_t channel)
|
||||
return channel_data[channel];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupt handler for USART
|
||||
*/
|
||||
void PIOS_SBUS_irq_handler(uint32_t usart_id)
|
||||
{
|
||||
/* Grab the config for this device from the underlying USART device */
|
||||
const struct pios_usart_cfg * cfg;
|
||||
cfg = PIOS_USART_GetConfig(usart_id);
|
||||
PIOS_Assert(cfg);
|
||||
|
||||
/* by always reading DR after SR make sure to clear any error interrupts */
|
||||
volatile uint16_t sr = cfg->regs->SR;
|
||||
volatile uint8_t b = cfg->regs->DR;
|
||||
|
||||
/* process received byte if one has arrived */
|
||||
if (sr & USART_SR_RXNE) {
|
||||
/* process byte and clear receive timer */
|
||||
process_byte(b);
|
||||
receive_timer = 0;
|
||||
}
|
||||
|
||||
/* ignore TXE interrupts */
|
||||
if (sr & USART_SR_TXE) {
|
||||
/* disable TXE interrupt (TXEIE=0) */
|
||||
USART_ITConfig(cfg->regs, USART_IT_TXE, DISABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Input data supervisor is called periodically and provides
|
||||
* two functions: frame syncing and failsafe triggering.
|
||||
|
@ -60,20 +60,45 @@ uint16_t supv_timer=0;
|
||||
|
||||
static void PIOS_SPEKTRUM_Supervisor(uint32_t spektrum_id);
|
||||
static bool PIOS_SPEKTRUM_Bind(const struct pios_spektrum_cfg * cfg);
|
||||
static int32_t PIOS_SPEKTRUM_Decode(uint8_t b);
|
||||
|
||||
static uint16_t PIOS_SPEKTRUM_RxInCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield)
|
||||
{
|
||||
/* process byte(s) and clear receive timer */
|
||||
for (uint8_t i = 0; i < buf_len; i++) {
|
||||
PIOS_SPEKTRUM_Decode(buf[i]);
|
||||
supv_timer = 0;
|
||||
}
|
||||
|
||||
/* Always signal that we can accept another byte */
|
||||
if (headroom) {
|
||||
*headroom = 1;
|
||||
}
|
||||
|
||||
/* We never need a yield */
|
||||
*need_yield = false;
|
||||
|
||||
/* Always indicate that all bytes were consumed */
|
||||
return (buf_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind and Initialise Spektrum satellite receiver
|
||||
*/
|
||||
void PIOS_SPEKTRUM_Init(const struct pios_spektrum_cfg * cfg, bool bind)
|
||||
int32_t PIOS_SPEKTRUM_Init(uint32_t * spektrum_id, const struct pios_spektrum_cfg *cfg, const struct pios_com_driver * driver, uint32_t lower_id, bool bind)
|
||||
{
|
||||
// TODO: need setting flag for bind on next powerup
|
||||
if (bind) {
|
||||
PIOS_SPEKTRUM_Bind(cfg);
|
||||
}
|
||||
|
||||
(driver->bind_rx_cb)(lower_id, PIOS_SPEKTRUM_RxInCallback, 0);
|
||||
|
||||
if (!PIOS_RTC_RegisterTickCallback(PIOS_SPEKTRUM_Supervisor, 0)) {
|
||||
PIOS_DEBUG_Assert(0);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,32 +229,6 @@ static int32_t PIOS_SPEKTRUM_Decode(uint8_t b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Custom interrupt handler for USART */
|
||||
void PIOS_SPEKTRUM_irq_handler(uint32_t usart_id) {
|
||||
/* Grab the config for this device from the underlying USART device */
|
||||
const struct pios_usart_cfg * cfg;
|
||||
cfg = PIOS_USART_GetConfig(usart_id);
|
||||
PIOS_Assert(cfg);
|
||||
|
||||
/* by always reading DR after SR make sure to clear any error interrupts */
|
||||
volatile uint16_t sr = cfg->regs->SR;
|
||||
volatile uint8_t b = cfg->regs->DR;
|
||||
|
||||
/* check if RXNE flag is set */
|
||||
if (sr & USART_SR_RXNE) {
|
||||
if (PIOS_SPEKTRUM_Decode(b) < 0) {
|
||||
/* Here we could add some error handling */
|
||||
}
|
||||
}
|
||||
|
||||
if (sr & USART_SR_TXE) { // check if TXE flag is set
|
||||
/* Disable TXE interrupt (TXEIE=0) */
|
||||
USART_ITConfig(cfg->regs, USART_IT_TXE, DISABLE);
|
||||
}
|
||||
/* byte arrived so clear "watchdog" timer */
|
||||
supv_timer=0;
|
||||
}
|
||||
|
||||
/**
|
||||
*@brief This function is called between frames and when a spektrum word hasnt been decoded for too long
|
||||
*@brief clears the channel values
|
||||
|
@ -38,17 +38,17 @@
|
||||
|
||||
/* Provide a COM driver */
|
||||
static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud);
|
||||
static int32_t PIOS_USART_TxBufferPutMoreNonBlocking(uint32_t usart_id, const uint8_t *buffer, uint16_t len);
|
||||
static int32_t PIOS_USART_TxBufferPutMore(uint32_t usart_id, const uint8_t *buffer, uint16_t len);
|
||||
static int32_t PIOS_USART_RxBufferGet(uint32_t usart_id);
|
||||
static int32_t PIOS_USART_RxBufferUsed(uint32_t usart_id);
|
||||
static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback rx_in_cb, uint32_t context);
|
||||
static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback tx_out_cb, uint32_t context);
|
||||
static void PIOS_USART_TxStart(uint32_t usart_id, uint16_t tx_bytes_avail);
|
||||
static void PIOS_USART_RxStart(uint32_t usart_id, uint16_t rx_bytes_avail);
|
||||
|
||||
const struct pios_com_driver pios_usart_com_driver = {
|
||||
.set_baud = PIOS_USART_ChangeBaud,
|
||||
.tx_nb = PIOS_USART_TxBufferPutMoreNonBlocking,
|
||||
.tx = PIOS_USART_TxBufferPutMore,
|
||||
.rx = PIOS_USART_RxBufferGet,
|
||||
.rx_avail = PIOS_USART_RxBufferUsed,
|
||||
.tx_start = PIOS_USART_TxStart,
|
||||
.rx_start = PIOS_USART_RxStart,
|
||||
.bind_tx_cb = PIOS_USART_RegisterTxCallback,
|
||||
.bind_rx_cb = PIOS_USART_RegisterRxCallback,
|
||||
};
|
||||
|
||||
enum pios_usart_dev_magic {
|
||||
@ -59,13 +59,10 @@ struct pios_usart_dev {
|
||||
enum pios_usart_dev_magic magic;
|
||||
const struct pios_usart_cfg * cfg;
|
||||
|
||||
// align to 32-bit to try and provide speed improvement;
|
||||
uint8_t rx_buffer[PIOS_USART_RX_BUFFER_SIZE] __attribute__ ((aligned(4)));
|
||||
t_fifo_buffer rx;
|
||||
|
||||
// align to 32-bit to try and provide speed improvement;
|
||||
uint8_t tx_buffer[PIOS_USART_TX_BUFFER_SIZE] __attribute__ ((aligned(4)));
|
||||
t_fifo_buffer tx;
|
||||
pios_com_callback rx_in_cb;
|
||||
uint32_t rx_in_context;
|
||||
pios_com_callback tx_out_cb;
|
||||
uint32_t tx_out_context;
|
||||
};
|
||||
|
||||
static bool PIOS_USART_validate(struct pios_usart_dev * usart_dev)
|
||||
@ -147,10 +144,6 @@ int32_t PIOS_USART_Init(uint32_t * usart_id, const struct pios_usart_cfg * cfg)
|
||||
/* Bind the configuration to the device instance */
|
||||
usart_dev->cfg = cfg;
|
||||
|
||||
/* Clear buffer counters */
|
||||
fifoBuf_init(&usart_dev->rx, usart_dev->rx_buffer, sizeof(usart_dev->rx_buffer));
|
||||
fifoBuf_init(&usart_dev->tx, usart_dev->tx_buffer, sizeof(usart_dev->tx_buffer));
|
||||
|
||||
/* Enable the USART Pins Software Remapping */
|
||||
if (usart_dev->cfg->remap) {
|
||||
GPIO_PinRemapConfig(usart_dev->cfg->remap, ENABLE);
|
||||
@ -203,17 +196,23 @@ out_fail:
|
||||
return(-1);
|
||||
}
|
||||
|
||||
const struct pios_usart_cfg * PIOS_USART_GetConfig(uint32_t usart_id)
|
||||
static void PIOS_USART_RxStart(uint32_t usart_id, uint16_t rx_bytes_avail)
|
||||
{
|
||||
struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
|
||||
|
||||
bool valid = PIOS_USART_validate(usart_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
if (!valid) {
|
||||
return (NULL);
|
||||
}
|
||||
USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE);
|
||||
}
|
||||
static void PIOS_USART_TxStart(uint32_t usart_id, uint16_t tx_bytes_avail)
|
||||
{
|
||||
struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
|
||||
|
||||
return usart_dev->cfg;
|
||||
bool valid = PIOS_USART_validate(usart_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -240,170 +239,26 @@ static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud)
|
||||
USART_Init(usart_dev->cfg->regs, &USART_InitStructure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of used bytes in receive buffer
|
||||
* \param[in] USART USART name
|
||||
* \return > 0: number of used bytes
|
||||
* \return 0 if USART not available
|
||||
*/
|
||||
static int32_t PIOS_USART_RxBufferUsed(uint32_t usart_id)
|
||||
static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback rx_in_cb, uint32_t context)
|
||||
{
|
||||
struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
|
||||
|
||||
bool valid = PIOS_USART_validate(usart_dev);
|
||||
PIOS_Assert(valid)
|
||||
PIOS_Assert(valid);
|
||||
|
||||
return (fifoBuf_getUsed(&usart_dev->rx));
|
||||
usart_dev->rx_in_cb = rx_in_cb;
|
||||
usart_dev->rx_in_context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a byte from the receive buffer
|
||||
* \param[in] USART USART name
|
||||
* \return -1 if no new byte available
|
||||
* \return >= 0: actual byte received
|
||||
*/
|
||||
static int32_t PIOS_USART_RxBufferGet(uint32_t usart_id)
|
||||
static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback tx_out_cb, uint32_t context)
|
||||
{
|
||||
struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
|
||||
|
||||
bool valid = PIOS_USART_validate(usart_dev);
|
||||
PIOS_Assert(valid)
|
||||
PIOS_Assert(valid);
|
||||
|
||||
if (fifoBuf_getUsed(&usart_dev->rx) == 0) {
|
||||
/* Nothing new in the buffer */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get byte - this operation should be atomic! */
|
||||
uint8_t b = fifoBuf_getByte(&usart_dev->rx);
|
||||
|
||||
/* Return received byte */
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* puts a byte onto the receive buffer
|
||||
* \param[in] USART USART name
|
||||
* \param[in] b byte which should be put into Rx buffer
|
||||
* \return 0 if no error
|
||||
* \return -1 if buffer full (retry)
|
||||
*/
|
||||
static int32_t PIOS_USART_RxBufferPut(uint32_t usart_id, uint8_t b)
|
||||
{
|
||||
struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
|
||||
|
||||
bool valid = PIOS_USART_validate(usart_dev);
|
||||
PIOS_Assert(valid)
|
||||
|
||||
if (fifoBuf_getFree(&usart_dev->rx) < 1) {
|
||||
/* Buffer full (retry) */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy received byte into receive buffer */
|
||||
/* This operation should be atomic! */
|
||||
fifoBuf_putByte(&usart_dev->rx, b);
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns number of used bytes in transmit buffer
|
||||
* \param[in] USART USART name
|
||||
* \return number of used bytes
|
||||
* \return 0 if USART not available
|
||||
*/
|
||||
static int32_t PIOS_USART_TxBufferUsed(uint32_t usart_id)
|
||||
{
|
||||
struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
|
||||
|
||||
bool valid = PIOS_USART_validate(usart_dev);
|
||||
PIOS_Assert(valid)
|
||||
|
||||
return (fifoBuf_getUsed(&usart_dev->tx));
|
||||
}
|
||||
|
||||
/**
|
||||
* gets a byte from the transmit buffer
|
||||
* \param[in] USART USART name
|
||||
* \return -1 if no new byte available
|
||||
* \return >= 0: transmitted byte
|
||||
*/
|
||||
static int32_t PIOS_USART_TxBufferGet(uint32_t usart_id)
|
||||
{
|
||||
struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
|
||||
|
||||
bool valid = PIOS_USART_validate(usart_dev);
|
||||
PIOS_Assert(valid)
|
||||
|
||||
if (fifoBuf_getUsed(&usart_dev->tx) == 0) {
|
||||
/* Nothing new in the buffer */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get byte - this operation should be atomic! */
|
||||
PIOS_IRQ_Disable();
|
||||
uint8_t b = fifoBuf_getByte(&usart_dev->tx);
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
/* Return received byte */
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* puts more than one byte onto the transmit buffer (used for atomic sends)
|
||||
* \param[in] USART USART name
|
||||
* \param[in] *buffer pointer to buffer to be sent
|
||||
* \param[in] len number of bytes to be sent
|
||||
* \return 0 if no error
|
||||
* \return -1 if buffer full or cannot get all requested bytes (retry)
|
||||
*/
|
||||
static int32_t PIOS_USART_TxBufferPutMoreNonBlocking(uint32_t usart_id, const uint8_t *buffer, uint16_t len)
|
||||
{
|
||||
struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
|
||||
|
||||
bool valid = PIOS_USART_validate(usart_dev);
|
||||
PIOS_Assert(valid)
|
||||
|
||||
if (len >= fifoBuf_getFree(&usart_dev->tx)) {
|
||||
/* Buffer cannot accept all requested bytes (retry) */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy bytes to be transmitted into transmit buffer */
|
||||
/* This operation should be atomic! */
|
||||
PIOS_IRQ_Disable();
|
||||
|
||||
uint16_t used = fifoBuf_getUsed(&usart_dev->tx);
|
||||
fifoBuf_putData(&usart_dev->tx,buffer,len);
|
||||
|
||||
if (used == 0) {
|
||||
/* enable sending when buffer was previously empty */
|
||||
USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
|
||||
}
|
||||
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* puts more than one byte onto the transmit buffer (used for atomic sends)<BR>
|
||||
* (blocking function)
|
||||
* \param[in] USART USART name
|
||||
* \param[in] *buffer pointer to buffer to be sent
|
||||
* \param[in] len number of bytes to be sent
|
||||
* \return 0 if no error
|
||||
*/
|
||||
static int32_t PIOS_USART_TxBufferPutMore(uint32_t usart_id, const uint8_t *buffer, uint16_t len)
|
||||
{
|
||||
int32_t rc;
|
||||
|
||||
while ((rc = PIOS_USART_TxBufferPutMoreNonBlocking(usart_id, buffer, len)) == -1);
|
||||
|
||||
return rc;
|
||||
usart_dev->tx_out_cb = tx_out_cb;
|
||||
usart_dev->tx_out_context = context;
|
||||
}
|
||||
|
||||
static void PIOS_USART_generic_irq_handler(uint32_t usart_id)
|
||||
@ -413,41 +268,46 @@ static void PIOS_USART_generic_irq_handler(uint32_t usart_id)
|
||||
bool valid = PIOS_USART_validate(usart_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
/* Call any user provided callback function instead of processing
|
||||
* the interrupt ourselves.
|
||||
*/
|
||||
if (usart_dev->cfg->irq.handler) {
|
||||
(usart_dev->cfg->irq.handler)(usart_id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Force read of dr after sr to make sure to clear error flags */
|
||||
volatile uint16_t sr = usart_dev->cfg->regs->SR;
|
||||
volatile uint8_t dr = usart_dev->cfg->regs->DR;
|
||||
|
||||
/* Check if RXNE flag is set */
|
||||
bool rx_need_yield = false;
|
||||
if (sr & USART_SR_RXNE) {
|
||||
if (PIOS_USART_RxBufferPut(usart_id, dr) < 0) {
|
||||
/* Here we could add some error handling */
|
||||
uint8_t byte = dr;
|
||||
if (usart_dev->rx_in_cb) {
|
||||
(void) (usart_dev->rx_in_cb)(usart_dev->rx_in_context, &byte, 1, NULL, &rx_need_yield);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if TXE flag is set */
|
||||
bool tx_need_yield = false;
|
||||
if (sr & USART_SR_TXE) {
|
||||
if (PIOS_USART_TxBufferUsed(usart_id) > 0) {
|
||||
int32_t b = PIOS_USART_TxBufferGet(usart_id);
|
||||
if (usart_dev->tx_out_cb) {
|
||||
uint8_t b;
|
||||
uint16_t bytes_to_send;
|
||||
|
||||
if (b < 0) {
|
||||
/* Here we could add some error handling */
|
||||
usart_dev->cfg->regs->DR = 0xff;
|
||||
bytes_to_send = (usart_dev->tx_out_cb)(usart_dev->tx_out_context, &b, 1, NULL, &tx_need_yield);
|
||||
|
||||
if (bytes_to_send > 0) {
|
||||
/* Send the byte we've been given */
|
||||
usart_dev->cfg->regs->DR = b;
|
||||
} else {
|
||||
usart_dev->cfg->regs->DR = b & 0xff;
|
||||
/* No bytes to send, disable TXE interrupt */
|
||||
USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
|
||||
}
|
||||
} else {
|
||||
/* Disable TXE interrupt (TXEIE=0) */
|
||||
/* No bytes to send, disable TXE interrupt */
|
||||
USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (rx_need_yield || tx_need_yield) {
|
||||
vPortYieldFromISR();
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -36,76 +36,106 @@
|
||||
#include "usb_lib.h"
|
||||
#include "pios_usb_hid_desc.h"
|
||||
#include "stm32f10x.h"
|
||||
#include "fifo_buffer.h"
|
||||
|
||||
#include "pios_usb_hid_priv.h"
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
#define USE_FREERTOS
|
||||
#endif
|
||||
|
||||
static int32_t PIOS_USB_HID_TxBufferPutMoreNonBlocking(uint32_t usbcom_id, const uint8_t *buffer, uint16_t len);
|
||||
static int32_t PIOS_USB_HID_TxBufferPutMore(uint32_t usbcom_id, const uint8_t *buffer, uint16_t len);
|
||||
static int32_t PIOS_USB_HID_RxBufferGet(uint32_t usbcom_id);
|
||||
static int32_t PIOS_USB_HID_RxBufferUsed(uint32_t usbcom_id);
|
||||
static void PIOS_USB_HID_TxStart(uint32_t usbcom_id, uint16_t tx_bytes_avail);
|
||||
static void PIOS_USB_HID_RxStart(uint32_t usbcom_id, uint16_t rx_bytes_avail);
|
||||
static void PIOS_USB_HID_RegisterTxCallback(uint32_t usbcom_id, pios_com_callback tx_out_cb, uint32_t context);
|
||||
static void PIOS_USB_HID_RegisterRxCallback(uint32_t usbcom_id, pios_com_callback rx_in_cb, uint32_t context);
|
||||
|
||||
const struct pios_com_driver pios_usb_com_driver = {
|
||||
.tx_nb = PIOS_USB_HID_TxBufferPutMoreNonBlocking,
|
||||
.tx = PIOS_USB_HID_TxBufferPutMore,
|
||||
.rx = PIOS_USB_HID_RxBufferGet,
|
||||
.rx_avail = PIOS_USB_HID_RxBufferUsed,
|
||||
.tx_start = PIOS_USB_HID_TxStart,
|
||||
.rx_start = PIOS_USB_HID_RxStart,
|
||||
.bind_tx_cb = PIOS_USB_HID_RegisterTxCallback,
|
||||
.bind_rx_cb = PIOS_USB_HID_RegisterRxCallback,
|
||||
};
|
||||
|
||||
// TODO: Eventually replace the transmit and receive buffers with bigger ring bufers
|
||||
// so there isn't hte 64 byte cap in place by the USB interrupt packet definition
|
||||
enum pios_usb_hid_dev_magic {
|
||||
PIOS_USB_HID_DEV_MAGIC = 0xAABBCCDD,
|
||||
};
|
||||
|
||||
struct pios_usb_hid_dev {
|
||||
enum pios_usb_hid_dev_magic magic;
|
||||
const struct pios_usb_hid_cfg * cfg;
|
||||
|
||||
pios_com_callback rx_in_cb;
|
||||
uint32_t rx_in_context;
|
||||
pios_com_callback tx_out_cb;
|
||||
uint32_t tx_out_context;
|
||||
|
||||
uint8_t rx_packet_buffer[PIOS_USB_HID_DATA_LENGTH + 2];
|
||||
uint8_t tx_packet_buffer[PIOS_USB_HID_DATA_LENGTH + 2];
|
||||
};
|
||||
|
||||
static bool PIOS_USB_HID_validate(struct pios_usb_hid_dev * usb_hid_dev)
|
||||
{
|
||||
return (usb_hid_dev->magic == PIOS_USB_HID_DEV_MAGIC);
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS) && 0
|
||||
static struct pios_usb_hid_dev * PIOS_USB_HID_alloc(void)
|
||||
{
|
||||
struct pios_usb_hid_dev * usb_hid_dev;
|
||||
|
||||
usb_hid_dev = (struct pios_usb_hid_dev *)malloc(sizeof(*usb_hid_dev));
|
||||
if (!usb_hid_dev) return(NULL);
|
||||
|
||||
usb_hid_dev->magic = PIOS_USB_HID_DEV_MAGIC;
|
||||
return(usb_hid_dev);
|
||||
}
|
||||
#else
|
||||
static struct pios_usb_hid_dev pios_usb_hid_devs[PIOS_USB_HID_MAX_DEVS];
|
||||
static uint8_t pios_usb_hid_num_devs;
|
||||
static struct pios_usb_hid_dev * PIOS_USB_HID_alloc(void)
|
||||
{
|
||||
struct pios_usb_hid_dev * usb_hid_dev;
|
||||
|
||||
if (pios_usb_hid_num_devs >= PIOS_USB_HID_MAX_DEVS) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
usb_hid_dev = &pios_usb_hid_devs[pios_usb_hid_num_devs++];
|
||||
usb_hid_dev->magic = PIOS_USB_HID_DEV_MAGIC;
|
||||
|
||||
return (usb_hid_dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Rx/Tx status */
|
||||
static uint8_t transfer_possible = 0;
|
||||
static uint8_t rx_packet_buffer[PIOS_USB_HID_DATA_LENGTH + 2] = { 0 };
|
||||
static uint8_t tx_packet_buffer[PIOS_USB_HID_DATA_LENGTH + 2] = { 0 };
|
||||
|
||||
uint8_t rx_pios_fifo_buf[PIOS_USB_RX_BUFFER_SIZE] __attribute__ ((aligned(4))); // align to 32-bit to try and provide speed improvement
|
||||
t_fifo_buffer rx_pios_fifo_buffer;
|
||||
|
||||
uint8_t tx_pios_fifo_buf[PIOS_USB_TX_BUFFER_SIZE] __attribute__ ((aligned(4))); // align to 32-bit to try and provide speed improvement
|
||||
t_fifo_buffer tx_pios_fifo_buffer;
|
||||
|
||||
#if defined(USE_FREERTOS)
|
||||
xSemaphoreHandle pios_usb_tx_semaphore;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialises USB COM layer
|
||||
* \param[in] mode currently only mode 0 supported
|
||||
* \return < 0 if initialisation failed
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_USB_HID_Init(uint32_t mode)
|
||||
static uint32_t pios_usb_hid_id;
|
||||
int32_t PIOS_USB_HID_Init(uint32_t * usb_hid_id, const struct pios_usb_hid_cfg * cfg)
|
||||
{
|
||||
/* Currently only mode 0 supported */
|
||||
if (mode != 0) {
|
||||
/* Unsupported mode */
|
||||
return -1;
|
||||
}
|
||||
PIOS_Assert(usb_hid_id);
|
||||
PIOS_Assert(cfg);
|
||||
|
||||
fifoBuf_init(&rx_pios_fifo_buffer, rx_pios_fifo_buf, sizeof(rx_pios_fifo_buf));
|
||||
fifoBuf_init(&tx_pios_fifo_buffer, tx_pios_fifo_buf, sizeof(tx_pios_fifo_buf));
|
||||
struct pios_usb_hid_dev * usb_hid_dev;
|
||||
|
||||
usb_hid_dev = (struct pios_usb_hid_dev *) PIOS_USB_HID_alloc();
|
||||
if (!usb_hid_dev) goto out_fail;
|
||||
|
||||
/* Bind the configuration to the device instance */
|
||||
usb_hid_dev->cfg = cfg;
|
||||
|
||||
PIOS_USB_HID_Reenumerate();
|
||||
|
||||
/* Create semaphore before enabling interrupts */
|
||||
#if defined(USE_FREERTOS)
|
||||
vSemaphoreCreateBinary(pios_usb_tx_semaphore);
|
||||
#endif
|
||||
/*
|
||||
* This is a horrible hack to make this available to
|
||||
* the interrupt callbacks. This should go away ASAP.
|
||||
*/
|
||||
pios_usb_hid_id = (uint32_t) usb_hid_dev;
|
||||
|
||||
/* Enable the USB Interrupts */
|
||||
/* 2 bit for pre-emption priority, 2 bits for subpriority */
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
NVIC_Init(&usb_hid_dev->cfg->irq.init);
|
||||
|
||||
/* Select USBCLK source */
|
||||
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
|
||||
@ -122,7 +152,12 @@ int32_t PIOS_USB_HID_Init(uint32_t mode)
|
||||
USB_Init();
|
||||
USB_SIL_Init();
|
||||
|
||||
*usb_hid_id = (uint32_t) usb_hid_dev;
|
||||
|
||||
return 0; /* No error */
|
||||
|
||||
out_fail:
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -201,127 +236,118 @@ int32_t PIOS_USB_HID_CheckAvailable(uint8_t id)
|
||||
return (PIOS_USB_DETECT_GPIO_PORT->IDR & PIOS_USB_DETECT_GPIO_PIN) != 0 && transfer_possible ? 1 : 0;
|
||||
}
|
||||
|
||||
void sendChunk()
|
||||
static void PIOS_USB_HID_SendReport(struct pios_usb_hid_dev * usb_hid_dev)
|
||||
{
|
||||
uint16_t bytes_to_tx;
|
||||
|
||||
uint32_t size = fifoBuf_getUsed(&tx_pios_fifo_buffer);
|
||||
if ((size > 0) && (GetEPTxStatus(ENDP1) != EP_TX_VALID)) {
|
||||
if (size > PIOS_USB_HID_DATA_LENGTH)
|
||||
size = PIOS_USB_HID_DATA_LENGTH;
|
||||
if (!usb_hid_dev->tx_out_cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool need_yield = false;
|
||||
#ifdef USB_HID
|
||||
fifoBuf_getData(&tx_pios_fifo_buffer, &tx_packet_buffer[1], size + 1);
|
||||
tx_packet_buffer[0] = 1; /* report ID */
|
||||
bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context,
|
||||
&usb_hid_dev->tx_packet_buffer[1],
|
||||
sizeof(usb_hid_dev->tx_packet_buffer)-1,
|
||||
NULL,
|
||||
&need_yield);
|
||||
#else
|
||||
fifoBuf_getData(&tx_pios_fifo_buffer, &tx_packet_buffer[2], size);
|
||||
tx_packet_buffer[0] = 1; /* report ID */
|
||||
tx_packet_buffer[1] = size; /* valid data length */
|
||||
|
||||
bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context,
|
||||
&usb_hid_dev->tx_packet_buffer[2],
|
||||
sizeof(usb_hid_dev->tx_packet_buffer)-2,
|
||||
NULL,
|
||||
&need_yield);
|
||||
#endif
|
||||
if (bytes_to_tx == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
UserToPMABufferCopy((uint8_t *) tx_packet_buffer, GetEPTxAddr(EP1_IN & 0x7F), size + 2);
|
||||
SetEPTxCount((EP1_IN & 0x7F), PIOS_USB_HID_DATA_LENGTH + 2);
|
||||
/* Always set type as report ID */
|
||||
usb_hid_dev->tx_packet_buffer[0] = 1;
|
||||
|
||||
/* Send Buffer */
|
||||
#ifdef USB_HID
|
||||
UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer, GetEPTxAddr(EP1_IN & 0x7F), bytes_to_tx + 1);
|
||||
#else
|
||||
usb_hid_dev->tx_packet_buffer[1] = bytes_to_tx;
|
||||
UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer, GetEPTxAddr(EP1_IN & 0x7F), bytes_to_tx + 2);
|
||||
#endif
|
||||
/* Is this correct? Why do we always send the whole buffer? */
|
||||
SetEPTxCount((EP1_IN & 0x7F), sizeof(usb_hid_dev->tx_packet_buffer));
|
||||
SetEPTxValid(ENDP1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts more than one byte onto the transmit buffer (used for atomic sends)
|
||||
* \param[in] *buffer pointer to buffer which should be transmitted
|
||||
* \param[in] len number of bytes which should be transmitted
|
||||
* \return 0 if no error
|
||||
* \return -1 if port unavailable (disconnected)
|
||||
* \return -2 if too many bytes to be send
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
static int32_t PIOS_USB_HID_TxBufferPutMoreNonBlocking(uint32_t usbcom_id, const uint8_t * buffer, uint16_t len)
|
||||
{
|
||||
uint16_t ret;
|
||||
|
||||
if(!transfer_possible)
|
||||
return -1;
|
||||
|
||||
if (len > fifoBuf_getFree(&tx_pios_fifo_buffer)) {
|
||||
sendChunk(); /* Try and send what's in the buffer though */
|
||||
return -2; /* Cannot send all requested bytes */
|
||||
}
|
||||
|
||||
/* don't check returned bytes because it should always succeed */
|
||||
/* after previous thread and no meaningful way to deal with the */
|
||||
/* case it only buffers half the bytes */
|
||||
#if defined(USE_FREERTOS)
|
||||
if(!xSemaphoreTake(pios_usb_tx_semaphore,10 / portTICK_RATE_MS))
|
||||
return -3;
|
||||
#endif
|
||||
|
||||
ret = fifoBuf_putData(&tx_pios_fifo_buffer, buffer, len);
|
||||
|
||||
#if defined(USE_FREERTOS)
|
||||
xSemaphoreGive(pios_usb_tx_semaphore);
|
||||
#endif
|
||||
|
||||
sendChunk();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts more than one byte onto the transmit buffer (used for atomic sends)<br>
|
||||
* (Blocking Function)
|
||||
* \param[in] *buffer pointer to buffer which should be transmitted
|
||||
* \param[in] len number of bytes which should be transmitted
|
||||
* \return 0 if no error
|
||||
* \return -1 if too many bytes to be send
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
static int32_t PIOS_USB_HID_TxBufferPutMore(uint32_t usbcom_id, const uint8_t *buffer, uint16_t len)
|
||||
{
|
||||
if(len > (fifoBuf_getUsed(&tx_pios_fifo_buffer) + fifoBuf_getFree(&tx_pios_fifo_buffer)))
|
||||
return -1;
|
||||
|
||||
uint32_t error;
|
||||
while ((error = PIOS_USB_HID_TxBufferPutMoreNonBlocking(usbcom_id, buffer, len)) == -2) {
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
taskYIELD();
|
||||
#endif
|
||||
if (need_yield) {
|
||||
vPortYieldFromISR();
|
||||
}
|
||||
|
||||
return error;
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a byte from the receive buffer
|
||||
* \return -1 if no new byte available
|
||||
* \return >= 0: received byte
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
static int32_t PIOS_USB_HID_RxBufferGet(uint32_t usbcom_id)
|
||||
{
|
||||
uint8_t read;
|
||||
static void PIOS_USB_HID_RxStart(uint32_t usbcom_id, uint16_t rx_bytes_avail) {
|
||||
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usbcom_id;
|
||||
|
||||
if(fifoBuf_getUsed(&rx_pios_fifo_buffer) == 0)
|
||||
return -1;
|
||||
bool valid = PIOS_USB_HID_validate(usb_hid_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
read = fifoBuf_getByte(&rx_pios_fifo_buffer);
|
||||
if (!transfer_possible) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If endpoint was stalled and there is now space make it valid
|
||||
if ((GetEPRxStatus(ENDP1) != EP_RX_VALID) && (fifoBuf_getFree(&rx_pios_fifo_buffer) > 62)) {
|
||||
PIOS_IRQ_Disable();
|
||||
if ((GetEPRxStatus(ENDP1) != EP_RX_VALID) &&
|
||||
(rx_bytes_avail > PIOS_USB_HID_DATA_LENGTH)) {
|
||||
SetEPRxStatus(ENDP1, EP_RX_VALID);
|
||||
}
|
||||
return read;
|
||||
PIOS_IRQ_Enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of used bytes in receive buffer
|
||||
* \return > 0: number of used bytes
|
||||
* \return 0 nothing available
|
||||
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
static int32_t PIOS_USB_HID_RxBufferUsed(uint32_t usbcom_id)
|
||||
static void PIOS_USB_HID_TxStart(uint32_t usbcom_id, uint16_t tx_bytes_avail)
|
||||
{
|
||||
return fifoBuf_getUsed(&rx_pios_fifo_buffer);
|
||||
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usbcom_id;
|
||||
|
||||
bool valid = PIOS_USB_HID_validate(usb_hid_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
if (!transfer_possible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetEPTxStatus(ENDP1) == EP_TX_VALID) {
|
||||
/* Endpoint is already transmitting */
|
||||
return;
|
||||
}
|
||||
|
||||
PIOS_USB_HID_SendReport(usb_hid_dev);
|
||||
}
|
||||
|
||||
static void PIOS_USB_HID_RegisterRxCallback(uint32_t usbcom_id, pios_com_callback rx_in_cb, uint32_t context)
|
||||
{
|
||||
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usbcom_id;
|
||||
|
||||
bool valid = PIOS_USB_HID_validate(usb_hid_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
/*
|
||||
* Order is important in these assignments since ISR uses _cb
|
||||
* field to determine if it's ok to dereference _cb and _context
|
||||
*/
|
||||
usb_hid_dev->rx_in_context = context;
|
||||
usb_hid_dev->rx_in_cb = rx_in_cb;
|
||||
}
|
||||
|
||||
static void PIOS_USB_HID_RegisterTxCallback(uint32_t usbcom_id, pios_com_callback tx_out_cb, uint32_t context)
|
||||
{
|
||||
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usbcom_id;
|
||||
|
||||
bool valid = PIOS_USB_HID_validate(usb_hid_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
/*
|
||||
* Order is important in these assignments since ISR uses _cb
|
||||
* field to determine if it's ok to dereference _cb and _context
|
||||
*/
|
||||
usb_hid_dev->tx_out_context = context;
|
||||
usb_hid_dev->tx_out_cb = tx_out_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -330,7 +356,16 @@ static int32_t PIOS_USB_HID_RxBufferUsed(uint32_t usbcom_id)
|
||||
*/
|
||||
void PIOS_USB_HID_EP1_IN_Callback(void)
|
||||
{
|
||||
sendChunk();
|
||||
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)pios_usb_hid_id;
|
||||
|
||||
bool valid = PIOS_USB_HID_validate(usb_hid_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
if (!transfer_possible) {
|
||||
return;
|
||||
}
|
||||
|
||||
PIOS_USB_HID_SendReport(usb_hid_dev);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -338,28 +373,58 @@ void PIOS_USB_HID_EP1_IN_Callback(void)
|
||||
*/
|
||||
void PIOS_USB_HID_EP1_OUT_Callback(void)
|
||||
{
|
||||
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)pios_usb_hid_id;
|
||||
|
||||
bool valid = PIOS_USB_HID_validate(usb_hid_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
uint32_t DataLength = 0;
|
||||
|
||||
/* Read received data (63 bytes) */
|
||||
/* Get the number of received data on the selected Endpoint */
|
||||
DataLength = GetEPRxCount(ENDP1 & 0x7F);
|
||||
if (DataLength > sizeof(usb_hid_dev->rx_packet_buffer)) {
|
||||
DataLength = sizeof(usb_hid_dev->rx_packet_buffer);
|
||||
}
|
||||
|
||||
/* Use the memory interface function to write to the selected endpoint */
|
||||
PMAToUserBufferCopy((uint8_t *) &rx_packet_buffer[0], GetEPRxAddr(ENDP1 & 0x7F), DataLength);
|
||||
PMAToUserBufferCopy((uint8_t *) usb_hid_dev->rx_packet_buffer, GetEPRxAddr(ENDP1 & 0x7F), DataLength);
|
||||
|
||||
if (!usb_hid_dev->rx_in_cb) {
|
||||
/* No Rx call back registered, disable the receiver */
|
||||
SetEPRxStatus(ENDP1, EP_RX_NAK);
|
||||
return;
|
||||
}
|
||||
|
||||
/* The first byte is report ID (not checked), the second byte is the valid data length */
|
||||
uint16_t headroom;
|
||||
bool need_yield = false;
|
||||
#ifdef USB_HID
|
||||
fifoBuf_putData(&rx_pios_fifo_buffer, &rx_packet_buffer[1], PIOS_USB_HID_DATA_LENGTH + 1);
|
||||
(usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
|
||||
&usb_hid_dev->rx_packet_buffer[1],
|
||||
sizeof(usb_hid_dev->rx_packet_buffer)-1,
|
||||
&headroom,
|
||||
&need_yield);
|
||||
#else
|
||||
fifoBuf_putData(&rx_pios_fifo_buffer, &rx_packet_buffer[2], rx_packet_buffer[1]);
|
||||
(usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
|
||||
&usb_hid_dev->rx_packet_buffer[2],
|
||||
usb_hid_dev->rx_packet_buffer[1],
|
||||
&headroom,
|
||||
&need_yield);
|
||||
#endif
|
||||
|
||||
// Only reactivate endpoint if available space in buffer
|
||||
if (fifoBuf_getFree(&rx_pios_fifo_buffer) > 62) {
|
||||
if (headroom > PIOS_USB_HID_DATA_LENGTH) {
|
||||
/* We have room for a maximum length message */
|
||||
SetEPRxStatus(ENDP1, EP_RX_VALID);
|
||||
} else {
|
||||
/* Not enough room left for a message, apply backpressure */
|
||||
SetEPRxStatus(ENDP1, EP_RX_NAK);
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (need_yield) {
|
||||
vPortYieldFromISR();
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -32,17 +32,19 @@
|
||||
#ifndef PIOS_COM_H
|
||||
#define PIOS_COM_H
|
||||
|
||||
typedef uint16_t (*pios_com_callback)(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * task_woken);
|
||||
|
||||
struct pios_com_driver {
|
||||
void (*init)(uint32_t id);
|
||||
void (*set_baud)(uint32_t id, uint32_t baud);
|
||||
int32_t (*tx_nb)(uint32_t id, const uint8_t *buffer, uint16_t len);
|
||||
int32_t (*tx)(uint32_t id, const uint8_t *buffer, uint16_t len);
|
||||
int32_t (*rx)(uint32_t id);
|
||||
int32_t (*rx_avail)(uint32_t id);
|
||||
void (*tx_start)(uint32_t id, uint16_t tx_bytes_avail);
|
||||
void (*rx_start)(uint32_t id, uint16_t rx_bytes_avail);
|
||||
void (*bind_rx_cb)(uint32_t id, pios_com_callback rx_in_cb, uint32_t context);
|
||||
void (*bind_tx_cb)(uint32_t id, pios_com_callback tx_out_cb, uint32_t context);
|
||||
};
|
||||
|
||||
/* Public Functions */
|
||||
extern int32_t PIOS_COM_Init(uint32_t * com_id, const struct pios_com_driver * driver, const uint32_t lower_id);
|
||||
extern int32_t PIOS_COM_Init(uint32_t * com_id, const struct pios_com_driver * driver, uint32_t lower_id);
|
||||
extern int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud);
|
||||
extern int32_t PIOS_COM_SendCharNonBlocking(uint32_t com_id, char c);
|
||||
extern int32_t PIOS_COM_SendChar(uint32_t com_id, char c);
|
||||
@ -52,7 +54,7 @@ extern int32_t PIOS_COM_SendStringNonBlocking(uint32_t com_id, const char *str);
|
||||
extern int32_t PIOS_COM_SendString(uint32_t com_id, const char *str);
|
||||
extern int32_t PIOS_COM_SendFormattedStringNonBlocking(uint32_t com_id, const char *format, ...);
|
||||
extern int32_t PIOS_COM_SendFormattedString(uint32_t com_id, const char *format, ...);
|
||||
extern uint8_t PIOS_COM_ReceiveBuffer(uint32_t com_id);
|
||||
extern uint16_t PIOS_COM_ReceiveBuffer(uint32_t com_id, uint8_t * buf, uint16_t buf_len, uint32_t timeout_ms);
|
||||
extern int32_t PIOS_COM_ReceiveBufferUsed(uint32_t com_id);
|
||||
|
||||
#endif /* PIOS_COM_H */
|
||||
|
@ -34,16 +34,6 @@
|
||||
|
||||
#include <pios.h>
|
||||
|
||||
enum pios_com_dev_magic {
|
||||
PIOS_COM_DEV_MAGIC = 0xaa55aa55,
|
||||
};
|
||||
|
||||
struct pios_com_dev {
|
||||
enum pios_com_dev_magic magic;
|
||||
uint32_t id;
|
||||
const struct pios_com_driver * driver;
|
||||
};
|
||||
|
||||
extern int32_t PIOS_COM_ReceiveHandler(uint32_t com_id);
|
||||
|
||||
#endif /* PIOS_COM_PRIV_H */
|
||||
|
@ -75,11 +75,9 @@ struct pios_sbus_cfg {
|
||||
BitAction gpio_inv_enable;
|
||||
};
|
||||
|
||||
extern void PIOS_SBUS_irq_handler();
|
||||
|
||||
extern const struct pios_rcvr_driver pios_sbus_rcvr_driver;
|
||||
|
||||
extern void PIOS_SBUS_Init(const struct pios_sbus_cfg * cfg);
|
||||
extern int32_t PIOS_SBUS_Init(uint32_t * sbus_id, const struct pios_sbus_cfg *cfg, const struct pios_com_driver * driver, uint32_t lower_id);
|
||||
|
||||
#endif /* PIOS_SBUS_PRIV_H */
|
||||
|
||||
|
@ -40,11 +40,9 @@ struct pios_spektrum_cfg {
|
||||
uint32_t remap; /* GPIO_Remap_* */
|
||||
};
|
||||
|
||||
extern void PIOS_SPEKTRUM_irq_handler();
|
||||
|
||||
extern const struct pios_rcvr_driver pios_spektrum_rcvr_driver;
|
||||
|
||||
extern void PIOS_SPEKTRUM_Init(const struct pios_spektrum_cfg * cfg, bool bind);
|
||||
extern int32_t PIOS_SPEKTRUM_Init(uint32_t * spektrum_id, const struct pios_spektrum_cfg *cfg, const struct pios_com_driver * driver, uint32_t lower_id, bool bind);
|
||||
|
||||
#endif /* PIOS_PWM_PRIV_H */
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#define PIOS_STM32_H
|
||||
|
||||
struct stm32_irq {
|
||||
void (*handler) (uint32_t);
|
||||
uint32_t flags;
|
||||
NVIC_InitTypeDef init;
|
||||
};
|
||||
|
@ -41,7 +41,6 @@
|
||||
#define PIOS_USB_HID_DATA_LENGTH 62
|
||||
|
||||
/* Global functions */
|
||||
extern int32_t PIOS_USB_HID_Init(uint32_t mode);
|
||||
extern int32_t PIOS_USB_HID_Reenumerate();
|
||||
extern int32_t PIOS_USB_HID_ChangeConnectionState(uint32_t Connected);
|
||||
extern int32_t PIOS_USB_HID_CheckAvailable(uint8_t id);
|
||||
|
49
flight/PiOS/inc/pios_usb_hid_priv.h
Normal file
49
flight/PiOS/inc/pios_usb_hid_priv.h
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS_USB_HID USB_HID Functions
|
||||
* @brief PIOS interface for USB_HID port
|
||||
* @{
|
||||
*
|
||||
* @file pios_usb_hid_priv.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief USB_HID private definitions.
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef PIOS_USB_HID_PRIV_H
|
||||
#define PIOS_USB_HID_PRIV_H
|
||||
|
||||
#include <pios.h>
|
||||
#include <pios_stm32.h>
|
||||
|
||||
struct pios_usb_hid_cfg {
|
||||
struct stm32_irq irq;
|
||||
};
|
||||
|
||||
extern int32_t PIOS_USB_HID_Init(uint32_t * usb_hid_id, const struct pios_usb_hid_cfg * cfg);
|
||||
|
||||
#endif /* PIOS_USB_HID_PRIV_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
@ -794,7 +794,8 @@ void apiconfig_process(void)
|
||||
int32_t bytes = PIOS_COM_ReceiveBufferUsed(PIOS_COM_SERIAL);
|
||||
while (bytes > 0)
|
||||
{
|
||||
PIOS_COM_ReceiveBuffer(PIOS_COM_SERIAL);
|
||||
uint8_t c;
|
||||
PIOS_COM_ReceiveBuffer(PIOS_COM_SERIAL, &c, 1, 0);
|
||||
bytes--;
|
||||
}
|
||||
}
|
||||
@ -812,9 +813,12 @@ void apiconfig_process(void)
|
||||
if (com_num > sizeof(apiconfig_rx_buffer) - apiconfig_rx_buffer_wr)
|
||||
com_num = sizeof(apiconfig_rx_buffer) - apiconfig_rx_buffer_wr;
|
||||
|
||||
|
||||
while (com_num > 0)
|
||||
{ // fetch a byte from the comm-port RX buffer and save it into our RX buffer
|
||||
apiconfig_rx_buffer[apiconfig_rx_buffer_wr++] = PIOS_COM_ReceiveBuffer(apiconfig_comm_port);
|
||||
uint8_t c;
|
||||
PIOS_COM_ReceiveBuffer(apiconfig_comm_port, &c, 1, 0);
|
||||
apiconfig_rx_buffer[apiconfig_rx_buffer_wr++] = c;
|
||||
com_num--;
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,6 @@ static const struct pios_spi_cfg pios_spi_port_cfg =
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
.irq =
|
||||
{
|
||||
.handler = NULL,
|
||||
.flags = (DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA1_Channel2_IRQn,
|
||||
@ -193,7 +192,6 @@ static const struct pios_adc_cfg pios_adc_cfg = {
|
||||
.dma = {
|
||||
.ahb_clk = RCC_AHBPeriph_DMA1,
|
||||
.irq = {
|
||||
.handler = NULL,
|
||||
.flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA1_Channel1_IRQn,
|
||||
@ -259,7 +257,6 @@ static const struct pios_usart_cfg pios_usart_serial_cfg =
|
||||
},
|
||||
.irq =
|
||||
{
|
||||
.handler = NULL,
|
||||
.init =
|
||||
{
|
||||
.NVIC_IRQChannel = USART1_IRQn,
|
||||
@ -302,6 +299,21 @@ static const struct pios_usart_cfg pios_usart_serial_cfg =
|
||||
|
||||
// ***********************************************************************************
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
#include "pios_usb_hid_priv.h"
|
||||
|
||||
static const struct pios_usb_hid_cfg pios_usb_hid_main_cfg = {
|
||||
.irq = {
|
||||
.init = {
|
||||
.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
.NVIC_IRQChannelCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
};
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
||||
extern const struct pios_com_driver pios_usb_com_driver;
|
||||
|
||||
uint32_t pios_com_serial_id;
|
||||
@ -334,10 +346,11 @@ void PIOS_Board_Init(void) {
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
PIOS_USB_HID_Init(0);
|
||||
uint32_t pios_usb_hid_id;
|
||||
PIOS_USB_HID_Init(&pios_usb_hid_id, &pios_usb_hid_main_cfg);
|
||||
#if defined(PIOS_INCLUDE_COM)
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, 0)) {
|
||||
PIOS_DEBUG_Assert(0);
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, pios_usb_hid_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
@ -91,7 +91,8 @@ void trans_process(void)
|
||||
int32_t bytes = PIOS_COM_ReceiveBufferUsed(PIOS_COM_SERIAL);
|
||||
while (bytes > 0)
|
||||
{
|
||||
PIOS_COM_ReceiveBuffer(PIOS_COM_SERIAL);
|
||||
uint8_t c;
|
||||
PIOS_COM_ReceiveBuffer(PIOS_COM_SERIAL, &c, 1, 0);
|
||||
bytes--;
|
||||
}
|
||||
}
|
||||
@ -134,8 +135,7 @@ void trans_process(void)
|
||||
|
||||
// copy data received down the comm-port into our temp buffer
|
||||
register uint16_t bytes_saved = 0;
|
||||
while (bytes_saved < com_num)
|
||||
trans_temp_buffer1[bytes_saved++] = PIOS_COM_ReceiveBuffer(comm_port);
|
||||
bytes_saved = PIOS_COM_ReceiveBuffer(comm_port, trans_temp_buffer1, com_num, 0);
|
||||
|
||||
// put the received comm-port data bytes into the RF packet handler TX buffer
|
||||
if (bytes_saved > 0)
|
||||
@ -147,8 +147,11 @@ void trans_process(void)
|
||||
else
|
||||
{ // empty the comm-ports rx buffer
|
||||
int32_t com_num = PIOS_COM_ReceiveBufferUsed(comm_port);
|
||||
while (com_num > 0)
|
||||
PIOS_COM_ReceiveBuffer(comm_port);
|
||||
while (com_num > 0) {
|
||||
uint8_t c;
|
||||
PIOS_COM_ReceiveBuffer(comm_port, &c, 1, 0);
|
||||
com_num--;
|
||||
}
|
||||
}
|
||||
|
||||
// ********************
|
||||
|
@ -1,7 +1,7 @@
|
||||
define connect
|
||||
target remote localhost:3333
|
||||
monitor cortex_m3 vector_catch all
|
||||
file ./build/bl_coptercontrol/CopterControl_BL.elf
|
||||
file ./build/bl_coptercontrol/bl_coptercontrol.elf
|
||||
end
|
||||
#monitor reset halt
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user