Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F79094592
dma_sbcp.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Aug 24, 17:42
Size
9 KB
Mime Type
text/x-c
Expires
Mon, Aug 26, 17:42 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
20150288
Attached To
R6619 Oncilla Motordriver Firmware
dma_sbcp.h
View Options
/*
* dma_sbcp.h
*
* Copyright (c) Alexandre Tuleu
* EPFL Biorobotics Laboratory (http://biorob.epfl.ch)
* EPFL Ecole Polytechnique Federale de Lausanne (http://www.epfl.ch)
*
* 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, see <http://www.gnu.org/licenses/>.
*
*/
/**
* \file dma_sbcp.h
* DMA management for SBCP protocol
* \author Alexandre Tuleu
*
*/
#ifndef DMA_SBCP_H_
#define DMA_SBCP_H_
#include "dma_packet_queue.h"
#include "sbcp.h"
/**
* Initializes a channel for reception
* \param channel : the number of the dma channel to initialize
* \param type : either usb or bus
* \param TYPE : the same than type, but in capitals
* \param mask : the mask to use forincrementing DMA_packet_buffer_handler
*/
#define DMA_INIT_CHANNEL_FOR_RX(channel,type,TYPE) do {\
DMA_PACKET_QUEUE_INCREMENT_TAIL(dma_sbcp.type ## _rx_queue);\
DMA ## channel ## STA = DMA_PACKET_QUEUE_ ## TYPE ##_GET_DMA(dma_sbcp.type ## _rx_queue.tail);\
dma_sbcp.current_ ## type ##_rx_packet = DMA_PACKET_QUEUE_## TYPE ## _GET_CPU(dma_sbcp.type ## _rx_queue.tail);\
DMA ## channel ## CNT = 0; \
dma_sbcp.type ## _rx_state = DMA_WAIT_FOR_HEADER_BYTE;\
DMA ## channel ## CONbits.CHEN = 1;}while(0)
#ifdef SBCP_IS_MASTER
/**
* Initialize the USB dma channel.
*/
#define DMA_INIT_USB_RX do{\
DMA_PACKET_QUEUE_INCREMENT_TAIL(dma_sbcp.rx_queue);\
DMA2STA = DMA_PACKET_QUEUE_USB_GET_DMA(dma_sbcp.rx_queue.tail);\
dma_sbcp.current_usb_rx_packet = DMA_PACKET_QUEUE_USB_GET_CPU(dma_sbcp.rx_queue.tail);\
DMA2CNT = 0;\
dma_sbcp.usb_rx_state = DMA_WAIT_FOR_HEADER_BYTE;\
DMA2CONbits.CHEN = 1;\
dma_sbcp.packet_states[dma_sbcp.rx_queue.tail] = SBCP_FORWARD_STARTED_RECEPTION;\
}while(0)
//DMA_INIT_CHANNEL_FOR_RX(2,usb,USB)
/**
* Initialize the BUS dma channel
*/
#define DMA_INIT_BUS_RX do{\
DMA0STA = DMA_PACKET_QUEUE_BUS_GET_DMA(dma_sbcp.bus_rx_packet);\
dma_sbcp.current_bus_rx_packet = DMA_PACKET_QUEUE_BUS_GET_CPU(dma_sbcp.bus_rx_packet);\
DMA0CNT = 0;\
dma_sbcp.bus_rx_state = DMA_WAIT_FOR_HEADER_BYTE;\
DMA0CONbits.CHEN = 1;\
dma_sbcp.packet_states[dma_sbcp.bus_rx_packet] = SBCP_WAIT_FOR_FEEDBACK;\
}while(0)
#elif defined(SBCP_IS_SLAVE)
#define DMA_INIT_BUS_RX \
DMA_INIT_CHANNEL_FOR_RX(0,bus,BUS)
#endif
//DMA_INIT_CHANNEL_FOR_RX(0,bus,BUS)
/**
* Config a DMA channel to get the end of the header of a packet.
* \param channel : the number of the channel to use
* \param type : the queue to use
*/
#define DMA_CHANNEL_CONFIG_GET_END_HEADER(channel,type) do { \
DMA ## channel ## CONbits.CHEN = 0; \
DMA ## channel ## STA += 2;\
DMA ## channel ## CNT = 2;\
DMA ## channel ## CONbits.CHEN = 1; \
dma_sbcp.type ## _rx_state = DMA_WAIT_FOR_FULL_HEADER; } while(0)
#ifdef SBCP_IS_MASTER
/// Config the usb Rx channel to get the end of the headre of an packet
#define DMA_USB_CHANNEL_CONFIG_GET_END_HEADER \
DMA_CHANNEL_CONFIG_GET_END_HEADER(2,usb)
#endif
/// Config the bus Rx channel to get the end of the headre of an packet
#define DMA_BUS_CHANNEL_CONFIG_GET_END_HEADER \
DMA_CHANNEL_CONFIG_GET_END_HEADER(0,bus)
/**
* Config a channel to get the end of an packet.
* \param channel : the number of teh channel to use
* \param type : the associated type
*/
#define DMA_CHANNEL_CONFIG_GET_END_PACKET(channel,type) do { \
DMA ## channel ## CONbits.CHEN = 0;\
DMA ## channel ## STA += 6; \
unsigned char length = ((unsigned char *)dma_sbcp.current_## type ##_rx_packet)[2 * SBCP_POS_PAYLOAD_LENGTH]; \
if(length > DMA_SBCP_MAX_PACKET_PAYLOAD_SIZE){ length = DMA_SBCP_MAX_PACKET_PAYLOAD_SIZE; } \
DMA ## channel ## CNT = length + 1; \
DMA ## channel ## CONbits.CHEN = 1; \
dma_sbcp.type ## _rx_state = DMA_WAIT_FOR_FULL_PACKET;} while(0)
#ifdef SBCP_IS_MASTER
/**
* Config the usb rx channel to get the end of an packet.
*/
#define DMA_USB_CHANNEL_CONFIG_GET_END_PACKET \
DMA_CHANNEL_CONFIG_GET_END_PACKET(2,usb)
#endif
/**
* Config the bus rx channel to get the end of an packet.
*/
#define DMA_BUS_CHANNEL_CONFIG_GET_END_PACKET \
DMA_CHANNEL_CONFIG_GET_END_PACKET(0,bus)
#define DMA_BUS_DISABLE_ERR_DETECTION do{\
dma_sbcp.bus_uart_error_enable_flags = DMA_UART_ALL_ERRORS_DISABLED;\
}while(0)
#define DMA_BUS_ENABLE_ERR_DETECTION do{\
dma_sbcp.bus_uart_error_enable_flags = DMA_UART_FERR_ENABLED \
| DMA_UART_PERR_ENABLED \
| DMA_UART_OERR_ENABLED;\
}while(0)
#ifdef SBCP_IS_MASTER
/**
* Config a tx channel to send data over the bus.
* \param channel : the number of the channel to use
* \param type : aither usb or bus
* \param TYPE : the same than type, but in capitals
* \param state : the state that should have the channel after the transmission
* is started.
*/
/*#define DMA_CHANNEL_CONFIG_TRANSMISSION(channel,type,TYPE,LENGTH,state) do { \
DMA ## channel ## STA = DMA_PACKET_QUEUE_ ## TYPE ##_GET_DMA(dma_sbcp.type ## _rx_queue.head);\
DMA ## channel ## CNT = (LENGTH) & DMA_SBCP_MAX_PACKET_SIZE_MASK;\
sbcp.type ## _tx_state = state;\
DMA ## channel ## CONbits.CHEN = 1;\
DMA ## channel ## REQbits.FORCE = 1; \
}while(0) */
#elif defined(SBCP_IS_SLAVE)
#define DMA_INIT_BUS_TRANSMISSION do{\
DMA1CNT = ((((volatile unsigned int )DMA_PACKET_QUEUE_BUS_TX_BUFFER_CPU[SBCP_POS_PAYLOAD_LENGTH]) + 5 ) & DMA_SBCP_MAX_PACKET_SIZE_MASK );\
PORT_RS485_RECEIVER_DISABLE;\
PORT_RS485_DRIVER_ENABLE;\
DMA1REQbits.FORCE = 1;\
DMA1CONbits.CHEN = 1;\
}while(0)
#endif
#ifdef SBCP_IS_SLAVE
#endif
//SBCP_IS_SLAVE
/**
* State for dma reception channel. REally simple state machine :
* DMA_WAIT_FOR_HEADER_BYTE > DMA_WAIT_FOR_FULL_HEADER >
* DMA_WAIT_FOR_FULL_PACKET > DMA_OVERFLOW_PEDNING;
* any state > DMA_WAIT_FOR_HEADER_BYTE
*/
typedef
enum
DMA_rx_state
{
DMA_NO_RECEPTION
=
0x00
,
DMA_WAIT_FOR_HEADER_BYTE
=
0x01
,
///< Wait to get a 0xff
DMA_WAIT_FOR_FULL_HEADER
=
0x02
,
///< Wait to get the 4 first byte of an packet
DMA_WAIT_FOR_FULL_PACKET
=
0x03
,
///< Wait to get the complete packet
DMA_OVERFLOW_PENDING
=
0x04
///< an overflow is pending, reception is therefore *disabled*
}
DMA_rx_state
;
typedef
enum
DMA_UART_err_flags
{
DMA_UART_ALL_ERRORS_DISABLED
=
0x00
,
DMA_UART_FERR_ENABLED
=
0x01
,
DMA_UART_PERR_ENABLED
=
0x02
,
DMA_UART_OERR_ENABLED
=
0x04
}
DMA_UART_err_flags
;
#ifdef SBCP_IS_SLAVE
/**
* Static data for DMA management
*/
typedef
struct
DMA_SBCP_data
{
/**
* state of the bus transmission
*/
DMA_rx_state
bus_rx_state
;
/**
* Represent the packet slots available for bis reception, and therefore for
* usb transmission.
*/
DMA_packet_queue
bus_rx_queue
;
/**
* Is 1 if a timeout issued while receiving over the bus.
*/
unsigned
int
bus_rx_error
;
/**
* Pointer to the current received bus packet.
*/
unsigned
int
*
current_bus_rx_packet
;
DMA_UART_err_flags
bus_uart_error_enable_flags
;
}
DMA_SBCP_data
;
#elif defined(SBCP_IS_MASTER)
typedef
enum
eSBCP_tx_state
{
SBCP_IDLE
,
///< is free
SBCP_TX_FINISHED_PACKET
,
///< is transmitting a well, finished packet
SBCP_TX_UNFINISHED_PACKET
,
///< is transmitting an unfunished packet(unsafe !)
SBCP_HALF_DUPLEX_WAITING_RESPONSE
}
eSBCP_tx_state
;
typedef
enum
eSBCP_packet_flags
{
SBCP_UNCHECKED
=
0x00
,
SBCP_CS_CHECKED
=
0x01
,
SBCP_CS_IS_CORRECT
=
0x02
,
SBCP_DEST_CHECKED
=
0x04
,
SBCP_DEST_IS_US
=
0x08
,
}
eSBCP_packet_flags
;
typedef
enum
eSBCP_packet_state
{
SBCP_INEXISTANT
=
0x00
,
SBCP_FORWARD_STARTED_RECEPTION
,
SBCP_FORWARD_DEST_AND_SIZE_KNOWN
,
SBCP_FORWARD_READY_TO_TREAT
,
SBCP_FORWARD_NEED_TO_BE_TRANSMITTED
,
SBCP_FORWARD_NEED_TO_BE_TREATED_LOCALLY
,
SBCP_FORWARD_IN_TX
,
SBCP_WAIT_FOR_FEEDBACK
,
SBCP_FEEDBACK_DEST_AND_SIZE_KNOWN
,
SBCP_FEEDBACK_FULLY_RECEIVED
,
SBCP_FEEDBACK_IN_TRANSMISSION
}
eSBCP_packet_state
;
typedef
struct
DMA_SBCP_data
{
/**
* state of the usb transmission
*/
DMA_rx_state
usb_rx_state
;
DMA_rx_state
bus_rx_state
;
eSBCP_tx_state
bus_tx_state
;
eSBCP_tx_state
usb_tx_state
;
/**
* Represent the packet slots available for usb reception, (and thus bus
* transmission).
*/
DMA_packet_queue
rx_queue
;
DMA_packet_queue_buffer_handler
bus_rx_packet
;
/**
* Is 1 if a timeout issued while receiving over the usb.
*/
unsigned
int
usb_rx_error
;
unsigned
int
bus_rx_error
;
/**
* Pointer to the current received usb packet.
*/
unsigned
int
*
current_usb_rx_packet
;
unsigned
int
*
current_bus_rx_packet
;
eSBCP_packet_flags
packet_flags
[
DMA_PACKET_QUEUE_LENGTH
];
eSBCP_packet_state
packet_states
[
DMA_PACKET_QUEUE_LENGTH
];
DMA_UART_err_flags
bus_uart_error_enable_flags
;
}
DMA_SBCP_data
;
#endif
/**
* The global data of the dma module
*/
extern
volatile
DMA_SBCP_data
dma_sbcp
;
void
dma_sbcp_init
();
#endif
//DMA_H_
///TODO :
/// seting priority of interruption :
/// timer should have a lower priority than interrupt of DMA
Event Timeline
Log In to Comment