Commit 3e927a85 authored by Guilherme Sanches's avatar Guilherme Sanches

IOP_CAN example and Configure tool

An implementation of support for the OCCAN driver is being made on the
configure tool. At the same time there are changes on the iop_can xml
file to achive a configuration frame work.
parent 0b17e43b
......@@ -86,7 +86,6 @@ void eth_writer(iop_physical_device_t *pdev){
*
*/
void eth_reader(iop_physical_device_t *pdev){
/* get task physical device */
// iop_physical_device_t *pdev = (iop_physical_device_t *)arg;
......
......@@ -82,11 +82,19 @@ void pmk_channels_init(void) {
void pmk_partition_ports_init(pmk_partition_t *partition) {
printk(" :: pmk_partition_port_init is here!\n");
#ifdef PMK_DEBUG
printk(" :: The pmk_partition_ports_init is taking place.\n Number of ports for this parition: %d \n",
partition->ports.length);
#endif
int i;
for (i = 0; i < partition->ports.length; ++i) {
/* get port */
pmk_port_t *port = ((pmk_port_t **)partition->ports.elements)[i];
#ifdef PMK_DEBUG
printk(" :: The pmk_partition_ports_init channel info %s\n", port->channel->name);
#endif
/* link port to partition */
port->partition = partition;
......
......@@ -142,9 +142,9 @@ arch_configure = air_sparc.get_sparc_configuration
# IOP devices and definitions
iop = IOP(defines=[],
devices=['greth0', 'greth1', 'gr1553b0', 'grspw0', 'grspw1', 'grspw2', 'grspw3', 'grspw4', 'spwrtr0', 'cpsw0', 'mil0'],
drivers=['amba', 'greth', 'gr1553', 'cpsw', 'mil1553', 'grspw'],
alias=dict(eth0='greth0',eth1='greth1', spw0='grspw0', spw1='grspw1', spw2='grspw2', spw3='grspw3', spw4='grspw4', cpsw='cpsw0', spwrtr='spwrtr0', mil='mil0'),
devices=['greth0', 'greth1', 'gr1553b0', 'grspw0', 'grspw1', 'grspw2', 'grspw3', 'grspw4', 'spwrtr0', 'cpsw0', 'mil0', 'occan0', 'occan1'],
drivers=['amba', 'greth', 'gr1553', 'cpsw', 'mil1553', 'grspw', 'occan'],
alias=dict(eth0='greth0',eth1='greth1', spw0='grspw0', spw1='grspw1', spw2='grspw2', spw3='grspw3', spw4='grspw4', cpsw='cpsw0', spwrtr='spwrtr0', mil='mil0', can0 = 'occan0', can1 = 'occan1'),
arch=iop_arch)
# AIR application arch config
......
......@@ -3,13 +3,13 @@ SPW = 'SPW'
MIL = 'MIL'
ETH = 'ETH'
RTR = 'SPWRTR'
CAN = 'CANBUS'
CAN = 'CAN'
SUPPORTED_DEVICES = { SPW : ['GRSPW'],
MIL : ['GR1553B', 'BRM1553'],
ETH : ['GRETH'],
RTR : ['SPWRTR'],
CAN : ['CANBUS'] }
CAN : ['OCCAN'] }
IOP_PORT_TYPE = { 'SamplingPort' : 'IOP_SAMPLING_PORT',
'QueuingPort' : 'IOP_QUEUING_PORT' }
......@@ -77,7 +77,7 @@ CANHEADER_ID = 'CANId'
import utils.parser as parserutils
VALID_STR = [ str, lambda x : len(x) ]
VALID_NAME_TYPE = [ str, lambda x : 0 < len(x) < 31 ]
VALID_NAME_TlYPE = [ str, lambda x : 0 < len(x) < 31 ]
VALID_DEVICE_ID_TYPE = [ parserutils.str2int, lambda x : x >= 0 ]
VALID_PORT = [ parserutils.str2int, lambda x : x > 0]
VALID_IP = [ lambda x: str(x).strip().split('.'), lambda x: len(x) == 4 ]
......@@ -87,13 +87,14 @@ VALID_FLOAT_TYPE = [ parserutils.str2float, lambda x : x >= 0 ]
VALID_DECIMAL_TYPE = [ parserutils.str2int, lambda x : x >= 0 ]
VALID_BOOLEAN_TYPE = [ parserutils.str2bool, lambda x : isinstance(x, bool) ]
VALID_DIRECTION_TYPE = [ str, lambda x : x in [ REMOTE_PORT_SRC, REMOTE_PORT_DST] ]
VALID_ID = [ lambda x: x < 15]
VALID_ID = [ lambda x: x > 0]
LOGICAL_DEVICE_STR = 'Logical Device (Id: {0}, Name: {1})'
PHYSICAL_DEVICE_STR = 'Physical Device (Id: {0}, Device: {1})'
ETH_HEADER_STR = 'Ethernet Header (Mac: {0}, Ip: {1}, Port: {2})'
SPW_HEADER_STR = 'SpaceWire Header (Address: {0})'
CAN_HEADER_STR = 'Canbus Header (extended: {0}, Rtr: {1}, Sshot: {2}, Id: {3})'
CAN_HEADER_STR = 'Canbus Header (extended: {0}, Rtr: {1}, Sshot: {2}, CanId: {3})'
REMOTE_PORT_STR = 'Remote Port (Name: {0})'
ROUTE_STR = 'Route (Id: {0})'
ROUTE_PHYSICAL_STR = 'Physical Route (Id: {0})'
......@@ -274,17 +275,17 @@ class CANHeader(object):
self.extended = 0
self.rtr = 0
self.sshot = 0
self.id = 0
self.can_id = 0
def __eq__(self, other):
return isinstance(other, self.__class__) and \
self.id == other.id
self.can_id == other.can_id
def __ne__(self, other):
return not self.__eq__(other)
def __str__(self):
return CAN_HEADER_STR.format(self.extended, self.rtr, self.sshot, self.id)
return CAN_HEADER_STR.format(self.extended, self.rtr, self.sshot, self.can_id)
def __repr__(self):
return self.__str__()
......
......@@ -42,13 +42,23 @@ SPWRTR_IID = 'Idd'
SPWRTR_IDIV = 'Idiv'
SPWRTR_PRESCALER = 'Prescaler'
# Insert definition for CANBUS
CANBUS_ID = 'CanID'
CANBUS_SPEED = 'Speed'
CANBUS_INTERNAL_QUEUE = 'InternalQueue'
CANBUS_TXD = 'TXD'
CANBUS_RXD = 'RXD'
CANBUS_READS = 'Reads'
CANBUS_SINGLE_MODE = 'SingleMode'
CANBUS_CODE = 'Code'
CANBUS_MASK = 'Mask'
VALID_EN = [ parserutils.str2int, lambda x : 0 <= x <= 1 ]
VALID_XD = [ parserutils.str2int, lambda x : 0 <= x <= 128 ]
VALID_XD = [ parserutils.str2int, lambda x : 0 <= x <= 2048 ]
VALID_READS = [ parserutils.str2int, lambda x : 0 <= x <= 2048 ]
VALID_TIMER = [ parserutils.str2int, lambda x : -1 <= x <= 50 ]
VALID_MASK = [ parserutils.str2int, lambda x : 0 <= x <= 255 ]
VALID_BOOL = [ parserutils.str2bool, lambda x: type(x) is bool ]
VALID_NODE_ADDRESS = [ parserutils.str2int, lambda x : -1 <= x <= 31 ]
VALID_RXMAX = [ parserutils.str2int, lambda x : 4 <= x <= 1520 ]
......@@ -140,16 +150,32 @@ class SPWRTRSchSetup(object):
# CANBUS physical device
class CANBUSPhySetup(object):
class OCCANPhySetup(object):
def __init__(self):
self.can_id = 0
self.speed = 0
self.txd = 0
self.rxd = 0
self.internal_queue = 0
self.single_mode = False
self.code = ''
self.mask = ''
def details(self):
return 'CAN Physical Device Setup (Speed: {0} Code: {1} Mask: {3})'\
.format(self.speed, bin(self.code), bin(self.masks))
return 'CAN Physical Device Setup (CanID: {0} Speed: {1} TXD: {2} RXD: {3} InternalQueue: {4} SingleMode: {5} Code: {6} Mask: {7})'\
.format(bin(self.can_id), bin(self.speed), bin(self.txd), bin(self.rxd), bin(self.internal_queue), bin(int(self.single_mode)), bin(self.code), bin(self.masks))
# CANBUS Schedule device setup
class OCCANSchSetup(object):
def __init__(self):
self.device = None
self.reads = '' # number of reads per period
def details(self):
return 'CANBUS Schedule Setup (Reads - {0}'.format(self.reads)
## Greth physical device setup
# @param iop_parser IOP parser object
......@@ -288,12 +314,48 @@ def sch_spwrtr(iop_parser, xml, pdevice):
setup.device = pdevice
return setup
def phy_canbus(iop_parser, xml, pdevices):
## CANBUS physical device setup
# @param iop_parser IOP parser object
# @param xml XML setup node
# @param pdevice current physical device
def phy_occan(iop_parser, xml, pdevices):
# clear previous errors and warnings
iop_parser.logger.clear_errors(0)
# parse setup
setup = OCCANPhySetup()
setup.speed = xml.parse_attr(CANBUS_SPEED, VALID_READS, True, iop_parser.logger)
setup.txd_count = xml.parse_attr(CANBUS_TXD, VALID_XD, True, iop_parser.logger)
setup.rxd_count = xml.parse_attr(CANBUS_RXD, VALID_XD, True, iop_parser.logger)
setup.internal_queue = xml.parse_attr(CANBUS_INTERNAL_QUEUE, VALID_READS, True, iop_parser.logger)
setup.single_mode = xml.parse_attr(CANBUS_SINGLE_MODE, VALID_BOOL, True, iop_parser.logger)
setup.code = xml.parse_attr(CANBUS_CODE, VALID_MASK, True, iop_parser.logger)
setup.mask = xml.parse_attr(CANBUS_MASK, VALID_MASK, True, iop_parser.logger)
# sanity check
if iop_parser.logger.check_errors(): return False
pdevices.setup = setup
return True
## CANBUS schedule device setup
# @param iop_parser IOP parser object
# @param xml XML setup node
# @param pdevice current physical device
def sch_occan(iop_parser, xml, pdevice):
# clear previous errors and warnings
iop_parser.logger.clear_errors(0)
# parse setup
setup = CANBUSchSetup()
setup.reads = xml.parse_attr(CANBUS_READS, VALID_READS, True, iop_parser.logger)
# sanity check
if iop_parser.logger.check_errors(): return None
# parse complete
setup.device = pdevice
return setup
......@@ -329,6 +329,11 @@ class IOParser(object):
xml_header = xml.parse_tag(SPWHEADER, 1, 1, self.logger)
if self.logger.check_errors(): return None
return self.parse_spw_header(xml_header)
elif pdevice.type == CAN:
xml_header = xml.parse_tag(CANHEADER, 1, 1, self.logger)
if self.logger.check_errprs(): return None
return self.parse_can_header(xml_header)
# invalid header
return None
......@@ -367,6 +372,25 @@ class IOParser(object):
if self.logger.check_errors(): return False
return header
## Parse CANBUS Header
# @param self object pointer
# @param xml SpaceWire Header xml node
def parse_can_header(selfself, xml):
# clear previous errors and warning
self.logger.clear_errors(3)
# parse attributes
header = CanbusHeader()
header.extended = xml.parse_attr(CANHEADER_EXTENDED, VALID_BOOLEAN_TYPE, True, self.logger)
header.rtr = xml.parse_attr(CANHEADER_RTR, VALID_BOOLEAN_TYPE, True, self.logger)
header.sshot = xml.parse_attr(CANHEADER_SSHOT, VALID_BOOLEAN_TYPE, True, self.looger)
header.id = xml.parse_attr(CANHEADER_ID, VALID_ID, True, self.logger)
# sanity check
if self.logger.check_errors(): return False
return header
def parse_schedule(self, xml):
# clear previous errors and warnings
......
......@@ -27,7 +27,7 @@ ${EthHeader(route.header)}${',' if i < len(pdevice.routes) - 1 else ''}
${SpwHeader(route.header)}${',' if i < len(pdevice.routes) - 1 else ''}
% endfor
%elif pdevice.type =='CAN':
${CANHeader(route.header)}${',' if i < len(pdevice.routes) -1 else ''}
${CanHeader(route.header)}${',' if i < len(pdevice.routes) -1 else ''}
% endif
};
......
......@@ -14,6 +14,8 @@ static iop_header_t route_header[${len(device.routes)}] = ${'\\'}
${iop_template.EthHeader(route.header)}${',' if i < len(device.routes) - 1 else ''}
%elif route.device.type == 'SPW':
${iop_template.SpwHeader(route.header)}${',' if i < len(device.routes) - 1 else ''}
%elif route.device.type == 'CAN':
${iop_template.CanHeader(route.header)}${',' if i < len(device.routes) - 1 else ''}
%endif
% endfor
};
......
......@@ -19,10 +19,9 @@
</PhysicalDevices>-->
<PhysicalDevices>
<Device Id="0" Device="CAN0" Speed="250" TXD="32" RXD="32" InternalBuf="8">
<Filter SingleMode="true" Code="f:f:f:f" Mask="f:f:f:f" />
<Device Id="0" Device="CAN0" CanID = "2" Speed="250" TXD="32" RXD="32" InternalQueue="8" SingleMode="true" Code="f:f:f:f" Mask="f:f:f:f">
<LogicalRoute Id="1" LogicalDeviceId="1">
<CANHeader Extended="0" RTR="0" SSHOT="0" CANId="1"/>
<CanHeader Extended="0" RTR="0" SSHOT="0" CanID="1"/>
</LogicalRoute>
</Device>
</PhysicalDevices>
......@@ -30,7 +29,7 @@
<ModuleSchedules>
<Schedule ScheduleIdentifier="1">
<DevicesConfiguration>
<Device DeviceId="0" Device="ETH0" Reads="5"/>
<Device DeviceId="0" Device="CAN0" Reads="5"/>
</DevicesConfiguration>
<RoutesConfiguration>
<Route RouteId="1" Active="true"/>
......
......@@ -8,10 +8,6 @@
#include <can_support.h>
#include <iop.h>
/*
* Stub functions
*/
void can_copy_header(
iop_physical_device_t *iop_dev,
iop_wrapper_t *wrapper,
......@@ -19,6 +15,9 @@ void can_copy_header(
}
/* This function compares the ID on the wrapper
* to the ID of a given header. */
uint16_t can_compare_header(
iop_wrapper_t *wrapper,
iop_header_t *header){
......
......@@ -40,17 +40,15 @@ void can_write(iop_physical_device_t *pdev)
iop_wrapper_t *wrapper = obtain_wrapper(&error);
iop_chain_append(&pdev->sendqueue, &wrapper->node);
}
}
void can_reader(iop_physical_device_t *pdev)
{
/* Initialize error control chain (packets to be resent) */
iop_chain_control error;
iop_chain_initialize_empty(&error);
/* Get underlaying driver */
/* Get underlying driver */
iop_can_device_t *driver = (iop_can_device_t *) pdev->driver;
iop_debug(" :: can-read running!\n");
......
......@@ -15,13 +15,14 @@
//#include <rtems/libio.h>
//#include <string.h>
#include "../occan/include/iop_occan.h"
#include <bsp.h>
#include <leon.h>
#include <ambapp.h>
#include <iop_occan.h>
#include <can_support.h>
#include <occan_msg_queue.h>
#include "../occan/include/occan_msg_queue.h"
/* RTEMS -> ERRNO decoding table
......@@ -176,15 +177,17 @@ static void pelican_open(occan_priv *priv){
/* Set defaults */
priv->speed = OCCAN_SPEED_250K;
/* No need to set filter since that is done on the
* iop configuration files */
/* set acceptance filters to accept all messages */
priv->filter.code[0] = 0;
priv->filter.code[1] = 0;
priv->filter.code[2] = 0;
priv->filter.code[3] = 0;
priv->filter.mask[0] = 0xff;
priv->filter.mask[1] = 0xff;
priv->filter.mask[2] = 0xff;
priv->filter.mask[3] = 0xff;
// priv->filter.code[0] = 0;
// priv->filter.code[1] = 0;
// priv->filter.code[2] = 0;
// priv->filter.code[3] = 0;
// priv->filter.mask[0] = 0xff;
// priv->filter.mask[1] = 0xff;
// priv->filter.mask[2] = 0xff;
// priv->filter.mask[3] = 0xff;
/* Set clock divider to extended mode, clkdiv not connected
*/
......
#include <occan_msg_queue.h>
#include "../occan/include/occan_msg_queue.h"
CANMsg empty_msg(){
CANMsg msg ={
......
......@@ -10,7 +10,7 @@
#include <iop.h>
#include <rtems.h>
#include <iop_support.h>
#include <occan_msg_queue.h>
#include "../drivers/occan/include/occan_msg_queue.h"
typedef struct {
/* Generic device configuration */
......
......@@ -40,9 +40,9 @@ static iop_buffer_t *rx_iop_buffer[${device.setup.rxd_count}];
* message queue
*/
static CANMsg rx_msg_fifo[${}];
static CANMsg rx_msg_fifo[${device.setup.internal_queue}];
static CANMsg tx_msg_fifo[${}];
static CANMsg tx_msg_fifo[${device.setup.internal_queue}];
/**
* @brief RX and TX descriptor table
......@@ -55,9 +55,9 @@ static occan_priv occan_driver = \
{
.speed = ${device.setup.speed},
.filter = {
.single_mode = ${0 \
.single_mode = ${1 \
if device.setup.single_mode is True else \
1},
0},
.code = {${device.setup.code}},
.mask = {${device.setup.mask}},
},
......@@ -66,12 +66,12 @@ static occan_priv occan_driver = \
.iop_buffers_storage = iop_buffers_storage,
.rx_fifo = {
.max = ${device.setup.internal_buffer},
.max = ${device.setup.internal_queue},
.fifo = rx_msg_fifo,
},
.tx_fifo = {
.max = ${},
.max = ${device.setup.internal_queue},
.fifo = tx_msg_fifo,
}
}
......@@ -90,9 +90,6 @@ static iop_can_device_t device_configuration =${'\\'}
.close = occan_close,
},
.dev_name = ${},
.count = ${},
.flags = ${},
.bytes_moved = ${},
}
${iop_template.PhysicalDevice(iop_configuration, device, device_functions)}\
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment