Commit eb5d738e authored by claes's avatar claes

Support for SPI Slave added

parent 78b0ad08
/*
* Proview Open Source Process Control.
* Copyright (C) 2005-2011 SSAB Oxelosund AB.
*
* This file is part of Proview.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Proview. If not, see <http://www.gnu.org/licenses/>
*
* Linking Proview statically or dynamically with other modules is
* making a combined work based on Proview. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
* Proview give you permission to, from the build function in the
* Proview Configurator, combine Proview with modules generated by the
* Proview PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of Proview (the version used to produce the
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
/* rt_io_m_spi_slave.c -- I/O methods for SPI */
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include "pwr.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_otherioclasses.h"
#include "co_time.h"
#include "co_cdh.h"
#include "rt_io_base.h"
#include "rt_io_bus.h"
#include "rt_io_card_init.h"
#include "rt_io_card_close.h"
#include "rt_io_card_read.h"
#include "rt_io_card_read.h"
#include "rt_io_msg.h"
#include "rt_iom_msg.h"
typedef struct {
int fd;
int byte_ordering;
int float_representation;
int input_area_size;
int output_area_size;
char *input_area;
char *output_area;
int softlimit_logged;
int writeerror_logged;
int readerror_logged;
__u8 mode;
} io_sLocalSPI_Slave;
static pwr_tStatus IoCardInit( io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp)
{
io_sLocalSPI_Slave *local;
pwr_sClass_SPI_Slave *op = (pwr_sClass_SPI_Slave *)cp->op;
unsigned int input_area_offset = 0;
unsigned int input_area_chansize = 0;
unsigned int output_area_offset = 0;
unsigned int output_area_chansize = 0;
int sts;
local = (io_sLocalSPI_Slave *) calloc( 1, sizeof(io_sLocalSPI_Slave));
cp->Local = local;
op->Status = IOM__UDP_INIT;
local->fd = open( op->Device, O_RDWR);
if ( local->fd < 0) {
errh_Error( "SPI Slave, unable to open device %s, '%s'", op->Device, cp->Name);
op->Status = IOM__SPI_DEVICE;
return IO__INITFAIL;
}
sts = ioctl( local->fd, SPI_IOC_RD_MODE, &local->mode);
if ( sts < 0) {
errh_Error( "SPI Slave, init error errno %d, '%s'", errno, cp->Name);
op->Status = IOM__SPI_INIT;
return IO__INITFAIL;
}
local->byte_ordering = op->ByteOrdering;
io_bus_card_init( ctx, cp, &input_area_offset, &input_area_chansize,
&output_area_offset, &output_area_chansize, local->byte_ordering);
local->input_area_size = input_area_offset + input_area_chansize;
local->output_area_size = output_area_offset + output_area_chansize;
op->InputAreaSize = local->input_area_size;
op->OutputAreaSize = local->output_area_size;
if ( local->input_area_size > 0)
local->input_area = calloc( 1, local->input_area_size);
if ( local->output_area_size > 0)
local->output_area = calloc( 1, local->output_area_size);
errh_Info( "Init of SPI Slave '%s'", cp->Name);
op->Status = IOM__SPI_NORMAL;
return IO__SUCCESS;
}
static pwr_tStatus IoCardClose( io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp)
{
io_sLocalSPI_Slave *local = (io_sLocalSPI_Slave *)cp->Local;
close( local->fd);
if ( local->input_area)
free( local->input_area);
if ( local->output_area)
free( local->output_area);
if ( cp->Local)
free( cp->Local);
return IO__SUCCESS;
}
static pwr_tStatus IoCardRead( io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp)
{
io_sLocalSPI_Slave *local = (io_sLocalSPI_Slave *)cp->Local;
pwr_sClass_SPI_Slave *op = (pwr_sClass_SPI_Slave *)cp->op;
int sts;
sts = read( local->fd, local->input_area, local->input_area_size);
if ( sts < 0) {
op->ErrorCount++;
if ( !local->readerror_logged) {
errh_Error( "SPI read error errno %d, '%s'", errno, cp->Name);
local->readerror_logged = 1;
}
op->Status = IOM__SPI_READERROR;
}
else if ( sts < local->input_area_size) {
op->ErrorCount++;
if ( !local->readerror_logged) {
errh_Error( "SPI read buffer smaller than expected: %d, '%s'", sts, cp->Name);
local->readerror_logged = 1;
}
op->Status = IOM__SPI_READERROR;
}
else {
local->readerror_logged = 0;
op->Status = IOM__SPI_NORMAL;
io_bus_card_read( ctx, rp, cp, local->input_area, 0,
local->byte_ordering, pwr_eFloatRepEnum_FloatIEEE);
}
if ( op->ErrorCount == op->ErrorSoftLimit && !local->softlimit_logged) {
errh_Warning( "IO Card ErrorSoftLimit reached, '%s'", cp->Name);
local->softlimit_logged = 1;
}
if ( op->ErrorCount >= op->ErrorHardLimit) {
errh_Error( "IO Card ErrorHardLimit reached '%s', IO stopped", cp->Name);
ctx->Node->EmergBreakTrue = 1;
return IO__ERRDEVICE;
}
return IO__SUCCESS;
}
static pwr_tStatus IoCardWrite( io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp)
{
io_sLocalSPI_Slave *local = (io_sLocalSPI_Slave *)cp->Local;
pwr_sClass_SPI_Slave *op = (pwr_sClass_SPI_Slave *)cp->op;
int sts;
io_bus_card_write( ctx, cp, local->output_area,
local->byte_ordering, pwr_eFloatRepEnum_FloatIEEE);
sts = write( local->fd, local->output_area, local->output_area_size);
if ( sts < 0) {
op->ErrorCount++;
if ( !local->writeerror_logged) {
errh_Error( "SPI write error errno %d, '%s'", errno, cp->Name);
local->writeerror_logged = 1;
}
op->Status = IOM__SPI_WRITEERROR;
}
else if ( sts != local->output_area_size) {
op->ErrorCount++;
if ( !local->writeerror_logged) {
errh_Error( "SPI write buffer unexpected size %d, '%s'", sts, cp->Name);
local->writeerror_logged = 1;
}
op->Status = IOM__SPI_WRITEERROR;
}
else {
local->writeerror_logged = 0;
op->Status = IOM__SPI_NORMAL;
}
if ( op->ErrorCount == op->ErrorSoftLimit && !local->softlimit_logged) {
errh_Warning( "IO Card ErrorSoftLimit reached, '%s'", cp->Name);
local->softlimit_logged = 1;
}
if ( op->ErrorCount >= op->ErrorHardLimit) {
errh_Error( "IO Card ErrorHardLimit reached '%s', IO stopped", cp->Name);
ctx->Node->EmergBreakTrue = 1;
return IO__ERRDEVICE;
}
return IO__SUCCESS;
}
/* Every method should be registred here. */
pwr_dExport pwr_BindIoMethods(SPI_Slave) = {
pwr_BindIoMethod(IoCardInit),
pwr_BindIoMethod(IoCardClose),
pwr_BindIoMethod(IoCardRead),
pwr_BindIoMethod(IoCardWrite),
pwr_NullMethod
};
......@@ -18,4 +18,5 @@ Hilscher_cifX_Master
Hilscher_cifX_Module
USB_Joystick
UDP_IO
SPI_Slave
#endif
\ No newline at end of file
Volume OtherIO $ClassVolume 0.0.250.10
Body SysBody 01-JAN-1970 01:00:00.00
Attr NextOix = "_X247"
Attr NextCix = "_X26"
Attr NextOix = "_X256"
Attr NextCix = "_X27"
Attr NextTix[0] = "_X10"
EndBody
Object Type $TypeHier 1 15-NOV-2007 14:35:37.90
......@@ -4586,5 +4586,199 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndBody
EndObject
EndObject
!/**
! @Version 1.0
! @Group IO
! @Summary Card object for SPI Slave.
! Card object for SPI Slave.
!
! The object is configured as a child to a generic Rack object.
!
! @b See also
! @classlink BaseIORack basecomponent_baseiorack.html
!*/
Object SPI_Slave $ClassDef 26 10-JUL-2011 07:17:19.39
Body SysBody 10-JUL-2011 07:17:08.04
Attr Editor = 0
Attr Method = 0
Attr Flags = 51280
EndBody
Object RtBody $ObjBodyDef 1 10-JUL-2011 07:19:29.31
Body SysBody 10-JUL-2011 07:17:25.64
Attr StructName = "SPI_Slave"
Attr NextAix = "_X56"
EndBody
!/**
! Optional description.
!*/
Object Description $Attribute 30 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "Description"
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! @Summary Process that handles the module. Plc(1), rt_io_comm(2) or application process(4).
! Process that handles the module.
!
! 1: The module is read by the plc process, and is handled by a specific
! thread in the plc, which is specified in the ThreadObject attribute.
! 2: The module is read by the rt_io_comm process.
! 4: The module is handled by an application program.
!*/
Object Process $Attribute 31 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "Process"
Attr TypeRef = "pwrb:Type-IoProcessMask"
EndBody
EndObject
!/**
! @Summary Plc thread that handles the card.
! The PlcThread object of the plc thread that handles the card.
! The card is read with the scantime of the thread.
!*/
Object ThreadObject $Attribute 32 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "ThreadObject"
Attr TypeRef = "pwrs:Type-$Objid"
EndBody
EndObject
!/**
! Device for the SPI slave.
!*/
Object Device $Attribute 33 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "Device"
Attr TypeRef = "pwrs:Type-$String32"
EndBody
EndObject
!/**
! Byte ordering for slave.
!*/
Object ByteOrdering $Attribute 38 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "ByteOrdering"
Attr TypeRef = "pwrb:Type-ByteOrderingEnum"
EndBody
EndObject
!/**
! Float representation for slave. Not yet implemented.
!*/
Object FloatRepresentation $Attribute 39 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "FloatRepresentation"
Attr Flags = 1040
Attr TypeRef = "pwrb:Type-FloatRepEnum"
EndBody
EndObject
!/**
! Status for slave communication.
!*/
Object Status $Attribute 43 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "Status"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$Status"
EndBody
EndObject
!/**
! Error counter.
!*/
Object ErrorCount $Attribute 51 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "ErrorCount"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Value of the error counter, when a message is sent to the console log.
!*/
Object ErrorSoftLimit $Attribute 52 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "ErrorSoftLimit"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Value of the error counter, when all IO handling is aborted.
!*/
Object ErrorHardLimit $Attribute 53 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "ErrorHardLimit"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Size of input area, calculated at runtime initialization.
!*/
Object InputAreaSize $Attribute 54 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "InputAreaSize"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Size of output area, calculated at runtime initialization.
!*/
Object OutputAreaSize $Attribute 55 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr PgmName = "OutputAreaSize"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
EndObject
Object IoMethods $RtMethod 248 10-JUL-2011 07:17:08.04
Object IoCardInit $Method 249 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:59.13
Attr MethodName = "SPI_Slave-IoCardInit"
EndBody
EndObject
Object IoCardClose $Method 250 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:18:10.72
Attr MethodName = "SPI_Slave-IoCardClose"
EndBody
EndObject
Object IoCardRead $Method 251 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:18:25.24
Attr MethodName = "SPI_Slave-IoCardRead"
EndBody
EndObject
Object IoCardWrite $Method 252 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:18:33.39
Attr MethodName = "SPI_Slave-IoCardWrite"
EndBody
EndObject
EndObject
Object ConfiguratorPoson $Menu 253 10-JUL-2011 07:17:08.04
Object Pointed $Menu 254 10-JUL-2011 07:17:08.04
Object Connect $MenuButton 255 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr ButtonName = "Connect PlcThread"
Attr MethodName = "$Objid-Connect"
Attr MethodArguments[0] = "ThreadObject"
Attr MethodArguments[1] = "PlcThread"
Attr FilterName = "$Objid-IsOkConnect"
Attr FilterArguments[0] = "ThreadObject"
Attr FilterArguments[1] = "PlcThread"
EndBody
EndObject
EndObject
EndObject
Object PostCreate $DbCallBack 256 10-JUL-2011 07:17:08.04
Body SysBody 10-JUL-2011 07:17:08.04
Attr MethodName = "BaseIOCard-PostCreate"
EndBody
EndObject
Object Template SPI_Slave 2154528768 01-JAN-1970 01:00:00.00
Body RtBody 10-JUL-2011 07:20:38.66
Attr Process = 1
Attr ErrorSoftLimit = 50
Attr ErrorHardLimit = 100
EndBody
EndObject
EndObject
EndObject
EndVolume
......@@ -44,6 +44,11 @@ udp_down <UDP link is down> /error
udp_socket <UDP create socket error> /error
udp_bind <UDP bind socket error> /error
udp_remote <UDP unknown remote host> /error
spi_device <SPI no such device> /error
spi_init <SPI initialization error> /error
spi_normal <SPI normal operating state> /info
spi_readerror <SPI read error> /error
spi_writeerror <SPI write error> /error
.end
......@@ -329,6 +329,10 @@ palette NavigatorPalette
class OneWire_AiDevice
class Maxim_DS18B20
}
menu SPI
{
class SPI_Slave
}
menu USB
{
class USB_Agent
......
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