Changeset ad203e58 in rtems
- Timestamp:
- 01/24/17 09:00:07 (6 years ago)
- Branches:
- 5, master
- Children:
- bc40b4d
- Parents:
- 229c4249
- git-author:
- Martin Aberg <maberg@…> (01/24/17 09:00:07)
- git-committer:
- Daniel Hellstrom <daniel@…> (05/14/17 10:31:57)
- Location:
- c/src/lib/libbsp/sparc/shared
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libbsp/sparc/shared/can/grcan.c
r229c4249 rad203e58 11 11 12 12 #include <bsp.h> 13 #include <rtems/libio.h>14 13 #include <stdlib.h> 15 14 #include <stdio.h> … … 23 22 #include <drvmgr/ambapp_bus.h> 24 23 #include <ambapp.h> 24 25 /* Maximum number of GRCAN devices supported by driver */ 26 #define GRCAN_COUNT_MAX 8 25 27 26 28 #define WRAP_AROUND_TX_MSGS 1 … … 138 140 }; 139 141 140 static rtems_device_driver grcan_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);141 static rtems_device_driver grcan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);142 static rtems_device_driver grcan_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);143 static rtems_device_driver grcan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);144 static rtems_device_driver grcan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);145 static rtems_device_driver grcan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);146 147 #define GRCAN_DRIVER_TABLE_ENTRY { grcan_initialize, grcan_open, grcan_close, grcan_read, grcan_write, grcan_ioctl }148 149 142 static void __inline__ grcan_hw_reset(struct grcan_regs *regs); 150 143 … … 210 203 #endif 211 204 212 213 static rtems_driver_address_table grcan_driver = GRCAN_DRIVER_TABLE_ENTRY; 214 static int grcan_driver_io_registered = 0; 215 static rtems_device_major_number grcan_driver_io_major = 0; 205 static int grcan_count = 0; 206 static struct grcan_priv *priv_tab[GRCAN_COUNT_MAX]; 216 207 217 208 /******************* Driver manager interface ***********************/ 218 209 219 210 /* Driver prototypes */ 220 int grcan_register_io(rtems_device_major_number *m);221 211 int grcan_device_init(struct grcan_priv *pDev); 222 212 … … 266 256 267 257 DBG("GRCAN[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name); 258 if (GRCAN_COUNT_MAX <= grcan_count) 259 return DRVMGR_ENORES; 268 260 priv = dev->priv = malloc(sizeof(struct grcan_priv)); 269 261 if ( !priv ) … … 281 273 struct grcan_priv *priv; 282 274 char prefix[32]; 283 rtems_status_code status;284 275 285 276 priv = dev->priv; 286 277 287 /* Do initialization */ 288 289 if ( grcan_driver_io_registered == 0) { 290 /* Register the I/O driver only once for all cores */ 291 if ( grcan_register_io(&grcan_driver_io_major) ) { 292 /* Failed to register I/O driver */ 293 dev->priv = NULL; 294 return DRVMGR_FAIL; 295 } 296 297 grcan_driver_io_registered = 1; 298 } 299 300 /* I/O system registered and initialized 278 /* 301 279 * Now we take care of device initialization. 302 280 */ … … 305 283 return DRVMGR_FAIL; 306 284 } 285 286 priv_tab[grcan_count] = priv; 287 grcan_count++; 307 288 308 289 /* Get Filesystem name prefix */ … … 320 301 } 321 302 322 /* Register Device */323 status = rtems_io_register_name(priv->devName, grcan_driver_io_major, dev->minor_drv);324 if (status != RTEMS_SUCCESSFUL) {325 return DRVMGR_FAIL;326 }327 328 303 return DRVMGR_OK; 329 }330 331 /******************* Driver Implementation ***********************/332 333 int grcan_register_io(rtems_device_major_number *m)334 {335 rtems_status_code r;336 337 if ((r = rtems_io_register_driver(0, &grcan_driver, m)) == RTEMS_SUCCESSFUL) {338 DBG("GRCAN driver successfully registered, major: %d\n", *m);339 } else {340 switch(r) {341 case RTEMS_TOO_MANY:342 printk("GRCAN rtems_io_register_driver failed: RTEMS_TOO_MANY\n");343 return -1;344 case RTEMS_INVALID_NUMBER:345 printk("GRCAN rtems_io_register_driver failed: RTEMS_INVALID_NUMBER\n");346 return -1;347 case RTEMS_RESOURCE_IN_USE:348 printk("GRCAN rtems_io_register_driver failed: RTEMS_RESOURCE_IN_USE\n");349 return -1;350 default:351 printk("GRCAN rtems_io_register_driver failed\n");352 return -1;353 }354 }355 return 0;356 304 } 357 305 … … 429 377 } 430 378 431 static rtems_device_driver grcan_ start(struct grcan_priv *pDev)379 static rtems_device_driver grcan_hw_start(struct grcan_priv *pDev) 432 380 { 433 381 /* … … 504 452 } 505 453 506 static void grcan_ stop(struct grcan_priv *pDev)454 static void grcan_hw_stop(struct grcan_priv *pDev) 507 455 { 508 456 FUNCDBG(); … … 1211 1159 } 1212 1160 1213 static rtems_device_driver grcan_initialize( 1214 rtems_device_major_number major, 1215 rtems_device_minor_number unused, 1216 void *arg 1217 ) 1218 { 1219 return RTEMS_SUCCESSFUL; 1220 } 1221 1222 static rtems_device_driver grcan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) 1161 int grcan_dev_count(void) 1162 { 1163 return grcan_count; 1164 } 1165 1166 void *grcan_open(int dev_no) 1223 1167 { 1224 1168 struct grcan_priv *pDev; 1225 rtems_device_driver ret; 1226 struct drvmgr_dev *dev; 1169 void *ret; 1227 1170 union drvmgr_key_value *value; 1228 1171 1229 1172 FUNCDBG(); 1230 1173 1231 if ( drvmgr_get_dev(&grcan_drv_info.general, minor, &dev)) {1232 DBG("Wrong minor %d\n", minor);1233 return RTEMS_INVALID_NAME;1234 } 1235 pDev = (struct grcan_priv *)dev->priv;1174 if (grcan_count == 0 || (grcan_count <= dev_no)) { 1175 return NULL; 1176 } 1177 1178 pDev = priv_tab[dev_no]; 1236 1179 1237 1180 /* Wait until we get semaphore */ 1238 1181 if (rtems_semaphore_obtain(pDev->dev_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) 1239 1182 != RTEMS_SUCCESSFUL) { 1240 return RTEMS_INTERNAL_ERROR;1183 return NULL; 1241 1184 } 1242 1185 1243 1186 /* is device busy/taken? */ 1244 1187 if ( pDev->open ) { 1245 ret =RTEMS_RESOURCE_IN_USE;1188 ret = NULL; 1246 1189 goto out; 1247 1190 } … … 1298 1241 1299 1242 if ( grcan_alloc_buffers(pDev,1,1) ) { 1300 ret =RTEMS_NO_MEMORY;1243 ret = NULL; 1301 1244 goto out; 1302 1245 } … … 1305 1248 memset(&pDev->stats,0,sizeof(struct grcan_stats)); 1306 1249 1307 ret = RTEMS_SUCCESSFUL;1250 ret = pDev; 1308 1251 out: 1309 1252 rtems_semaphore_release(pDev->dev_sem); … … 1311 1254 } 1312 1255 1313 static rtems_device_driver grcan_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) 1314 { 1315 struct grcan_priv *pDev; 1316 struct drvmgr_dev *dev; 1317 1318 FUNCDBG(); 1319 1320 if ( drvmgr_get_dev(&grcan_drv_info.general, minor, &dev) ) { 1321 return RTEMS_INVALID_NAME; 1322 } 1323 pDev = (struct grcan_priv *)dev->priv; 1256 int grcan_close(void *d) 1257 { 1258 struct grcan_priv *pDev = d; 1259 1260 FUNCDBG(); 1324 1261 1325 1262 if ( pDev->started ) 1326 grcan_ stop(pDev);1263 grcan_hw_stop(pDev); 1327 1264 1328 1265 grcan_hw_reset(pDev->regs); … … 1333 1270 pDev->open = 0; 1334 1271 1335 return RTEMS_SUCCESSFUL; 1336 } 1337 1338 static rtems_device_driver grcan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) 1339 { 1340 struct grcan_priv *pDev; 1341 struct drvmgr_dev *dev; 1342 rtems_libio_rw_args_t *rw_args; 1272 return 0; 1273 } 1274 1275 int grcan_read(void *d, CANMsg *msg, size_t ucount) 1276 { 1277 struct grcan_priv *pDev = d; 1343 1278 CANMsg *dest; 1344 1279 unsigned int count, left; … … 1347 1282 FUNCDBG(); 1348 1283 1349 if ( drvmgr_get_dev(&grcan_drv_info.general, minor, &dev) ) { 1350 return RTEMS_INVALID_NAME; 1351 } 1352 pDev = (struct grcan_priv *)dev->priv; 1353 1354 rw_args = (rtems_libio_rw_args_t *) arg; 1355 dest = (CANMsg *) rw_args->buffer; 1356 req_cnt = rw_args->count / sizeof(CANMsg); 1284 dest = msg; 1285 req_cnt = ucount; 1357 1286 1358 1287 if ( (!dest) || (req_cnt<1) ) 1359 return RTEMS_INVALID_NAME;1288 return -1; 1360 1289 1361 1290 if ( !pDev->started ) 1362 return RTEMS_RESOURCE_IN_USE;1291 return -2; 1363 1292 1364 1293 /*FUNCDBG("grcan_read [%i,%i]: buf: 0x%x len: %i\n",major, minor, (unsigned int)rw_args->buffer,rw_args->count);*/ … … 1368 1297 if ( count > 0 ) { 1369 1298 /* Successfully received messages (at least one) */ 1370 rw_args->bytes_moved = count * sizeof(CANMsg); 1371 return RTEMS_SUCCESSFUL; 1299 return count; 1372 1300 } 1373 1301 … … 1375 1303 if ( !pDev->rxblock ) { 1376 1304 /* non-blocking mode */ 1377 rw_args->bytes_moved = 0; 1378 return RTEMS_TIMEOUT; 1305 return -3; 1379 1306 } 1380 1307 } … … 1402 1329 * thread. 1403 1330 */ 1404 rw_args->bytes_moved = count * sizeof(CANMsg); 1405 return RTEMS_UNSATISFIED; 1331 return count; 1406 1332 } 1407 1333 … … 1414 1340 } 1415 1341 /* no need to unmask IRQ as IRQ Handler do that for us. */ 1416 rw_args->bytes_moved = count * sizeof(CANMsg); 1417 return RTEMS_SUCCESSFUL; 1418 } 1419 1420 static rtems_device_driver grcan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) 1421 { 1422 struct grcan_priv *pDev; 1423 struct drvmgr_dev *dev; 1424 rtems_libio_rw_args_t *rw_args; 1342 return count; 1343 } 1344 1345 int grcan_write(void *d, CANMsg *msg, size_t ucount) 1346 { 1347 struct grcan_priv *pDev = d; 1425 1348 CANMsg *source; 1426 1349 unsigned int count, left; … … 1429 1352 DBGC(DBG_TX,"\n"); 1430 1353 1431 if ( drvmgr_get_dev(&grcan_drv_info.general, minor, &dev) ) {1432 return RTEMS_INVALID_NAME;1433 }1434 pDev = (struct grcan_priv *)dev->priv;1435 1436 1354 if ( !pDev->started || pDev->config.silent || pDev->flushing ) 1437 return RTEMS_RESOURCE_IN_USE; 1438 1439 rw_args = (rtems_libio_rw_args_t *) arg; 1440 req_cnt = rw_args->count / sizeof(CANMsg); 1441 source = (CANMsg *) rw_args->buffer; 1355 return -2; 1356 1357 req_cnt = ucount; 1358 source = (CANMsg *) msg; 1442 1359 1443 1360 /* check proper length and buffer pointer */ 1444 1361 if (( req_cnt < 1) || (source == NULL) ){ 1445 return RTEMS_INVALID_NAME;1362 return -1; 1446 1363 } 1447 1364 … … 1450 1367 if ( count > 0 ) { 1451 1368 /* Successfully transmitted chars (at least one char) */ 1452 rw_args->bytes_moved = count * sizeof(CANMsg); 1453 return RTEMS_SUCCESSFUL; 1369 return count; 1454 1370 } 1455 1371 … … 1457 1373 if ( !pDev->txblock ) { 1458 1374 /* non-blocking mode */ 1459 rw_args->bytes_moved = 0; 1460 return RTEMS_TIMEOUT; 1375 return -3; 1461 1376 } 1462 1377 } … … 1489 1404 * with error status. 1490 1405 */ 1491 rw_args->bytes_moved = count * sizeof(CANMsg); 1492 return RTEMS_UNSATISFIED; 1406 return count; 1493 1407 } 1494 1408 … … 1510 1424 /* no need to unmask IRQ as IRQ Handler do that for us. */ 1511 1425 1512 rw_args->bytes_moved = count * sizeof(CANMsg); 1513 return RTEMS_SUCCESSFUL; 1514 } 1515 1516 static rtems_device_driver grcan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) 1517 { 1518 struct grcan_priv *pDev; 1519 struct drvmgr_dev *dev; 1520 rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *)arg; 1521 unsigned int *data = ioarg->buffer; 1426 return count; 1427 } 1428 1429 int grcan_start(void *d) 1430 { 1431 struct grcan_priv *pDev = d; 1432 rtems_device_driver status; 1433 1434 FUNCDBG(); 1435 1436 if ( pDev->started ) 1437 return -1; 1438 1439 if ( (status=grcan_hw_start(pDev)) != RTEMS_SUCCESSFUL ){ 1440 return -2; 1441 } 1442 1443 /* Read and write are now open... */ 1444 pDev->started = 1; 1445 1446 /* Register interrupt routine and enable IRQ at IRQ ctrl */ 1447 drvmgr_interrupt_register(pDev->dev, 0, "grcan", grcan_interrupt, pDev); 1448 1449 return 0; 1450 } 1451 1452 int grcan_stop(void *d) 1453 { 1454 struct grcan_priv *pDev = d; 1455 1456 FUNCDBG(); 1457 1458 if ( !pDev->started ) 1459 return -1; 1460 1461 /* Disable interrupts */ 1462 drvmgr_interrupt_unregister(pDev->dev, 0, grcan_interrupt, pDev); 1463 1464 grcan_hw_stop(pDev); 1465 pDev->started = 0; 1466 1467 return 0; 1468 } 1469 1470 int grcan_isstarted(void *d) 1471 { 1472 struct grcan_priv *pDev = d; 1473 1474 FUNCDBG(); 1475 1476 return pDev->started; 1477 } 1478 1479 int grcan_flush(void *d) 1480 { 1481 struct grcan_priv *pDev = d; 1482 int tmp; 1483 1484 FUNCDBG(); 1485 1486 if ( !pDev->started || pDev->flushing || pDev->config.silent ) 1487 return -1; 1488 1489 pDev->flushing = 1; 1490 tmp = grcan_tx_flush(pDev); 1491 pDev->flushing = 0; 1492 if ( tmp ) { 1493 /* The wait has been aborted, probably due to 1494 * the device driver has been closed by another 1495 * thread. 1496 */ 1497 return -1; 1498 } 1499 1500 return 0; 1501 } 1502 1503 int grcan_set_silent(void* d, int silent) 1504 { 1505 struct grcan_priv *pDev = d; 1506 1507 FUNCDBG(); 1508 1509 if ( pDev->started ) 1510 return -1; 1511 1512 pDev->config.silent = silent; 1513 pDev->config_changed = 1; 1514 1515 return 0; 1516 } 1517 1518 int grcan_set_abort(void* d, int abort) 1519 { 1520 struct grcan_priv *pDev = d; 1521 1522 FUNCDBG(); 1523 1524 if ( pDev->started ) 1525 return -1; 1526 1527 pDev->config.abort = abort; 1528 /* This Configuration parameter doesn't need HurriCANe reset 1529 * ==> no pDev->config_changed = 1; 1530 */ 1531 1532 return 0; 1533 } 1534 1535 int grcan_set_selection(void *d, const struct grcan_selection *selection) 1536 { 1537 struct grcan_priv *pDev = d; 1538 1539 FUNCDBG(); 1540 1541 if ( pDev->started ) 1542 return -1; 1543 1544 if ( !selection ) 1545 return -2; 1546 1547 pDev->config.selection = *selection; 1548 pDev->config_changed = 1; 1549 1550 return 0; 1551 } 1552 1553 int grcan_set_rxblock(void *d, int block) 1554 { 1555 struct grcan_priv *pDev = d; 1556 1557 FUNCDBG(); 1558 1559 pDev->rxblock = block; 1560 1561 return 0; 1562 } 1563 1564 int grcan_set_txblock(void *d, int block) 1565 { 1566 struct grcan_priv *pDev = d; 1567 1568 FUNCDBG(); 1569 1570 pDev->txblock = block; 1571 1572 return 0; 1573 } 1574 1575 int grcan_set_txcomplete(void *d, int complete) 1576 { 1577 struct grcan_priv *pDev = d; 1578 1579 FUNCDBG(); 1580 1581 pDev->txcomplete = complete; 1582 1583 return 0; 1584 } 1585 1586 int grcan_set_rxcomplete(void *d, int complete) 1587 { 1588 struct grcan_priv *pDev = d; 1589 1590 FUNCDBG(); 1591 1592 pDev->rxcomplete = complete; 1593 1594 return 0; 1595 } 1596 1597 int grcan_get_stats(void *d, struct grcan_stats *stats) 1598 { 1599 struct grcan_priv *pDev = d; 1600 1601 FUNCDBG(); 1602 1603 if ( !stats ) 1604 return -1; 1605 1606 *stats = pDev->stats; 1607 1608 return 0; 1609 } 1610 1611 int grcan_clr_stats(void *d) 1612 { 1613 struct grcan_priv *pDev = d; 1614 IRQ_GLOBAL_PREPARE(oldLevel); 1615 1616 FUNCDBG(); 1617 1618 IRQ_GLOBAL_DISABLE(oldLevel); 1619 memset(&pDev->stats,0,sizeof(struct grcan_stats)); 1620 IRQ_GLOBAL_ENABLE(oldLevel); 1621 1622 return 0; 1623 } 1624 1625 int grcan_set_speed(void *d, unsigned int speed) 1626 { 1627 struct grcan_priv *pDev = d; 1522 1628 struct grcan_timing timing; 1523 unsigned int speed; 1524 struct grcan_selection *selection; 1525 int tmp,ret; 1526 rtems_device_driver status; 1527 struct grcan_stats *stats; 1528 struct grcan_filter *filter; 1529 IRQ_GLOBAL_PREPARE(oldLevel); 1530 1531 FUNCDBG(); 1532 1533 if ( drvmgr_get_dev(&grcan_drv_info.general, minor, &dev) ) { 1534 return RTEMS_INVALID_NAME; 1535 } 1536 pDev = (struct grcan_priv *)dev->priv; 1537 1538 if (!ioarg) 1539 return RTEMS_INVALID_NAME; 1540 1541 ioarg->ioctl_return = 0; 1542 switch(ioarg->command) { 1543 case GRCAN_IOC_START: 1544 if ( pDev->started ) 1545 return RTEMS_RESOURCE_IN_USE; /* EBUSY */ 1546 1547 if ( (status=grcan_start(pDev)) != RTEMS_SUCCESSFUL ){ 1548 return status; 1549 } 1550 /* Read and write are now open... */ 1551 pDev->started = 1; 1552 1553 /* Register interrupt routine and enable IRQ at IRQ ctrl */ 1554 drvmgr_interrupt_register(dev, 0, "grcan", grcan_interrupt, pDev); 1555 1556 break; 1557 1558 case GRCAN_IOC_STOP: 1559 if ( !pDev->started ) 1560 return RTEMS_RESOURCE_IN_USE; 1561 1562 /* Disable interrupts */ 1563 drvmgr_interrupt_unregister(dev, 0, grcan_interrupt, pDev); 1564 1565 grcan_stop(pDev); 1566 pDev->started = 0; 1567 break; 1568 1569 case GRCAN_IOC_ISSTARTED: 1570 if ( !pDev->started ) 1571 return RTEMS_RESOURCE_IN_USE; 1572 break; 1573 1574 case GRCAN_IOC_FLUSH: 1575 if ( !pDev->started || pDev->flushing || pDev->config.silent ) 1576 return RTEMS_RESOURCE_IN_USE; 1577 1578 pDev->flushing = 1; 1579 tmp = grcan_tx_flush(pDev); 1580 pDev->flushing = 0; 1581 if ( tmp ) { 1582 /* The wait has been aborted, probably due to 1583 * the device driver has been closed by another 1584 * thread. 1585 */ 1586 return RTEMS_UNSATISFIED; 1587 } 1588 break; 1589 1590 #if 0 1591 /* Set physical link */ 1592 case GRCAN_IOC_SET_LINK: 1593 #ifdef REDUNDANT_CHANNELS 1594 if ( pDev->started ) 1595 return RTEMS_RESOURCE_IN_USE; /* EBUSY */ 1596 1597 /* switch HW channel */ 1598 pDev->channel = (unsigned int)ioargs->buffer; 1599 #else 1600 return RTEMS_NOT_IMPLEMENTED; 1601 #endif 1602 break; 1603 #endif 1604 1605 case GRCAN_IOC_SET_SILENT: 1606 if ( pDev->started ) 1607 return RTEMS_RESOURCE_IN_USE; 1608 pDev->config.silent = (int)ioarg->buffer; 1609 pDev->config_changed = 1; 1610 break; 1611 1612 case GRCAN_IOC_SET_ABORT: 1613 if ( pDev->started ) 1614 return RTEMS_RESOURCE_IN_USE; 1615 pDev->config.abort = (int)ioarg->buffer; 1616 /* This Configuration parameter doesn't need HurriCANe reset 1617 * ==> no pDev->config_changed = 1; 1618 */ 1619 break; 1620 1621 case GRCAN_IOC_SET_SELECTION: 1622 if ( pDev->started ) 1623 return RTEMS_RESOURCE_IN_USE; 1624 1625 selection = (struct grcan_selection *)ioarg->buffer; 1626 if ( !selection ) 1627 return RTEMS_INVALID_NAME; 1628 1629 pDev->config.selection = *selection; 1630 pDev->config_changed = 1; 1631 break; 1632 1633 case GRCAN_IOC_SET_RXBLOCK: 1634 pDev->rxblock = (int)ioarg->buffer; 1635 break; 1636 1637 case GRCAN_IOC_SET_TXBLOCK: 1638 pDev->txblock = (int)ioarg->buffer; 1639 break; 1640 1641 case GRCAN_IOC_SET_TXCOMPLETE: 1642 pDev->txcomplete = (int)ioarg->buffer; 1643 break; 1644 1645 case GRCAN_IOC_SET_RXCOMPLETE: 1646 pDev->rxcomplete = (int)ioarg->buffer; 1647 break; 1648 1649 case GRCAN_IOC_GET_STATS: 1650 stats = (struct grcan_stats *)ioarg->buffer; 1651 if ( !stats ) 1652 return RTEMS_INVALID_NAME; 1653 *stats = pDev->stats; 1654 break; 1655 1656 case GRCAN_IOC_CLR_STATS: 1657 IRQ_GLOBAL_DISABLE(oldLevel); 1658 memset(&pDev->stats,0,sizeof(struct grcan_stats)); 1659 IRQ_GLOBAL_ENABLE(oldLevel); 1660 break; 1661 1662 case GRCAN_IOC_SET_SPEED: 1663 /* cannot change speed during run mode */ 1664 if ( pDev->started ) 1665 return RTEMS_RESOURCE_IN_USE; /* EBUSY */ 1666 1667 /* get speed rate from argument */ 1668 speed = (unsigned int)ioarg->buffer; 1669 ret = grcan_calc_timing(speed, pDev->corefreq_hz, GRCAN_SAMPLING_POINT, &timing); 1670 if ( ret ) 1671 return RTEMS_INVALID_NAME; /* EINVAL */ 1672 1673 /* save timing/speed */ 1674 pDev->config.timing = timing; 1675 pDev->config_changed = 1; 1676 break; 1677 1678 case GRCAN_IOC_SET_BTRS: 1679 /* Set BTR registers manually 1680 * Read GRCAN/HurriCANe Manual. 1681 */ 1682 if ( pDev->started ) 1683 return RTEMS_RESOURCE_IN_USE; /* EBUSY */ 1684 if ( !ioarg->buffer ) 1685 return RTEMS_INVALID_NAME; 1686 1687 pDev->config.timing = *(struct grcan_timing *)ioarg->buffer; 1688 pDev->config_changed = 1; 1689 break; 1690 1691 case GRCAN_IOC_SET_AFILTER: 1692 filter = (struct grcan_filter *)ioarg->buffer; 1693 if ( !filter ){ 1694 /* Disable filtering - let all messages pass */ 1695 pDev->afilter.mask = 0x0; 1696 pDev->afilter.code = 0x0; 1697 }else{ 1698 /* Save filter */ 1699 pDev->afilter = *filter; 1700 } 1701 /* Set hardware acceptance filter */ 1702 grcan_hw_accept(pDev->regs,&pDev->afilter); 1703 break; 1704 1705 case GRCAN_IOC_SET_SFILTER: 1706 filter = (struct grcan_filter *)ioarg->buffer; 1707 if ( !filter ){ 1708 /* disable TX/RX SYNC filtering */ 1709 pDev->sfilter.mask = 0xffffffff; 1710 pDev->sfilter.mask = 0; 1711 1712 /* disable Sync interrupt */ 1713 pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~(GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ); 1714 }else{ 1715 /* Save filter */ 1716 pDev->sfilter = *filter; 1717 1718 /* Enable Sync interrupt */ 1719 pDev->regs->imr = READ_REG(&pDev->regs->imr) | (GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ); 1720 } 1721 /* Set Sync RX/TX filter */ 1722 grcan_hw_sync(pDev->regs,&pDev->sfilter); 1723 break; 1724 1725 case GRCAN_IOC_GET_STATUS: 1726 if ( !data ) 1727 return RTEMS_INVALID_NAME; 1728 /* Read out the statsu register from the GRCAN core */ 1729 data[0] = READ_REG(&pDev->regs->stat); 1730 break; 1731 1732 default: 1733 return RTEMS_NOT_DEFINED; 1734 } 1735 return RTEMS_SUCCESSFUL; 1629 int ret; 1630 1631 FUNCDBG(); 1632 1633 /* cannot change speed during run mode */ 1634 if ( pDev->started ) 1635 return -1; 1636 1637 /* get speed rate from argument */ 1638 ret = grcan_calc_timing(speed, pDev->corefreq_hz, GRCAN_SAMPLING_POINT, &timing); 1639 if ( ret ) 1640 return -2; 1641 1642 /* save timing/speed */ 1643 pDev->config.timing = timing; 1644 pDev->config_changed = 1; 1645 1646 return 0; 1647 } 1648 1649 int grcan_set_btrs(void *d, const struct grcan_timing *timing) 1650 { 1651 struct grcan_priv *pDev = d; 1652 1653 FUNCDBG(); 1654 1655 /* Set BTR registers manually 1656 * Read GRCAN/HurriCANe Manual. 1657 */ 1658 if ( pDev->started ) 1659 return -1; 1660 1661 if ( !timing ) 1662 return -2; 1663 1664 pDev->config.timing = *timing; 1665 pDev->config_changed = 1; 1666 1667 return 0; 1668 } 1669 1670 int grcan_set_afilter(void *d, const struct grcan_filter *filter) 1671 { 1672 struct grcan_priv *pDev = d; 1673 1674 FUNCDBG(); 1675 1676 if ( !filter ){ 1677 /* Disable filtering - let all messages pass */ 1678 pDev->afilter.mask = 0x0; 1679 pDev->afilter.code = 0x0; 1680 }else{ 1681 /* Save filter */ 1682 pDev->afilter = *filter; 1683 } 1684 /* Set hardware acceptance filter */ 1685 grcan_hw_accept(pDev->regs,&pDev->afilter); 1686 1687 return 0; 1688 } 1689 1690 int grcan_set_sfilter(void *d, const struct grcan_filter *filter) 1691 { 1692 struct grcan_priv *pDev = d; 1693 1694 FUNCDBG(); 1695 1696 if ( !filter ){ 1697 /* disable TX/RX SYNC filtering */ 1698 pDev->sfilter.mask = 0xffffffff; 1699 pDev->sfilter.mask = 0; 1700 1701 /* disable Sync interrupt */ 1702 pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~(GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ); 1703 }else{ 1704 /* Save filter */ 1705 pDev->sfilter = *filter; 1706 1707 /* Enable Sync interrupt */ 1708 pDev->regs->imr = READ_REG(&pDev->regs->imr) | (GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ); 1709 } 1710 /* Set Sync RX/TX filter */ 1711 grcan_hw_sync(pDev->regs,&pDev->sfilter); 1712 1713 return 0; 1714 } 1715 1716 int grcan_get_status(void* d, unsigned int *data) 1717 { 1718 struct grcan_priv *pDev = d; 1719 1720 FUNCDBG(); 1721 1722 if ( !data ) 1723 return -1; 1724 1725 /* Read out the statsu register from the GRCAN core */ 1726 data[0] = READ_REG(&pDev->regs->stat); 1727 1728 return 0; 1736 1729 } 1737 1730 … … 1764 1757 */ 1765 1758 pDev->started = 0; 1766 grcan_ stop(pDev); /* this mask all IRQ sources */1759 grcan_hw_stop(pDev); /* this mask all IRQ sources */ 1767 1760 status=0x1ffff; /* clear all interrupts */ 1768 1761 goto out; -
c/src/lib/libbsp/sparc/shared/include/grcan.h
r229c4249 rad203e58 157 157 #define GRCAN_STAT_TXERRCNT 0xff0000 158 158 159 /* IOCTL Commands controlling operational 159 /* 160 * Return number of GRCAN devices available to driver 161 */ 162 extern int grcan_dev_count(void); 163 164 /* 165 * Open a GRCAN device 166 * 167 * dev_no: Device number to open 168 * return: Device handle to use with all other grcan_ API functions. The 169 * function returns NULL if device can not be opened. 170 */ 171 extern void *grcan_open(int dev_no); 172 173 /* 174 * Close a GRCAN device 175 * 176 * return: This function always returns 0 (success) 177 */ 178 extern int grcan_close(void *d); 179 180 /* 181 * Receive CAN messages 182 * 183 * Multiple CAN messages can be received in one call. 184 * 185 * d: Device handle 186 * msg: Pointer to receive messages 187 * count: Number of CAN messages to receive 188 * 189 * return: 190 * >=0: Number of CAN messages received. This can be less than the 191 * count parameter. 192 * -1: count parameter less than size of struct grcan_msg or NULL msg. 193 * -2: Device not in started mode 194 * -3: Timeout in non-blocking mode 195 * -4: A blocking read was interrupted by a Bus-off error. Device has 196 * left started mode. 197 */ 198 extern int grcan_read( 199 void *d, 200 CANMsg *msg, 201 size_t count 202 ); 203 204 /* 205 * Transmit CAN messages 206 * 207 * Multiple CAN messages can be transmit in one call. 208 * 209 * d: Device handle 210 * msg: Pointer to messages to transmit 211 * count: Number of CAN messages to transmit 212 * 213 * return: 214 * >=0: Number of CAN messages transmitted. This can be less than the 215 * count parameter. 216 * -1: count parameter less than size of struct grcan_msg 217 * -2: Device not in started mode 218 * -3: Timeout in non-blocking mode 219 * -4: Bus-off error. Device has left started mode 220 */ 221 extern int grcan_write( 222 void *d, 223 CANMsg *msg, 224 size_t count 225 ); 226 227 /* The remaining functions return 0 on success and non-zero on failure. */ 228 229 /* Functions controlling operational 160 230 * mode 161 231 */ 162 #define GRCAN_IOC_START 1 /* Bring the link up after open or bus-off */ 163 #define GRCAN_IOC_STOP 2 /* stop to change baud rate/config or closing down */ 164 #define GRCAN_IOC_ISSTARTED 3 /* return RTEMS_SUCCESSFUL when started, othervise EBUSY */ 165 #define GRCAN_IOC_FLUSH 4 /* Waits until all TX messages has been sent */ 166 167 /* IOCTL Commands that require connection 232 /* Bring the link up after open or bus-off */ 233 extern int grcan_start(void *d); 234 /* stop to change baud rate/config or closing down */ 235 extern int grcan_stop(void *d); 236 /* return 1 when started, othervise 0 */ 237 extern int grcan_isstarted(void *d); 238 /* Wait until all TX messages have been sent */ 239 extern int grcan_flush(void *d); 240 241 /* Functions that require connection 168 242 * to be stopped 169 243 */ 170 #define GRCAN_IOC_SET_SILENT 16 /* enable silent mode read only state */ 171 #define GRCAN_IOC_SET_ABORT 17 /* enable/disable stopping link on AHB Error */ 172 #define GRCAN_IOC_SET_SELECTION 18 /* Set Enable0,Enable1,Selection */ 173 #define GRCAN_IOC_SET_SPEED 19 /* Set baudrate by using driver's baud rate timing calculation routines */ 174 #define GRCAN_IOC_SET_BTRS 20 /* Set baudrate by specifying the timing registers manually */ 175 176 /* IOCTL Commands can be called whenever */ 177 #define GRCAN_IOC_SET_RXBLOCK 32 /* Enable/disable Blocking on reception (until at least one message has been received) */ 178 #define GRCAN_IOC_SET_TXBLOCK 33 /* Enable/disable Blocking on transmission (until at least one message has been transmitted) */ 179 #define GRCAN_IOC_SET_TXCOMPLETE 34 /* Enable/disable Blocking until all requested messages has been sent */ 180 #define GRCAN_IOC_SET_RXCOMPLETE 35 /* Enable/disable Blocking until all requested has been received */ 181 #define GRCAN_IOC_GET_STATS 36 /* Get Statistics */ 182 #define GRCAN_IOC_CLR_STATS 37 /* Clear Statistics */ 183 #define GRCAN_IOC_SET_AFILTER 38 /* Set Acceptance filters, provide pointer to "struct grcan_filter" or NULL to disable filtering (let all messages pass) */ 184 #define GRCAN_IOC_SET_SFILTER 40 /* Set Sync Messages RX/TX filters, NULL disables the IRQ completely */ 185 #define GRCAN_IOC_GET_STATUS 41 /* Get status register of GRCAN core */ 186 244 /* enable silent mode read only state */ 245 extern int grcan_set_silent(void *d, int silent); 246 /* enable/disable stopping link on AHB Error */ 247 extern int grcan_set_abort(void *d, int abort); 248 /* Set Enable0,Enable1,Selection */ 249 extern int grcan_set_selection(void *d, const struct grcan_selection *selection); 250 /* Set baudrate by using driver's baud rate timing calculation routines */ 251 extern int grcan_set_speed(void *d, unsigned int hz); 252 /* Set baudrate by specifying the timing registers manually */ 253 extern int grcan_set_btrs(void *d, const struct grcan_timing *timing); 254 255 /* Functions can be called whenever */ 256 /* Enable/disable Blocking on reception (until at least one message has been received) */ 257 int grcan_set_rxblock(void* d, int block); 258 /* Enable/disable Blocking on transmission (until at least one message has been transmitted) */ 259 int grcan_set_txblock(void* d, int block); 260 /* Enable/disable Blocking until all requested messages has been sent */ 261 int grcan_set_txcomplete(void* d, int complete); 262 /* Enable/disable Blocking until all requested has been received */ 263 int grcan_set_rxcomplete(void* d, int complete); 264 /* Get statistics */ 265 extern int grcan_get_stats(void *d, struct grcan_stats *stats); 266 /* Clear statistics */ 267 extern int grcan_clr_stats(void *d); 268 /* Set Acceptance filters, provide pointer to "struct grcan_filter" or NULL to disable filtering (let all messages pass) */ 269 extern int grcan_set_afilter(void *d, const struct grcan_filter *filter); 270 /* Set Sync Messages RX/TX filters, NULL disables the IRQ completely */ 271 extern int grcan_set_sfilter(void *d, const struct grcan_filter *filter); 272 /* Get status register of GRCAN core */ 273 extern int grcan_get_status(void *d, unsigned int *status); 187 274 188 275 void grcan_register_drv(void);
Note: See TracChangeset
for help on using the changeset viewer.