1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
# -*- coding: utf-8 -*-
#
# AWL simulator - status word
# Copyright 2012 Michael Buesch <m@bues.ch>
#
# Licensed under the terms of the GNU General Public License version 2.
#
from util import *
class S7StatusWord(object):
"STEP 7 status word"
name2nr = {
"/ER" : 0,
"VKE" : 1,
"STA" : 2,
"OR" : 3,
"OS" : 4,
"OV" : 5,
"A0" : 6,
"A1" : 7,
"BIE" : 8,
}
nr2name = { }
for name, type in name2nr.items():
nr2name[type] = name
NR_BITS = 9
@classmethod
def getBitnrByName(cls, name):
try:
return cls.name2nr[name]
except KeyError as e:
raise AwlSimError("Invalid status word bit "
"name: " + str(name))
def __init__(self):
self.reset()
def getByBitNumber(self, bitNumber):
try:
return (self.NER, self.VKE, self.STA, self.OR,
self.OS, self.OV, self.A0, self.A1,
self.BIE)[bitNumber]
except IndexError as e:
raise AwlSimError("Status word bit fetch '%d' "
"out of range" % bitNumber)
def getWord(self):
return self.NER | (self.VKE << 1) | (self.STA << 2) |\
(self.OR << 3) | (self.OS << 4) | (self.OV << 5) |\
(self.A0 << 6) | (self.A1 << 7) | (self.BIE << 8)
def reset(self):
self.NER = 0 # /ER => Erstabfrage
self.VKE = 0 # VKE => Verknuepfungsergebnis
self.STA = 0 # STA => Statusbit
self.OR = 0 # OR => Oderbit
self.OS = 0 # OS => Ueberlauf speichernd
self.OV = 0 # OV => Ueberlauf
self.A0 = 0 # A0 => Ergebnisanzeige 0
self.A1 = 0 # A1 => Ergebnisanzeige 1
self.BIE = 0 # BIE => Binaerergebnis
def copy(self):
new = S7StatusWord()
new.NER = self.NER
new.VKE = self.VKE
new.STA = self.STA
new.OR = self.OR
new.OS = self.OS
new.OV = self.OV
new.A0 = self.A0
new.A1 = self.A1
new.BIE = self.BIE
return new
def setForFloatingPoint(self, pyFloat):
dword = pyFloatToDWord(pyFloat)
dwordNoSign, s = dword & 0x7FFFFFFF, self
if isDenormalPyFloat(pyFloat) or\
(dwordNoSign < 0x00800000 and dwordNoSign != 0):
# denorm
s.A1, s.A0, s.OV, s.OS = 0, 0, 1, 1
elif dwordNoSign == 0:
# zero
s.A1, s.A0, s.OV = 0, 0, 0
elif dwordNoSign >= 0x7F800000:
if dwordNoSign == 0x7F800000:
# inf
if dword & 0x80000000:
s.A1, s.A0, s.OV, s.OS = 0, 1, 1, 1
else:
s.A1, s.A0, s.OV, s.OS = 1, 0, 1, 1
else:
# nan
s.A1, s.A0, s.OV, s.OS = 1, 1, 1, 1
elif dword & 0x80000000:
# norm neg
s.A1, s.A0, s.OV = 0, 1, 0
else:
# norm pos
s.A1, s.A0, s.OV = 1, 0, 0
def __repr__(self):
ret = []
for i in range(self.NR_BITS - 1, -1, -1):
ret.append("%s=%d" % (
self.nr2name[i],
self.getByBitNumber(i)
))
return ', '.join(ret)
|