PIC24 Support Libraries
esos_ecan.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2013 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30  /**
31  * \addtogroup ESOS_Task_ECAN_Service
32  * @{
33  */
34 
35  /** \file
36  * This file contains macros, prototypes, and definitions for
37  * ECAN services for ESOS tasks.
38  */
39 
40 /*** I N C L U D E S *************************************************/
41 #include <string.h>
42 #include "esos.h"
43 #include "esos_ecan.h"
44 #include "pic24/esos_pic24_ecan.h"
45 
46 /*** D E F I N E ******************************************************/
47 #define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
48 
49 /*** T H E C O D E *************************************************/
50 client_t canfactory_clients[MAX_CANFACTORY_CLIENTS];
51 ESOS_TASK_HANDLE __esos_ecan_hTask;
52 MAILMESSAGE __esos_ecan_mailMsg;
53 uint8_t u8_numCANFactoryClients = 0;
54 
55 __eds__ ECANMSG __esos_ecan_msgBuf[__ESOS_ECAN_HW_NUM_BUFS] __attribute__((space(dma),aligned(__ESOS_ECAN_HW_NUM_BUFS*16),eds));
56 
57 /*void esos_ecan_send ( uint16_t u16_can_id, uint8_t *pu8_msg, uint8_t u8_len ) {
58 
59  __esos_ecan_hTask = esos_GetTaskHandle( CANFactory );
60  if ( ESOS_TASK_MAILBOX_GOT_AT_LEAST_DATA_BYTES( __esos_ecan_hTask, __MAIL_MSG_HEADER_LEN + sizeof( uint8_t ) * u8_len + sizeof( uint16_t ) ) ) {
61  *( ( uint16_t* ) &__esos_mail_msgBuf[0] ) = u16_can_id;
62  memcpy( &__esos_mail_msgBuf[ sizeof( uint16_t ) ], pu8_msg, u8_len );
63  ESOS_TASK_MAKE_MSG_AUINT8 ( __esos_ecan_mailMsg, __esos_mail_msgBuf, sizeof( uint8_t ) * u8_len + sizeof( uint16_t ) );
64  ESOS_TASK_SEND_MESSAGE( __esos_ecan_hTask, &__esos_ecan_mailMsg );
65  }
66 
67  return;
68 }*/
69 
70 ESOS_USER_TASK ( CANFactory ) {
71  uint8_t u8_i;
72  static uint8_t au8_msgBuf[10], u8_y;
73  static MAILMESSAGE st_Msg;
74  static uint8_t u8_len;
75  static uint16_t u16_rx_buff_id, u16_msg_id;
76  static ESOS_TASK_HANDLE hTask;
77  //__esos_ecan_hw_config_ecan();
79  //DISABLE_DEBUG_MODE();
80  //__esos_ecan_hw_config_ecan();
81  while ( TRUE ) {
82  /* Check to see if any CAN messages have arrived.
83  * If so, parse and send mail to the appropriate task.
84  * If task does not have room in their task mailbox, discard message.
85  */
86  //ESOS_TASK_WAIT_TICKS(1000);
87  if ( __ESOS_ECAN_HW_ARE_MESSAGES_WAITING() ) {
88 
89 
90  _DMA1IF = 0; //Rx accepted
91  u16_rx_buff_id = __ESOS_ECAN_HW_GET_BUFFER_ID();
92  u16_msg_id = __esos_ecan_msgBuf[ u16_rx_buff_id ].w0.SID;
93  u8_len = __esos_ecan_msgBuf[ u16_rx_buff_id ].w2.DLC;
94  //(u16_msg_id & canfactory_clients[ u8_i ].u16_idMask ) == canfactory_clients[ u8_i ].u16_canID)
95  //esos_ecan_mask_check (uint16_t u16_subscribed, uint16_t u16_recieved, uint16_t u16_mask)
96  for ( u8_i = 0; u8_i < u8_numCANFactoryClients; ++u8_i ) {
97  if ( ( canfactory_clients[ u8_i ].m_idMaskControl == MASKCONTROL_FIELD_NONZERO && ( esos_ecan_mask_check(canfactory_clients[u8_i].u16_canID, u16_msg_id, canfactory_clients[u8_i].u16_idMask)) ) |
98  ( canfactory_clients[ u8_i ].m_idMaskControl == MASKCONTROL_EQUAL && ( u16_msg_id == canfactory_clients[ u8_i ].u16_idMask ) )
99  ) {
100  hTask = esos_GetTaskHandle( canfactory_clients[ u8_i ].pf_task );
101 
102  if ( ESOS_TASK_MAILBOX_GOT_AT_LEAST_DATA_BYTES( hTask, __MAIL_MSG_HEADER_LEN + sizeof( uint8_t ) * u8_len + sizeof( uint16_t ) ) ) {
103  uint8_t u8_count;
104  *( ( uint16_t* ) &au8_msgBuf[0] ) = u16_msg_id;
105  for ( u8_count = 0; u8_count < u8_len; ++u8_count ) {
106  au8_msgBuf[ sizeof( uint16_t ) + u8_count ] = __esos_ecan_msgBuf[ u16_rx_buff_id ].data.u8[u8_count];
107 
108  }
109  ESOS_TASK_MAKE_MSG_AUINT8( st_Msg, au8_msgBuf, sizeof( uint8_t ) * u8_len + sizeof( uint16_t ) );
110  ESOS_TASK_SEND_MESSAGE( hTask, &st_Msg );
111 
112  if (CHECK_DEBUG_MODE_ENABLED()){
114  ESOS_TASK_WAIT_ON_SEND_STRING("Rx Buff: ");
118  }
119 
120  }
121  }
122  else{
123  if (CHECK_DEBUG_MODE_ENABLED()){
125  ESOS_TASK_WAIT_ON_SEND_STRING("Rx Buff: ");
128  ESOS_TASK_SEND_STRING("Message ID: ");
129  ESOS_TASK_WAIT_ON_SEND_UINT12_AS_HEX_STRING(u16_msg_id);
130  ESOS_TASK_SEND_STRING(" rejected by acceptance filter.\n");
132  }
133  }
134  }
135  __esos_ecan_hw_mark_message_received( u16_rx_buff_id );
136  }
137  else if (!__ESOS_ECAN_HW_ARE_MESSAGES_WAITING()){
138  //printf("Message ID 0x%X rejected by acceptance filter.\n", u16_msg_id);
139  /*ESOS_TASK_WAIT_ON_AVAILABLE_OUT_COMM();
140  ESOS_TASK_WAIT_ON_SEND_STRING("Rx Buff: ");
141  ESOS_TASK_WAIT_ON_SEND_UINT8_AS_DEC_STRING(u16_rx_buff_id);
142  ESOS_TASK_WAIT_ON_SEND_STRING(" ");
143  ESOS_TASK_SEND_STRING("Message ID: ");
144  ESOS_TASK_WAIT_ON_SEND_UINT12_AS_HEX_STRING(u16_msg_id);
145  ESOS_TASK_SEND_STRING(" rejected by acceptance filter.\n");
146  ESOS_TASK_SIGNAL_AVAILABLE_OUT_COMM();*/
147  }
148  /* Check to see if any user tasks have sent mail containing a CAN
149  * message to transmit.
150  * If so, parse the incoming mail message(s), creating and sending the
151  * CAN message(s).
152  */
153  while ( ESOS_TASK_IVE_GOT_MAIL() ) {
154  static ECANMSG temp_Msg;
155  static uint8_t u8_len, u8_payload_len;
156  static uint16_t u16_can_id;
157  //printf("GOT MESSAGE");
158  ESOS_TASK_GET_NEXT_MESSAGE( &st_Msg );
159  u8_len = ESOS_GET_PMSG_DATA_LENGTH( ( &st_Msg ) );
160  u16_can_id = st_Msg.au16_Contents[0];
161  u8_payload_len = u8_len - 2;
162  u8_y = 0;
163  for ( u8_i = 0; u8_i < u8_payload_len; ++u8_i ) {
164  temp_Msg.data.u8[ u8_i ] = st_Msg.au8_Contents[ u8_i + 2 ];
165  //ESOS_TASK_WAIT_ON_AVAILABLE_OUT_COMM();
166  //ESOS_TASK_WAIT_ON_SEND_STRING("data: ");
167  //ESOS_TASK_WAIT_ON_SEND_UINT8_AS_HEX_STRING(st_Msg.au8_Contents[u8_i + 2]);
168  //ESOS_TASK_WAIT_ON_SEND_STRING("\n");
169  //ESOS_TASK_SIGNAL_AVAILABLE_OUT_COMM();
170  }
171  /*ESOS_TASK_WAIT_ON_AVAILABLE_OUT_COMM();
172  ESOS_TASK_WAIT_ON_SEND_UINT8(temp_Msg.data.u8[1]);
173  ESOS_TASK_SIGNAL_AVAILABLE_OUT_COMM();*/
174 
175  __esos_ecan_hw_format_and_send( &temp_Msg, u16_can_id, u8_payload_len );
176  ESOS_TASK_WAIT_WHILE( __ESOS_ECAN_HW_TX_IN_PROGRESS() ); //It freezes here.
177  _DMA0IF = 1;
178 
179  }
180 
181  ESOS_TASK_YIELD();
182  }
183 
184  ESOS_TASK_END();
185 }
186 
187 void esos_ecan_canfactory_subscribe(ESOS_TASK_HANDLE pst_Task, uint16_t u16_can_id, uint16_t u16_mask, maskcontrol_t m_mask_control) {
188  canfactory_clients[ u8_numCANFactoryClients ].pf_task = (*pst_Task).pfn;
189  canfactory_clients[ u8_numCANFactoryClients ].u16_canID = u16_can_id;
190  canfactory_clients[ u8_numCANFactoryClients ].u16_idMask = u16_mask;
191  canfactory_clients[ u8_numCANFactoryClients++ ].m_idMaskControl = m_mask_control;
192 
193  return;
194 }
195 
196 void esos_ecan_canfactory_unsubscribe ( uint8_t (*pst_Task) (ESOS_TASK_HANDLE), uint16_t u16_can_id, uint16_t u16_mask, maskcontrol_t m_mask_control ) {
197  uint8_t u8_i;
198 
199  for ( u8_i = 0; u8_i < u8_numCANFactoryClients; ++u8_i ) {
200  if ( canfactory_clients[ u8_i ].pf_task == pst_Task && canfactory_clients[ u8_i ].u16_canID == u16_can_id && canfactory_clients[ u8_i ].u16_idMask == u16_mask && canfactory_clients[ u8_i ].m_idMaskControl == m_mask_control ) {
201  uint8_t u8_n;
202 
203  for ( u8_n = u8_i; u8_n < u8_numCANFactoryClients - 1; ++u8_n ) {
204  canfactory_clients[ u8_n ] = canfactory_clients[ u8_n + 1 ];
205  }
206  --u8_numCANFactoryClients;
207  break;
208  }
209  }
210 
211  return;
212 }
213 
214 BOOL esos_ecan_mask_check (uint16_t u16_subscribed, uint16_t u16_recieved, uint16_t u16_mask) {
215  int8_t i = 15;
216  uint8_t u8_errorCount = 0;
217  for (i = 15; i >= 0; i--) {
218  if (CHECK_BIT(u16_mask,i)) {
219  u8_errorCount += (CHECK_BIT(u16_subscribed,i) ^ CHECK_BIT(u16_recieved,i));
220  }
221  }
222  if (u8_errorCount == 0) {
223  return TRUE;
224  }
225  else {
226  return FALSE;
227  }
228 }
void esos_ecan_canfactory_subscribe(ESOS_TASK_HANDLE pst_Task, uint16_t u16_can_id, uint16_t u16_mask, maskcontrol_t m_mask_control)
Definition: esos_ecan.c:187
BOOL esos_ecan_mask_check(uint16_t u16_subscribed, uint16_t u16_recieved, uint16_t u16_mask)
Definition: esos_ecan.c:214
#define ESOS_TASK_SIGNAL_AVAILABLE_OUT_COMM()
Definition: esos_comm.h:271
BOOL
Definition: all_generic.h:402
#define ESOS_TASK_YIELD()
Definition: esos_task.h:590
#define ESOS_TASK_WAIT_ON_SEND_STRING(psz_out)
Definition: esos_comm.h:439
ESOS_TASK_HANDLE esos_GetTaskHandle(uint8_t(*taskname)(ESOS_TASK_HANDLE pstTask))
Definition: esos.c:219
#define ESOS_TASK_END()
Definition: esos_task.h:272
#define ESOS_TASK_WAIT_WHILE(cond)
Definition: esos_task.h:364
#define ESOS_TASK_WAIT_ON_AVAILABLE_OUT_COMM()
Definition: esos_comm.h:228
#define ESOS_TASK_BEGIN()
Definition: esos_task.h:260
#define ESOS_TASK_IVE_GOT_MAIL()
Definition: esos_mail.h:141
This file contains routines which configure and use an ECAN interface on the Microchip PIC24 MCUs...
ESOS_USER_TASK(CANFactory)
Definition: esos_ecan.c:70
#define ESOS_TASK_WAIT_ON_SEND_UINT8_AS_DEC_STRING(u8_out)
Definition: esos_comm.h:417
#define ESOS_TASK_MAILBOX_GOT_AT_LEAST_DATA_BYTES(pstTask, x)
Definition: esos_mail.h:216
void esos_ecan_canfactory_unsubscribe(uint8_t(*pst_Task)(ESOS_TASK_HANDLE), uint16_t u16_can_id, uint16_t u16_mask, maskcontrol_t m_mask_control)
Definition: esos_ecan.c:196
unsigned char uint8_t
An abbreviation for an 8-bit unsigned integer.
Definition: dataXferImpl.h:194