po_hi_driver_rasta_serial.c 10.7 KB
Newer Older
1
2
3
4
5
/*
 * This is a part of PolyORB-HI-C distribution, a minimal
 * middleware written for generated code from AADL models.
 * You should use it with the Ocarina toolsuite.
 *
6
7
8
9
10
11
12
13
14
15
16
 * Copyright (C) 2010-2011, European Space Agency
 */

/*! \file po_hi_driver_rasta_serial.c
 *  \brief Driver that interface PolyORB-HI-C and the serial interface of RASTA boards using the RTEMS 4.8 driver.
 *
 *  This driver works ONLY with the RTEMS 4.8 version that was available on GAISLER website
 *  on April 2010. This version is available at:
 *    - http://download.tuxfamily.org/taste/tools/rtems-4.8-gaisler.tgz
 *  However, please note that it is no longer supported by GAISLER and contains
 *  other bugs (such as the serial driver for the LEON that does not work).
17
18
 */

19
20
#include <deployment.h>
/* Generated code header */
21

22
#ifdef __PO_HI_NEED_DRIVER_SERIAL_RASTA
23

24
#include <activity.h>
25
26
#include <marshallers.h>

27
#include <po_hi_debug.h>
28
29
30
#include <po_hi_transport.h>
#include <po_hi_gqueue.h>
#include <po_hi_messages.h>
31
#include <po_hi_returns.h>
32
#include <po_hi_utils.h>
33
#include <drivers/po_hi_rtems_utils.h>
34
#include <drivers/po_hi_driver_rasta_serial.h>
35
#include <drivers/po_hi_driver_rasta_common.h>
36

37
38
#include <drivers/po_hi_driver_serial_common.h>

39
40
41
42
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
julien.delange's avatar
julien.delange committed
43
#include <termios.h>
44
45
/* POSIX-style files */

46
47
48
49
50
#include <pci.h>
#include <rasta.h>
#include <apbuart_rasta.h>
/* Rasta includes from GAISLER drivers */

51
#include <drivers/configuration/serial.h>
52

53
54
55
int po_hi_c_driver_rasta_serial_fd_read[__PO_HI_NB_DEVICES];
int po_hi_c_driver_rasta_serial_fd_write[__PO_HI_NB_DEVICES];

56

57
58
59
60
61
62
63
64
65
66
/*!
 * \fn void __po_hi_c_driver_serial_rasta_poller (const __po_hi_device_id dev_id)
 * \brief Polling function for the RASTA.
 *
 * This function is the poller for the serial interface of the RASTA board.
 * It is supposed to be called by the underlying AADL code at a given period/rate.
 * The argument dev_id is the device_id handled by the device driver. By using
 * such an argument, we can use this function on a single node that uses several
 * driver instances (several serial interfaces connected to different serial buses).
 */
67

68
void __po_hi_c_driver_serial_rasta_poller (const __po_hi_device_id dev_id)
69
{
70
71
72
73
74
   int                  n;
   int                  ts;
   uint8_t*             ptr;
   __po_hi_request_t    __po_hi_c_driver_rasta_serial_request;
   __po_hi_msg_t        __po_hi_c_driver_rasta_serial_msg;
75

julien.delange's avatar
julien.delange committed
76
   ts = __PO_HI_MESSAGES_MAX_SIZE;
77
78
   ptr = &(__po_hi_c_driver_rasta_serial_msg.content[0]);
   __po_hi_msg_reallocate (&__po_hi_c_driver_rasta_serial_msg);
julien.delange's avatar
julien.delange committed
79
   while (ts > 0)
80
   {
81
      __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Poller waits for incoming message (%d bytes are required)!\n", ts);
82
      n = read (po_hi_c_driver_rasta_serial_fd_read[dev_id], ptr, ts); 
julien.delange's avatar
julien.delange committed
83

84
      __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] read() %d returns %d!\n", po_hi_c_driver_rasta_serial_fd_read[dev_id], n);
julien.delange's avatar
julien.delange committed
85
86
      if (n == -1)
      {
87
         __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Cannot read on socket !\n");
julien.delange's avatar
julien.delange committed
88
89
         return;
      }
90
91
92
93
94
      else
      {
         ptr += n;
         ts -= n;
      }
95
96
   }

97
   __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Message received by poller: 0x");
98
   for (ts = 0 ; ts < __PO_HI_MESSAGES_MAX_SIZE ; ts++)
99
   {
100
      __PO_HI_DEBUG_DEBUG ("%x", __po_hi_c_driver_rasta_serial_msg.content[ts]);
101
   }
102
   __PO_HI_DEBUG_DEBUG ("\n");
103

104
   __po_hi_c_driver_rasta_serial_msg.length = __PO_HI_MESSAGES_MAX_SIZE;
105

106
107
   __po_hi_unmarshall_request (&__po_hi_c_driver_rasta_serial_request,
                               &__po_hi_c_driver_rasta_serial_msg);
108

109
   __po_hi_main_deliver (&__po_hi_c_driver_rasta_serial_request);
110
111
}

112
113
114
extern amba_confarea_type* __po_hi_driver_rasta_common_get_bus ();
void __po_hi_rasta_interrrupt_register(void *handler, int irqno, void *arg);

115
116
117
118
119
120
121
122
123
124
/*!
 * \fn void __po_hi_c_driver_serial_rasta_init (__po_hi_device_id id)
 * \brief Initialization function for the RASTA serial driver.
 *
 * This function  is used to initialize the device driver connected to the
 * serial interface to a RASTA board. It uses the configuration properties
 * from its associated configuration parameters (using the 
 * __po_hi_get_device_configuration function).
 */

125
void __po_hi_c_driver_serial_rasta_init (__po_hi_device_id id)
126
{
127
128
   __po_hi_c_serial_conf_t* serialconf;

129
   __po_hi_c_driver_rasta_common_init ();
130

131
   serialconf = (__po_hi_c_serial_conf_t*)__po_hi_get_device_configuration (id);
132

133
   if (serialconf == NULL)
134
135
136
137
138
   {
      __PO_HI_DEBUG_INFO ("[RASTA SERIAL] Cannot get the name of the device !\n");
      return;
   }

139
140
141
142
    /* provide the spacewire driver with AMBA Plug&Play
     * info so that it can find the GRSPW cores.
     */

143
   __PO_HI_DEBUG_INFO ("[RASTA SERIAL] Initialization starts !\n");
144

145
146
   po_hi_c_driver_rasta_serial_fd_write[id] = 
   po_hi_c_driver_rasta_serial_fd_read[id] = open (serialconf->devname, O_RDWR);
147
148
149
   /*
   po_hi_c_driver_rasta_serial_fd_write = open (serialconf->devname, O_WRONLY);
   */
150

151
   if (po_hi_c_driver_rasta_serial_fd_read[id] < 0)
152
   {
153
      __PO_HI_DEBUG_CRITICAL ("[RASTA SERIAL] Error while opening device %s for reading\n", serialconf->devname);
154
   }
155
   if (po_hi_c_driver_rasta_serial_fd_write[id] < 0)
156
157
158
159
   {
      __PO_HI_DEBUG_CRITICAL ("[RASTA SERIAL] Error while opening device %s for writing\n", serialconf->devname);
   }

160
161
   __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Device opened for read (%s), fd=%d\n", serialconf->devname , po_hi_c_driver_rasta_serial_fd_read[id]);
   __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Device opened for write (%s), fd=%d\n", serialconf->devname , po_hi_c_driver_rasta_serial_fd_write[id]);
162

163
164
165
   switch (__po_hi_c_driver_serial_common_get_speed (id))
   {
      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_19200:
166
167
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_BAUDRATE, 19200);
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_write[id], APBUART_SET_BAUDRATE, 19200);
168
169
170
         break;

      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_38400:
171
172
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_BAUDRATE, 38400);
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_write[id], APBUART_SET_BAUDRATE, 38400);
173
174
175
         break;

      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_57600:
176
177
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_BAUDRATE, 57600);
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_write[id], APBUART_SET_BAUDRATE, 57600);
178
179
180
         break;

      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_115200:
181
182
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_BAUDRATE, 115200);
         __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_write[id], APBUART_SET_BAUDRATE, 115200);
183
184
185
186
187
188
189
         break;

      case __PO_HI_DRIVER_SERIAL_COMMON_SPEED_UNKNWON:
         __PO_HI_DEBUG_INFO ("[RASTA SERIAL] Unknwon speed for the serial line\n");
         break;
   }

190
   /*
191
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd, APBUART_SET_BLOCKING, APBUART_BLK_RX | APBUART_BLK_TX | APBUART_BLK_FLUSH);
192
193
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd, APBUART_SET_BLOCKING, APBUART_BLK_FLUSH | APBUART_BLK_RX);
  */
194
195
196
197
198
199
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_BLOCKING, APBUART_BLK_FLUSH | APBUART_BLK_TX );
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_TXFIFO_LEN, 256);  /* Transmitt buffer 64 chars */
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_RXFIFO_LEN, 256); /* Receive buffer 256 chars */
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_SET_ASCII_MODE, 0); /* Make \n go \n\r or \r\n */
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_CLR_STATS, 0);
  __PO_HI_DRIVERS_RTEMS_UTILS_IOCTL(po_hi_c_driver_rasta_serial_fd_read[id], APBUART_START, 0);
julien.delange's avatar
julien.delange committed
200

201

202
  if (tcflush (po_hi_c_driver_rasta_serial_fd_read[id], TCIOFLUSH) != 0)
203
204
205
206
  {
     __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Error when trying to flush read part\n");
  }

207
  if (tcflush (po_hi_c_driver_rasta_serial_fd_write[id], TCIOFLUSH) != 0)
julien.delange's avatar
julien.delange committed
208
  {
209
     __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Error when trying to flush write part\n");
julien.delange's avatar
julien.delange committed
210
  }
211
212

  __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Initialization complete !\n");
213
214
}

215
216
217
218
219
220
221
222
223
224
225
226
227
228
/*!
 * \fn int __po_hi_c_driver_serial_rasta_sender (const __po_hi_task_id task_id, const __po_hi_port_t port)
 * \brief Function related to the RASTA serial driver - sender function.
 *
 * This function implements the sender function to send bytes through the serial line using
 * the RASTA device. 
 * There are the description of the arguments used by the function:
 *   - task_id: task that actually sends the data (emitter/producer task)
 *   - port   : (global) port that contains the data
 * It returns the following possible values :
 *   - __PO_HI_UNAVAILABLE : the driver does not handle the device connected to argument port.
 *   - __PO_HI_SUCCESS     : either no value was available to be sent or the function
 *                           send the message successfully over the network.
 */
229
230
int __po_hi_c_driver_serial_rasta_sender (const __po_hi_task_id task_id, const __po_hi_port_t port)
{
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
   int                     n;
   int                     ts;
   __po_hi_local_port_t    local_port;
   __po_hi_request_t*      request;
   __po_hi_msg_t           msg;
   __po_hi_port_t          destination_port;
   __po_hi_device_id       dev_id;

   dev_id = __po_hi_get_device_from_port (port);

   if (dev_id == invalid_device_id)
   {
      __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Invalid device id for sending\n");
      return __PO_HI_UNAVAILABLE;
   }
246
247
248
249
250

   local_port = __po_hi_get_local_port_from_global_port (port);

   request = __po_hi_gqueue_get_most_recent_value (task_id, local_port);

251
252
253
254
255
256
   if (request->port == -1)
   {
      __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Send output task %d, port %d (local_port=%d): no value to send\n", task_id, port, local_port);
      return __PO_HI_SUCCESS;
   }

257
258
259
260
261
   destination_port     = __po_hi_gqueue_get_destination (task_id, local_port, 0);

   __po_hi_msg_reallocate (&msg);

   request->port = destination_port;
262
   __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Destination port= %d\n", destination_port);
263
264
265

   __po_hi_marshall_request (request, &msg);

266
   __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] Message sent: 0x");
267
268
   for (ts = 0 ; ts < __PO_HI_MESSAGES_MAX_SIZE ; ts++)
   {
269
      __PO_HI_DEBUG_DEBUG ("%x", msg.content[ts]);
270
   }
271

272
   __PO_HI_DEBUG_DEBUG ("\n");
273

274
   n = write (po_hi_c_driver_rasta_serial_fd_write[dev_id], &msg, __PO_HI_MESSAGES_MAX_SIZE);
275

276
   __PO_HI_DEBUG_DEBUG ("[RASTA SERIAL] write() returns %d\n", n);
277
278
279

   request->port = __PO_HI_GQUEUE_INVALID_PORT;

280
281
282
   return 1;
}

283
284
#endif