Added BTstack porting layer for Micrium's uC/OS.

This commit is contained in:
peter.voser.btstack@gmail.com 2011-10-12 09:11:21 +00:00
parent 39f5baa59a
commit d417710f00
11 changed files with 1973 additions and 0 deletions

View File

@ -0,0 +1,261 @@
/*
* Copyright (C) 2011 by Matthias Ringwald
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/*
* btstack_memory_ucos.c
*
* @brief BTstack memory management via configurable memory pools
*
* Created by Albis Technologies.
*/
#include <btstack/port_ucos.h>
#include "../config.h"
#include "btstack_memory.h"
#include "hci.h"
#include "l2cap.h"
#include "rfcomm.h"
DEFINE_THIS_FILE
/*=============================================================================
=============================================================================*/
static MEM_POOL hci_connection_pool;
void * btstack_memory_hci_connection_get(void)
{
LIB_ERR err;
return Mem_PoolBlkGet(&hci_connection_pool,
sizeof(hci_connection_t),
&err);
}
void btstack_memory_hci_connection_free(void *hci_connection)
{
LIB_ERR err;
Mem_PoolBlkFree(&hci_connection_pool, hci_connection, &err);
}
/*=============================================================================
=============================================================================*/
static MEM_POOL l2cap_service_pool;
void * btstack_memory_l2cap_service_get(void)
{
LIB_ERR err;
return Mem_PoolBlkGet(&l2cap_service_pool,
sizeof(l2cap_service_t),
&err);
}
void btstack_memory_l2cap_service_free(void *l2cap_service)
{
LIB_ERR err;
Mem_PoolBlkFree(&l2cap_service_pool, l2cap_service, &err);
}
/*=============================================================================
=============================================================================*/
static MEM_POOL l2cap_channel_pool;
void * btstack_memory_l2cap_channel_get(void)
{
LIB_ERR err;
return Mem_PoolBlkGet(&l2cap_channel_pool,
sizeof(l2cap_channel_t),
&err);
}
void btstack_memory_l2cap_channel_free(void *l2cap_channel)
{
LIB_ERR err;
Mem_PoolBlkFree(&l2cap_channel_pool, l2cap_channel, &err);
}
/*=============================================================================
=============================================================================*/
static MEM_POOL rfcomm_multiplexer_pool;
void * btstack_memory_rfcomm_multiplexer_get(void)
{
LIB_ERR err;
return Mem_PoolBlkGet(&rfcomm_multiplexer_pool,
sizeof(rfcomm_multiplexer_t),
&err);
}
void btstack_memory_rfcomm_multiplexer_free(void *rfcomm_multiplexer)
{
LIB_ERR err;
Mem_PoolBlkFree(&rfcomm_multiplexer_pool, rfcomm_multiplexer, &err);
}
/*=============================================================================
=============================================================================*/
static MEM_POOL rfcomm_service_pool;
void * btstack_memory_rfcomm_service_get(void)
{
LIB_ERR err;
return Mem_PoolBlkGet(&rfcomm_service_pool,
sizeof(rfcomm_service_t),
&err);
}
void btstack_memory_rfcomm_service_free(void *rfcomm_service)
{
LIB_ERR err;
Mem_PoolBlkFree(&rfcomm_service_pool, rfcomm_service, &err);
}
/*=============================================================================
=============================================================================*/
static MEM_POOL rfcomm_channel_pool;
void * btstack_memory_rfcomm_channel_get(void)
{
LIB_ERR err;
return Mem_PoolBlkGet(&rfcomm_channel_pool,
sizeof(rfcomm_channel_t),
&err);
}
void btstack_memory_rfcomm_channel_free(void *rfcomm_channel)
{
LIB_ERR err;
Mem_PoolBlkFree(&rfcomm_channel_pool, rfcomm_channel, &err);
}
/*=============================================================================
=============================================================================*/
static MEM_POOL db_mem_device_pool;
void * btstack_memory_db_mem_device_get(void){
LIB_ERR err;
return Mem_PoolBlkGet(&db_mem_device_pool,
sizeof(db_mem_device_t),
&err);
}
void btstack_memory_db_mem_device_free(void *db_mem_device){
LIB_ERR err;
Mem_PoolBlkFree(&db_mem_device_pool, db_mem_device, &err);
}
/*=============================================================================
=============================================================================*/
static MEM_POOL db_mem_service_pool;
void * btstack_memory_db_mem_service_get(void){
LIB_ERR err;
return Mem_PoolBlkGet(&db_mem_service_pool,
sizeof(db_mem_service_t),
&err);
}
void btstack_memory_db_mem_service_free(void *db_mem_service){
LIB_ERR err;
Mem_PoolBlkFree(&db_mem_service_pool, db_mem_service, &err);
}
/*=============================================================================
=============================================================================*/
void btstack_memory_init(void)
{
LIB_ERR err;
CPU_SIZE_T octetsReqd;
Mem_PoolCreate(&hci_connection_pool,
0,
MAX_NO_HCI_CONNECTIONS * sizeof(hci_connection_t),
MAX_NO_HCI_CONNECTIONS,
sizeof(hci_connection_t),
sizeof(unsigned long),
&octetsReqd,
&err);
SYS_ASSERT(err == LIB_MEM_ERR_NONE);
Mem_PoolCreate(&l2cap_service_pool,
0,
MAX_NO_L2CAP_SERVICES * sizeof(l2cap_service_t),
MAX_NO_L2CAP_SERVICES,
sizeof(l2cap_service_t),
sizeof(unsigned long),
&octetsReqd,
&err);
SYS_ASSERT(err == LIB_MEM_ERR_NONE);
Mem_PoolCreate(&l2cap_channel_pool,
0,
MAX_NO_L2CAP_CHANNELS * sizeof(l2cap_channel_t),
MAX_NO_L2CAP_CHANNELS,
sizeof(l2cap_channel_t),
sizeof(unsigned long),
&octetsReqd,
&err);
SYS_ASSERT(err == LIB_MEM_ERR_NONE);
Mem_PoolCreate(&rfcomm_multiplexer_pool,
0,
MAX_NO_RFCOMM_MULTIPLEXERS * sizeof(rfcomm_multiplexer_t),
MAX_NO_RFCOMM_MULTIPLEXERS,
sizeof(rfcomm_multiplexer_t),
sizeof(unsigned long),
&octetsReqd,
&err);
SYS_ASSERT(err == LIB_MEM_ERR_NONE);
Mem_PoolCreate(&rfcomm_service_pool,
0,
MAX_NO_RFCOMM_SERVICES * sizeof(rfcomm_service_t),
MAX_NO_RFCOMM_SERVICES,
sizeof(rfcomm_service_t),
sizeof(unsigned long),
&octetsReqd,
&err);
SYS_ASSERT(err == LIB_MEM_ERR_NONE);
Mem_PoolCreate(&rfcomm_channel_pool,
0,
MAX_NO_RFCOMM_CHANNELS * sizeof(rfcomm_channel_t),
MAX_NO_RFCOMM_CHANNELS,
sizeof(rfcomm_channel_t),
sizeof(unsigned long),
&octetsReqd,
&err);
SYS_ASSERT(err == LIB_MEM_ERR_NONE);
Mem_PoolCreate(&db_mem_device_pool,
0,
MAX_NO_DB_MEM_DEVICES * sizeof(db_mem_device_t),
MAX_NO_DB_MEM_DEVICES,
sizeof(db_mem_device_t),
sizeof(unsigned long),
&octetsReqd,
&err);
SYS_ASSERT(err == LIB_MEM_ERR_NONE);
Mem_PoolCreate(&db_mem_service_pool,
0,
MAX_NO_DB_MEM_SERVICES * sizeof(db_mem_service_t),
MAX_NO_DB_MEM_SERVICES,
sizeof(db_mem_service_t),
sizeof(unsigned long),
&octetsReqd,
&err);
SYS_ASSERT(err == LIB_MEM_ERR_NONE);
}

View File

@ -0,0 +1,317 @@
/*
* Copyright (C) 2011 by Matthias Ringwald
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/*
* hci_transport_h4_ucos.c
*
* @brief BTstack serial H4 transport for uC/OS
*
* Created by Albis Technologies.
*/
#include <btstack/port_ucos.h>
#include "hci.h"
#include "hci_transport.h"
#include "hci_dump.h"
#include "run_loop_ucos.h"
#include "bsp_btuart.h"
DEFINE_THIS_FILE
typedef enum
{
H4_W4_PACKET_TYPE,
H4_W4_EVENT_HEADER,
H4_W4_ACL_HEADER,
H4_W4_PAYLOAD,
H4_W4_PICKUP
} H4RxState;
static int h4_reader_process(struct data_source *ds);
static void h4_rx_data(unsigned char *data, unsigned long size);
static void dummyHandler(uint8_t packetType, uint8_t *packet, uint16_t size);
static void (*incomingPacketHandler)(uint8_t a,
uint8_t *b,
uint16_t c) = dummyHandler;
static struct
{
data_source_t dataSource;
hci_transport_t transport;
} hciTransportH4;
/*=============================================================================
* H4 receiver.
*============================================================================*/
#define NOF_RX_BUFFERS 20
#define RX_BUFFER_SIZE 1020
typedef struct
{
unsigned char data[RX_BUFFER_SIZE];
unsigned long nofBytes;
} ReceiveBuffer;
static struct
{
/* H4 Rx state and remaining number of Bytes in this state. */
H4RxState state;
unsigned long remainingInState;
/* H4 packet ring buffer and current buffer in use for Rx data. */
ReceiveBuffer buffers[NOF_RX_BUFFERS];
ReceiveBuffer *currBuffer;
volatile unsigned long enqueueIdx;
volatile unsigned long dequeueIdx;
volatile unsigned long nextEnqueueIdx;
}rx;
/*=============================================================================
=============================================================================*/
static void advanceToNextBuffer(void)
{
rx.nextEnqueueIdx = rx.enqueueIdx + 1;
if(rx.nextEnqueueIdx >= NOF_RX_BUFFERS)
{
rx.nextEnqueueIdx = 0;
}
if(rx.nextEnqueueIdx == rx.dequeueIdx)
{
/* The ring buffer is full. */
SYS_ERROR(1);
}
/* Prepare current buffer for receiving. */
rx.currBuffer = &rx.buffers[rx.enqueueIdx];
rx.currBuffer->nofBytes = 0;
}
/*=============================================================================
=============================================================================*/
static int h4_open(void *config)
{
/* Initialise H4 receiver. */
rx.enqueueIdx = 0;
rx.dequeueIdx = 0;
advanceToNextBuffer();
BSP_BTUART_EnableRxCallback(h4_rx_data);
/* Prepare for 1st H4 packet type ID. */
rx.state = H4_W4_PACKET_TYPE;
rx.remainingInState = 1;
BSP_BTUART_AnounceDmaReceiverSize(rx.remainingInState);
hciTransportH4.dataSource.process = h4_reader_process;
run_loop_add_data_source(&hciTransportH4.dataSource);
return 0;
}
/*=============================================================================
=============================================================================*/
static int h4_close(void *config)
{
BSP_BTUART_DisableRxCallback();
return 0;
}
/*=============================================================================
=============================================================================*/
static int h4_send_packet(uint8_t packetType, uint8_t *packet, int size)
{
hci_dump_packet(packetType, 0, packet, size);
BSP_BTUART_Transmit(&packetType, 1);
BSP_BTUART_Transmit(packet, size);
return 0;
}
/*=============================================================================
=============================================================================*/
static void h4_register_packet_handler(void (*handler)(uint8_t a,
uint8_t *b,
uint16_t c))
{
incomingPacketHandler = handler;
}
/*=============================================================================
=============================================================================*/
static void h4_rx_fsm(void)
{
switch(rx.state)
{
case H4_W4_PACKET_TYPE:
if(rx.currBuffer->data[0] == HCI_EVENT_PACKET)
{
rx.remainingInState = HCI_EVENT_PKT_HDR;
rx.state = H4_W4_EVENT_HEADER;
}
else if(rx.currBuffer->data[0] == HCI_ACL_DATA_PACKET)
{
rx.remainingInState = HCI_ACL_DATA_PKT_HDR;
rx.state = H4_W4_ACL_HEADER;
}
else
{
rx.currBuffer->nofBytes = 0;
rx.remainingInState = 1;
}
break;
case H4_W4_EVENT_HEADER:
rx.remainingInState = rx.currBuffer->data[2];
rx.state = H4_W4_PAYLOAD;
break;
case H4_W4_ACL_HEADER:
rx.remainingInState = READ_BT_16(rx.currBuffer->data, 3);
rx.state = H4_W4_PAYLOAD;
break;
case H4_W4_PAYLOAD:
rx.state = H4_W4_PICKUP;
break;
default:
break;
}
if(rx.remainingInState)
{
BSP_BTUART_AnounceDmaReceiverSize(rx.remainingInState);
}
}
/*=============================================================================
=============================================================================*/
static int h4_reader_process(struct data_source *ds)
{
unsigned long pickUpSize;
unsigned char *pickUpBuffer;
unsigned long nextDequeueIdx;
pickUpSize = rx.buffers[rx.dequeueIdx].nofBytes - 1;
pickUpBuffer = rx.buffers[rx.dequeueIdx].data;
/* Handle complete incoming HCI packet. */
SYS_ASSERT(pickUpSize >= 2);
hci_dump_packet(*pickUpBuffer, 1, pickUpBuffer + 1, pickUpSize);
incomingPacketHandler(*pickUpBuffer, pickUpBuffer + 1, pickUpSize);
nextDequeueIdx = rx.dequeueIdx + 1;
if(nextDequeueIdx >= NOF_RX_BUFFERS)
{
nextDequeueIdx = 0;
}
rx.dequeueIdx = nextDequeueIdx;
return 0;
}
/*=============================================================================
=============================================================================*/
static void h4_rx_data(unsigned char *data, unsigned long size)
{
unsigned long i;
SYS_ASSERT(size + rx.currBuffer->nofBytes <= RX_BUFFER_SIZE);
SYS_ASSERT(size <= rx.remainingInState);
/* Copy from DMA buffer to Rx buffer (no memcpy() or Mem_Copy()). */
for(i = 0; i < size; ++i)
{
rx.currBuffer->data[rx.currBuffer->nofBytes + i] = data[i];
}
rx.currBuffer->nofBytes += size;
rx.remainingInState -= size;
if(rx.remainingInState == 0)
{
h4_rx_fsm();
if(rx.state == H4_W4_PICKUP)
{
/* Advance to next Rx buffer. */
rx.enqueueIdx = rx.nextEnqueueIdx;
advanceToNextBuffer();
/* Prepare for next H4 packet type ID. */
rx.state = H4_W4_PACKET_TYPE;
rx.remainingInState = 1;
BSP_BTUART_AnounceDmaReceiverSize(rx.remainingInState);
/* Notify complete Rx packet. */
run_loop_notify_incoming_transport_packet();
}
}
}
/*=============================================================================
=============================================================================*/
static int h4_set_baudrate(uint32_t baudrate)
{
BSP_BTUART_SetBaudrate(baudrate);
return 0;
}
/*=============================================================================
=============================================================================*/
const char * h4_transport_name(void)
{
return "H4";
}
/*=============================================================================
=============================================================================*/
static void dummyHandler(uint8_t packetType, uint8_t *packet, uint16_t size)
{
}
/*=============================================================================
* H4 transport instance.
*============================================================================*/
hci_transport_t * hci_transport_h4_instance(void)
{
hciTransportH4.transport.open = h4_open;
hciTransportH4.transport.close = h4_close;
hciTransportH4.transport.send_packet = h4_send_packet;
hciTransportH4.transport.register_packet_handler = h4_register_packet_handler;
hciTransportH4.transport.get_transport_name = h4_transport_name;
hciTransportH4.transport.set_baudrate = h4_set_baudrate;
return &hciTransportH4.transport;
}

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2009 by Matthias Ringwald
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/*
* port_ucos.c
*
* uC/OS porting layer.
*
* Created by Albis Technologies.
*/
#include <btstack/port_ucos.h>
#include "../config.h"
/*=============================================================================
=============================================================================*/
int gettimeofday(struct timeval *tv, void *tzp)
{
INT32U ticks = OSTimeGet();
tv->tv_sec = ticks / OS_TICKS_PER_SEC;
tv->tv_usec = (ticks - (tv->tv_sec * OS_TICKS_PER_SEC)) *
(1000000UL / OS_TICKS_PER_SEC);
return 0;
}
/*=============================================================================
=============================================================================*/
uint32_t embedded_get_ticks(void)
{
return OSTimeGet();
}
/*=============================================================================
=============================================================================*/
uint32_t embedded_ticks_for_ms(uint32_t time_in_ms)
{
return MSEC_TO_TICKS(time_in_ms);
}
/*=============================================================================
=============================================================================*/
int gethostname(char *name, size_t len)
{
Str_Copy_N((CPU_CHAR *)name, (CPU_CHAR *)BT_DEV_NAME, len - 1);
return 0;
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2009 by Matthias Ringwald
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/*
* port_ucos.h
*
* uC/OS porting layer.
*
* Created by Albis Technologies.
*/
#ifndef PORT_UCOS_H
#define PORT_UCOS_H
/* uC/OS-II include files. */
#include <ucos_ii.h>
#include <lib_mem.h>
#include <lib_str.h>
/* These standard includes are allowed. */
#include <stdarg.h>
#include <stdint.h>
/* OS version depending macros. */
#define USE_OS_NO_ERROR OS_NO_ERR
#define USE_OS_TIMEOUT OS_TIMEOUT
/* Convert msec to OS ticks. */
#define MSEC_TO_TICKS(ms) \
((ms > 0u) ? (((ms * OS_TICKS_PER_SEC) + 1000u - 1u) / 1000u) : 0u)
/* Map stdlib functions to uC/LIB ones. */
#define memcpy(a, b, c) (Mem_Copy((void *)(a), (void *)(b), c))
#define memset(a, b, c) (Mem_Set((void *)(a), b, c))
#define bzero(a, c) (Mem_Set((void *)(a), 0, c))
#define memcmp(a, b, c) (!Mem_Cmp((void *)(a), (void *)(b), c))
#define strncpy(a, b, c) (Str_Copy_N((CPU_CHAR *)(a), (CPU_CHAR *)b, c))
#define strncmp(a, b, c) (Str_Cmp_N((CPU_CHAR *)(a), (CPU_CHAR *)b, c))
#define strlen(a) (Str_Len((CPU_CHAR *)(a)))
extern void * memmove(void *dst, const void *src, unsigned int length);
/* There are no such uC-LIB implementations. */
#define sprintf(a, b, ...) __error__
#define sscanf(a, ...) __error__
/* Time function. */
struct timeval
{
unsigned long tv_sec;
unsigned long tv_usec;
};
int gettimeofday(struct timeval *tv, void *tzp);
/* Host name. */
int gethostname(char *name, size_t len);
/* Debug output. */
#include "bsp_debug.h"
#define ENABLE_BTSTACK_DEBUG_OUTPUT 0
#if(ENABLE_BTSTACK_DEBUG_OUTPUT == 1)
#define printf(...) { printos(__VA_ARGS__); }
#define fprintf(_fd, ...) { printos(__VA_ARGS__); }
#define log_debug(...) { printos(__VA_ARGS__); }
#define log_info(...) { printos(__VA_ARGS__); }
#define log_error(...) { printos(__VA_ARGS__); }
#else
#define printf(...)
#define fprintf(_fd, ...)
#define log_debug(...)
#define log_info(...)
#define log_error(...)
#endif /* ENABLE_BTSTACK_DEBUG_OUTPUT */
#endif /* PORT_UCOS_H */

View File

@ -0,0 +1,172 @@
/*
* Copyright (C) 2011 by Matthias Ringwald
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/*
* run_loop_ucos.c
*
* @brief BTstack run loop for uC/OS
*
* Created by Albis Technologies.
*/
#include <btstack/port_ucos.h>
#include <btstack/run_loop.h>
#include "run_loop_ucos.h"
#include "hci_transport.h"
#include "serial.h"
DEFINE_THIS_FILE
static linked_list_t timers;
static data_source_t *transportDataSource = 0;
/*=============================================================================
* Run loop message queue.
*============================================================================*/
#define MSG_QUEUE_BUFFER_SIZE 32
#define MSG_ID_INCOMING_TRANSPORT_PACKET 1
#define MSG_ID_OUTGOING_RFCOMM_DATA 2
static struct
{
OS_EVENT *queue;
void * queueBuffer[MSG_QUEUE_BUFFER_SIZE];
} messages;
/*=============================================================================
=============================================================================*/
void run_loop_notify_incoming_transport_packet(void)
{
INT8U err;
err = OSQPost(messages.queue, (void *)MSG_ID_INCOMING_TRANSPORT_PACKET);
SYS_ASSERT(err == USE_OS_NO_ERROR);
}
/*=============================================================================
=============================================================================*/
void run_loop_notify_outgoing_rfcomm_data(void)
{
INT8U err;
err = OSQPost(messages.queue, (void *)MSG_ID_OUTGOING_RFCOMM_DATA);
SYS_ASSERT(err == USE_OS_NO_ERROR);
}
/*=============================================================================
=============================================================================*/
void run_loop_add_data_source(data_source_t *ds)
{
transportDataSource = ds;
}
/*=============================================================================
=============================================================================*/
void run_loop_add_timer(timer_source_t *ts)
{
linked_item_t *it;
for(it = (linked_item_t *)&timers; it->next; it = it->next)
{
if(ts->timeout < ((timer_source_t *)it->next)->timeout)
{
break;
}
}
ts->item.next = it->next;
it->next = (linked_item_t *)ts;
}
/*=============================================================================
=============================================================================*/
void run_loop_set_timer(timer_source_t *ts, uint32_t timeout_in_ms)
{
unsigned long ticks = MSEC_TO_TICKS(timeout_in_ms);
ts->timeout = OSTimeGet() + ticks;
}
/*=============================================================================
=============================================================================*/
int run_loop_remove_timer(timer_source_t *ts)
{
return linked_list_remove(&timers, (linked_item_t *) ts);
}
/*=============================================================================
=============================================================================*/
void run_loop_execute(void)
{
INT8U err;
void *event;
INT16U timeout;
for(;;)
{
/* Get next timeout. */
timeout = 0;
if(timers)
{
timeout = ((timer_source_t *)timers)->timeout - OSTimeGet();
}
event = OSQPend(messages.queue, timeout, &err);
if(err == USE_OS_NO_ERROR)
{
if((unsigned long)event == MSG_ID_INCOMING_TRANSPORT_PACKET)
{
transportDataSource->process(transportDataSource);
}
}
/* Process timers. */
while(timers)
{
timer_source_t *ts = (timer_source_t *)timers;
if(ts->timeout > OSTimeGet()) break;
run_loop_remove_timer(ts);
ts->process(ts);
}
}
}
/*=============================================================================
=============================================================================*/
void run_loop_init(RUN_LOOP_TYPE type)
{
timers = 0;
messages.queue = OSQCreate(messages.queueBuffer, MSG_QUEUE_BUFFER_SIZE);
SYS_ASSERT(messages.queue);
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2011 by Matthias Ringwald
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/*
* run_loop_ucos.h
*
* @brief BTstack run loop for uC/OS
*
* Created by Albis Technologies.
*/
#pragma once
void run_loop_notify_incoming_transport_packet(void);

199
Ports/uCOS/example/Makefile Normal file
View File

@ -0,0 +1,199 @@
#==============================================================================
# (C) Copyright Albis Technologies Ltd 2011
#==============================================================================
# STM32 Example Code
#==============================================================================
# File name: Makefile
#
# Notes: -
#==============================================================================
firsttarget: all
include project.settings
SHELL=/bin/bash.exe
GCC=arm-none-eabi-gcc.exe
AS=arm-none-eabi-as.exe
OBJCPY=arm-none-eabi-objcopy
RM=rm
ECHO=echo
#==============================================================================
# Building.
#==============================================================================
AFLAGS=-mcpu=cortex-m3 \
CFLAGS=-Wall \
-Wpointer-arith \
-Wstrict-prototypes \
-Werror \
-mcpu=cortex-m3 \
-mthumb \
-g \
-O2 \
$(LED_DEFINES) \
LFLAGS=-nostartfiles \
-nostdlib \
-mcpu=cortex-m3 \
.s.o:
$(AS) $(AFLAGS) -c $< -o $@
.c.o:
$(GCC) $(CFLAGS) $(INCL) -c $< -o $@
#==============================================================================
# Repository directories.
#==============================================================================
PATH_OS_SRC=../../../../uCOS-II/Source
PATH_CM3_SRC=../../../../uCOS-II/Ports/ARM-Cortex-M3/Generic/GNU
PATH_BSP_SRC=..
PATH_CPU_SRC=../../../../uC-CPU/ARM-Cortex-M3/GNU
PATH_CPU_INC=../../../../uC-CPU
PATH_UCLIB_SRC=../../../../uC-LIB
PATH_STM32_SRC=../../../../CPU/ST/STM32/src
PATH_STM32_INC=../../../../CPU/ST/STM32/inc
PATH_BTSTACK_SRC=../../../../../../BTstack/src
PATH_BTSTACK_INC=../../../../../../BTstack/include
PATH_APPL_SRC=../../../../../../Application
PATH_APPL_INC=../../../../../../Application
#==============================================================================
# Board support package (BSP).
#==============================================================================
ASMS_START=vector_table.o \
OBJS_BSP=$(PATH_BSP_SRC)/app_hooks.o \
$(PATH_BSP_SRC)/bsp.o \
$(PATH_BSP_SRC)/bsp_debug.o \
$(PATH_BSP_SRC)/bsp_i2c.o \
$(PATH_BSP_SRC)/bsp_int.o \
$(PATH_BSP_SRC)/bsp_periph.o \
$(PATH_BSP_SRC)/bsp_stlm75.o \
$(PATH_BSP_SRC)/main.o \
$(PATH_BSP_SRC)/T32_Term.o \
$(PATH_BSP_SRC)/uCOS-II/bsp_os.o \
vector_funcs.o \
ifeq ($(STM32_USART_DMA),yes)
OBJS_BSP+=$(PATH_BSP_SRC)/bsp_btuart_dma.o
else
OBJS_BSP+=$(PATH_BSP_SRC)/bsp_btuart_nodma.o
endif
INCL_BSP=-I$(PATH_BSP_SRC) \
-I$(PATH_BSP_SRC)/uCOS-II
#==============================================================================
# uC/OS-II.
#==============================================================================
ASMS_UCOS=$(PATH_CM3_SRC)/os_cpu_a.o \
$(PATH_CPU_SRC)/cpu_a.o \
OBJS_UCOS=$(PATH_OS_SRC)/os_core.o \
$(PATH_OS_SRC)/os_flag.o \
$(PATH_OS_SRC)/os_mbox.o \
$(PATH_OS_SRC)/os_mem.o \
$(PATH_OS_SRC)/os_mutex.o \
$(PATH_OS_SRC)/os_q.o \
$(PATH_OS_SRC)/os_sem.o \
$(PATH_OS_SRC)/os_task.o \
$(PATH_OS_SRC)/os_time.o \
$(PATH_OS_SRC)/os_tmr.o \
$(PATH_CM3_SRC)/os_cpu_c.o \
$(PATH_CM3_SRC)/os_dbg.o \
$(PATH_CPU_SRC)/cpu_c.o
INCL_UCOS=-I$(PATH_OS_SRC) \
-I$(PATH_CM3_SRC) \
-I$(PATH_CPU_SRC) \
-I$(PATH_CPU_INC) \
#==============================================================================
# uC/LIB.
#==============================================================================
OBJS_UCLIB=$(PATH_UCLIB_SRC)/lib_mem.o \
$(PATH_UCLIB_SRC)/lib_str.o \
$(PATH_UCLIB_SRC)/memmove.o \
INCL_UCLIB=-I$(PATH_UCLIB_SRC) \
#==============================================================================
# STM32.
#==============================================================================
OBJS_STM32=$(PATH_STM32_SRC)/stm32f10x_flash.o \
$(PATH_STM32_SRC)/stm32f10x_gpio.o \
$(PATH_STM32_SRC)/stm32f10x_rcc.o \
$(PATH_STM32_SRC)/stm32f10x_usart.o \
ifeq ($(STM32_USART_DMA),yes)
OBJS_STM32+=$(PATH_STM32_SRC)/stm32f10x_dma.o $(PATH_STM32_SRC)/misc.o
endif
INCL_STM32=-I$(PATH_STM32_INC) \
-I$(PATH_STM32_SRC) \
#==============================================================================
# BTstack.
#==============================================================================
OBJS_BTSTACK=$(PATH_BTSTACK_SRC)/btstack_memory_ucos.o \
$(PATH_BTSTACK_SRC)/daemon.o \
$(PATH_BTSTACK_SRC)/hci.o \
$(PATH_BTSTACK_SRC)/hci_cmds.o \
$(PATH_BTSTACK_SRC)/hci_dump_ucos.o \
$(PATH_BTSTACK_SRC)/hci_transport_h4_ucos.o \
$(PATH_BTSTACK_SRC)/l2cap.o \
$(PATH_BTSTACK_SRC)/l2cap_signaling.o \
$(PATH_BTSTACK_SRC)/linked_list.o \
$(PATH_BTSTACK_SRC)/port_ucos.o \
$(PATH_BTSTACK_SRC)/remote_device_db_memory.o \
$(PATH_BTSTACK_SRC)/rfcomm.o \
$(PATH_BTSTACK_SRC)/run_loop_ucos.o \
$(PATH_BTSTACK_SRC)/sdp.o \
$(PATH_BTSTACK_SRC)/sdp_util.o \
$(PATH_BTSTACK_SRC)/sdp_spp_record.o \
$(PATH_BTSTACK_SRC)/utils.o \
ifeq ($(BT_CHIPSET),CSR_BC4)
OBJS_BTSTACK+=$(PATH_BTSTACK_SRC)/bt_chipset_csrbc4.o
CFLAGS+=-DBT_CHIPSET_CSR_BC4=1
CFLAGS+=-DBT_CHIPSET_CSR_BC4_CHANGE_BAUDRATE=$(CSR_BC4_CHANGE_BAUDRATE_ID)
endif
ifeq ($(BT_CHIPSET),PAN1315)
OBJS_BTSTACK+=$(PATH_BTSTACK_SRC)/bt_chipset_pan1315.o
OBJS_BTSTACK+=$(PATH_BTSTACK_SRC)/pan1315_init.o
CFLAGS+=-DBT_CHIPSET_PAN1315=1
endif
INCL_BTSTACK=-I$(PATH_BTSTACK_INC) \
-I$(PATH_BTSTACK_SRC) \
#==============================================================================
# Application.
#==============================================================================
OBJS_APPL=$(PATH_APPL_SRC)/api.o \
$(PATH_APPL_SRC)/serial.o \
INCL_APPL=-I$(PATH_APPL_INC)
#==============================================================================
# All objects for binary.
#==============================================================================
ASMS=$(ASMS_START) $(ASMS_UCOS)
OBJS=$(OBJS_BSP) $(OBJS_UCOS) $(OBJS_UCLIB) $(OBJS_STM32) $(OBJS_BTSTACK) $(OBJS_APPL)
INCL=$(INCL_BSP) $(INCL_UCOS) $(INCL_UCLIB) $(INCL_STM32) $(INCL_BTSTACK) $(INCL_APPL)
BIN=btstackfw
all: $(ASMS) $(OBJS)
@$(ECHO) Linking Flash image...
$(GCC) $(LFLAGS) -Wl,-Map,$(BIN).map -Tlinker.lds -o $(BIN).elf $(ASMS) $(OBJS)
$(OBJCPY) -O binary $(BIN).elf $(BIN).bin
@$(ECHO)
@$(ECHO) Successfully built BTstack Flash image for $(BT_CHIPSET), STM32 UART DMA $(STM32_USART_DMA).
@$(ECHO)
clean:
$(RM) -f *.elf *.bin *.map $(ASMS) $(OBJS)

View File

@ -0,0 +1,74 @@
#==============================================================================
# (C) Copyright Albis Technologies Ltd 2011
#==============================================================================
# Example Code
#==============================================================================
# File name: project.settings
#
# Notes: -
#==============================================================================
# Choose evaluation board. Available:
# EVAL_BOARD=MICRIUM (UM0780)
# EVAL_BOARD=OLIMEX (STM32-P107)
EVAL_BOARD=MICRIUM
# Choose Bluetooth chipset. Available:
# BT_CHIPSET=CSR_BC4 (CSR BlueCore4)
# BT_CHIPSET=PAN1315 (Panasonic PAN1315)
BT_CHIPSET=CSR_BC4
# CSR BlueCore4 only : change to higher baud rate during initialisation.
# Set 0 for no change.
# 1 : 38400
# 2 : 57600
# 3 : 115200
# 4 : 230400
# 5 : 460800
# 6 : 500000
# 7 : 921600
ifeq ($(BT_CHIPSET),CSR_BC4)
CSR_BC4_CHANGE_BAUDRATE_ID=6
endif
# Choose whether or not STM32 USART DMA in use [yes|no].
STM32_USART_DMA=no
# Notification LEDs.
#
# Micrium STM32 evaluation board UM0780
# Green : PD13
# Orange : PD14
# Red : PD15
#
# Olimex STM32 evaluation board STM32-P107
# Green : PC6
# Orange : PC7
# Red : none
ifeq ($(EVAL_BOARD),MICRIUM)
LED_PORT=4
LED_GREEN_PRESENT=1
LED_GREEN=13
LED_ORANGE_PRESENT=1
LED_ORANGE=14
LED_RED_PRESENT=1
LED_RED=15
endif
ifeq ($(EVAL_BOARD),OLIMEX)
LED_PORT=3
LED_GREEN_PRESENT=1
LED_GREEN=6
LED_ORANGE_PRESENT=1
LED_ORANGE=7
LED_RED_PRESENT=0
LED_RED=0
endif
LED_DEFINES=-DLED_PORT=$(LED_PORT)
LED_DEFINES+=-DLED_GREEN_PRESENT=$(LED_GREEN_PRESENT)
LED_DEFINES+=-DLED_GREEN=$(LED_GREEN)
LED_DEFINES+=-DLED_ORANGE_PRESENT=$(LED_ORANGE_PRESENT)
LED_DEFINES+=-DLED_ORANGE=$(LED_ORANGE)
LED_DEFINES+=-DLED_RED_PRESENT=$(LED_RED_PRESENT)
LED_DEFINES+=-DLED_RED=$(LED_RED)

View File

@ -0,0 +1,156 @@
/*=============================================================================
* (C) Copyright Albis Technologies Ltd 2011
*==============================================================================
* STM32 Example Code
*==============================================================================
* File name: bsp_btuart.h
*
* Notes: STM32 Bluetooth UART driver.
*============================================================================*/
#ifndef BSP_BTUART_H
#define BSP_BTUART_H
/*=============================================================================
* Prototype of receiver callback function.
=============================================================================*/
typedef void(* RxCallbackFunc)(unsigned char *data, unsigned long size);
/*=============================================================================
* PURPOSE: Initialising Bluetooth UART.
*
* PARAMETERS:
* -
*
* RETURN VALUE:
* -
*
* COMMENTS: -
=============================================================================*/
void BSP_BTUART_Initialise(void);
/*=============================================================================
* PURPOSE: Setting Bluetooth UART baud rate.
*
* PARAMETERS:
* baudrate - baud rate to set.
*
* RETURN VALUE:
* -
*
* COMMENTS: -
=============================================================================*/
void BSP_BTUART_SetBaudrate(unsigned long baudrate);
/*=============================================================================
* PURPOSE: Activating BT chip reset.
*
* PARAMETERS:
* -
*
* RETURN VALUE:
* -
*
* COMMENTS: -
=============================================================================*/
void BSP_BTUART_ActivateReset(void);
/*=============================================================================
* PURPOSE: Deactivating BT chip reset.
*
* PARAMETERS:
* -
*
* RETURN VALUE:
* -
*
* COMMENTS: -
=============================================================================*/
void BSP_BTUART_DeactivateReset(void);
/*=============================================================================
* PURPOSE: Sending on Bluetooth UART.
*
* PARAMETERS:
* buffer - pointer to buffer to send.
* count - number of bytes to send.
*
* RETURN VALUE:
* -
*
* COMMENTS: -
=============================================================================*/
void BSP_BTUART_Transmit(unsigned char *buffer, unsigned long count);
/*=============================================================================
* PURPOSE: Anouncing DMA receiver size.
*
* PARAMETERS:
* count - number of bytes to receive with DMA.
*
* RETURN VALUE:
* -
*
* COMMENTS: -
=============================================================================*/
void BSP_BTUART_AnounceDmaReceiverSize(unsigned long count);
/*=============================================================================
* PURPOSE: Receiving on Bluetooth UART without receiver callback.
*
* PARAMETERS:
* buffer - pointer to buffer for received bytes.
* maxCount - maximal number of bytes buffer can hold.
* rxCount - output: pointer to number of received bytes.
* timeout - timeout in msec, zero = wait forever.
*
* RETURN VALUE:
* -
*
* COMMENTS: -
=============================================================================*/
void BSP_BTUART_Receive(unsigned char *buffer,
unsigned long maxCount,
unsigned long *rxCount,
unsigned long timeout);
/*=============================================================================
* PURPOSE: Draining bytes already received.
*
* PARAMETERS:
* -
*
* RETURN VALUE:
* -
*
* COMMENTS: -
=============================================================================*/
void BSP_BTUART_DrainReceiver(void);
/*=============================================================================
* PURPOSE: Enabling Bluetooth receiver callback.
*
* PARAMETERS:
* callbackFunc - receiver callback function.
*
* RETURN VALUE:
* -
*
* COMMENTS: -
=============================================================================*/
void BSP_BTUART_EnableRxCallback(RxCallbackFunc callbackFunc);
/*=============================================================================
* PURPOSE: Disabling Bluetooth receiver callback.
*
* PARAMETERS:
* -
*
* RETURN VALUE:
* -
*
* COMMENTS: -
=============================================================================*/
void BSP_BTUART_DisableRxCallback(void);
#endif /* BSP_BTUART_H */

View File

@ -0,0 +1,300 @@
/*=============================================================================
* (C) Copyright Albis Technologies Ltd 2011
*==============================================================================
* STM32 Example Code
*==============================================================================
* File name: bsp_btuart_dma.c
*
* Notes: STM32 Bluetooth UART driver with DMA.
*============================================================================*/
#include "bsp.h"
#include "bsp_btuart.h"
#include "bsp_debug.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_usart.h"
DEFINE_THIS_FILE
/* OS version depending macros. */
#define USE_OS_NO_ERROR OS_NO_ERR
#define USE_OS_TIMEOUT OS_TIMEOUT
#define USE_OS_Q_FULL OS_Q_FULL
/* PD2 is BT chipset reset. */
#define BT_RESET_PIN (1UL << 2)
/* BT UART is USART2 (remapped). */
#define BTUART_INST_IN_USE USART2
/* Convert msec to OS ticks. */
#define MSEC_TO_TICKS(ms) \
((ms > 0u) ? (((ms * OS_TICKS_PER_SEC) + 1000u - 1u) / 1000u) : 0u)
/* USART instance in use. */
static USART_TypeDef *usartInst = 0;
/* UART receiver with callback. */
static RxCallbackFunc rxCallbackFunc = 0;
/* DMA channels for Rx/Tx. */
static OS_EVENT *dmaRxComplete = 0;
static OS_EVENT *dmaTxComplete = 0;
static DMA_Channel_TypeDef *dmaRx;
static DMA_Channel_TypeDef *dmaTx;
static unsigned long dmaRxDataLength;
static unsigned char dmaRxData[1024];
/*=============================================================================
=============================================================================*/
static void isr_usart_rx_dma(void)
{
INT8U err;
DMA_ClearITPendingBit(DMA1_IT_TC6);
DMA_Cmd(dmaRx, DISABLE);
if(rxCallbackFunc)
{
rxCallbackFunc(dmaRxData, dmaRxDataLength);
}
else
{
err = OSSemPost(dmaRxComplete);
SYS_ASSERT(err == USE_OS_NO_ERROR);
}
}
/*=============================================================================
=============================================================================*/
static void isr_usart_tx_dma(void)
{
INT8U err;
DMA_ClearITPendingBit(DMA1_IT_TC7);
err = OSSemPost(dmaTxComplete);
SYS_ASSERT(err == USE_OS_NO_ERROR);
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_Initialise(void)
{
DMA_InitTypeDef dmaInit;
GPIO_InitTypeDef gpioInit;
NVIC_InitTypeDef nvicInit;
USART_ClockInitTypeDef usartClkInit;
/* UART instance in use. */
usartInst = BTUART_INST_IN_USE;
/* DMA Rx/Tx complete. */
dmaRxComplete = OSSemCreate(0);
SYS_ASSERT(dmaRxComplete);
dmaTxComplete = OSSemCreate(0);
SYS_ASSERT(dmaTxComplete);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
/* Common DMA channel settings. */
DMA_StructInit(&dmaInit);
dmaInit.DMA_PeripheralBaseAddr = (unsigned long)&usartInst->DR;
dmaInit.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dmaInit.DMA_MemoryInc = DMA_MemoryInc_Enable;
dmaInit.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dmaInit.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dmaInit.DMA_Mode = DMA_Mode_Normal;
dmaInit.DMA_M2M = DMA_M2M_Disable;
dmaInit.DMA_BufferSize = 1;
/* Init DMA Tx channel MEM -> USART. */
dmaTx = DMA1_Channel7;
dmaInit.DMA_Priority = DMA_Priority_Low;
dmaInit.DMA_DIR = DMA_DIR_PeripheralDST;
BSP_IntVectSet(BSP_INT_ID_DMA1_CH7, isr_usart_tx_dma);
DMA_Init(dmaTx, &dmaInit);
DMA_ITConfig(dmaTx, DMA_IT_TC, ENABLE);
USART_DMACmd(usartInst, USART_DMAReq_Tx, ENABLE);
/* Init DMA Rx channel USART -> MEM. */
dmaRx = DMA1_Channel6;
dmaInit.DMA_Priority = DMA_Priority_Medium;
dmaInit.DMA_DIR = DMA_DIR_PeripheralSRC;
BSP_IntVectSet(BSP_INT_ID_DMA1_CH6, isr_usart_rx_dma);
DMA_Init(dmaRx, &dmaInit);
DMA_ITConfig(dmaRx, DMA_IT_TC, ENABLE);
USART_DMACmd(usartInst, USART_DMAReq_Rx, ENABLE);
nvicInit.NVIC_IRQChannelPreemptionPriority = 0;
nvicInit.NVIC_IRQChannelSubPriority = 0;
nvicInit.NVIC_IRQChannelCmd = ENABLE;
nvicInit.NVIC_IRQChannel = DMA1_Channel6_IRQn;
NVIC_Init(&nvicInit);
nvicInit.NVIC_IRQChannel = DMA1_Channel7_IRQn;
NVIC_Init(&nvicInit);
USART_ClockStructInit(&usartClkInit);
usartClkInit.USART_Clock = USART_Clock_Disable;
usartClkInit.USART_CPOL = USART_CPOL_Low;
usartClkInit.USART_CPHA = USART_CPHA_2Edge;
usartClkInit.USART_LastBit = USART_LastBit_Disable;
BSP_PeriphEn(BSP_PERIPH_ID_USART2);
BSP_PeriphEn(BSP_PERIPH_ID_IOPD);
BSP_PeriphEn(BSP_PERIPH_ID_AFIO);
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
/* Configure GPIOD.5 (TX) as push-pull. */
gpioInit.GPIO_Pin = GPIO_Pin_5;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
gpioInit.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &gpioInit);
/* Configure GPIOD.4 (RTS) as push-pull. */
gpioInit.GPIO_Pin = GPIO_Pin_4;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
gpioInit.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &gpioInit);
/* Configure GPIOD.6 (RX) as input floating. */
gpioInit.GPIO_Pin = GPIO_Pin_6;
gpioInit.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &gpioInit);
/* Configure GPIOD.3 (CTS) as input floating. */
gpioInit.GPIO_Pin = GPIO_Pin_3;
gpioInit.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &gpioInit);
BSP_BTUART_SetBaudrate(115200);
USART_ClockInit(usartInst, &usartClkInit);
USART_Cmd(usartInst, ENABLE);
/* GPO for BT chipset reset. */
gpioInit.GPIO_Pin = BT_RESET_PIN;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
gpioInit.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &gpioInit);
BSP_BTUART_ActivateReset();
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_SetBaudrate(unsigned long baudrate)
{
USART_InitTypeDef usartInit;
USART_StructInit(&usartInit);
usartInit.USART_BaudRate = baudrate / 2;
usartInit.USART_WordLength = USART_WordLength_8b;
usartInit.USART_StopBits = USART_StopBits_1;
usartInit.USART_Parity = USART_Parity_No;
usartInit.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
usartInit.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(usartInst, &usartInit);
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_ActivateReset(void)
{
GPIO_ResetBits(GPIOD, BT_RESET_PIN);
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_DeactivateReset(void)
{
GPIO_SetBits(GPIOD, BT_RESET_PIN);
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_Transmit(unsigned char *buffer, unsigned long count)
{
INT8U err;
dmaTx->CMAR = (unsigned long)buffer;
dmaTx->CNDTR = count;
DMA_Cmd(dmaTx, ENABLE);
OSSemPend(dmaTxComplete, MSEC_TO_TICKS(2000), &err);
if(err == USE_OS_TIMEOUT)
{
DMA_Cmd(dmaTx, DISABLE);
return;
}
SYS_ASSERT(err == USE_OS_NO_ERROR);
DMA_Cmd(dmaTx, DISABLE);
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_AnounceDmaReceiverSize(unsigned long count)
{
dmaRx->CMAR = (unsigned long)(&dmaRxData[0]);
dmaRx->CNDTR = count;
dmaRxDataLength = count;
DMA_Cmd(dmaRx, ENABLE);
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_Receive(unsigned char *buffer,
unsigned long maxCount,
unsigned long *rxCount,
unsigned long timeout)
{
INT8U err;
unsigned short timeoutTicks = MSEC_TO_TICKS(timeout);
rxCallbackFunc = 0;
BSP_BTUART_AnounceDmaReceiverSize(maxCount);
OSSemPend(dmaRxComplete, timeoutTicks, &err);
if(err == USE_OS_TIMEOUT)
{
*rxCount = 0;
return;
}
SYS_ASSERT(err == USE_OS_NO_ERROR);
Mem_Copy(buffer, dmaRxData, dmaRxDataLength);
*rxCount = dmaRxDataLength;
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_DrainReceiver(void)
{
/* Nothing to do. */
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_EnableRxCallback(RxCallbackFunc callbackFunc)
{
rxCallbackFunc = callbackFunc;
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_DisableRxCallback(void)
{
rxCallbackFunc = 0;
}

View File

@ -0,0 +1,270 @@
/*=============================================================================
* (C) Copyright Albis Technologies Ltd 2011
*==============================================================================
* STM32 Example Code
*==============================================================================
* File name: bsp_btuart_nodma.c
*
* Notes: STM32 Bluetooth UART driver without DMA.
*============================================================================*/
#include "bsp.h"
#include "bsp_btuart.h"
#include "bsp_debug.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_usart.h"
DEFINE_THIS_FILE
/* OS version depending macros. */
#define USE_OS_NO_ERROR OS_NO_ERR
#define USE_OS_TIMEOUT OS_TIMEOUT
#define USE_OS_Q_FULL OS_Q_FULL
/* PD2 is BT chipset reset. */
#define BT_RESET_PIN (1UL << 2)
/* BT UART is USART2 (remapped). */
#define BTUART_INST_IN_USE USART2
/* Convert msec to OS ticks. */
#define MSEC_TO_TICKS(ms) \
((ms > 0u) ? (((ms * OS_TICKS_PER_SEC) + 1000u - 1u) / 1000u) : 0u)
/* USART instance in use. */
static USART_TypeDef *usartInst = 0;
/* UART receiver without callback. */
#define RX_QUEUE_BUFFER_SIZE 512
static OS_EVENT *rxQueue = 0;
static void * rxQueueBuffer[RX_QUEUE_BUFFER_SIZE];
/* UART receiver with callback. */
static RxCallbackFunc rxCallbackFunc = 0;
//=============================================================================
//=============================================================================
static void isr_bluetooth_usart(void)
{
INT8U err;
CPU_INT32U rxData;
if(USART_GetITStatus(usartInst, USART_IT_RXNE) != RESET)
{
rxData = USART_ReceiveData(usartInst) & 0xff;
if(rxCallbackFunc)
{
rxCallbackFunc((unsigned char *)&rxData, 1);
}
else
{
err = OSQPost(rxQueue, (void *)rxData);
if(err == USE_OS_NO_ERROR)
{
// Ok.
}
else if(err == USE_OS_Q_FULL)
{
printos("Tossing BT data!\r\n");
}
else
{
SYS_ERROR(1);
}
}
USART_ClearITPendingBit(usartInst, USART_IT_RXNE);
}
else
{
SYS_ERROR(1);
}
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_Initialise(void)
{
GPIO_InitTypeDef gpioInit;
USART_ClockInitTypeDef usartClkInit;
/* UART instance in use. */
usartInst = BTUART_INST_IN_USE;
/* Create Rx queue. */
rxQueue = OSQCreate(rxQueueBuffer, RX_QUEUE_BUFFER_SIZE);
SYS_ASSERT(rxQueue);
USART_ClockStructInit(&usartClkInit);
usartClkInit.USART_Clock = USART_Clock_Disable;
usartClkInit.USART_CPOL = USART_CPOL_Low;
usartClkInit.USART_CPHA = USART_CPHA_2Edge;
usartClkInit.USART_LastBit = USART_LastBit_Disable;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
BSP_PeriphEn(BSP_PERIPH_ID_USART2);
BSP_PeriphEn(BSP_PERIPH_ID_IOPD);
BSP_PeriphEn(BSP_PERIPH_ID_AFIO);
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
/* Configure GPIOD.5 (TX) as push-pull. */
gpioInit.GPIO_Pin = GPIO_Pin_5;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
gpioInit.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &gpioInit);
/* Configure GPIOD.4 (RTS) as push-pull. */
gpioInit.GPIO_Pin = GPIO_Pin_4;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
gpioInit.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &gpioInit);
/* Configure GPIOD.6 (RX) as input floating. */
gpioInit.GPIO_Pin = GPIO_Pin_6;
gpioInit.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &gpioInit);
/* Configure GPIOD.3 (CTS) as input floating. */
gpioInit.GPIO_Pin = GPIO_Pin_3;
gpioInit.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &gpioInit);
BSP_BTUART_SetBaudrate(115200);
USART_ClockInit(usartInst, &usartClkInit);
USART_Cmd(usartInst, ENABLE);
BSP_IntVectSet(BSP_INT_ID_USART2, isr_bluetooth_usart);
BSP_IntEn(BSP_INT_ID_USART2);
USART_ITConfig(usartInst, USART_IT_RXNE, ENABLE);
/* GPO for BT chipset reset. */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
gpioInit.GPIO_Pin = BT_RESET_PIN;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
gpioInit.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &gpioInit);
BSP_BTUART_ActivateReset();
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_SetBaudrate(unsigned long baudrate)
{
USART_InitTypeDef usartInit;
USART_StructInit(&usartInit);
usartInit.USART_BaudRate = baudrate / 2;
usartInit.USART_WordLength = USART_WordLength_8b;
usartInit.USART_StopBits = USART_StopBits_1;
usartInit.USART_Parity = USART_Parity_No;
usartInit.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
usartInit.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(usartInst, &usartInit);
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_ActivateReset(void)
{
GPIO_ResetBits(GPIOD, BT_RESET_PIN);
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_DeactivateReset(void)
{
GPIO_SetBits(GPIOD, BT_RESET_PIN);
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_Transmit(unsigned char *buffer, unsigned long count)
{
unsigned long i;
for(i = 0; i < count; ++i)
{
while(USART_GetFlagStatus(usartInst, USART_FLAG_TXE) != SET);
USART_SendData(usartInst, buffer[i]);
}
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_AnounceDmaReceiverSize(unsigned long count)
{
/* Nothing to do: no DMA. */
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_Receive(unsigned char *buffer,
unsigned long maxCount,
unsigned long *rxCount,
unsigned long timeout)
{
INT8U err;
void *event = 0;
unsigned long rxCounter = 0;
unsigned short timeoutTicks = MSEC_TO_TICKS(timeout);
for(;;)
{
event = OSQPend(rxQueue, timeoutTicks, &err);
if(err == USE_OS_NO_ERROR)
{
buffer[rxCounter++] = (unsigned char)(unsigned long)event;
if(rxCounter >= maxCount)
{
// Received expected number of bytes.
break;
}
}
else if(err == USE_OS_TIMEOUT)
{
break;
}
else
{
SYS_ERROR(1);
}
}
if(rxCount)
{
*rxCount = rxCounter;
}
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_DrainReceiver(void)
{
INT8U err;
do
{
OSQPend(rxQueue, 1, &err);
} while(err == OS_ERR_NONE);
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_EnableRxCallback(RxCallbackFunc callbackFunc)
{
rxCallbackFunc = callbackFunc;
}
/*=============================================================================
=============================================================================*/
void BSP_BTUART_DisableRxCallback(void)
{
rxCallbackFunc = 0;
}