Subversion Repositories svn.mios32

Rev

Rev 2653 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2653 Rev 2657
1
// $Id: mios32_can.c 2312 2016-02-27 23:04:51Z tk $
1
// $Id: mios32_can.c 2312 2016-02-27 23:04:51Z tk $
2
//! \defgroup MIOS32_CAN
2
//! \defgroup MIOS32_CAN
3
//!
3
//!
4
//! U(S)ART functions for MIOS32
4
//! U(S)ART functions for MIOS32
5
//!
5
//!
6
//! Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
6
//! Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
7
//!
7
//!
8
//! \{
8
//! \{
9
/* ==========================================================================
9
/* ==========================================================================
10
 *
10
 *
11
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
11
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
12
 *  Licensed for personal non-commercial use only.
12
 *  Licensed for personal non-commercial use only.
13
 *  All other rights reserved.
13
 *  All other rights reserved.
14
 *
14
 *
15
 * ==========================================================================
15
 * ==========================================================================
16
 */
16
 */
17
17
18
/////////////////////////////////////////////////////////////////////////////
18
/////////////////////////////////////////////////////////////////////////////
19
// Include files
19
// Include files
20
/////////////////////////////////////////////////////////////////////////////
20
/////////////////////////////////////////////////////////////////////////////
21
21
22
#include <mios32.h>
22
#include <mios32.h>
23
23
24
// this module can be optionally enabled in a local mios32_config.h file (included from mios32.h)
24
// this module can be optionally enabled in a local mios32_config.h file (included from mios32.h)
25
#if defined(MIOS32_USE_CAN)
25
#if defined(MIOS32_USE_CAN)
26
26
27
27
28
/////////////////////////////////////////////////////////////////////////////
28
/////////////////////////////////////////////////////////////////////////////
29
// Pin definitions and USART mappings
29
// Pin definitions and USART mappings
30
/////////////////////////////////////////////////////////////////////////////
30
/////////////////////////////////////////////////////////////////////////////
31
31
32
// how many CANs are supported?
32
// how many CANs are supported?
33
#define NUM_SUPPORTED_CANS MIOS32_CAN_NUM
33
#define NUM_SUPPORTED_CANS MIOS32_CAN_NUM
34
#if MIOS32_CAN_NUM >1
34
#if MIOS32_CAN_NUM >1
35
// Note:If CAN2 is used, J19:SO(PB5) and J4B:SC(PB6))  OR  J8/9:SC(PB13) and J8/9:RC1(PB12) are no more available! :-/
35
// Note:If CAN2 is used, J19:SO(PB5) and J4B:SC(PB6))  OR  J8/9:SC(PB13) and J8/9:RC1(PB12) are no more available! :-/
36
// Defines the start filter bank for the CAN2 interface (Slave) in the range 0 to 27.
36
// Defines the start filter bank for the CAN2 interface (Slave) in the range 0 to 27.
37
#define MIOS32_CAN2_STARTBANK 14
37
#define MIOS32_CAN2_STARTBANK 14
38
#else
38
#else
39
// All filters banks for CAN1
39
// All filters banks for CAN1
40
#define MIOS32_CAN2_STARTBANK 27 // no bank for CAN2
40
#define MIOS32_CAN2_STARTBANK 27 // no bank for CAN2
41
#endif
41
#endif
42
#define MIOS32_CAN1             CAN1
42
#define MIOS32_CAN1             CAN1
43
#define MIOS32_CAN1_RX_PORT     GPIOD
43
#define MIOS32_CAN1_RX_PORT     GPIOD
44
#define MIOS32_CAN1_RX_PIN      GPIO_Pin_0
44
#define MIOS32_CAN1_RX_PIN      GPIO_Pin_0
45
#define MIOS32_CAN1_TX_PORT     GPIOD
45
#define MIOS32_CAN1_TX_PORT     GPIOD
46
#define MIOS32_CAN1_TX_PIN      GPIO_Pin_1
46
#define MIOS32_CAN1_TX_PIN      GPIO_Pin_1
47
#define MIOS32_CAN1_REMAP_FUNC  { GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1); GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1); }
47
#define MIOS32_CAN1_REMAP_FUNC  { GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1); GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1); }
48
#define MIOS32_CAN1_RX0_IRQn    CAN1_RX0_IRQn
48
#define MIOS32_CAN1_RX0_IRQn    CAN1_RX0_IRQn
49
#define MIOS32_CAN1_RX1_IRQn    CAN1_RX1_IRQn
49
#define MIOS32_CAN1_RX1_IRQn    CAN1_RX1_IRQn
50
#define MIOS32_CAN1_TX_IRQn     CAN1_TX_IRQn
50
#define MIOS32_CAN1_TX_IRQn     CAN1_TX_IRQn
51
#define MIOS32_CAN1_ER_IRQn     CAN1_SCE_IRQn
51
#define MIOS32_CAN1_ER_IRQn     CAN1_SCE_IRQn
52
#define MIOS32_CAN1_RX0_IRQHANDLER_FUNC void CAN1_RX0_IRQHandler(void)
52
#define MIOS32_CAN1_RX0_IRQHANDLER_FUNC void CAN1_RX0_IRQHandler(void)
53
#define MIOS32_CAN1_RX1_IRQHANDLER_FUNC void CAN1_RX1_IRQHandler(void)
53
#define MIOS32_CAN1_RX1_IRQHANDLER_FUNC void CAN1_RX1_IRQHandler(void)
54
#define MIOS32_CAN1_TX_IRQHANDLER_FUNC void CAN1_TX_IRQHandler(void)
54
#define MIOS32_CAN1_TX_IRQHANDLER_FUNC void CAN1_TX_IRQHandler(void)
55
#define MIOS32_CAN1_ER_IRQHANDLER_FUNC void CAN1_SCE_IRQHandler(void)
55
#define MIOS32_CAN1_ER_IRQHANDLER_FUNC void CAN1_SCE_IRQHandler(void)
56
56
57
57
58
#define MIOS32_CAN2             CAN2
58
#define MIOS32_CAN2             CAN2
59
#if MIOS32_CAN2_ALTFUNC == 0    //  0: CAN2.RX->PB5, CAN2.TX->PB6
59
#if MIOS32_CAN2_ALTFUNC == 0    //  0: CAN2.RX->PB5, CAN2.TX->PB6
60
#define MIOS32_CAN2_RX_PORT     GPIOB
60
#define MIOS32_CAN2_RX_PORT     GPIOB
61
#define MIOS32_CAN2_RX_PIN      GPIO_Pin_5
61
#define MIOS32_CAN2_RX_PIN      GPIO_Pin_5
62
#define MIOS32_CAN2_TX_PORT     GPIOB
62
#define MIOS32_CAN2_TX_PORT     GPIOB
63
#define MIOS32_CAN2_TX_PIN      GPIO_Pin_6
63
#define MIOS32_CAN2_TX_PIN      GPIO_Pin_6
64
#define MIOS32_CAN2_REMAP_FUNC  { GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_CAN2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_CAN2); }
64
#define MIOS32_CAN2_REMAP_FUNC  { GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_CAN2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_CAN2); }
65
#else                           //  1: CAN2.RX->PB12, CAN2.TX->PB13
65
#else                           //  1: CAN2.RX->PB12, CAN2.TX->PB13
66
#define MIOS32_CAN2_RX_PORT     GPIOB
66
#define MIOS32_CAN2_RX_PORT     GPIOB
67
#define MIOS32_CAN2_RX_PIN      GPIO_Pin_12
67
#define MIOS32_CAN2_RX_PIN      GPIO_Pin_12
68
#define MIOS32_CAN2_TX_PORT     GPIOB
68
#define MIOS32_CAN2_TX_PORT     GPIOB
69
#define MIOS32_CAN2_TX_PIN      GPIO_Pin_13
69
#define MIOS32_CAN2_TX_PIN      GPIO_Pin_13
70
#define MIOS32_CAN2_REMAP_FUNC  { GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2); }
70
#define MIOS32_CAN2_REMAP_FUNC  { GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2); }
71
#endif
71
#endif
72
#define MIOS32_CAN2_RX0_IRQn    CAN2_RX0_IRQn
72
#define MIOS32_CAN2_RX0_IRQn    CAN2_RX0_IRQn
73
#define MIOS32_CAN2_RX1_IRQn    CAN2_RX1_IRQn
73
#define MIOS32_CAN2_RX1_IRQn    CAN2_RX1_IRQn
74
#define MIOS32_CAN2_TX_IRQn     CAN2_TX_IRQn
74
#define MIOS32_CAN2_TX_IRQn     CAN2_TX_IRQn
75
#define MIOS32_CAN2_ER_IRQn     CAN2_SCE_IRQn
75
#define MIOS32_CAN2_ER_IRQn     CAN2_SCE_IRQn
76
#define MIOS32_CAN2_RX0_IRQHANDLER_FUNC void CAN2_RX0_IRQHandler(void)
76
#define MIOS32_CAN2_RX0_IRQHANDLER_FUNC void CAN2_RX0_IRQHandler(void)
77
#define MIOS32_CAN2_RX1_IRQHANDLER_FUNC void CAN2_RX1_IRQHandler(void)
77
#define MIOS32_CAN2_RX1_IRQHANDLER_FUNC void CAN2_RX1_IRQHandler(void)
78
#define MIOS32_CAN2_TX_IRQHANDLER_FUNC void CAN2_TX_IRQHandler(void)
78
#define MIOS32_CAN2_TX_IRQHANDLER_FUNC void CAN2_TX_IRQHandler(void)
79
#define MIOS32_CAN2_ER_IRQHANDLER_FUNC void CAN2_SCE_IRQHandler(void)
79
#define MIOS32_CAN2_ER_IRQHANDLER_FUNC void CAN2_SCE_IRQHandler(void)
80
80
81
//#define MIOS32_CAN_MIDI_FILT_BK_NODE_SYSEX    0     //Filter Number for Node SysEx
81
//#define MIOS32_CAN_MIDI_FILT_BK_NODE_SYSEX    0     //Filter Number for Node SysEx
82
//#define MIOS32_CAN_MIDI_FILT_BK_SYSEX         1     //Filter Number for Device SysEx
82
//#define MIOS32_CAN_MIDI_FILT_BK_SYSEX         1     //Filter Number for Device SysEx
83
//
83
//
84
//#define MIOS32_CAN_MIDI_FILT_BK_NODE_SYSCOM   2     //Filter Number for Node SysCom
84
//#define MIOS32_CAN_MIDI_FILT_BK_NODE_SYSCOM   2     //Filter Number for Node SysCom
85
//#define MIOS32_CAN_MIDI_FILT_BK_BYPASS        2     //Filter Number for Node SysCom
85
//#define MIOS32_CAN_MIDI_FILT_BK_BYPASS        2     //Filter Number for Node SysCom
86
//
86
//
87
//#define MIOS32_CAN_BANK_FILT_BK_RT       3     //Filter Number for Real time messges
87
//#define MIOS32_CAN_BANK_FILT_BK_RT       3     //Filter Number for Real time messges
88
//#define MIOS32_CAN_MIDI_FILT_BK_SYSCOM   3     //Filter Number for Real time messges
88
//#define MIOS32_CAN_MIDI_FILT_BK_SYSCOM   3     //Filter Number for Real time messges
89
//
89
//
90
//#define MIOS32_CAN_MIDI_FILT_BK_NODE_SYSEX    0     //Filter Number for Node SysEx
90
//#define MIOS32_CAN_MIDI_FILT_BK_NODE_SYSEX    0     //Filter Number for Node SysEx
91
//#define MIOS32_CAN_MIDI_FILT_BK_SYSEX         1     //Filter Number for Device SysEx
91
//#define MIOS32_CAN_MIDI_FILT_BK_SYSEX         1     //Filter Number for Device SysEx
92
92
93
/////////////////////////////////////////////////////////////////////////////
93
/////////////////////////////////////////////////////////////////////////////
94
// Local variables
94
// Local variables
95
/////////////////////////////////////////////////////////////////////////////
95
/////////////////////////////////////////////////////////////////////////////
96
96
97
#if NUM_SUPPORTED_CANS >= 1
97
#if NUM_SUPPORTED_CANS >= 1
98
static u8  can_assigned_to_midi;
98
static u8  can_assigned_to_midi;
99
static can_packet_t rx_buffer[NUM_SUPPORTED_CANS][MIOS32_CAN_RX_BUFFER_SIZE];
99
static mios32_can_packet_t rx_buffer[NUM_SUPPORTED_CANS][MIOS32_CAN_RX_BUFFER_SIZE];
100
static volatile u16 rx_buffer_tail[NUM_SUPPORTED_CANS];
100
static volatile u16 rx_buffer_tail[NUM_SUPPORTED_CANS];
101
static volatile u16 rx_buffer_head[NUM_SUPPORTED_CANS];
101
static volatile u16 rx_buffer_head[NUM_SUPPORTED_CANS];
102
static volatile u16 rx_buffer_size[NUM_SUPPORTED_CANS];
102
static volatile u16 rx_buffer_size[NUM_SUPPORTED_CANS];
103
103
104
static can_packet_t tx_buffer[NUM_SUPPORTED_CANS][MIOS32_CAN_TX_BUFFER_SIZE];
104
static mios32_can_packet_t tx_buffer[NUM_SUPPORTED_CANS][MIOS32_CAN_TX_BUFFER_SIZE];
105
static volatile u16 tx_buffer_tail[NUM_SUPPORTED_CANS];
105
static volatile u16 tx_buffer_tail[NUM_SUPPORTED_CANS];
106
static volatile u16 tx_buffer_head[NUM_SUPPORTED_CANS];
106
static volatile u16 tx_buffer_head[NUM_SUPPORTED_CANS];
107
static volatile u16 tx_buffer_size[NUM_SUPPORTED_CANS];
107
static volatile u16 tx_buffer_size[NUM_SUPPORTED_CANS];
108
108
109
static can_stat_report_t can_stat_report[NUM_SUPPORTED_CANS];
109
static mios32_can_stat_report_t can_stat_report[NUM_SUPPORTED_CANS];
110
#endif
110
#endif
111
111
112
#if defined MIOS32_CAN_VERBOSE
112
#if defined MIOS32_CAN_VERBOSE
113
static u8 can_verbose = MIOS32_CAN_VERBOSE;
113
static u8 can_verbose = MIOS32_CAN_VERBOSE;
114
#else
114
#else
115
static u8 can_verbose = 0;
115
static u8 can_verbose = 0;
116
#endif
116
#endif
117
-
 
118
u32 can_temp;
-
 
119
-
 
120
117
121
118
122
/////////////////////////////////////////////////////////////////////////////
119
/////////////////////////////////////////////////////////////////////////////
123
//! Initializes CAN MIDI layer
120
//! Initializes CAN MIDI layer
124
//! \param[in] mode currently only mode 0 supported
121
//! \param[in] mode currently only mode 0 supported
125
//! \return < 0 if initialisation failed
122
//! \return < 0 if initialisation failed
126
//! \note Applications shouldn't call this function directly, instead please use \ref MIOS32_MIDI layer functions
123
//! \note Applications shouldn't call this function directly, instead please use \ref MIOS32_MIDI layer functions
127
/////////////////////////////////////////////////////////////////////////////
124
/////////////////////////////////////////////////////////////////////////////
128
s32 MIOS32_CAN_VerboseSet(u8 level)
125
s32 MIOS32_CAN_VerboseSet(u8 level)
129
{
126
{
130
#if MIOS32_CAN_NUM == 0
127
#if MIOS32_CAN_NUM == 0
131
  return -1; // no CAN enabled
128
  return -1; // no CAN enabled
132
#else
129
#else
133
 
130
 
134
  can_verbose = level;
131
  can_verbose = level;
135
 
132
 
136
  return 0; // no error
133
  return 0; // no error
137
#endif
134
#endif
138
}
135
}
139
136
140
137
141
/////////////////////////////////////////////////////////////////////////////
138
/////////////////////////////////////////////////////////////////////////////
142
//! Initializes CAN MIDI layer
139
//! Initializes CAN MIDI layer
143
//! \param[in] mode currently only mode 0 supported
140
//! \param[in] mode currently only mode 0 supported
144
//! \return < 0 if initialisation failed
141
//! \return < 0 if initialisation failed
145
//! \note Applications shouldn't call this function directly, instead please use \ref MIOS32_MIDI layer functions
142
//! \note Applications shouldn't call this function directly, instead please use \ref MIOS32_MIDI layer functions
146
/////////////////////////////////////////////////////////////////////////////
143
/////////////////////////////////////////////////////////////////////////////
147
s32 MIOS32_CAN_VerboseGet(void)
144
s32 MIOS32_CAN_VerboseGet(void)
148
{
145
{
149
#if MIOS32_CAN_NUM == 0
146
#if MIOS32_CAN_NUM == 0
150
  return -1; // no CAN enabled
147
  return -1; // no CAN enabled
151
#else
148
#else
152
  return can_verbose; // no error
149
  return can_verbose; // no error
153
#endif
150
#endif
154
}
151
}
155
152
156
153
157
/////////////////////////////////////////////////////////////////////////////
154
/////////////////////////////////////////////////////////////////////////////
158
//! Initializes CAN interfaces
155
//! Initializes CAN interfaces
159
//! \param[in] mode currently only mode 0 supported
156
//! \param[in] mode currently only mode 0 supported
160
//! \return < 0 if initialisation failed
157
//! \return < 0 if initialisation failed
161
//! \note Applications shouldn't call this function directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
158
//! \note Applications shouldn't call this function directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
162
/////////////////////////////////////////////////////////////////////////////
159
/////////////////////////////////////////////////////////////////////////////
163
s32 MIOS32_CAN_Init(u32 mode)
160
s32 MIOS32_CAN_Init(u32 mode)
164
{
161
{
165
  // currently only mode 0 supported
162
  // currently only mode 0 supported
166
  if( mode != 0 )
163
  if( mode != 0 )
167
    return -1; // unsupported mode
164
    return -1; // unsupported mode
168
165
169
#if NUM_SUPPORTED_CANS == 0
166
#if NUM_SUPPORTED_CANS == 0
170
  return -1; // no CANs
167
  return -1; // no CANs
171
#else
168
#else
172
 
169
 
173
  // map and init CAN pins
170
  // map and init CAN pins
174
#if  MIOS32_CAN1_ASSIGNMENT != 0 // not disabled
171
#if  MIOS32_CAN1_ASSIGNMENT != 0 // not disabled
175
  MIOS32_CAN1_REMAP_FUNC;
172
  MIOS32_CAN1_REMAP_FUNC;
176
#endif
173
#endif
177
#if NUM_SUPPORTED_CANS >= 2 && MIOS32_CAN2_ASSIGNMENT != 0
174
#if NUM_SUPPORTED_CANS >= 2 && MIOS32_CAN2_ASSIGNMENT != 0
178
  MIOS32_CAN2_REMAP_FUNC;
175
  MIOS32_CAN2_REMAP_FUNC;
179
#endif
176
#endif
180
 
177
 
181
  // enable CANx clocks
178
  // enable CANx clocks
182
#if  MIOS32_CAN1_ASSIGNMENT != 0 // not disabled
179
#if  MIOS32_CAN1_ASSIGNMENT != 0 // not disabled
183
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
180
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
184
#endif
181
#endif
185
#if NUM_SUPPORTED_CANS >= 2 && MIOS32_CAN2_ASSIGNMENT != 0
182
#if NUM_SUPPORTED_CANS >= 2 && MIOS32_CAN2_ASSIGNMENT != 0
186
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
183
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
187
#endif
184
#endif
188
 
185
 
189
  // initialize CANs and clear buffers
186
  // initialize CANs and clear buffers
190
  u8 can;
187
  u8 can;
191
  for(can=0; can<NUM_SUPPORTED_CANS; ++can) {
188
  for(can=0; can<NUM_SUPPORTED_CANS; ++can) {
192
    // initialize Tx/Rx Buffers
189
    // initialize Tx/Rx Buffers
193
    rx_buffer_tail[can] = rx_buffer_head[can] = rx_buffer_size[can] = 0;
190
    rx_buffer_tail[can] = rx_buffer_head[can] = rx_buffer_size[can] = 0;
194
    tx_buffer_tail[can] = tx_buffer_head[can] = tx_buffer_size[can] = 0;
191
    tx_buffer_tail[can] = tx_buffer_head[can] = tx_buffer_size[can] = 0;
195
    // initialize info report structure
192
    // initialize info report structure
196
    MIOS32_CAN_ReportReset(can);
193
    MIOS32_CAN_ReportReset(can);
197
    // initialize Default port
194
    // initialize Default port
198
    MIOS32_CAN_InitPortDefault(can);
195
    MIOS32_CAN_InitPortDefault(can);
199
    // initialize peripheral
196
    // initialize peripheral
200
    if(MIOS32_CAN_InitPeriph(can) < 0)return -1;
197
    if(MIOS32_CAN_InitPeriph(can) < 0)return -1;
201
  }
198
  }
202
 
199
 
203
  // configure and enable CAN interrupts
200
  // configure and enable CAN interrupts
204
#if MIOS32_CAN1_ASSIGNMENT != 0 // not disabled
201
#if MIOS32_CAN1_ASSIGNMENT != 0 // not disabled
205
  // enable CAN interrupt
202
  // enable CAN interrupt
206
  MIOS32_CAN1->IER = 0x0000000;
203
  MIOS32_CAN1->IER = 0x0000000;
207
  /* Enable MIOS32_CAN1 RX0 interrupt IRQ channel */
204
  /* Enable MIOS32_CAN1 RX0 interrupt IRQ channel */
208
  MIOS32_IRQ_Install(MIOS32_CAN1_RX0_IRQn, MIOS32_IRQ_CAN_PRIORITY);
205
  MIOS32_IRQ_Install(MIOS32_CAN1_RX0_IRQn, MIOS32_IRQ_CAN_PRIORITY);
209
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_FMP0, ENABLE);
206
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_FMP0, ENABLE);
210
  /* Enable MIOS32_CAN1 RX1 interrupt IRQ channel */
207
  /* Enable MIOS32_CAN1 RX1 interrupt IRQ channel */
211
  MIOS32_IRQ_Install(MIOS32_CAN1_RX1_IRQn, MIOS32_IRQ_CAN_PRIORITY);
208
  MIOS32_IRQ_Install(MIOS32_CAN1_RX1_IRQn, MIOS32_IRQ_CAN_PRIORITY);
212
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_FMP1, ENABLE);
209
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_FMP1, ENABLE);
213
  /* Enable MIOS32_CAN1 TX interrupt IRQ channel */
210
  /* Enable MIOS32_CAN1 TX interrupt IRQ channel */
214
  MIOS32_IRQ_Install(MIOS32_CAN1_TX_IRQn, MIOS32_IRQ_CAN_PRIORITY);
211
  MIOS32_IRQ_Install(MIOS32_CAN1_TX_IRQn, MIOS32_IRQ_CAN_PRIORITY);
215
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_TME, DISABLE);
212
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_TME, DISABLE);
216
#if 1
213
#if 1
217
  /* Enable MIOS32_CAN1 SCE(errors) interrupts IRQ channels */
214
  /* Enable MIOS32_CAN1 SCE(errors) interrupts IRQ channels */
218
  MIOS32_IRQ_Install(MIOS32_CAN1_ER_IRQn, MIOS32_IRQ_CAN_PRIORITY);
215
  MIOS32_IRQ_Install(MIOS32_CAN1_ER_IRQn, MIOS32_IRQ_CAN_PRIORITY);
219
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_EWG, ENABLE);
216
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_EWG, ENABLE);
220
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_EPV, ENABLE);
217
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_EPV, ENABLE);
221
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_BOF, ENABLE);
218
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_BOF, ENABLE);
222
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_LEC, DISABLE);
219
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_LEC, DISABLE);
223
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, ENABLE);
220
  CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, ENABLE);
224
#endif
221
#endif
225
#endif
222
#endif
226
 
223
 
227
#if NUM_SUPPORTED_CANS >= 2 && MIOS32_CAN1_ASSIGNMENT != 0
224
#if NUM_SUPPORTED_CANS >= 2 && MIOS32_CAN1_ASSIGNMENT != 0
228
  // enable CAN interrupt
225
  // enable CAN interrupt
229
  MIOS32_CAN2->IER = 0x0000000;
226
  MIOS32_CAN2->IER = 0x0000000;
230
  /* Enable MIOS32_CAN2 RX0 interrupt IRQ channel */
227
  /* Enable MIOS32_CAN2 RX0 interrupt IRQ channel */
231
  MIOS32_IRQ_Install(MIOS32_CAN2_RX0_IRQn, MIOS32_IRQ_CAN_PRIORITY);
228
  MIOS32_IRQ_Install(MIOS32_CAN2_RX0_IRQn, MIOS32_IRQ_CAN_PRIORITY);
232
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_FMP0, ENABLE);
229
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_FMP0, ENABLE);
233
  /* Enable MIOS32_CAN2 RX1 interrupt IRQ channel */
230
  /* Enable MIOS32_CAN2 RX1 interrupt IRQ channel */
234
  MIOS32_IRQ_Install(MIOS32_CAN2_RX1_IRQn, MIOS32_IRQ_CAN_PRIORITY);
231
  MIOS32_IRQ_Install(MIOS32_CAN2_RX1_IRQn, MIOS32_IRQ_CAN_PRIORITY);
235
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_FMP1, ENABLE);
232
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_FMP1, ENABLE);
236
  /* Enable MIOS32_CAN2 TX interrupt IRQ channel */
233
  /* Enable MIOS32_CAN2 TX interrupt IRQ channel */
237
  MIOS32_IRQ_Install(MIOS32_CAN2_TX_IRQn, MIOS32_IRQ_CAN_PRIORITY);
234
  MIOS32_IRQ_Install(MIOS32_CAN2_TX_IRQn, MIOS32_IRQ_CAN_PRIORITY);
238
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_TME, ENABLE);
235
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_TME, ENABLE);
239
#if 0
236
#if 0
240
  /* Enable MIOS32_CAN2 SCE(errors) interrupts IRQ channels */
237
  /* Enable MIOS32_CAN2 SCE(errors) interrupts IRQ channels */
241
  MIOS32_IRQ_Install(MIOS32_CAN2_ER_IRQn, MIOS32_IRQ_PRIO_MED);
238
  MIOS32_IRQ_Install(MIOS32_CAN2_ER_IRQn, MIOS32_IRQ_PRIO_MED);
242
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_EWG, ENABLE);
239
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_EWG, ENABLE);
243
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_EPV, ENABLE);
240
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_EPV, ENABLE);
244
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_BOF, ENABLE);
241
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_BOF, ENABLE);
245
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_LEC, ENABLE);
242
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_LEC, ENABLE);
246
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_ERR, ENABLE);
243
  CAN_ITConfig(MIOS32_CAN2, CAN_IT_ERR, ENABLE);
247
#endif
244
#endif
248
#endif
245
#endif
249
 
246
 
250
  return 0; // no error
247
  return 0; // no error
251
#endif
248
#endif
252
}
249
}
253
250
254
251
255
/////////////////////////////////////////////////////////////////////////////
252
/////////////////////////////////////////////////////////////////////////////
256
//! \return 0 if CAN is not assigned to a MIDI function
253
//! \return 0 if CAN is not assigned to a MIDI function
257
//! \return 1 if CAN is assigned to a MIDI function
254
//! \return 1 if CAN is assigned to a MIDI function
258
/////////////////////////////////////////////////////////////////////////////
255
/////////////////////////////////////////////////////////////////////////////
259
s32 MIOS32_CAN_IsAssignedToMIDI(u8 can)
256
s32 MIOS32_CAN_IsAssignedToMIDI(u8 can)
260
{
257
{
261
#if NUM_SUPPORTED_CANS == 0
258
#if NUM_SUPPORTED_CANS == 0
262
  return 0; // no CAN available
259
  return 0; // no CAN available
263
#else
260
#else
264
  return (can_assigned_to_midi & (1 << can)) ? 1 : 0;
261
  return (can_assigned_to_midi & (1 << can)) ? 1 : 0;
265
#endif
262
#endif
266
}
263
}
267
264
268
265
269
/////////////////////////////////////////////////////////////////////////////
266
/////////////////////////////////////////////////////////////////////////////
270
//! Initializes a given CAN interface based on given baudrate and TX output mode
267
//! Initializes a given CAN interface based on given baudrate and TX output mode
271
//! \param[in] CAN number (0..1)
268
//! \param[in] CAN number (0..1)
272
//! \param[in] is_midi MIDI or common CAN interface?
269
//! \param[in] is_midi MIDI or common CAN interface?
273
//! \return < 0 if initialisation failed
270
//! \return < 0 if initialisation failed
274
/////////////////////////////////////////////////////////////////////////////
271
/////////////////////////////////////////////////////////////////////////////
275
s32 MIOS32_CAN_InitPort(u8 can, u8 is_midi)
272
s32 MIOS32_CAN_InitPort(u8 can, u8 is_midi)
276
{
273
{
277
#if NUM_SUPPORTED_CANS == 0
274
#if NUM_SUPPORTED_CANS == 0
278
  return -1; // no CAN available
275
  return -1; // no CAN available
279
#else
276
#else
280
  GPIO_InitTypeDef GPIO_InitStructure;
277
  GPIO_InitTypeDef GPIO_InitStructure;
281
  GPIO_StructInit(&GPIO_InitStructure);
278
  GPIO_StructInit(&GPIO_InitStructure);
282
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
279
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
283
 
280
 
284
  if( can >= NUM_SUPPORTED_CANS )
281
  if( can >= NUM_SUPPORTED_CANS )
285
    return -1; // unsupported CAN
282
    return -1; // unsupported CAN
286
 
283
 
287
  // MIDI assignment
284
  // MIDI assignment
288
  if( is_midi ) {
285
  if( is_midi ) {
289
    can_assigned_to_midi |= (1 << can);
286
    can_assigned_to_midi |= (1 << can);
290
  } else {
287
  } else {
291
    can_assigned_to_midi &= ~(1 << can);
288
    can_assigned_to_midi &= ~(1 << can);
292
  }
289
  }
293
 
290
 
294
  switch( can ) {
291
  switch( can ) {
295
#if NUM_SUPPORTED_CANS >= 1 && MIOS32_CAN1_ASSIGNMENT != 0
292
#if NUM_SUPPORTED_CANS >= 1 && MIOS32_CAN1_ASSIGNMENT != 0
296
    case 0: {
293
    case 0: {
297
      // configure CAN pins
294
      // configure CAN pins
298
      GPIO_InitTypeDef GPIO_InitStructure;
295
      GPIO_InitTypeDef GPIO_InitStructure;
299
      GPIO_StructInit(&GPIO_InitStructure);
296
      GPIO_StructInit(&GPIO_InitStructure);
300
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
297
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
301
     
298
     
302
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
299
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
303
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
300
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
304
      GPIO_InitStructure.GPIO_Pin = MIOS32_CAN1_RX_PIN;
301
      GPIO_InitStructure.GPIO_Pin = MIOS32_CAN1_RX_PIN;
305
      GPIO_Init(MIOS32_CAN1_RX_PORT, &GPIO_InitStructure);
302
      GPIO_Init(MIOS32_CAN1_RX_PORT, &GPIO_InitStructure);
306
     
303
     
307
      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
304
      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
308
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
305
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
309
      GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
306
      GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
310
      GPIO_InitStructure.GPIO_Pin = MIOS32_CAN1_TX_PIN;
307
      GPIO_InitStructure.GPIO_Pin = MIOS32_CAN1_TX_PIN;
311
      GPIO_Init(MIOS32_CAN1_TX_PORT, &GPIO_InitStructure);
308
      GPIO_Init(MIOS32_CAN1_TX_PORT, &GPIO_InitStructure);
312
    } break;
309
    } break;
313
#endif
310
#endif
314
     
311
     
315
#if NUM_SUPPORTED_CANS >= 2 && MIOS32_CAN2_ASSIGNMENT != 0
312
#if NUM_SUPPORTED_CANS >= 2 && MIOS32_CAN2_ASSIGNMENT != 0
316
    case 1: {
313
    case 1: {
317
      // configure CAN pins
314
      // configure CAN pins
318
      GPIO_InitTypeDef GPIO_InitStructure;
315
      GPIO_InitTypeDef GPIO_InitStructure;
319
      GPIO_StructInit(&GPIO_InitStructure);
316
      GPIO_StructInit(&GPIO_InitStructure);
320
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
317
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
321
     
318
     
322
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
319
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
323
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
320
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
324
      GPIO_InitStructure.GPIO_Pin = MIOS32_CAN2_RX_PIN;
321
      GPIO_InitStructure.GPIO_Pin = MIOS32_CAN2_RX_PIN;
325
      GPIO_Init(MIOS32_CAN2_RX_PORT, &GPIO_InitStructure);
322
      GPIO_Init(MIOS32_CAN2_RX_PORT, &GPIO_InitStructure);
326
     
323
     
327
      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
324
      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
328
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
325
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
329
      GPIO_InitStructure.GPIO_Pin = MIOS32_CAN2_TX_PIN;
326
      GPIO_InitStructure.GPIO_Pin = MIOS32_CAN2_TX_PIN;
330
      GPIO_Init(MIOS32_CAN2_TX_PORT, &GPIO_InitStructure);
327
      GPIO_Init(MIOS32_CAN2_TX_PORT, &GPIO_InitStructure);
331
    } break;
328
    } break;
332
#endif
329
#endif
333
     
330
     
334
    default:
331
    default:
335
      return -1; // unsupported CAN
332
      return -1; // unsupported CAN
336
  }
333
  }
337
 
334
 
338
  return 0; // no error
335
  return 0; // no error
339
#endif
336
#endif
340
}
337
}
341
338
342
339
343
/////////////////////////////////////////////////////////////////////////////
340
/////////////////////////////////////////////////////////////////////////////
344
//! Initializes a given CAN interface based on default settings
341
//! Initializes a given CAN interface based on default settings
345
//! \param[in] CAN number (0..1)
342
//! \param[in] CAN number (0..1)
346
//! \return < 0 if initialisation failed
343
//! \return < 0 if initialisation failed
347
/////////////////////////////////////////////////////////////////////////////
344
/////////////////////////////////////////////////////////////////////////////
348
s32 MIOS32_CAN_InitPortDefault(u8 can)
345
s32 MIOS32_CAN_InitPortDefault(u8 can)
349
{
346
{
350
#if NUM_SUPPORTED_CANS == 0
347
#if NUM_SUPPORTED_CANS == 0
351
  return -1; // no CAN available
348
  return -1; // no CAN available
352
#else
349
#else
353
  switch( can ) {
350
  switch( can ) {
354
#if NUM_SUPPORTED_CANS >= 1 && MIOS32_CAN1_ASSIGNMENT != 0
351
#if NUM_SUPPORTED_CANS >= 1 && MIOS32_CAN1_ASSIGNMENT != 0
355
    case 0: {
352
    case 0: {
356
      MIOS32_CAN_InitPort(0, MIOS32_CAN1_ASSIGNMENT == 1);
353
      MIOS32_CAN_InitPort(0, MIOS32_CAN1_ASSIGNMENT == 1);
357
    } break;
354
    } break;
358
#endif
355
#endif
359
     
356
     
360
#if NUM_SUPPORTED_CANS >= 2 && MIOS32_CAN2_ASSIGNMENT != 0
357
#if NUM_SUPPORTED_CANS >= 2 && MIOS32_CAN2_ASSIGNMENT != 0
361
    case 1: {
358
    case 1: {
362
      MIOS32_CAN_InitPort(1, MIOS32_CAN2_ASSIGNMENT == 1);
359
      MIOS32_CAN_InitPort(1, MIOS32_CAN2_ASSIGNMENT == 1);
363
    } break;
360
    } break;
364
#endif
361
#endif
365
     
362
     
366
    default:
363
    default:
367
      return -1; // unsupported CAN
364
      return -1; // unsupported CAN
368
  }
365
  }
369
 
366
 
370
  return 0; // no error
367
  return 0; // no error
371
#endif
368
#endif
372
}
369
}
373
370
374
371
375
/////////////////////////////////////////////////////////////////////////////
372
/////////////////////////////////////////////////////////////////////////////
376
//! sets the baudrate of a CAN port
373
//! sets the baudrate of a CAN port
377
//! \param[in] CAN number (0..1)
374
//! \param[in] CAN number (0..1)
378
//! \return -1: can not available
375
//! \return -1: can not available
379
//! \return -2: function not prepared for this CAN
376
//! \return -2: function not prepared for this CAN
380
//! \return -3: CAN Initialisation failed
377
//! \return -3: CAN Initialisation failed
381
/////////////////////////////////////////////////////////////////////////////
378
/////////////////////////////////////////////////////////////////////////////
382
s32 MIOS32_CAN_InitPeriph(u8 can)
379
s32 MIOS32_CAN_InitPeriph(u8 can)
383
{
380
{
384
#if NUM_SUPPORTED_CANS == 0
381
#if NUM_SUPPORTED_CANS == 0
385
  return -1; // no CAN available
382
  return -1; // no CAN available
386
#else
383
#else
387
  if( can >= NUM_SUPPORTED_CANS )
384
  if( can >= NUM_SUPPORTED_CANS )
388
    return -1;
385
    return -1;
389
 
386
 
390
  // CAN initialisation
387
  // CAN initialisation
391
  CAN_InitTypeDef CAN_InitStruct;
388
  CAN_InitTypeDef CAN_InitStruct;
392
  CAN_StructInit(&CAN_InitStruct);
389
  CAN_StructInit(&CAN_InitStruct);
393
  CAN_InitStruct.CAN_TTCM = DISABLE;
390
  CAN_InitStruct.CAN_TTCM = DISABLE;
394
  CAN_InitStruct.CAN_NART = DISABLE;
391
  CAN_InitStruct.CAN_NART = DISABLE;
395
  CAN_InitStruct.CAN_RFLM = ENABLE;
392
  CAN_InitStruct.CAN_RFLM = ENABLE;
396
  CAN_InitStruct.CAN_TXFP = ENABLE;
393
  CAN_InitStruct.CAN_TXFP = ENABLE;
397
  CAN_InitStruct.CAN_ABOM = ENABLE;
394
  CAN_InitStruct.CAN_ABOM = ENABLE;
398
  CAN_InitStruct.CAN_Mode = CAN_Mode_Normal;
395
  CAN_InitStruct.CAN_Mode = CAN_Mode_Normal;
399
  // -> 84 Mhz / 2 / 3 -> 14 MHz --> 7 quanta for 2 MBaud
396
  // -> 84 Mhz / 2 / 3 -> 14 MHz --> 7 quanta for 2 MBaud
400
  CAN_InitStruct.CAN_SJW = CAN_SJW_1tq;
397
  CAN_InitStruct.CAN_SJW = CAN_SJW_1tq;
401
  CAN_InitStruct.CAN_BS1 = CAN_BS1_4tq;
398
  CAN_InitStruct.CAN_BS1 = CAN_BS1_4tq;
402
  CAN_InitStruct.CAN_BS2 = CAN_BS2_2tq;
399
  CAN_InitStruct.CAN_BS2 = CAN_BS2_2tq;
403
  CAN_InitStruct.CAN_Prescaler = 4;
400
  CAN_InitStruct.CAN_Prescaler = 4;
404
 
401
 
405
  switch( can ) {
402
  switch( can ) {
406
    case 0: if(CAN_Init(MIOS32_CAN1, &CAN_InitStruct) == CAN_InitStatus_Failed)return -3; break;
403
    case 0: if(CAN_Init(MIOS32_CAN1, &CAN_InitStruct) == CAN_InitStatus_Failed)return -3; break;
407
#if NUM_SUPPORTED_CANS >= 2
404
#if NUM_SUPPORTED_CANS >= 2
408
    case 1: if(CAN_Init(MIOS32_CAN2, &CAN_InitStruct) == CAN_InitStatus_Failed)return -3; break;
405
    case 1: if(CAN_Init(MIOS32_CAN2, &CAN_InitStruct) == CAN_InitStatus_Failed)return -3; break;
409
#endif
406
#endif
410
    default:
407
    default:
411
      return -2; // not prepared
408
      return -2; // not prepared
412
  }
409
  }
413
 
410
 
414
  return 0;
411
  return 0;
415
#endif
412
#endif
416
}
413
}
417
414
418
/////////////////////////////////////////////////////////////////////////////
415
/////////////////////////////////////////////////////////////////////////////
419
//! Initializes a 32 bits filter
416
//! Initializes a 32 bits filter
420
//! \param[in] can filter bank number
417
//! \param[in] can filter bank number
421
//! \param[in] extended id for filter
418
//! \param[in] extended id for filter
422
//! \param[in] extended id for mask
419
//! \param[in] extended id for mask
423
//! \return < 0 if initialisation failed
420
//! \return < 0 if initialisation failed
424
/////////////////////////////////////////////////////////////////////////////
421
/////////////////////////////////////////////////////////////////////////////
425
s32 MIOS32_CAN_Init32bitFilter(u8 bank, u8 fifo, can_ext_filter_t filter, u8 enabled)
422
s32 MIOS32_CAN_Init32bitFilter(u8 bank, u8 fifo, mios32_can_ext_filter_t filter, u8 enabled)
426
{
423
{
427
#if MIOS32_CAN_NUM == 0
424
#if MIOS32_CAN_NUM == 0
428
  return -1; // no CAN enabled
425
  return -1; // no CAN enabled
429
#else
426
#else
430
  CAN_FilterInitTypeDef CAN_FilterInitStructure;
427
  CAN_FilterInitTypeDef CAN_FilterInitStructure;
431
  // bank / mode / scale
428
  // bank / mode / scale
432
  CAN_FilterInitStructure.CAN_FilterNumber=bank;
429
  CAN_FilterInitStructure.CAN_FilterNumber=bank;
433
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
430
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
434
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
431
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
435
  // filter / mask
432
  // filter / mask
436
  CAN_FilterInitStructure.CAN_FilterIdHigh=filter.filt.data_h;
433
  CAN_FilterInitStructure.CAN_FilterIdHigh=filter.filt.data_h;
437
  CAN_FilterInitStructure.CAN_FilterIdLow=filter.filt.data_l;
434
  CAN_FilterInitStructure.CAN_FilterIdLow=filter.filt.data_l;
438
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=filter.mask.data_h;
435
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=filter.mask.data_h;
439
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=filter.mask.data_l;
436
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=filter.mask.data_l;
440
  // fifo / enable
437
  // fifo / enable
441
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
438
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
442
  CAN_FilterInitStructure.CAN_FilterActivation=enabled;
439
  CAN_FilterInitStructure.CAN_FilterActivation=enabled;
443
  CAN_FilterInit(&CAN_FilterInitStructure);
440
  CAN_FilterInit(&CAN_FilterInitStructure);
444
 
441
 
445
  return 0; // no error
442
  return 0; // no error
446
#endif
443
#endif
447
}
444
}
448
445
449
/////////////////////////////////////////////////////////////////////////////
446
/////////////////////////////////////////////////////////////////////////////
450
//! Initializes a 16 bits filter
447
//! Initializes a 16 bits filter
451
//! \param[in] can filter bank number
448
//! \param[in] can filter bank number
452
//! \param[in] standard id for filter
449
//! \param[in] standard id for filter
453
//! \param[in] standard id for mask
450
//! \param[in] standard id for mask
454
//! \return < 0 if initialisation failed
451
//! \return < 0 if initialisation failed
455
/////////////////////////////////////////////////////////////////////////////
452
/////////////////////////////////////////////////////////////////////////////
456
s32 MIOS32_CAN_Init16bitFilter(u8 bank, u8 fifo, can_std_filter_t filter1, can_std_filter_t filter2, u8 enabled)
453
s32 MIOS32_CAN_Init16bitFilter(u8 bank, u8 fifo, mios32_can_std_filter_t filter1, mios32_can_std_filter_t filter2, u8 enabled)
457
{
454
{
458
#if MIOS32_CAN_NUM == 0
455
#if MIOS32_CAN_NUM == 0
459
  return -1; // no CAN enabled
456
  return -1; // no CAN enabled
460
#else
457
#else
461
  CAN_FilterInitTypeDef CAN_FilterInitStructure;
458
  CAN_FilterInitTypeDef CAN_FilterInitStructure;
462
  // bank / mode / scale
459
  // bank / mode / scale
463
  CAN_FilterInitStructure.CAN_FilterNumber=bank;
460
  CAN_FilterInitStructure.CAN_FilterNumber=bank;
464
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
461
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
465
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
462
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
466
  // first filter/ firsf mask
463
  // first filter/ firsf mask
467
  CAN_FilterInitStructure.CAN_FilterIdLow = filter1.filt.ALL;
464
  CAN_FilterInitStructure.CAN_FilterIdLow = filter1.filt.ALL;
468
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = filter1.mask.ALL;
465
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = filter1.mask.ALL;
469
  // second filter / second mask
466
  // second filter / second mask
470
  CAN_FilterInitStructure.CAN_FilterIdHigh =  filter2.filt.ALL;
467
  CAN_FilterInitStructure.CAN_FilterIdHigh =  filter2.filt.ALL;
471
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = filter2.mask.ALL;
468
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = filter2.mask.ALL;
472
  // fifo / enable
469
  // fifo / enable
473
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=fifo;
470
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=fifo;
474
  CAN_FilterInitStructure.CAN_FilterActivation=enabled;
471
  CAN_FilterInitStructure.CAN_FilterActivation=enabled;
475
  CAN_FilterInit(&CAN_FilterInitStructure);
472
  CAN_FilterInit(&CAN_FilterInitStructure);
476
 
473
 
477
  return 0; // no error
474
  return 0; // no error
478
#endif
475
#endif
479
}
476
}
480
477
481
/////////////////////////////////////////////////////////////////////////////
478
/////////////////////////////////////////////////////////////////////////////
482
//! sets the baudrate of a CAN port
479
//! sets the baudrate of a CAN port
483
//! \param[in] CAN number (0..1)
480
//! \param[in] CAN number (0..1)
484
//! \return -1: can not available
481
//! \return -1: can not available
485
//! \return -2: function not prepared for this CAN
482
//! \return -2: function not prepared for this CAN
486
//! \return -3: CAN Initialisation failed
483
//! \return -3: CAN Initialisation failed
487
/////////////////////////////////////////////////////////////////////////////
484
/////////////////////////////////////////////////////////////////////////////
488
s32 MIOS32_CAN_InitPacket(can_packet_t *packet)
485
s32 MIOS32_CAN_InitPacket(mios32_can_packet_t *packet)
489
{
486
{
490
#if NUM_SUPPORTED_CANS == 0
487
#if NUM_SUPPORTED_CANS == 0
491
  return -1; // no CAN available
488
  return -1; // no CAN available
492
#else
489
#else
493
  // reset
490
  // reset
494
  packet->id.ALL = 0;
491
  packet->id.ALL = 0;
495
  packet->ctrl.ALL = 0;
492
  packet->ctrl.ALL = 0;
496
  packet->data.data_l = 0;
493
  packet->data.data_l = 0;
497
  packet->data.data_h = 0;
494
  packet->data.data_h = 0;
498
  return 0;
495
  return 0;
499
#endif
496
#endif
500
}
497
}
501
498
502
/////////////////////////////////////////////////////////////////////////////
499
/////////////////////////////////////////////////////////////////////////////
503
//! returns number of free bytes in receive buffer
500
//! returns number of free bytes in receive buffer
504
//! \param[in] CAN number (0..1)
501
//! \param[in] CAN number (0..1)
505
//! \return can number of free bytes
502
//! \return can number of free bytes
506
//! \return 1: can available
503
//! \return 1: can available
507
//! \return 0: can not available
504
//! \return 0: can not available
508
/////////////////////////////////////////////////////////////////////////////
505
/////////////////////////////////////////////////////////////////////////////
509
s32 MIOS32_CAN_RxBufferFree(u8 can)
506
s32 MIOS32_CAN_RxBufferFree(u8 can)
510
{
507
{
511
#if NUM_SUPPORTED_CANS == 0
508
#if NUM_SUPPORTED_CANS == 0
512
  return 0; // no CAN available
509
  return 0; // no CAN available
513
#else
510
#else
514
  if( can >= NUM_SUPPORTED_CANS )
511
  if( can >= NUM_SUPPORTED_CANS )
515
    return 0;
512
    return 0;
516
  else
513
  else
517
    return MIOS32_CAN_RX_BUFFER_SIZE - rx_buffer_size[can];
514
    return MIOS32_CAN_RX_BUFFER_SIZE - rx_buffer_size[can];
518
#endif
515
#endif
519
}
516
}
520
517
521
518
522
/////////////////////////////////////////////////////////////////////////////
519
/////////////////////////////////////////////////////////////////////////////
523
//! returns number of used bytes in receive buffer
520
//! returns number of used bytes in receive buffer
524
//! \param[in] CAN number (0..1)
521
//! \param[in] CAN number (0..1)
525
//! \return > 0: number of used bytes
522
//! \return > 0: number of used bytes
526
//! \return 0 if can not available
523
//! \return 0 if can not available
527
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
524
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
528
/////////////////////////////////////////////////////////////////////////////
525
/////////////////////////////////////////////////////////////////////////////
529
s32 MIOS32_CAN_RxBufferUsed(u8 can)
526
s32 MIOS32_CAN_RxBufferUsed(u8 can)
530
{
527
{
531
#if NUM_SUPPORTED_CANS == 0
528
#if NUM_SUPPORTED_CANS == 0
532
  return 0; // no CAN available
529
  return 0; // no CAN available
533
#else
530
#else
534
  if( can >= NUM_SUPPORTED_CANS )
531
  if( can >= NUM_SUPPORTED_CANS )
535
    return 0;
532
    return 0;
536
  else
533
  else
537
    return rx_buffer_size[can];
534
    return rx_buffer_size[can];
538
#endif
535
#endif
539
}
536
}
540
537
541
538
542
/////////////////////////////////////////////////////////////////////////////
539
/////////////////////////////////////////////////////////////////////////////
543
//! gets a byte from the receive buffer
540
//! gets a byte from the receive buffer
544
//! \param[in] CAN number (0..1)
541
//! \param[in] CAN number (0..1)
545
//! \return -1 if CAN not available
542
//! \return -1 if CAN not available
546
//! \return -2 if no new byte available
543
//! \return -2 if no new byte available
547
//! \return >= 0: number of received bytes
544
//! \return >= 0: number of received bytes
548
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
545
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
549
/////////////////////////////////////////////////////////////////////////////
546
/////////////////////////////////////////////////////////////////////////////
550
s32 MIOS32_CAN_RxBufferGet(u8 can, can_packet_t *p)
547
s32 MIOS32_CAN_RxBufferGet(u8 can, mios32_can_packet_t *p)
551
{
548
{
552
#if NUM_SUPPORTED_CANS == 0
549
#if NUM_SUPPORTED_CANS == 0
553
  return -1; // no CAN available
550
  return -1; // no CAN available
554
#else
551
#else
555
  if( can >= NUM_SUPPORTED_CANS )
552
  if( can >= NUM_SUPPORTED_CANS )
556
    return -1; // CAN not available
553
    return -1; // CAN not available
557
 
554
 
558
  if( !rx_buffer_size[can] )
555
  if( !rx_buffer_size[can] )
559
    return -2; // nothing new in buffer
556
    return -2; // nothing new in buffer
560
 
557
 
561
  // get byte - this operation should be atomic!
558
  // get byte - this operation should be atomic!
562
  MIOS32_IRQ_Disable();
559
  MIOS32_IRQ_Disable();
563
  *p = rx_buffer[can][rx_buffer_tail[can]];
560
  *p = rx_buffer[can][rx_buffer_tail[can]];
564
  if( ++rx_buffer_tail[can] >= MIOS32_CAN_RX_BUFFER_SIZE )
561
  if( ++rx_buffer_tail[can] >= MIOS32_CAN_RX_BUFFER_SIZE )
565
    rx_buffer_tail[can] = 0;
562
    rx_buffer_tail[can] = 0;
566
  --rx_buffer_size[can];
563
  --rx_buffer_size[can];
567
 
564
 
568
  //can_stat_report[can].tx_done_ctr++;
565
  //can_stat_report[can].tx_done_ctr++;
569
  MIOS32_IRQ_Enable();
566
  MIOS32_IRQ_Enable();
570
 
567
 
571
  return 0; // return received byte
568
  return 0; // return received byte
572
#endif
569
#endif
573
}
570
}
574
571
575
572
576
/////////////////////////////////////////////////////////////////////////////
573
/////////////////////////////////////////////////////////////////////////////
577
//! returns the next byte of the receive buffer without taking it
574
//! returns the next byte of the receive buffer without taking it
578
//! \param[in] CAN number (0..1)
575
//! \param[in] CAN number (0..1)
579
//! \return -1 if CAN not available
576
//! \return -1 if CAN not available
580
//! \return -2 if no new byte available
577
//! \return -2 if no new byte available
581
//! \return >= 0: number of received bytes
578
//! \return >= 0: number of received bytes
582
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
579
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
583
/////////////////////////////////////////////////////////////////////////////
580
/////////////////////////////////////////////////////////////////////////////
584
s32 MIOS32_CAN_RxBufferPeek(u8 can, can_packet_t *p)
581
s32 MIOS32_CAN_RxBufferPeek(u8 can, mios32_can_packet_t *p)
585
{
582
{
586
#if NUM_SUPPORTED_CANS == 0
583
#if NUM_SUPPORTED_CANS == 0
587
  return -1; // no CAN available
584
  return -1; // no CAN available
588
#else
585
#else
589
  if( can >= NUM_SUPPORTED_CANS )
586
  if( can >= NUM_SUPPORTED_CANS )
590
    return -1; // CAN not available
587
    return -1; // CAN not available
591
 
588
 
592
  if( !rx_buffer_size[can] )
589
  if( !rx_buffer_size[can] )
593
    return -2; // nothing new in buffer
590
    return -2; // nothing new in buffer
594
 
591
 
595
  // get byte - this operation should be atomic!
592
  // get byte - this operation should be atomic!
596
  MIOS32_IRQ_Disable();
593
  MIOS32_IRQ_Disable();
597
  *p = rx_buffer[can][rx_buffer_tail[can]];
594
  *p = rx_buffer[can][rx_buffer_tail[can]];
598
  MIOS32_IRQ_Enable();
595
  MIOS32_IRQ_Enable();
599
 
596
 
600
  return 0; // return received byte
597
  return 0; // return received byte
601
#endif
598
#endif
602
}
599
}
603
600
604
/////////////////////////////////////////////////////////////////////////////
601
/////////////////////////////////////////////////////////////////////////////
605
//! remove the next byte of the receive buffer without taking it
602
//! remove the next byte of the receive buffer without taking it
606
//! \param[in] CAN number (0..1)
603
//! \param[in] CAN number (0..1)
607
//! \return -1 if CAN not available
604
//! \return -1 if CAN not available
608
//! \return -2 if no new byte available
605
//! \return -2 if no new byte available
609
//! \return >= 0: number of received bytes
606
//! \return >= 0: number of received bytes
610
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
607
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
611
/////////////////////////////////////////////////////////////////////////////
608
/////////////////////////////////////////////////////////////////////////////
612
s32 MIOS32_CAN_RxBufferRemove(u8 can)
609
s32 MIOS32_CAN_RxBufferRemove(u8 can)
613
{
610
{
614
#if NUM_SUPPORTED_CANS == 0
611
#if NUM_SUPPORTED_CANS == 0
615
  return -1; // no CAN available
612
  return -1; // no CAN available
616
#else
613
#else
617
  if( can >= NUM_SUPPORTED_CANS )
614
  if( can >= NUM_SUPPORTED_CANS )
618
    return -1; // CAN not available
615
    return -1; // CAN not available
619
 
616
 
620
  if( !rx_buffer_size[can] )
617
  if( !rx_buffer_size[can] )
621
    return -2; // nothing new in buffer
618
    return -2; // nothing new in buffer
622
 
619
 
623
  // dec buffer - this operation should be atomic!
620
  // dec buffer - this operation should be atomic!
624
  MIOS32_IRQ_Disable();
621
  MIOS32_IRQ_Disable();
625
  if( ++rx_buffer_tail[can] >= MIOS32_CAN_RX_BUFFER_SIZE )
622
  if( ++rx_buffer_tail[can] >= MIOS32_CAN_RX_BUFFER_SIZE )
626
    rx_buffer_tail[can] = 0;
623
    rx_buffer_tail[can] = 0;
627
  --rx_buffer_size[can];
624
  --rx_buffer_size[can];
628
  MIOS32_IRQ_Enable();
625
  MIOS32_IRQ_Enable();
629
 
626
 
630
  return 0; // return received byte
627
  return 0; // return received byte
631
#endif
628
#endif
632
}
629
}
633
630
634
/////////////////////////////////////////////////////////////////////////////
631
/////////////////////////////////////////////////////////////////////////////
635
//! puts a byte onto the receive buffer
632
//! puts a byte onto the receive buffer
636
//! \param[in] CAN number (0..1)
633
//! \param[in] CAN number (0..1)
637
//! \param[in] b byte which should be put into Rx buffer
634
//! \param[in] b byte which should be put into Rx buffer
638
//! \return 0 if no error
635
//! \return 0 if no error
639
//! \return -1 if CAN not available
636
//! \return -1 if CAN not available
640
//! \return -2 if buffer full (retry)
637
//! \return -2 if buffer full (retry)
641
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
638
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
642
/////////////////////////////////////////////////////////////////////////////
639
/////////////////////////////////////////////////////////////////////////////
643
s32 MIOS32_CAN_RxBufferPut(u8 can, can_packet_t p)
640
s32 MIOS32_CAN_RxBufferPut(u8 can, mios32_can_packet_t p)
644
{
641
{
645
#if NUM_SUPPORTED_CANS == 0
642
#if NUM_SUPPORTED_CANS == 0
646
  return -1; // no CAN available
643
  return -1; // no CAN available
647
#else
644
#else
648
  if( can >= NUM_SUPPORTED_CANS )
645
  if( can >= NUM_SUPPORTED_CANS )
649
    return -1; // CAN not available
646
    return -1; // CAN not available
650
 
647
 
651
  if( rx_buffer_size[can] >= MIOS32_CAN_RX_BUFFER_SIZE )
648
  if( rx_buffer_size[can] >= MIOS32_CAN_RX_BUFFER_SIZE )
652
    return -2; // buffer full (retry)
649
    return -2; // buffer full (retry)
653
 
650
 
654
  // copy received can packet into receive buffer
651
  // copy received can packet into receive buffer
655
  // this operation should be atomic!
652
  // this operation should be atomic!
656
  MIOS32_IRQ_Disable();
653
  MIOS32_IRQ_Disable();
657
  rx_buffer[can][rx_buffer_head[can]] = p;
654
  rx_buffer[can][rx_buffer_head[can]] = p;
658
  if( ++rx_buffer_head[can] >= MIOS32_CAN_RX_BUFFER_SIZE )
655
  if( ++rx_buffer_head[can] >= MIOS32_CAN_RX_BUFFER_SIZE )
659
    rx_buffer_head[can] = 0;
656
    rx_buffer_head[can] = 0;
660
  ++rx_buffer_size[can];
657
  ++rx_buffer_size[can];
661
 
658
 
662
 
659
 
663
  MIOS32_IRQ_Enable();
660
  MIOS32_IRQ_Enable();
664
 
661
 
665
  return 0; // no error
662
  return 0; // no error
666
#endif
663
#endif
667
}
664
}
668
665
669
/////////////////////////////////////////////////////////////////////////////
666
/////////////////////////////////////////////////////////////////////////////
670
//! returns number of free bytes in transmit buffer
667
//! returns number of free bytes in transmit buffer
671
//! \param[in] CAN number (0..1)
668
//! \param[in] CAN number (0..1)
672
//! \return number of free bytes
669
//! \return number of free bytes
673
//! \return 0 if can not available
670
//! \return 0 if can not available
674
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
671
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
675
/////////////////////////////////////////////////////////////////////////////
672
/////////////////////////////////////////////////////////////////////////////
676
s32 MIOS32_CAN_TxBufferFree(u8 can)
673
s32 MIOS32_CAN_TxBufferFree(u8 can)
677
{
674
{
678
#if NUM_SUPPORTED_CANS == 0
675
#if NUM_SUPPORTED_CANS == 0
679
  return -1; // no CAN available
676
  return -1; // no CAN available
680
#else
677
#else
681
  if( can >= NUM_SUPPORTED_CANS )
678
  if( can >= NUM_SUPPORTED_CANS )
682
    return -1;
679
    return -1;
683
  else
680
  else
684
    return MIOS32_CAN_TX_BUFFER_SIZE - tx_buffer_size[can];
681
    return MIOS32_CAN_TX_BUFFER_SIZE - tx_buffer_size[can];
685
#endif
682
#endif
686
}
683
}
687
684
688
685
689
/////////////////////////////////////////////////////////////////////////////
686
/////////////////////////////////////////////////////////////////////////////
690
//! returns number of used bytes in transmit buffer
687
//! returns number of used bytes in transmit buffer
691
//! \param[in] CAN number (0..1)
688
//! \param[in] CAN number (0..1)
692
//! \return number of used bytes
689
//! \return number of used bytes
693
//! \return 0 if can not available
690
//! \return 0 if can not available
694
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
691
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
695
/////////////////////////////////////////////////////////////////////////////
692
/////////////////////////////////////////////////////////////////////////////
696
s32 MIOS32_CAN_TxBufferUsed(u8 can)
693
s32 MIOS32_CAN_TxBufferUsed(u8 can)
697
{
694
{
698
#if NUM_SUPPORTED_CANS == 0
695
#if NUM_SUPPORTED_CANS == 0
699
  return -1; // no CAN available
696
  return -1; // no CAN available
700
#else
697
#else
701
  if( can >= NUM_SUPPORTED_CANS )
698
  if( can >= NUM_SUPPORTED_CANS )
702
    return -1;
699
    return -1;
703
  else
700
  else
704
    return tx_buffer_size[can];
701
    return tx_buffer_size[can];
705
#endif
702
#endif
706
}
703
}
707
704
708
705
709
/////////////////////////////////////////////////////////////////////////////
706
/////////////////////////////////////////////////////////////////////////////
710
//! gets a byte from the transmit buffer
707
//! gets a byte from the transmit buffer
711
//! \param[in] CAN number (0..1)
708
//! \param[in] CAN number (0..1)
712
//! \return -1 if CAN not available
709
//! \return -1 if CAN not available
713
//! \return -2 if no new byte available
710
//! \return -2 if no new byte available
714
//! \return >= 0: transmitted byte
711
//! \return >= 0: transmitted byte
715
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
712
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
716
/////////////////////////////////////////////////////////////////////////////
713
/////////////////////////////////////////////////////////////////////////////
717
s32 MIOS32_CAN_TxBufferGet(u8 can, can_packet_t *p)
714
s32 MIOS32_CAN_TxBufferGet(u8 can, mios32_can_packet_t *p)
718
{
715
{
719
#if NUM_SUPPORTED_CANS == 0
716
#if NUM_SUPPORTED_CANS == 0
720
  return -1; // no CAN available
717
  return -1; // no CAN available
721
#else
718
#else
722
  if( can >= NUM_SUPPORTED_CANS )
719
  if( can >= NUM_SUPPORTED_CANS )
723
    return -1; // CAN not available
720
    return -1; // CAN not available
724
 
721
 
725
  if( !tx_buffer_size[can] )
722
  if( !tx_buffer_size[can] )
726
    return -2; // nothing new in buffer
723
    return -2; // nothing new in buffer
727
 
724
 
728
  // get byte - this operation should be atomic!
725
  // get byte - this operation should be atomic!
729
  MIOS32_IRQ_Disable();
726
  MIOS32_IRQ_Disable();
730
  *p = tx_buffer[can][tx_buffer_tail[can]];
727
  *p = tx_buffer[can][tx_buffer_tail[can]];
731
  if( ++tx_buffer_tail[can] >= MIOS32_CAN_TX_BUFFER_SIZE )
728
  if( ++tx_buffer_tail[can] >= MIOS32_CAN_TX_BUFFER_SIZE )
732
    tx_buffer_tail[can] = 0;
729
    tx_buffer_tail[can] = 0;
733
  --tx_buffer_size[can];
730
  --tx_buffer_size[can];
734
  MIOS32_IRQ_Enable();
731
  MIOS32_IRQ_Enable();
735
 
732
 
736
  return 0; // return transmitted byte
733
  return 0; // return transmitted byte
737
#endif
734
#endif
738
}
735
}
739
736
740
737
741
/////////////////////////////////////////////////////////////////////////////
738
/////////////////////////////////////////////////////////////////////////////
742
//! puts more than one byte onto the transmit buffer (used for atomic sends)
739
//! puts more than one byte onto the transmit buffer (used for atomic sends)
743
//! \param[in] CAN number (0..1)
740
//! \param[in] CAN number (0..1)
744
//! \param[in] *buffer pointer to buffer to be sent
741
//! \param[in] *buffer pointer to buffer to be sent
745
//! \param[in] len number of bytes to be sent
742
//! \param[in] len number of bytes to be sent
746
//! \return 0 if no error
743
//! \return 0 if no error
747
//! \return -1 if CAN not available
744
//! \return -1 if CAN not available
748
//! \return -2 if buffer full or cannot get all requested bytes (retry)
745
//! \return -2 if buffer full or cannot get all requested bytes (retry)
749
//! \return -3 if CAN not supported by MIOS32_CAN_TxBufferPut Routine
746
//! \return -3 if CAN not supported by MIOS32_CAN_TxBufferPut Routine
750
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
747
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
751
/////////////////////////////////////////////////////////////////////////////
748
/////////////////////////////////////////////////////////////////////////////
752
s32 MIOS32_CAN_TxBufferPutMore_NonBlocking(u8 can, can_packet_t* p,u16 len)
749
s32 MIOS32_CAN_TxBufferPutMore_NonBlocking(u8 can, mios32_can_packet_t* p,u16 len)
753
{
750
{
754
#if NUM_SUPPORTED_CANS == 0
751
#if NUM_SUPPORTED_CANS == 0
755
  return -1; // no CAN available
752
  return -1; // no CAN available
756
#else
753
#else
757
  if( can >= NUM_SUPPORTED_CANS )
754
  if( can >= NUM_SUPPORTED_CANS )
758
    return -1; // CAN not available
755
    return -1; // CAN not available
759
 
756
 
760
  if( (tx_buffer_size[can] + len) >= MIOS32_CAN_TX_BUFFER_SIZE )
757
  if( (tx_buffer_size[can] + len) >= MIOS32_CAN_TX_BUFFER_SIZE )
761
    return -2; // buffer full or cannot get all requested bytes (retry)
758
    return -2; // buffer full or cannot get all requested bytes (retry)
762
759
763
  // exit immediately if CAN bus errors (CAN doesn't send messages anymore)
760
  // exit immediately if CAN bus errors (CAN doesn't send messages anymore)
764
  if( MIOS32_CAN_BusErrorCheck(can) < 0 )
761
  if( MIOS32_CAN_BusErrorCheck(can) < 0 )
765
    return -3; // bus error
762
    return -3; // bus error
766
 
763
 
767
  CAN_TypeDef* CANx = NULL;
764
  CAN_TypeDef* CANx = NULL;
768
  if(!can)CANx = MIOS32_CAN1;else CANx = MIOS32_CAN2;
765
  if(!can)CANx = MIOS32_CAN1;else CANx = MIOS32_CAN2;
769
  u16 i;
766
  u16 i;
770
  for(i=0; i<len; ++i) {
767
  for(i=0; i<len; ++i) {
771
    // if buffer is empty / interrupt is not enable
768
    // if buffer is empty / interrupt is not enable
772
    // we first try to fill some empty mailboxes
769
    // we first try to fill some empty mailboxes
773
    if(MIOS32_CAN_TxBufferUsed(can) == 0){
770
    if(MIOS32_CAN_TxBufferUsed(can) == 0){
774
      // is any mailbox empty ?
771
      // is any mailbox empty ?
775
      s8 mailbox = -1;
772
      s8 mailbox = -1;
776
      if( CANx->TSR & CAN_TSR_TME0)mailbox = 0;
773
      if( CANx->TSR & CAN_TSR_TME0)mailbox = 0;
777
      else if( CANx->TSR & CAN_TSR_TME1)mailbox = 1;
774
      else if( CANx->TSR & CAN_TSR_TME1)mailbox = 1;
778
      else if( CANx->TSR & CAN_TSR_TME2)mailbox = 2;
775
      else if( CANx->TSR & CAN_TSR_TME2)mailbox = 2;
779
     
776
     
780
      if(mailbox>=0){
777
      if(mailbox>=0){
781
        // yes, we send the packet
778
        // yes, we send the packet
782
        p[i].id.txrq = 1; //TX Req flag
779
        p[i].id.txrq = 1; //TX Req flag
783
        CANx->sTxMailBox[mailbox].TDTR = p[i].ctrl.ALL;
780
        CANx->sTxMailBox[mailbox].TDTR = p[i].ctrl.ALL;
784
        CANx->sTxMailBox[mailbox].TDLR = p[i].data.data_l;
781
        CANx->sTxMailBox[mailbox].TDLR = p[i].data.data_l;
785
        CANx->sTxMailBox[mailbox].TDHR = p[i].data.data_h;
782
        CANx->sTxMailBox[mailbox].TDHR = p[i].data.data_h;
786
        CANx->sTxMailBox[mailbox].TIR = p[i].id.ALL;
783
        CANx->sTxMailBox[mailbox].TIR = p[i].id.ALL;
787
        // for CAN_Report
784
        // for CAN_Report
788
        can_stat_report[can].tx_packets_ctr +=1;
785
        can_stat_report[can].tx_packets_ctr +=1;
789
        // packet directly put in mailbox
786
        // packet directly put in mailbox
790
        return mailbox; // >= 0 no error
787
        return mailbox; // >= 0 no error
791
      }
788
      }
792
    }
789
    }
793
    // there's something in buffer, new packet must be put after
790
    // there's something in buffer, new packet must be put after
794
    // or mailbpx < 0, we put packet in the buffer first
791
    // or mailbpx < 0, we put packet in the buffer first
795
    // copy bytes to be transmitted into transmit buffer
792
    // copy bytes to be transmitted into transmit buffer
796
    // this operation should be atomic!
793
    // this operation should be atomic!
797
    MIOS32_IRQ_Disable();
794
    MIOS32_IRQ_Disable();
798
    tx_buffer[can][tx_buffer_head[can]] = p[i];
795
    tx_buffer[can][tx_buffer_head[can]] = p[i];
799
    // for CAN_Report
796
    // for CAN_Report
800
    can_stat_report[can].tx_packets_ctr +=1;
797
    can_stat_report[can].tx_packets_ctr +=1;
801
    if( ++tx_buffer_head[can] >= MIOS32_CAN_TX_BUFFER_SIZE )
798
    if( ++tx_buffer_head[can] >= MIOS32_CAN_TX_BUFFER_SIZE )
802
      tx_buffer_head[can] = 0;
799
      tx_buffer_head[can] = 0;
803
    tx_buffer_size[can]++;
800
    tx_buffer_size[can]++;
804
801
805
    // and we start TME interrupt
802
    // and we start TME interrupt
806
    CANx->IER |= CAN_IT_TME;
803
    CANx->IER |= CAN_IT_TME;
807
   
804
   
808
    MIOS32_IRQ_Enable();
805
    MIOS32_IRQ_Enable();
809
  }
806
  }
810
807
811
808
812
  return 0; // no error
809
  return 0; // no error
813
#endif
810
#endif
814
}
811
}
815
812
816
/////////////////////////////////////////////////////////////////////////////
813
/////////////////////////////////////////////////////////////////////////////
817
//! puts more than one byte onto the transmit buffer (used for atomic sends)<BR>
814
//! puts more than one byte onto the transmit buffer (used for atomic sends)<BR>
818
//! (blocking function)
815
//! (blocking function)
819
//! \param[in] CAN number (0..1)
816
//! \param[in] CAN number (0..1)
820
//! \param[in] *buffer pointer to buffer to be sent
817
//! \param[in] *buffer pointer to buffer to be sent
821
//! \param[in] len number of bytes to be sent
818
//! \param[in] len number of bytes to be sent
822
//! \return 0 if no error
819
//! \return 0 if no error
823
//! \return -1 if CAN not available
820
//! \return -1 if CAN not available
824
//! \return -3 if CAN not supported by MIOS32_CAN_TxBufferPut Routine
821
//! \return -3 if CAN not supported by MIOS32_CAN_TxBufferPut Routine
825
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
822
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
826
/////////////////////////////////////////////////////////////////////////////
823
/////////////////////////////////////////////////////////////////////////////
827
s32 MIOS32_CAN_TxBufferPutMore(u8 can, can_packet_t *packets, u16 len)
824
s32 MIOS32_CAN_TxBufferPutMore(u8 can, mios32_can_packet_t *packets, u16 len)
828
{
825
{
829
  s32 error;
826
  s32 error;
830
 
827
 
831
  while( (error=MIOS32_CAN_TxBufferPutMore_NonBlocking(can, packets, len)) == -2 );
828
  while( (error=MIOS32_CAN_TxBufferPutMore_NonBlocking(can, packets, len)) == -2 );
832
 
829
 
833
  return error;
830
  return error;
834
}
831
}
835
832
836
833
837
/////////////////////////////////////////////////////////////////////////////
834
/////////////////////////////////////////////////////////////////////////////
838
//! puts a byte onto the transmit buffer
835
//! puts a byte onto the transmit buffer
839
//! \param[in] CAN number (0..1)
836
//! \param[in] CAN number (0..1)
840
//! \param[in] b byte which should be put into Tx buffer
837
//! \param[in] b byte which should be put into Tx buffer
841
//! \return 0 if no error
838
//! \return 0 if no error
842
//! \return -1 if CAN not available
839
//! \return -1 if CAN not available
843
//! \return -2 if buffer full (retry)
840
//! \return -2 if buffer full (retry)
844
//! \return -3 if CAN not supported by MIOS32_CAN_TxBufferPut Routine
841
//! \return -3 if CAN not supported by MIOS32_CAN_TxBufferPut Routine
845
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
842
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
846
/////////////////////////////////////////////////////////////////////////////
843
/////////////////////////////////////////////////////////////////////////////
847
s32 MIOS32_CAN_TxBufferPut_NonBlocking(u8 can, can_packet_t p)
844
s32 MIOS32_CAN_TxBufferPut_NonBlocking(u8 can, mios32_can_packet_t p)
848
{
845
{
849
  // for more comfortable usage...
846
  // for more comfortable usage...
850
  // -> just forward to MIOS32_CAN_TxBufferPutMore
847
  // -> just forward to MIOS32_CAN_TxBufferPutMore
851
  return MIOS32_CAN_TxBufferPutMore(can, &p, 1);
848
  return MIOS32_CAN_TxBufferPutMore(can, &p, 1);
852
}
849
}
853
850
854
851
855
/////////////////////////////////////////////////////////////////////////////
852
/////////////////////////////////////////////////////////////////////////////
856
//! puts a byte onto the transmit buffer<BR>
853
//! puts a byte onto the transmit buffer<BR>
857
//! (blocking function)
854
//! (blocking function)
858
//! \param[in] CAN number (0..1)
855
//! \param[in] CAN number (0..1)
859
//! \param[in] b byte which should be put into Tx buffer
856
//! \param[in] b byte which should be put into Tx buffer
860
//! \return 0 if no error
857
//! \return 0 if no error
861
//! \return -1 if CAN not available
858
//! \return -1 if CAN not available
862
//! \return -3 if CAN not supported by MIOS32_CAN_TxBufferPut Routine
859
//! \return -3 if CAN not supported by MIOS32_CAN_TxBufferPut Routine
863
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
860
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
864
/////////////////////////////////////////////////////////////////////////////
861
/////////////////////////////////////////////////////////////////////////////
865
s32 MIOS32_CAN_TxBufferPut(u8 can, can_packet_t p)
862
s32 MIOS32_CAN_TxBufferPut(u8 can, mios32_can_packet_t p)
866
{
863
{
867
  s32 error;
864
  s32 error;
868
 
865
 
869
  while( (error=MIOS32_CAN_TxBufferPutMore(can, &p, 1)) == -2 );
866
  while( (error=MIOS32_CAN_TxBufferPutMore(can, &p, 1)) == -2 );
870
 
867
 
871
  return error;
868
  return error;
872
}
869
}
873
870
874
871
875
/////////////////////////////////////////////////////////////////////////////
872
/////////////////////////////////////////////////////////////////////////////
876
// Used during transmit or receive polling to determine if a bus error has occured
873
// Used during transmit or receive polling to determine if a bus error has occured
877
// (e.g. receiver passive or no nodes connected to bus)
874
// (e.g. receiver passive or no nodes connected to bus)
878
// In this case, all pending transmissions will be aborted
875
// In this case, all pending transmissions will be aborted
879
// The midian_state.PANIC flag is set to report to the application, that the
876
// The midian_state.PANIC flag is set to report to the application, that the
880
// bus is not ready for transactions (flag accessible via MIDIAN_ErrorStateGet).
877
// bus is not ready for transactions (flag accessible via MIDIAN_ErrorStateGet).
881
// This flag will be cleared by WaitAck once we got back a message from any slave
878
// This flag will be cleared by WaitAck once we got back a message from any slave
882
// OUT: returns -1 if bus permanent off (requires re-initialisation)
879
// OUT: returns -1 if bus permanent off (requires re-initialisation)
883
//      returns -2 if panic state reached
880
//      returns -2 if panic state reached
884
/////////////////////////////////////////////////////////////////////////////
881
/////////////////////////////////////////////////////////////////////////////
885
s32 MIOS32_CAN_BusErrorCheck(u8 can)
882
s32 MIOS32_CAN_BusErrorCheck(u8 can)
886
{
883
{
887
#if NUM_SUPPORTED_CANS == 0
884
#if NUM_SUPPORTED_CANS == 0
888
  return -1; // no CAN available
885
  return -1; // no CAN available
889
#else
886
#else
890
887
891
  can_stat_err_t err;
888
  mios32_can_stat_err_t err;
892
  err = can_stat_report[can].bus_last_err;
889
  err = can_stat_report[can].bus_last_err;
893
  //if((CANx->ESR &7)!=0){
890
  //if((CANx->ESR &7)!=0){
894
  if((err.tec) > (can_stat_report[can].bus_curr_err.tec)){
891
  if((err.tec) > (can_stat_report[can].bus_curr_err.tec)){
895
      if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] %s %s %s. rec:%d, tec:%d>", err.ewgf? "warning" : "", err.epvf? "passive" : "", err.boff? "off" : "", err.rec, err.tec);
892
      if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] %s %s %s. rec:%d, tec:%d>", err.ewgf? "warning" : "", err.epvf? "passive" : "", err.boff? "off" : "", err.rec, err.tec);
896
893
897
      if(err.ewgf){
894
      if(err.ewgf){
898
          can_stat_report[can].bus_state = WARNING;
895
          can_stat_report[can].bus_state = WARNING;
899
      }
896
      }
900
897
901
      if(err.epvf){
898
      if(err.epvf){
902
          can_stat_report[can].bus_state = PASSIVE;
899
          can_stat_report[can].bus_state = PASSIVE;
903
      }
900
      }
904
      if(err.boff){
901
      if(err.boff){
905
          can_stat_report[can].bus_state = BUS_OFF;
902
          can_stat_report[can].bus_state = BUS_OFF;
906
      }
903
      }
907
      can_stat_report[can].bus_curr_err = err;
904
      can_stat_report[can].bus_curr_err = err;
908
  }else {
905
  }else {
909
      CAN_TypeDef* CANx = NULL;
906
      CAN_TypeDef* CANx = NULL;
910
      if(!can)CANx = MIOS32_CAN1;else CANx = MIOS32_CAN2;
907
      if(!can)CANx = MIOS32_CAN1;else CANx = MIOS32_CAN2;
911
      err.ALL = CANx->ESR;
908
      err.ALL = CANx->ESR;
912
      if((err.tec) < (can_stat_report[can].bus_curr_err.tec)){
909
      if((err.tec) < (can_stat_report[can].bus_curr_err.tec)){
913
          if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] %s %s %s. rec:%d, tec:%d<", err.ewgf? "warning" : "", err.epvf? "passive" : "", err.boff? "off" : "", err.rec, err.tec);
910
          if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] %s %s %s. rec:%d, tec:%d<", err.ewgf? "warning" : "", err.epvf? "passive" : "", err.boff? "off" : "", err.rec, err.tec);
914
          can_stat_report[can].bus_curr_err = err;
911
          can_stat_report[can].bus_curr_err = err;
915
          can_stat_report[can].bus_last_err = err;
912
          can_stat_report[can].bus_last_err = err;
916
      }
913
      }
917
      if(!(err.ALL & 7))can_stat_report[can].bus_state = BUS_OK;
914
      if(!(err.ALL & 7))can_stat_report[can].bus_state = BUS_OK;
918
915
919
  }
916
  }
920
//    CAN_TypeDef* CANx = NULL;
917
//    CAN_TypeDef* CANx = NULL;
921
//    if(!can)CANx = MIOS32_CAN1;else CANx = MIOS32_CAN2;
918
//    if(!can)CANx = MIOS32_CAN1;else CANx = MIOS32_CAN2;
922
//    err = CANx->ESR;
919
//    err = CANx->ESR;
923
//
920
//
924
//    if((err.ALL & 7) < (can_stat_report[can].bus_curr_err.ALL & 7)){
921
//    if((err.ALL & 7) < (can_stat_report[can].bus_curr_err.ALL & 7)){
925
//
922
//
926
//
923
//
927
//    if(!err.boff){
924
//    if(!err.boff){
928
//        //MIOS32_CAN_InitPeriph(can);
925
//        //MIOS32_CAN_InitPeriph(can);
929
//        can_stat_report[can].bus_state = PASSIVE;
926
//        can_stat_report[can].bus_state = PASSIVE;
930
//        if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] CAN is On! :)");
927
//        if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] CAN is On! :)");
931
//    }
928
//    }
932
//    if(!err.epvf){
929
//    if(!err.epvf){
933
//        can_stat_report[can].bus_state = WARNING;
930
//        can_stat_report[can].bus_state = WARNING;
934
//        CAN_ITConfig(MIOS32_CAN1, CAN_IT_BOF, ENABLE);
931
//        CAN_ITConfig(MIOS32_CAN1, CAN_IT_BOF, ENABLE);
935
//        CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, ENABLE);
932
//        CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, ENABLE);
936
//        if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] Leaves Passive.");
933
//        if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] Leaves Passive.");
937
//    }
934
//    }
938
//    if(!err.ewgf){
935
//    if(!err.ewgf){
939
//        can_stat_report[can].bus_state = WARNING;
936
//        can_stat_report[can].bus_state = WARNING;
940
//        CAN_ITConfig(MIOS32_CAN1, CAN_IT_EPV, ENABLE);
937
//        CAN_ITConfig(MIOS32_CAN1, CAN_IT_EPV, ENABLE);
941
//        CAN_ITConfig(MIOS32_CAN1, CAN_IT_BOF, ENABLE);
938
//        CAN_ITConfig(MIOS32_CAN1, CAN_IT_BOF, ENABLE);
942
//        CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, ENABLE);
939
//        CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, ENABLE);
943
//        if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] Leaves Warning.");
940
//        if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] Leaves Warning.");
944
//    }
941
//    }
945
//
942
//
946
//    can_stat_report[can].bus_curr_err = err;
943
//    can_stat_report[can].bus_curr_err = err;
947
//    CAN_ITConfig(MIOS32_CAN1, CAN_IT_EWG, ENABLE);
944
//    CAN_ITConfig(MIOS32_CAN1, CAN_IT_EWG, ENABLE);
948
//    CAN_ITConfig(MIOS32_CAN1, CAN_IT_EPV, ENABLE);
945
//    CAN_ITConfig(MIOS32_CAN1, CAN_IT_EPV, ENABLE);
949
//    CAN_ITConfig(MIOS32_CAN1, CAN_IT_BOF, ENABLE);
946
//    CAN_ITConfig(MIOS32_CAN1, CAN_IT_BOF, ENABLE);
950
//    CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, ENABLE);
947
//    CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, ENABLE);
951
//    can_stat_report[can].bus_state = BUS_OK;
948
//    can_stat_report[can].bus_state = BUS_OK;
952
//    if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] Bus OK.");
949
//    if(can_verbose)MIOS32_MIDI_SendDebugMessage("[MIOS32_CAN_BusErrorCheck] Bus OK.");
953
//  }
950
//  }
954
  //if(err.lec != 0)can_stat_report[can].bus_last_err = err;
951
  //if(err.lec != 0)can_stat_report[can].bus_last_err = err;
955
  return (s32)can_stat_report[can].bus_state ;
952
  return (s32)can_stat_report[can].bus_state ;
956
#endif
953
#endif
957
}
954
}
958
955
959
/////////////////////////////////////////////////////////////////////////////
956
/////////////////////////////////////////////////////////////////////////////
960
//! transmit more than one byte
957
//! transmit more than one byte
961
//! \param[in] CAN number (0..1)
958
//! \param[in] CAN number (0..1)
962
//! \param[in] *buffer pointer to buffer to be sent
959
//! \param[in] *buffer pointer to buffer to be sent
963
//! \param[in] len number of bytes to be sent
960
//! \param[in] len number of bytes to be sent
964
//! \return 0 if no error
961
//! \return 0 if no error
965
//! \return -1 if CAN not available
962
//! \return -1 if CAN not available
966
//! \return -2 if buffer full or cannot get all requested bytes (retry)
963
//! \return -2 if buffer full or cannot get all requested bytes (retry)
967
//! \return -3 if CAN not supported by MIOS32_CAN_TxBufferPut Routine
964
//! \return -3 if CAN not supported by MIOS32_CAN_TxBufferPut Routine
968
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
965
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
969
/////////////////////////////////////////////////////////////////////////////
966
/////////////////////////////////////////////////////////////////////////////
970
s32 MIOS32_CAN_Transmit(u8 can, can_packet_t p, s16 block_time)
967
s32 MIOS32_CAN_Transmit(u8 can, mios32_can_packet_t p, s16 block_time)
971
{
968
{
972
#if NUM_SUPPORTED_CANS == 0
969
#if NUM_SUPPORTED_CANS == 0
973
  return -1; // no CAN available
970
  return -1; // no CAN available
974
#else
971
#else
975
  if( can >= NUM_SUPPORTED_CANS )
972
  if( can >= NUM_SUPPORTED_CANS )
976
    return -1; // CAN not available
973
    return -1; // CAN not available
977
974
978
  s8 mailbox = -2;
975
  s8 mailbox = -2;
979
  CAN_TypeDef* CANx = NULL;
976
  CAN_TypeDef* CANx = NULL;
980
 
977
 
981
  //MIOS32_IRQ_Disable();
978
  //MIOS32_IRQ_Disable();
982
 
979
 
983
  if(!can)CANx = MIOS32_CAN1; else CANx = MIOS32_CAN2;
980
  if(!can)CANx = MIOS32_CAN1; else CANx = MIOS32_CAN2;
984
 
981
 
985
  // exit immediately if CAN bus errors (CAN doesn't send messages anymore)
982
  // exit immediately if CAN bus errors (CAN doesn't send messages anymore)
986
  //if( MIOS32_CAN_BusErrorCheck(can) < 0 )
983
  //if( MIOS32_CAN_BusErrorCheck(can) < 0 )
987
    //return -3; // bus error
984
    //return -3; // bus error
988
 
985
 
989
986
990
  do {
987
  do {
991
    if(block_time>=1)block_time--;
988
    if(block_time>=1)block_time--;
992
   
989
   
993
    // select an empty transmit mailbox
990
    // select an empty transmit mailbox
994
    if( CANx->TSR & CAN_TSR_TME0)mailbox = 0;
991
    if( CANx->TSR & CAN_TSR_TME0)mailbox = 0;
995
    else if( CANx->TSR & CAN_TSR_TME1)mailbox = 1;
992
    else if( CANx->TSR & CAN_TSR_TME1)mailbox = 1;
996
    else if( CANx->TSR & CAN_TSR_TME2)mailbox = 2;
993
    else if( CANx->TSR & CAN_TSR_TME2)mailbox = 2;
997
   
994
   
998
  } while (mailbox == -2 && block_time);
995
  } while (mailbox == -2 && block_time);
999
 
996
 
1000
  // exit on busy mailboxes and time out
997
  // exit on busy mailboxes and time out
1001
  if(mailbox == -2)return -2;
998
  if(mailbox == -2)return -2;
1002
 
999
 
1003
  p.id.txrq = 1;
1000
  p.id.txrq = 1;
1004
  CANx->sTxMailBox[mailbox].TDTR = p.ctrl.ALL;
1001
  CANx->sTxMailBox[mailbox].TDTR = p.ctrl.ALL;
1005
  CANx->sTxMailBox[mailbox].TDLR = p.data.data_l;
1002
  CANx->sTxMailBox[mailbox].TDLR = p.data.data_l;
1006
  CANx->sTxMailBox[mailbox].TDHR = p.data.data_h;
1003
  CANx->sTxMailBox[mailbox].TDHR = p.data.data_h;
1007
  CANx->sTxMailBox[mailbox].TIR = p.id.ALL;
1004
  CANx->sTxMailBox[mailbox].TIR = p.id.ALL;
1008
  // for CAN_Report
1005
  // for CAN_Report
1009
  can_stat_report[can].tx_packets_ctr++;
1006
  can_stat_report[can].tx_packets_ctr++;
1010
 
1007
 
1011
  //DEBUG_MSG("[MIOS32_CAN_Transmit] mailbox:%d",mailbox);
1008
  //DEBUG_MSG("[MIOS32_CAN_Transmit] mailbox:%d",mailbox);
1012
 
1009
 
1013
  return 0; // no error
1010
  return 0; // no error
1014
#endif
1011
#endif
1015
}
1012
}
1016
1013
1017
/////////////////////////////////////////////////////////////////////////////
1014
/////////////////////////////////////////////////////////////////////////////
1018
// Interrupt handler for first CAN
1015
// Interrupt handler for first CAN
1019
// always in this order TX, RX0, RX1, don't change it!
1016
// always in this order TX, RX0, RX1, don't change it!
1020
/////////////////////////////////////////////////////////////////////////////
1017
/////////////////////////////////////////////////////////////////////////////
1021
#if NUM_SUPPORTED_CANS >= 1
1018
#if NUM_SUPPORTED_CANS >= 1
1022
MIOS32_CAN1_TX_IRQHANDLER_FUNC
1019
MIOS32_CAN1_TX_IRQHANDLER_FUNC
1023
{
1020
{
1024
  //if( MIOS32_CAN1->IER & CAN_IT_TME ) { // check if TME enabled
1021
  //if( MIOS32_CAN1->IER & CAN_IT_TME ) { // check if TME enabled
1025
    while(CAN_GetITStatus(MIOS32_CAN1, CAN_IT_TME)){
1022
    while(CAN_GetITStatus(MIOS32_CAN1, CAN_IT_TME)){
1026
      if(MIOS32_CAN_TxBufferUsed(0) >= 1){
1023
      if(MIOS32_CAN_TxBufferUsed(0) >= 1){
1027
        u8 mailbox = -1;
1024
        u8 mailbox = -1;
1028
        if( MIOS32_CAN1->TSR & CAN_TSR_TME0)mailbox = 0;
1025
        if( MIOS32_CAN1->TSR & CAN_TSR_TME0)mailbox = 0;
1029
        else if( MIOS32_CAN1->TSR & CAN_TSR_TME1)mailbox = 1;
1026
        else if( MIOS32_CAN1->TSR & CAN_TSR_TME1)mailbox = 1;
1030
        else if( MIOS32_CAN1->TSR & CAN_TSR_TME2)mailbox = 2;
1027
        else if( MIOS32_CAN1->TSR & CAN_TSR_TME2)mailbox = 2;
1031
        can_packet_t p;
1028
        mios32_can_packet_t p;
1032
        MIOS32_CAN_TxBufferGet(0, &p);
1029
        MIOS32_CAN_TxBufferGet(0, &p);
1033
        p.id.txrq = 1; //TX Req flag, this reset RQCPx
1030
        p.id.txrq = 1; //TX Req flag, this reset RQCPx
1034
        MIOS32_CAN1->sTxMailBox[mailbox].TDTR = p.ctrl.ALL;
1031
        MIOS32_CAN1->sTxMailBox[mailbox].TDTR = p.ctrl.ALL;
1035
        MIOS32_CAN1->sTxMailBox[mailbox].TDLR = p.data.data_l;
1032
        MIOS32_CAN1->sTxMailBox[mailbox].TDLR = p.data.data_l;
1036
        MIOS32_CAN1->sTxMailBox[mailbox].TDHR = p.data.data_h;
1033
        MIOS32_CAN1->sTxMailBox[mailbox].TDHR = p.data.data_h;
1037
        MIOS32_CAN1->sTxMailBox[mailbox].TIR = p.id.ALL;
1034
        MIOS32_CAN1->sTxMailBox[mailbox].TIR = p.id.ALL;
1038
      }else{
1035
      }else{
1039
        // nothing to send anymore we reset all RQCPx flags
1036
        // nothing to send anymore we reset all RQCPx flags
1040
        MIOS32_CAN1->TSR |= CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2;
1037
        MIOS32_CAN1->TSR |= CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2;
1041
        // disable TME interrupt
1038
        // disable TME interrupt
1042
        MIOS32_CAN1->IER &=~CAN_IT_TME;
1039
        MIOS32_CAN1->IER &=~CAN_IT_TME;
1043
      }
1040
      }
1044
    }
1041
    }
1045
    // I don't knoow why
1042
    // I don't knoow why
1046
    //MIOS32_CAN1->TSR |= (CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2);
1043
    //MIOS32_CAN1->TSR |= (CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2);
1047
}
1044
}
1048
MIOS32_CAN1_RX0_IRQHANDLER_FUNC
1045
MIOS32_CAN1_RX0_IRQHANDLER_FUNC
1049
{
1046
{
1050
 
1047
 
1051
  while(MIOS32_CAN1->RF0R & CAN_RF0R_FMP0){     // FMP0 contains number of messages
1048
  while(MIOS32_CAN1->RF0R & CAN_RF0R_FMP0){     // FMP0 contains number of messages
1052
    // get EID, MSG and DLC
1049
    // get EID, MSG and DLC
1053
    can_packet_t p;
1050
    mios32_can_packet_t p;
1054
    p.id.ALL = MIOS32_CAN1->sFIFOMailBox[0].RIR;
1051
    p.id.ALL = MIOS32_CAN1->sFIFOMailBox[0].RIR;
1055
    p.ctrl.ALL = MIOS32_CAN1->sFIFOMailBox[0].RDTR;
1052
    p.ctrl.ALL = MIOS32_CAN1->sFIFOMailBox[0].RDTR;
1056
    p.data.data_l = MIOS32_CAN1->sFIFOMailBox[0].RDLR;
1053
    p.data.data_l = MIOS32_CAN1->sFIFOMailBox[0].RDLR;
1057
    p.data.data_h = MIOS32_CAN1->sFIFOMailBox[0].RDHR;
1054
    p.data.data_h = MIOS32_CAN1->sFIFOMailBox[0].RDHR;
1058
    can_stat_report[0].rx_packets_ctr++;
1055
    can_stat_report[0].rx_packets_ctr++;
1059
1056
1060
    s32 status = 0;
1057
    s32 status = 0;
1061
//    if((status = MIOS32_CAN_IsAssignedToMIDI(0))){
1058
//    if((status = MIOS32_CAN_IsAssignedToMIDI(0))){
1062
//      switch(p.id.event){
1059
//      switch(p.id.event){
1063
//        case 0x78 ... 0x7f:  // Realtime
1060
//        case 0x78 ... 0x7f:  // Realtime
1064
//          // no data, we forward (event +0x80)
1061
//          // no data, we forward (event +0x80)
1065
//          status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, 0x80 + p.id.event);
1062
//          status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, 0x80 + p.id.event);
1066
//          break;
1063
//          break;
1067
//        case 0x80 ... 0xe7:  // Channel Voice messages
1064
//        case 0x80 ... 0xe7:  // Channel Voice messages
1068
//          // Source and destination are transmited first. We just foward MIDI event bytes
1065
//          // Source and destination are transmited first. We just foward MIDI event bytes
1069
//          for( i=2; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1066
//          for( i=2; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1070
//          break;
1067
//          break;
1071
//        case 0xf0:  // SysEx messages
1068
//        case 0xf0:  // SysEx messages
1072
//          // Here we forward all data bytes
1069
//          // Here we forward all data bytes
1073
//          for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1070
//          for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1074
//          break;
1071
//          break;
1075
//        case 0xf1 ... 0xf7:  // System Common messages
1072
//        case 0xf1 ... 0xf7:  // System Common messages
1076
//          // depends on DLC
1073
//          // depends on DLC
1077
//          if(!p.ctrl.dlc)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.id.event);
1074
//          if(!p.ctrl.dlc)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.id.event);
1078
//          else for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1075
//          else for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1079
//          break;
1076
//          break;
1080
//        case 0xfe:  // Node active Sensing ;) 
1077
//        case 0xfe:  // Node active Sensing ;) 
1081
//          // Here we forward all data bytes
1078
//          // Here we forward all data bytes
1082
//          for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1079
//          for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1083
//          break;
1080
//          break;
1084
//        case 0xf8 ... 0xfd:  // Node System Exclusive and Common messages
1081
//        case 0xf8 ... 0xfd:  // Node System Exclusive and Common messages
1085
//          // toDo: foward to Node System Receive
1082
//          // toDo: foward to Node System Receive
1086
//          break;
1083
//          break;
1087
//        case 0xff:  // Node System Exclusive and Common messages
1084
//        case 0xff:  // Node System Exclusive and Common messages
1088
//          // toDo: foward to Node System Receive
1085
//          // toDo: foward to Node System Receive
1089
//          break;
1086
//          break;
1090
//        default:
1087
//        default:
1091
//          break;
1088
//          break;
1092
//      }
1089
//      }
1093
//    }
1090
//    }
1094
//    if( status == 0 ){
1091
//    if( status == 0 ){
1095
      if((status = MIOS32_CAN_RxBufferPut(0, p)) < 0 ){
1092
      if((status = MIOS32_CAN_RxBufferPut(0, p)) < 0 ){
1096
        can_stat_report[0].rx_last_buff_err = status;
1093
        can_stat_report[0].rx_last_buff_err = status;
1097
        can_stat_report[0].rx_buff_err_ctr = rx_buffer_size[0];
1094
        can_stat_report[0].rx_buff_err_ctr = rx_buffer_size[0];
1098
      }
1095
      }
1099
//    }
1096
//    }
1100
    // release FIFO
1097
    // release FIFO
1101
    MIOS32_CAN1->RF0R |= CAN_RF0R_RFOM0; // set RFOM1 flag
1098
    MIOS32_CAN1->RF0R |= CAN_RF0R_RFOM0; // set RFOM1 flag
1102
  }
1099
  }
1103
}
1100
}
1104
1101
1105
MIOS32_CAN1_RX1_IRQHANDLER_FUNC
1102
MIOS32_CAN1_RX1_IRQHANDLER_FUNC
1106
{
1103
{
1107
 
1104
 
1108
  while(MIOS32_CAN1->RF1R & CAN_RF1R_FMP1){     // FMP1 contains number of messages
1105
  while(MIOS32_CAN1->RF1R & CAN_RF1R_FMP1){     // FMP1 contains number of messages
1109
    // get EID, MSG and DLC
1106
    // get EID, MSG and DLC
1110
    can_packet_t p;
1107
    mios32_can_packet_t p;
1111
    p.id.ALL = MIOS32_CAN1->sFIFOMailBox[1].RIR;
1108
    p.id.ALL = MIOS32_CAN1->sFIFOMailBox[1].RIR;
1112
    p.ctrl.ALL = MIOS32_CAN1->sFIFOMailBox[1].RDTR;
1109
    p.ctrl.ALL = MIOS32_CAN1->sFIFOMailBox[1].RDTR;
1113
    p.data.data_l = MIOS32_CAN1->sFIFOMailBox[1].RDLR;
1110
    p.data.data_l = MIOS32_CAN1->sFIFOMailBox[1].RDLR;
1114
    p.data.data_h = MIOS32_CAN1->sFIFOMailBox[1].RDHR;
1111
    p.data.data_h = MIOS32_CAN1->sFIFOMailBox[1].RDHR;
1115
    can_stat_report[0].rx_packets_ctr++;
1112
    can_stat_report[0].rx_packets_ctr++;
1116
1113
1117
    s32 status = 0;
1114
    s32 status = 0;
1118
//    if((status = MIOS32_CAN_IsAssignedToMIDI(0))){
1115
//    if((status = MIOS32_CAN_IsAssignedToMIDI(0))){
1119
//      switch(p.id.event){
1116
//      switch(p.id.event){
1120
//        case 0x78 ... 0x7f:  // Realtime
1117
//        case 0x78 ... 0x7f:  // Realtime
1121
//          // no data, we forward (event +0x80)
1118
//          // no data, we forward (event +0x80)
1122
//          status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, 0x80 + p.id.event);
1119
//          status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, 0x80 + p.id.event);
1123
//          break;
1120
//          break;
1124
//        case 0x80 ... 0xe7:  // Channel Voice messages
1121
//        case 0x80 ... 0xe7:  // Channel Voice messages
1125
//          // Source and destination are transmited first. We just foward MIDI event bytes
1122
//          // Source and destination are transmited first. We just foward MIDI event bytes
1126
//          for( i=2; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1123
//          for( i=2; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1127
//          break;
1124
//          break;
1128
//        case 0xf0:  // SysEx messages
1125
//        case 0xf0:  // SysEx messages
1129
//          // Here we foward all data bytes
1126
//          // Here we foward all data bytes
1130
//          for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1127
//          for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1131
//          break;
1128
//          break;
1132
//        case 0xf1 ... 0xf7:  // System Common messages
1129
//        case 0xf1 ... 0xf7:  // System Common messages
1133
//          if(!p.ctrl.dlc)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.id.event);
1130
//          if(!p.ctrl.dlc)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.id.event);
1134
//          else for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1131
//          else for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0, p.data.bytes[i]);
1135
//          break;
1132
//          break;
1136
//        case 0xf8 ... 0xff:  // Node System Exclusive and Common messages
1133
//        case 0xf8 ... 0xff:  // Node System Exclusive and Common messages
1137
//          // toDo: foward to Node System Receive
1134
//          // toDo: foward to Node System Receive
1138
//          break;
1135
//          break;
1139
//        default:
1136
//        default:
1140
//          break;
1137
//          break;
1141
//      }
1138
//      }
1142
//    }
1139
//    }
1143
//    if( status == 0 ){
1140
//    if( status == 0 ){
1144
      if((status = MIOS32_CAN_RxBufferPut(0, p)) < 0 ){
1141
      if((status = MIOS32_CAN_RxBufferPut(0, p)) < 0 ){
1145
        can_stat_report[0].rx_last_buff_err = status;
1142
        can_stat_report[0].rx_last_buff_err = status;
1146
        can_stat_report[0].rx_buff_err_ctr = rx_buffer_size[0];
1143
        can_stat_report[0].rx_buff_err_ctr = rx_buffer_size[0];
1147
        can_stat_report[0].rx_packets_err++;
1144
        can_stat_report[0].rx_packets_err++;
1148
      }
1145
      }
1149
//    }
1146
//    }
1150
    // release FIFO
1147
    // release FIFO
1151
    MIOS32_CAN1->RF1R |= CAN_RF1R_RFOM1; // set RFOM1 flag
1148
    MIOS32_CAN1->RF1R |= CAN_RF1R_RFOM1; // set RFOM1 flag
1152
  }
1149
  }
1153
}
1150
}
1154
1151
1155
#if 1 // Here i tried to add a software fifo and using TME interrupt
1152
#if 1 // Here i tried to add a software fifo and using TME interrupt
1156
MIOS32_CAN1_ER_IRQHANDLER_FUNC
1153
MIOS32_CAN1_ER_IRQHANDLER_FUNC
1157
{
1154
{
1158
 
1155
 
1159
  if( CAN_GetITStatus(MIOS32_CAN1, CAN_IT_ERR) ) { // General Err interrupt is enabled
1156
  if( CAN_GetITStatus(MIOS32_CAN1, CAN_IT_ERR) ) { // General Err interrupt is enabled
1160
1157
1161
    if( (can_stat_report[0].bus_last_err.ALL & 7) != (MIOS32_CAN1->ESR & 7) ){
1158
    if( (can_stat_report[0].bus_last_err.ALL & 7) != (MIOS32_CAN1->ESR & 7) ){
1162
      //can_stat_err_t err = MIOS32_CAN1->ESR;
1159
      //mios32_can_stat_err_t err = MIOS32_CAN1->ESR;
1163
      can_stat_report[0].bus_last_err.ALL = MIOS32_CAN1->ESR;
1160
      can_stat_report[0].bus_last_err.ALL = MIOS32_CAN1->ESR;
1164
      //if(can_verbose)MIOS32_MIDI_SendDebugMessage("0x%0x", can_stat_report[0].bus_last_err.ALL & 7);
1161
      //if(can_verbose)MIOS32_MIDI_SendDebugMessage("0x%0x", can_stat_report[0].bus_last_err.ALL & 7);
1165
     
1162
     
1166
      if(can_stat_report[0].bus_last_err.ewgf){
1163
      if(can_stat_report[0].bus_last_err.ewgf){
1167
        //can_stat_report[0].bus_state = WARNING;
1164
        //can_stat_report[0].bus_state = WARNING;
1168
        CAN_ITConfig(MIOS32_CAN1, CAN_IT_EWG, DISABLE);
1165
        CAN_ITConfig(MIOS32_CAN1, CAN_IT_EWG, DISABLE);
1169
        //MIOS32_CAN_BusErrorCheck(0);
1166
        //MIOS32_CAN_BusErrorCheck(0);
1170
      }
1167
      }
1171
      if(can_stat_report[0].bus_last_err.epvf){
1168
      if(can_stat_report[0].bus_last_err.epvf){
1172
        // definively stop the interrupt
1169
        // definively stop the interrupt
1173
        //can_stat_report[0].bus_state = PASSIVE;
1170
        //can_stat_report[0].bus_state = PASSIVE;
1174
        //CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, DISABLE);
1171
        //CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, DISABLE);
1175
        CAN_ITConfig(MIOS32_CAN1, CAN_IT_EPV, DISABLE);
1172
        CAN_ITConfig(MIOS32_CAN1, CAN_IT_EPV, DISABLE);
1176
        //MIOS32_CAN_BusErrorCheck(0);
1173
        //MIOS32_CAN_BusErrorCheck(0);
1177
      }
1174
      }
1178
      if(can_stat_report[0].bus_last_err.boff){
1175
      if(can_stat_report[0].bus_last_err.boff){
1179
        // definively stop the interrupt
1176
        // definively stop the interrupt
1180
        //can_stat_report[0].bus_state = BUS_OFF;
1177
        //can_stat_report[0].bus_state = BUS_OFF;
1181
        CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, DISABLE);
1178
        CAN_ITConfig(MIOS32_CAN1, CAN_IT_ERR, DISABLE);
1182
        CAN_ITConfig(MIOS32_CAN1, CAN_IT_BOF, DISABLE);
1179
        CAN_ITConfig(MIOS32_CAN1, CAN_IT_BOF, DISABLE);
1183
        //MIOS32_CAN_BusErrorCheck(0);
1180
        //MIOS32_CAN_BusErrorCheck(0);
1184
      }
1181
      }
1185
    }
1182
    }
1186
    CAN_ClearITPendingBit(MIOS32_CAN1, CAN_IT_ERR);
1183
    CAN_ClearITPendingBit(MIOS32_CAN1, CAN_IT_ERR);
1187
   
1184
   
1188
  }
1185
  }
1189
}
1186
}
1190
#endif
1187
#endif
1191
1188
1192
#endif
1189
#endif
1193
1190
1194
1191
1195
/////////////////////////////////////////////////////////////////////////////
1192
/////////////////////////////////////////////////////////////////////////////
1196
// Interrupt handler for second CAN
1193
// Interrupt handler for second CAN
1197
/////////////////////////////////////////////////////////////////////////////
1194
/////////////////////////////////////////////////////////////////////////////
1198
#if NUM_SUPPORTED_CANS >= 2
1195
#if NUM_SUPPORTED_CANS >= 2
1199
#if 0
1196
#if 0
1200
MIOS32_CAN2_TX_IRQHANDLER_FUNC
1197
MIOS32_CAN2_TX_IRQHANDLER_FUNC
1201
{
1198
{
1202
  //if( MIOS32_CAN1->IER & CAN_IT_TME ) { // check if TME enabled
1199
  //if( MIOS32_CAN1->IER & CAN_IT_TME ) { // check if TME enabled
1203
  while(CAN_GetITStatus(MIOS32_CAN2, CAN_IT_TME)){
1200
  while(CAN_GetITStatus(MIOS32_CAN2, CAN_IT_TME)){
1204
    if(MIOS32_CAN_TxBufferUsed(1) >= 1){
1201
    if(MIOS32_CAN_TxBufferUsed(1) >= 1){
1205
      u8 mailbox = -1;
1202
      u8 mailbox = -1;
1206
      if( MIOS32_CAN2->TSR & CAN_TSR_TME0)mailbox = 0;
1203
      if( MIOS32_CAN2->TSR & CAN_TSR_TME0)mailbox = 0;
1207
      else if( MIOS32_CAN2->TSR & CAN_TSR_TME1)mailbox = 1;
1204
      else if( MIOS32_CAN2->TSR & CAN_TSR_TME1)mailbox = 1;
1208
      else if( MIOS32_CAN2->TSR & CAN_TSR_TME2)mailbox = 2;
1205
      else if( MIOS32_CAN2->TSR & CAN_TSR_TME2)mailbox = 2;
1209
      can_packet_t p;
1206
      mios32_can_packet_t p;
1210
      MIOS32_CAN_TxBufferGet(1, &p);
1207
      MIOS32_CAN_TxBufferGet(1, &p);
1211
      p.id.txrq = 1; //TX Req flag, this reset RQCPx
1208
      p.id.txrq = 1; //TX Req flag, this reset RQCPx
1212
      MIOS32_CAN2->sTxMailBox[mailbox].TDTR = p.ctrl.ALL;
1209
      MIOS32_CAN2->sTxMailBox[mailbox].TDTR = p.ctrl.ALL;
1213
      MIOS32_CAN2->sTxMailBox[mailbox].TDLR = p.data.data_l;
1210
      MIOS32_CAN2->sTxMailBox[mailbox].TDLR = p.data.data_l;
1214
      MIOS32_CAN2->sTxMailBox[mailbox].TDHR = p.data.data_h;
1211
      MIOS32_CAN2->sTxMailBox[mailbox].TDHR = p.data.data_h;
1215
      MIOS32_CAN2->sTxMailBox[mailbox].TIR = p.id.ALL;
1212
      MIOS32_CAN2->sTxMailBox[mailbox].TIR = p.id.ALL;
1216
    }else{
1213
    }else{
1217
      // nothing to send anymore we reset all RQCPx flags
1214
      // nothing to send anymore we reset all RQCPx flags
1218
      MIOS32_CAN2->TSR |= CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2;
1215
      MIOS32_CAN2->TSR |= CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2;
1219
      // disable TME interrupt
1216
      // disable TME interrupt
1220
      MIOS32_CAN2->IER &=~CAN_IT_TME;
1217
      MIOS32_CAN2->IER &=~CAN_IT_TME;
1221
    }
1218
    }
1222
  }
1219
  }
1223
  // I don't knoow why
1220
  // I don't knoow why
1224
  MIOS32_CAN2->TSR |= (CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2);
1221
  MIOS32_CAN2->TSR |= (CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2);
1225
}
1222
}
1226
#endif
1223
#endif
1227
MIOS32_CAN2_RX0_IRQHANDLER_FUNC
1224
MIOS32_CAN2_RX0_IRQHANDLER_FUNC
1228
{
1225
{
1229
  while(MIOS32_CAN2->RF0R & CAN_RF0R_FMP0){     // FMP0 contains number of messages
1226
  while(MIOS32_CAN2->RF0R & CAN_RF0R_FMP0){     // FMP0 contains number of messages
1230
    // get EID, MSG and DLC
1227
    // get EID, MSG and DLC
1231
    can_packet_t p;
1228
    mios32_can_packet_t p;
1232
    p.id.ALL = MIOS32_CAN2->sFIFOMailBox[0].RIR;
1229
    p.id.ALL = MIOS32_CAN2->sFIFOMailBox[0].RIR;
1233
    p.ctrl.ALL = MIOS32_CAN2->sFIFOMailBox[0].RDTR;
1230
    p.ctrl.ALL = MIOS32_CAN2->sFIFOMailBox[0].RDTR;
1234
    p.data.data_l = MIOS32_CAN2->sFIFOMailBox[0].RDLR;
1231
    p.data.data_l = MIOS32_CAN2->sFIFOMailBox[0].RDLR;
1235
    p.data.data_h = MIOS32_CAN2->sFIFOMailBox[0].RDHR;
1232
    p.data.data_h = MIOS32_CAN2->sFIFOMailBox[0].RDHR;
1236
   
1233
   
1237
    u8 i;
1234
    u8 i;
1238
    s32 status = 0;
1235
    s32 status = 0;
1239
1236
1240
    if(MIOS32_CAN_RxBufferPut(1, p) < 0 ){
1237
    if(MIOS32_CAN_RxBufferPut(1, p) < 0 ){
1241
      // here we could add some error handling
1238
      // here we could add some error handling
1242
    }
1239
    }
1243
    // release FIFO
1240
    // release FIFO
1244
    MIOS32_CAN2->RF0R |= CAN_RF0R_RFOM0; // set RFOM1 flag
1241
    MIOS32_CAN2->RF0R |= CAN_RF0R_RFOM0; // set RFOM1 flag
1245
  }
1242
  }
1246
}
1243
}
1247
1244
1248
MIOS32_CAN2_RX1_IRQHANDLER_FUNC
1245
MIOS32_CAN2_RX1_IRQHANDLER_FUNC
1249
{
1246
{
1250
  while(MIOS32_CAN2->RF1R & CAN_RF1R_FMP1 ){     // FMP1 contains number of messages
1247
  while(MIOS32_CAN2->RF1R & CAN_RF1R_FMP1 ){     // FMP1 contains number of messages
1251
    // get EID, MSG and DLC
1248
    // get EID, MSG and DLC
1252
    can_packet_t p;
1249
    mios32_can_packet_t p;
1253
    p.id.ALL = MIOS32_CAN2->sFIFOMailBox[1].RIR;
1250
    p.id.ALL = MIOS32_CAN2->sFIFOMailBox[1].RIR;
1254
    p.ctrl.ALL = MIOS32_CAN2->sFIFOMailBox[1].RDTR;
1251
    p.ctrl.ALL = MIOS32_CAN2->sFIFOMailBox[1].RDTR;
1255
    p.data.data_l = MIOS32_CAN2->sFIFOMailBox[1].RDLR;
1252
    p.data.data_l = MIOS32_CAN2->sFIFOMailBox[1].RDLR;
1256
    p.data.data_h = MIOS32_CAN2->sFIFOMailBox[1].RDHR;
1253
    p.data.data_h = MIOS32_CAN2->sFIFOMailBox[1].RDHR;
1257
   
1254
   
1258
    u8 i;
1255
    u8 i;
1259
    s32 status = 0;
1256
    s32 status = 0;
1260
    if((status = MIOS32_CAN_IsAssignedToMIDI(1))){
1257
    if((status = MIOS32_CAN_IsAssignedToMIDI(1))){
1261
      switch(p.id.event){
1258
      switch(p.id.event){
1262
        case 0x78 ... 0x7f:  // Realtime
1259
        case 0x78 ... 0x7f:  // Realtime
1263
          // no data, we forward (event +0x80)
1260
          // no data, we forward (event +0x80)
1264
          status = MIOS32_MIDI_SendByteToRxCallback(MCAN0+16, 0x80 + p.id.event);
1261
          status = MIOS32_MIDI_SendByteToRxCallback(MCAN0+16, 0x80 + p.id.event);
1265
          break;
1262
          break;
1266
        case 0x80 ... 0xe7:  // Channel Voice messages
1263
        case 0x80 ... 0xe7:  // Channel Voice messages
1267
          // Source and destination are transmited first. We just foward MIDI event bytes
1264
          // Source and destination are transmited first. We just foward MIDI event bytes
1268
          for( i=2; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0+16, p.data.bytes[i]);
1265
          for( i=2; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0+16, p.data.bytes[i]);
1269
          break;
1266
          break;
1270
        case 0xf0:  // SysEx messages
1267
        case 0xf0:  // SysEx messages
1271
          // Here we foward all data bytes
1268
          // Here we foward all data bytes
1272
          for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0+16, p.data.bytes[i]);
1269
          for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0+16, p.data.bytes[i]);
1273
          break;
1270
          break;
1274
        case 0xf1 ... 0xf7:  // System Common messages
1271
        case 0xf1 ... 0xf7:  // System Common messages
1275
          if(!p.ctrl.dlc)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0+16, p.id.event);
1272
          if(!p.ctrl.dlc)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0+16, p.id.event);
1276
          else for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0+16, p.data.bytes[i]);
1273
          else for( i=0; i< p.ctrl.dlc; i++)status = MIOS32_MIDI_SendByteToRxCallback(MCAN0+16, p.data.bytes[i]);
1277
          break;
1274
          break;
1278
        case 0xf8 ... 0xff:  // Node System Exclusive and Common messages
1275
        case 0xf8 ... 0xff:  // Node System Exclusive and Common messages
1279
          // toDo: foward to Node System Receive
1276
          // toDo: foward to Node System Receive
1280
          break;
1277
          break;
1281
        default:
1278
        default:
1282
          break;
1279
          break;
1283
      }
1280
      }
1284
    }
1281
    }
1285
    if( status == 0 ){
1282
    if( status == 0 ){
1286
      if(MIOS32_CAN_RxBufferPut(1, p) < 0 ){
1283
      if(MIOS32_CAN_RxBufferPut(1, p) < 0 ){
1287
        // here we could add some error handling
1284
        // here we could add some error handling
1288
      }
1285
      }
1289
    }
1286
    }
1290
    // release FIFO
1287
    // release FIFO
1291
    MIOS32_CAN2->RF1R |= CAN_RF1R_RFOM1; // set RFOM1 flag
1288
    MIOS32_CAN2->RF1R |= CAN_RF1R_RFOM1; // set RFOM1 flag
1292
  }
1289
  }
1293
}
1290
}
1294
1291
1295
#endif
1292
#endif
1296
1293
1297
1294
1298
/////////////////////////////////////////////////////////////////////////////
1295
/////////////////////////////////////////////////////////////////////////////
1299
//
1296
//
1300
/////////////////////////////////////////////////////////////////////////////
1297
/////////////////////////////////////////////////////////////////////////////
1301
s32 MIOS32_CAN_Hlp_ErrorVerbose(CAN_TypeDef* CANx)
1298
s32 MIOS32_CAN_Hlp_ErrorVerbose(CAN_TypeDef* CANx)
1302
{
1299
{
1303
#if NUM_SUPPORTED_CANS == 0
1300
#if NUM_SUPPORTED_CANS == 0
1304
  return -1; // no CAN available
1301
  return -1; // no CAN available
1305
#else
1302
#else
1306
 
1303
 
1307
 
1304
 
1308
  return 0; // no error
1305
  return 0; // no error
1309
#endif
1306
#endif
1310
}
1307
}
1311
1308
1312
1309
1313
/////////////////////////////////////////////////////////////////////////////
1310
/////////////////////////////////////////////////////////////////////////////
1314
//
1311
//
1315
/////////////////////////////////////////////////////////////////////////////
1312
/////////////////////////////////////////////////////////////////////////////
1316
s32 MIOS32_CAN_ReportLastErr(u8 can, can_stat_err_t* err)
1313
s32 MIOS32_CAN_ReportLastErr(u8 can, mios32_can_stat_err_t* err)
1317
{
1314
{
1318
#if NUM_SUPPORTED_CANS == 0
1315
#if NUM_SUPPORTED_CANS == 0
1319
  return -1; // no CAN available
1316
  return -1; // no CAN available
1320
#else
1317
#else
1321
  *err= can_stat_report[can].bus_last_err;
1318
  *err= can_stat_report[can].bus_last_err;
1322
  return 0; // no error
1319
  return 0; // no error
1323
#endif
1320
#endif
1324
}
1321
}
1325
1322
1326
/////////////////////////////////////////////////////////////////////////////
1323
/////////////////////////////////////////////////////////////////////////////
1327
//
1324
//
1328
/////////////////////////////////////////////////////////////////////////////
1325
/////////////////////////////////////////////////////////////////////////////
1329
s32 MIOS32_CAN_ReportGetCurr(u8 can, can_stat_report_t* report)
1326
s32 MIOS32_CAN_ReportGetCurr(u8 can, mios32_can_stat_report_t* report)
1330
{
1327
{
1331
#if NUM_SUPPORTED_CANS == 0
1328
#if NUM_SUPPORTED_CANS == 0
1332
  return -1; // no CAN available
1329
  return -1; // no CAN available
1333
#else
1330
#else
1334
  CAN_TypeDef* CANx = NULL;
1331
  CAN_TypeDef* CANx = NULL;
1335
  if(!can)CANx = MIOS32_CAN1;else CANx = MIOS32_CAN2;
1332
  if(!can)CANx = MIOS32_CAN1;else CANx = MIOS32_CAN2;
1336
 
1333
 
1337
  can_stat_report[can].bus_curr_err.ALL = CANx->ESR;
1334
  can_stat_report[can].bus_curr_err.ALL = CANx->ESR;
1338
  *report = can_stat_report[can];
1335
  *report = can_stat_report[can];
1339
 
1336
 
1340
  return 0; // no error
1337
  return 0; // no error
1341
#endif
1338
#endif
1342
}
1339
}
1343
1340
1344
/////////////////////////////////////////////////////////////////////////////
1341
/////////////////////////////////////////////////////////////////////////////
1345
//
1342
//
1346
/////////////////////////////////////////////////////////////////////////////
1343
/////////////////////////////////////////////////////////////////////////////
1347
s32 MIOS32_CAN_ReportReset(u8 can)
1344
s32 MIOS32_CAN_ReportReset(u8 can)
1348
{
1345
{
1349
#if NUM_SUPPORTED_CANS == 0
1346
#if NUM_SUPPORTED_CANS == 0
1350
  return -1; // no CAN available
1347
  return -1; // no CAN available
1351
#else
1348
#else
1352
1349
1353
  can_stat_report[can].tx_packets_ctr = 0;
1350
  can_stat_report[can].tx_packets_ctr = 0;
1354
  can_stat_report[can].rx_packets_err = 0;
1351
  can_stat_report[can].rx_packets_err = 0;
1355
  can_stat_report[can].rx_last_buff_err = 0;
1352
  can_stat_report[can].rx_last_buff_err = 0;
1356
  can_stat_report[can].rx_buff_err_ctr = 0;
1353
  can_stat_report[can].rx_buff_err_ctr = 0;
1357
  can_stat_report[can].rx_packets_ctr = 0;
1354
  can_stat_report[can].rx_packets_ctr = 0;
1358
 
1355
 
1359
  return 0; // no error
1356
  return 0; // no error
1360
#endif
1357
#endif
1361
}
1358
}
1362
1359
1363
1360
1364
#endif /* MIOS32_USE_CAN */
1361
#endif /* MIOS32_USE_CAN */
1365
 
1362