Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F102521380
sbcp_master.c
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
Fri, Feb 21, 14:46
Size
18 KB
Mime Type
text/x-c
Expires
Sun, Feb 23, 14:46 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
24340580
Attached To
R6617 Oncilla SBCP Master Firmware
sbcp_master.c
View Options
/*
sbcp.c
Copyright (C) 2010 Rico Moeckel <rico.moeckel at epfl dot ch>,
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/>.
*/
/**
\defgroup sbcp SBCP
\brief Simple Binary Communication Protocol.
This file contains the implements the Simple Binary Communication
Protocol (Master device) - a communication protocol for a single
master - multiple slave, half-duplex communication bus.
\author Rico Moeckel
\version 1.1
\date 2011-04-28
*/
/*@{*/
/** \file sbcp.c
\brief Simple Binary Communication Protocol.
*/
#include "sbcp.h"
#include <p33Fxxxx.h>
#include "config.h"
#include "port.h"
#include "dma_sbcp.h"
#include "timer.h"
#include "led.h"
/*************************************************************************
*
* VARIABLES
*
*************************************************************************/
extern
const
tSBCP_CmdTbl
sbcp_cmd_tbl
[];
extern
const
int
SBCP_COMMAND_TABLE_LENGTH
;
//static tSBCP_AppVar SbcpVar;
volatile
tSBCP_AppVar
sbcp
;
///< Container struct storing the local SBCP variables.
/*******************************************************************************
*
* INLINE FUNCTION !!!!
*
******************************************************************************/
/**
* COmputes the checksum of a given packet
* @param packet the pointer to the packet buffer
* @return the checksum of the packet
*/
inline
unsigned
char
sbcp_compute_checksum_of_packet
(
const
unsigned
int
*
packet
){
unsigned
char
res
=
0x00
;
unsigned
int
i
;
unsigned
int
size
=
(
packet
[
SBCP_POS_PAYLOAD_LENGTH
]
+
5
)
&
DMA_SBCP_MAX_PACKET_SIZE_MASK
;
for
(
i
=
SBCP_POS_CLASS
;
i
<
size
;
++
i
){
res
+=
packet
[
i
];
}
return
res
;
}
/**
* Mark the correct checksum flags for a finished packet
*/
#define SBCP_CHECK_CHECKSUM(bh) do{ \
unsigned int *_sbcp_packet = DMA_PACKET_QUEUE_USB_GET_CPU(bh); \
unsigned char _sbcp_correctCS = 0x00; \
_sbcp_correctCS += _sbcp_packet[SBCP_POS_CLASS]; \
_sbcp_correctCS += _sbcp_packet[SBCP_POS_ID]; \
_sbcp_correctCS += _sbcp_packet[SBCP_POS_PAYLOAD_LENGTH]; \
_sbcp_correctCS += _sbcp_packet[SBCP_POS_INSTRUCTION]; \
unsigned int _sbcp_i = SBCP_POS_PAYLOAD_START; \
unsigned int _sbcp_size = (_sbcp_packet[SBCP_POS_PAYLOAD_LENGTH] + 5) & DMA_SBCP_MAX_PACKET_SIZE_MASK; \
for(; _sbcp_i < _sbcp_size; ++_sbcp_i){ \
_sbcp_correctCS += _sbcp_packet[_sbcp_i]; \
} \
if(_sbcp_correctCS == _sbcp_packet[_sbcp_size]){ \
dma_sbcp.packet_flags[bh] |= SBCP_CS_CHECKED | SBCP_CS_IS_CORRECT; \
}else { \
dma_sbcp.packet_flags[bh] |= SBCP_CS_CHECKED; \
} \
}while(0)
#define SBCP_CHECK_CHECKSUM_IF_NEEDED(bh) do{ \
if(!(dma_sbcp.packet_flags[bh] & SBCP_CS_CHECKED)){ \
SBCP_CHECK_CHECKSUM(bh); \
} \
}while(0);
#define SBCP_CHECKED_CHECKSUM_IS_CORRECT(bh) \
((dma_sbcp.packet_flags[bh]) & SBCP_CS_IS_CORRECT)
/**
* Mark the correct destination flags for a finished packet.
*/
#define SBCP_CHECK_DESTINATION(bh) do{ \
unsigned int * _sbcp_packet = DMA_PACKET_QUEUE_USB_GET_CPU(bh); \
if(_sbcp_packet[SBCP_POS_CLASS] == SBCP_MY_CLASS && \
_sbcp_packet[SBCP_POS_ID] == SBCP_MY_ID ){ \
dma_sbcp.packet_flags[bh] |= SBCP_DEST_CHECKED | SBCP_DEST_IS_US; \
} else { \
dma_sbcp.packet_flags[bh] |= SBCP_DEST_CHECKED; \
} \
}while(0)
#define SBCP_CHECK_DESTINATION_IF_NEEDED(bh) do{ \
if(!(dma_sbcp.packet_flags[bh] & SBCP_DEST_CHECKED)){ \
SBCP_CHECK_DESTINATION(bh); \
} \
}while(0)
#define SBCP_CHECKED_DESTINATION_IS_CORRECT(bh) \
((dma_sbcp.packet_flags[bh]) & SBCP_DEST_IS_US)
/*
#define MARK_FIRST_READY_USB_PACKET_AS_TREATED do{\
sbcp.usb_packet_flags[sbcp.usb_ready_packet_queue.head] = SBCP_UNCHECKED;\
DMA_PACKET_QUEUE_INCREMENT_HEAD(sbcp.usb_ready_packet_queue);\
}while(0)
*/
/*************************************************************************
*
* FUNCTIONS
*
*************************************************************************/
/** \brief Function for initializing SBCP module.
This function initializes the SBCP module. It should be
called once in the main initialization function before executing
the sbcp_main() outine.
\param no parameters
\return no returns
*/
void
sbcp_init
()
{
PORT_RS485_TAKE_DRIVE
();
}
/** \brief SBCP instruction search and execution.
*
* Function calls function corresponding to the SBCP instruction (as being
* registered in table sbcp_cmd_tbl[]
* in file command.c) found in the SBCP packet. This function assumes that the entire
* packet is already received and the the check sum is correct.
*
* \param buffer:
* pointer to the buffer that contains the SBCP packet
* \return no returns
*/
static
void
sbcp_search_and_execute_instruction
(
DMA_packet_queue_buffer_handler
bh
,
unsigned
int
*
packet
)
{
unsigned
char
instruction
;
instruction
=
packet
[
SBCP_POS_INSTRUCTION
];
// check if instruction is valid number - meaning if entry in command table can exist
if
(
instruction
>=
SBCP_COMMAND_TABLE_LENGTH
)
{
sbcp_usb_send_com_error_code
(
bh
,
SBCP_COM_ERROR_CODE_UNKNOWN_INSTRUCTION
);
return
;
}
sbcp_cmd_tbl
[
instruction
].
cmd_function
(
packet
);
}
// sbcp_search_and_execute_command
/** \brief SBCP main function.
*
* This function implements all SBCP state machines for packet analysation. It
* should be peridically called in the main() function.
*
* \param no parameters
* \return no returns
*/
void
sbcp_main
()
{
//==========================================================================
// TIMEOUT
//==========================================================================
// First let handle any pending timeout.
if
(
dma_sbcp
.
usb_rx_error
!=
0
)
{
//timeout while getting packet from host
//we simply ignore the current packet, It may already be in
//transmission, so we fake the current checksum if it is the case.
U2MODEbits
.
UARTEN
=
0
;
//disable UART, ignoring data from now;
DMA2CONbits
.
CHEN
=
0
;
//disable the channel before anything
if
(
dma_sbcp
.
bus_tx_state
==
SBCP_TX_UNFINISHED_PACKET
)
{
//we are in trouble, the unsfunished packet is on transmission ! we must
//fake data, and still finish transmission
U1STAbits
.
UTXEN
=
0
;
//disable transmission
//compute the chacksum of packet
unsigned
int
*
packet
=
dma_sbcp
.
current_usb_rx_packet
;
packet
[
packet
[
SBCP_POS_PAYLOAD_LENGTH
]
+
SBCP_POS_PAYLOAD_START
]
=
~
(
sbcp_compute_checksum_of_packet
(
packet
));
// this is a bad checksum
//specify that we have finished the packet (it is a bad one, but now
//it is finished
U1STAbits
.
UTXEN
=
1
;
//reenable TX of data, will finish to send data, with bad checksum
//now mark that we are transmitting a finished packet.
dma_sbcp
.
bus_tx_state
=
SBCP_TX_FINISHED_PACKET
;
}
else
{
sbcp_usb_send_com_error_code
(
dma_sbcp
.
rx_queue
.
tail
,
dma_sbcp
.
usb_rx_error
);
}
TIMER_2_STOP_AND_CLEAR
();
//reinitialize Rx of USB data
DMA2STA
=
DMA_PACKET_QUEUE_USB_GET_DMA
(
dma_sbcp
.
rx_queue
.
tail
);
DMA2CNT
=
0
;
//get one byte
dma_sbcp
.
usb_rx_state
=
DMA_WAIT_FOR_HEADER_BYTE
;
DMA2CONbits
.
CHEN
=
1
;
U2MODEbits
.
UARTEN
=
1
;
//re-enable reception and transmission
U2STAbits
.
UTXEN
=
1
;
//clear time out
dma_sbcp
.
usb_rx_error
=
0
;
}
if
(
DMA0CONbits
.
CHEN
==
1
){
IEC0bits
.
DMA0IE
=
0
;
if
(
IFS1bits
.
T4IF
==
1
){
dma_sbcp
.
bus_rx_error
|=
SBCP_COM_ERROR_CODE_BUS_TIMEOUT
;
TIMER_4_STOP_AND_CLEAR
();
}
IEC0bits
.
DMA0IE
=
1
;
}
//this is a far more tricky situation. We get an error while receiving over
//the bus but we should not make any mistake, since we already started to
//make a packet. so don't start a new one, but only modify the existing one
if
(
dma_sbcp
.
bus_rx_error
!=
0
)
{
DMA0CONbits
.
CHEN
=
0
;
U1MODEbits
.
UARTEN
=
0
;
//disable the UART reception from the slave
//disbale the DMA channel we don't need to
//receive anymore
if
(
DMA3CONbits
.
CHEN
==
1
&&
dma_sbcp
.
usb_tx_state
==
SBCP_TX_UNFINISHED_PACKET
)
{
//we were already transmitting back, so we must fake data, and
//finish transmission
U2STAbits
.
UTXEN
=
0
;
//stop transmission now !!!
unsigned
int
*
packet
=
dma_sbcp
.
current_bus_rx_packet
;
packet
[
packet
[
SBCP_POS_PAYLOAD_LENGTH
]
+
SBCP_POS_PAYLOAD_START
]
=
~
(
sbcp_compute_checksum_of_packet
(
packet
));
// this is a bad checksum
//specify that the packet is finished
U2STAbits
.
UTXEN
=
1
;
//finsih the launch with another bunch of data.
dma_sbcp
.
usb_tx_state
=
SBCP_TX_FINISHED_PACKET
;
}
else
{
//if we don't even have started the transmission, send an error
//but here the data is already allocated, so we must change instead
//of realocating a new packet !
unsigned
int
*
message
=
DMA_PACKET_QUEUE_BUS_GET_CPU
(
dma_sbcp
.
bus_rx_packet
);
//we are alway receiving on the tail.
//now we completely erase our message being received, and remplace
//it by an error one.
message
[
SBCP_POS_HEADER
]
=
SBCP_HEADER
;
message
[
SBCP_POS_CLASS
]
=
SBCP_MY_CLASS
;
message
[
SBCP_POS_ID
]
=
SBCP_MY_ID
;
message
[
SBCP_POS_PAYLOAD_LENGTH
]
=
1
;
message
[
SBCP_POS_INSTRUCTION
]
=
SBCP_ERROR_FLAG_COM_ERROR
;
message
[
SBCP_POS_PAYLOAD_START
]
=
dma_sbcp
.
bus_rx_error
;
message
[
SBCP_POS_PAYLOAD_START
+
1
]
=
SBCP_MY_CLASS
+
SBCP_MY_ID
+
1
+
SBCP_ERROR_FLAG_COM_ERROR
+
dma_sbcp
.
bus_rx_error
;
//specify to the cpu that data is ready to send
dma_sbcp
.
packet_states
[
dma_sbcp
.
bus_rx_packet
]
=
SBCP_FEEDBACK_FULLY_RECEIVED
;
}
TIMER_4_STOP_AND_CLEAR
();
//don't reinit Rx of bus. We getted and error, we are now the master again !
PORT_RS485_TAKE_DRIVE
();
dma_sbcp
.
bus_rx_error
=
0
;
//clear the error flag, otherwise we are trapped !
dma_sbcp
.
bus_tx_state
=
SBCP_IDLE
;
U1MODEbits
.
UARTEN
=
1
;
U1STAbits
.
UTXEN
=
1
;
//re - enable UART, it may be useful :D
}
if
(
dma_sbcp
.
usb_tx_state
==
SBCP_IDLE
)
{
DMA_packet_queue_buffer_handler
packet
=
dma_sbcp
.
rx_queue
.
head
;
eSBCP_packet_state
packet_state
=
dma_sbcp
.
packet_states
[
packet
];
if
(
packet_state
==
SBCP_FEEDBACK_DEST_AND_SIZE_KNOWN
||
packet_state
==
SBCP_FEEDBACK_FULLY_RECEIVED
)
{
DMA3STA
=
DMA_PACKET_QUEUE_BUS_GET_DMA
(
packet
);
DMA3CNT
=
((
DMA_PACKET_QUEUE_BUS_GET_CPU
(
packet
))[
SBCP_POS_PAYLOAD_LENGTH
]
+
5
)
&
DMA_SBCP_MAX_PACKET_SIZE_MASK
;
DMA3CONbits
.
CHEN
=
1
;
DMA3REQbits
.
FORCE
=
1
;
IEC0bits
.
DMA0IE
=
0
;
if
(
dma_sbcp
.
packet_states
[
packet
]
==
SBCP_FEEDBACK_DEST_AND_SIZE_KNOWN
)
{
dma_sbcp
.
usb_tx_state
=
SBCP_TX_UNFINISHED_PACKET
;
}
else
{
dma_sbcp
.
usb_tx_state
=
SBCP_TX_FINISHED_PACKET
;
}
IEC0bits
.
DMA0IE
=
1
;
led_on
(
LED_YELLOW
);
}
}
if
(
dma_sbcp
.
bus_tx_state
==
SBCP_IDLE
)
{
IEC2bits
.
DMA3IE
=
0
;
DMA_packet_queue_buffer_handler
packet
=
dma_sbcp
.
rx_queue
.
head
;
signed
int
nb_packet_treatable
=
dma_sbcp
.
rx_queue
.
nb_packet
;
IEC2bits
.
DMA3IE
=
1
;
while
(
nb_packet_treatable
>
0
)
{
if
(
dma_sbcp
.
packet_states
[
packet
]
==
SBCP_FORWARD_NEED_TO_BE_TREATED_LOCALLY
)
{
dma_sbcp
.
bus_rx_packet
=
packet
;
sbcp_search_and_execute_instruction
(
packet
,
DMA_PACKET_QUEUE_USB_GET_CPU
(
packet
));
nb_packet_treatable
=
0
;
//we should not treat other packet now
}
if
(
dma_sbcp
.
packet_states
[
packet
]
==
SBCP_FORWARD_NEED_TO_BE_TRANSMITTED
)
{
dma_sbcp
.
bus_rx_packet
=
packet
;
DMA1STA
=
DMA_PACKET_QUEUE_USB_GET_DMA
(
packet
);
DMA1CNT
=
(
DMA_PACKET_QUEUE_USB_GET_CPU
(
packet
)[
SBCP_POS_PAYLOAD_LENGTH
]
+
5
)
&
DMA_SBCP_MAX_PACKET_SIZE_MASK
;
DMA1CONbits
.
CHEN
=
1
;
DMA1REQbits
.
FORCE
=
1
;
IEC1bits
.
DMA2IE
=
0
;
//desactivate the interrupt, because if we
//finish insideb this if, it will be catastrophic
if
(
packet
==
dma_sbcp
.
rx_queue
.
tail
)
{
dma_sbcp
.
bus_tx_state
=
SBCP_TX_UNFINISHED_PACKET
;
}
else
{
dma_sbcp
.
bus_tx_state
=
SBCP_TX_FINISHED_PACKET
;
}
IEC1bits
.
DMA2IE
=
1
;
dma_sbcp
.
packet_states
[
packet
]
=
SBCP_FORWARD_IN_TX
;
nb_packet_treatable
=
0
;
//we should not treat other packet now, or we will get inversions !
led_on
(
LED_GREEN_2
);
}
--
nb_packet_treatable
;
packet
=
(
packet
+
1
)
&
DMA_PACKET_QUEUE_MASK
;
}
}
IEC2bits
.
DMA3IE
=
0
;
DMA_packet_queue_buffer_handler
packet
=
dma_sbcp
.
rx_queue
.
head
;
signed
int
nb_packet_treatable
=
dma_sbcp
.
rx_queue
.
nb_packet
;
unsigned
int
isFirstPacket
=
1
;
while
(
nb_packet_treatable
>
0
)
{
if
(
nb_packet_treatable
>
DMA_PACKET_QUEUE_LENGTH
){
//super super bad error, we report it,and quit
led_blink_with_params
(
LED_RED
,
6
);
break
;
}
if
(
isFirstPacket
==
0
&&
dma_sbcp
.
packet_states
[
packet
]
==
SBCP_INEXISTANT
)
{
//REPORT Error this is not the head packet (that could from time to
//time become inexistant as it just finished) and it is inexistant
//this is really really bad !
led_blink_with_params
(
LED_RED
,
1
);
}
isFirstPacket
=
0
;
/*
if (dma_sbcp.packet_states[packet] == SBCP_FORWARD_STARTED_RECEPTION) {
// DO Nothing
}
*/
if
(
dma_sbcp
.
packet_states
[
packet
]
==
SBCP_FORWARD_DEST_AND_SIZE_KNOWN
)
{
SBCP_CHECK_DESTINATION_IF_NEEDED
(
packet
);
// comment this lines if you don't want to transmit packet ASAP on
//the bus, even when checksum is not finished.
if
((
dma_sbcp
.
rx_queue
.
head
==
packet
)
&&
!
SBCP_CHECKED_DESTINATION_IS_CORRECT
(
packet
))
{
//we only permit to fast forward transmit the first packet.
dma_sbcp
.
packet_states
[
packet
]
=
SBCP_FORWARD_NEED_TO_BE_TRANSMITTED
;
}
}
if
(
dma_sbcp
.
packet_states
[
packet
]
==
SBCP_FORWARD_READY_TO_TREAT
)
{
SBCP_CHECK_DESTINATION_IF_NEEDED
(
packet
);
SBCP_CHECK_CHECKSUM_IF_NEEDED
(
packet
);
if
(
!
SBCP_CHECKED_CHECKSUM_IS_CORRECT
(
packet
))
{
sbcp_usb_send_com_error_code
(
packet
,
SBCP_COM_ERROR_CODE_CHECKSUM_INCORRECT
);
}
if
(
SBCP_CHECKED_DESTINATION_IS_CORRECT
(
packet
))
{
dma_sbcp
.
packet_states
[
packet
]
=
SBCP_FORWARD_NEED_TO_BE_TREATED_LOCALLY
;
}
else
{
dma_sbcp
.
packet_states
[
packet
]
=
SBCP_FORWARD_NEED_TO_BE_TRANSMITTED
;
}
}
if
(
dma_sbcp
.
packet_states
[
packet
]
>
SBCP_FEEDBACK_IN_TRANSMISSION
)
{
led_blink_with_params
(
LED_RED
,
2
);
}
--
nb_packet_treatable
;
packet
=
(
packet
+
1
)
&
DMA_PACKET_QUEUE_MASK
;
}
IEC2bits
.
DMA3IE
=
1
;
//here we have some time for processing checksum, and checking destination
signed
int
dist
=
dma_sbcp
.
bus_rx_packet
-
dma_sbcp
.
rx_queue
.
head
;
if
(
dist
<
0
)
{
dist
+=
4
;
}
if
(
dist
>
1
&&
dma_sbcp
.
bus_tx_state
!=
SBCP_IDLE
)
{
led_blink_with_params
(
LED_RED
,
3
);
}
// in case of an overflow, we have to check when we are free again
if
(
dma_sbcp
.
usb_rx_state
==
DMA_OVERFLOW_PENDING
&&
!
DMA_PACKET_QUEUE_FULL
(
dma_sbcp
.
rx_queue
))
{
DMA_INIT_USB_RX
;
}
if
(
dma_sbcp
.
bus_tx_state
==
SBCP_IDLE
)
{
led_off
(
LED_GREEN_2
);
}
if
(
dma_sbcp
.
usb_tx_state
==
SBCP_IDLE
)
{
led_off
(
LED_YELLOW
);
}
}
/**
* @return a free pointer to a buffer for usb transmission.
*/
/*
unsigned int * sbcp_get_new_usb_tx_packet(){
while (DMA_PACKET_QUEUE_FULL(dma_sbcp.bus_rx_queue)) {
}
//stop channel2 Interruption, to prevent buffer order swapping, if we finish
//the reception of a packet at the same time !
IEC1bits.DMA2IE = 0;
DMA_PACKET_QUEUE_INCREMENT_TAIL(dma_sbcp.bus_rx_queue);
IEC1bits.DMA2IE = 1;
return DMA_PACKET_QUEUE_BUS_GET_CPU(dma_sbcp.bus_rx_queue.tail);
}*/
/** \brief Function for generation of standard acknowledgement messages.
This function generates a standard acknowledgement message
and sends it via the communication bus.
\param no parameters
\return no returns
*/
void
sbcp_usb_send_standard_acknowlegement
(
DMA_packet_queue_buffer_handler
bh
){
unsigned
int
*
message
=
DMA_PACKET_QUEUE_BUS_GET_CPU
(
bh
);
dma_sbcp
.
packet_states
[
bh
]
=
SBCP_FEEDBACK_FULLY_RECEIVED
;
message
[
SBCP_POS_HEADER
]
=
SBCP_HEADER
;
message
[
SBCP_POS_CLASS
]
=
SBCP_MY_CLASS
;
message
[
SBCP_POS_ID
]
=
SBCP_MY_ID
;
message
[
SBCP_POS_PAYLOAD_LENGTH
]
=
0x00
;
message
[
SBCP_POS_INSTRUCTION
]
=
SBCP_STANDARD_ACKNOWLEDGEMENT
;
message
[
SBCP_POS_PAYLOAD_START
]
=
SBCP_MY_CLASS
+
SBCP_MY_ID
+
SBCP_STANDARD_ACKNOWLEDGEMENT
;
//will tell the main fnction that it can send some data
// DMA_PACKET_QUEUE_INCREMENT_TAIL(sbcp.bus_ready_packet_queue);
}
/** \brief Function for generation of error messages.
This function generates a standard error message according to the
given error code and sends it via the USB interface.
\param error_code:
Error code to be transmitted.
\return no returns
*/
void
sbcp_usb_send_com_error_code
(
DMA_packet_queue_buffer_handler
bh
,
unsigned
char
error_code
)
{
unsigned
int
*
message
=
DMA_PACKET_QUEUE_BUS_GET_CPU
(
bh
);
dma_sbcp
.
packet_states
[
bh
]
=
SBCP_FEEDBACK_FULLY_RECEIVED
;
message
[
SBCP_POS_HEADER
]
=
SBCP_HEADER
;
message
[
SBCP_POS_CLASS
]
=
SBCP_MY_CLASS
;
message
[
SBCP_POS_ID
]
=
SBCP_MY_ID
;
message
[
SBCP_POS_PAYLOAD_LENGTH
]
=
0x01
;
message
[
SBCP_POS_INSTRUCTION
]
=
SBCP_ERROR_FLAG_COM_ERROR
;
message
[
SBCP_POS_PAYLOAD_START
]
=
error_code
;
message
[
SBCP_POS_PAYLOAD_START
+
1
]
=
SBCP_MY_CLASS
+
SBCP_MY_ID
+
1
+
SBCP_ERROR_FLAG_COM_ERROR
+
error_code
;
//will tell the main fnction that it can send some data
// DMA_PACKET_QUEUE_INCREMENT_TAIL(sbcp.bus_ready_packet_queue);
}
void
sbcp_usb_send_message
(
DMA_packet_queue_buffer_handler
bh
,
unsigned
char
error_code
,
unsigned
char
size
,
unsigned
char
*
data
){
unsigned
int
*
message
=
DMA_PACKET_QUEUE_BUS_GET_CPU
(
bh
);
dma_sbcp
.
packet_states
[
bh
]
=
SBCP_FEEDBACK_FULLY_RECEIVED
;
message
[
SBCP_POS_HEADER
]
=
SBCP_HEADER
;
message
[
SBCP_POS_CLASS
]
=
SBCP_MY_CLASS
;
message
[
SBCP_POS_ID
]
=
SBCP_MY_ID
;
message
[
SBCP_POS_PAYLOAD_LENGTH
]
=
size
;
message
[
SBCP_POS_INSTRUCTION
]
=
error_code
;
message
[
SBCP_POS_PAYLOAD_START
+
size
]
=
SBCP_MY_CLASS
+
SBCP_MY_ID
+
size
+
error_code
;
unsigned
int
i
;
for
(
i
=
0
;
i
<
size
;
++
i
){
message
[
SBCP_POS_PAYLOAD_START
+
i
]
=
data
[
i
];
message
[
SBCP_POS_PAYLOAD_START
+
size
]
+=
data
[
i
];
}
message
[
SBCP_POS_PAYLOAD_START
+
size
]
&=
0x00ff
;
}
/*@}*/
Event Timeline
Log In to Comment