diff --git a/FHEM/00_CUL.pm b/FHEM/00_CUL.pm deleted file mode 100644 index a42fcb4..0000000 --- a/FHEM/00_CUL.pm +++ /dev/null @@ -1,1738 +0,0 @@ -############################################## -# $Id: 00_CUL.pm 14119 2017-04-27 11:41:18Z rudolfkoenig $ -package main; - -use strict; -use warnings; -use Time::HiRes qw(gettimeofday); - -sub CUL_Attr(@); -sub CUL_Clear($); -sub CUL_HandleCurRequest($$); -sub CUL_HandleWriteQueue($); -sub CUL_Parse($$$$@); -sub CUL_Read($); -sub CUL_ReadAnswer($$$$); -sub CUL_Ready($); -sub CUL_Write($$$); - -sub CUL_SimpleWrite(@); -sub CUL_WriteInit($); - -my %gets = ( # Name, Data to send to the CUL, Regexp for the answer - "ccconf" => 1, - "version" => ["V", '^V .*'], - "raw" => ["", '.*'], - "uptime" => ["t", '^[0-9A-F]{8}[\r\n]*$' ], - "fhtbuf" => ["T03", '^[0-9A-F]+[\r\n]*$' ], - "cmds" => ["?", '.*Use one of( .)*[\r\n]*$' ], - "credit10ms" => [ "X", '^.. *\d*[\r\n]*$' ], -); - -my %sets = ( - "reopen" => "", - "hmPairForSec" => "HomeMatic", - "hmPairSerial" => "HomeMatic", - "raw" => "", - "freq" => "SlowRF", - "bWidth" => "SlowRF", - "rAmpl" => "SlowRF", - "sens" => "SlowRF", - "led" => "", - "patable" => "", - "ITClock" => "SlowRF" -); - -my @ampllist = (24, 27, 30, 33, 36, 38, 40, 42); # rAmpl(dB) - -my $sccMods = "STACKABLE_CC:TSSTACKED:STACKABLE"; -my $culNameRe = "^(CUL|TSCUL)\$"; - -my $clientsSlowRF = ":FS20:FHT.*:KS300:USF1000:BS:HMS: ". - ":CUL_EM:CUL_WS:CUL_FHTTK:CUL_HOERMANN: ". - ":ESA2000:CUL_IR:CUL_TX:Revolt:IT:UNIRoll:SOMFY: ". - ":$sccMods:CUL_RFR::CUL_TCM97001:CUL_REDIRECT:"; -my $clientsHomeMatic = ":CUL_HM:HMS:CUL_IR:$sccMods:"; -my $clientsMAX = ":CUL_MAX:HMS:CUL_IR:$sccMods:"; -my $clientsWMBus = ":WMBUS:HMS:CUL_IR:$sccMods:"; -my $clientsKOPP_FC = ":KOPP_FC:HMS:CUL_IR:$sccMods:"; -my $clientsBetty = ":Betty:HMS:CUL_IR:$sccMods:"; - -my %matchListSlowRF = ( - "1:USF1000" => "^81..(04|0c)..0101a001a5ceaa00....", - "2:BS" => "^81..(04|0c)..0101a001a5cf", - "3:FS20" => "^81..(04|0c)..0101a001", - "4:FHT" => "^81..(04|09|0d)..(0909a001|83098301|c409c401)..", - "5:KS300" => "^810d04..4027a001", - "6:CUL_WS" => "^K.....", - "7:CUL_EM" => "^E0.................\$", - "8:HMS" => "^810e04....(1|5|9).a001", - "9:CUL_FHTTK" => "^T[A-F0-9]{8}", - "A:CUL_RFR" => "^[0-9A-F]{4}U.", - "B:CUL_HOERMANN"=> "^R..........", - "C:ESA2000" => "^S................................\$", - "D:CUL_IR" => "^I............", - "E:CUL_TX" => "^TX[A-F0-9]{10}", - "F:Revolt" => "^r......................\$", - "G:IT" => "^i......", - "H:STACKABLE_CC"=>"^\\*", - "I:UNIRoll" => "^[0-9A-F]{5}(B|D|E)", - "J:SOMFY" => "^Y[r|t|s]:?[A-F0-9]+", - "K:CUL_TCM97001" => "^s[A-F0-9]+", - "L:CUL_REDIRECT" => "^o+", - "M:TSSTACKED"=>"^\\*", - "N:STACKABLE"=>"^\\*", -); - -my %matchListHomeMatic = ( - "1:CUL_HM" => "^A....................", - "8:HMS" => "^810e04....(1|5|9).a001", # CUNO OneWire HMS Emulation - "D:CUL_IR" => "^I............", - "H:STACKABLE_CC"=>"^\\*", - "M:TSSTACKED"=>"^\\*", - "N:STACKABLE"=>"^\\*", -); - -my %matchListMAX = ( - "1:CUL_MAX" => "^Z........................", - "8:HMS" => "^810e04....(1|5|9).a001", # CUNO OneWire HMS Emulation - "D:CUL_IR" => "^I............", - "H:STACKABLE_CC"=>"^\\*", - "M:TSSTACKED"=>"^\\*", - "N:STACKABLE"=>"^\\*", -); - -my %matchListWMBus = ( - "J:WMBUS" => "^b.*", - "8:HMS" => "^810e04....(1|5|9).a001", # CUNO OneWire HMS Emulation - "D:CUL_IR" => "^I............", - "H:STACKABLE_CC"=>"^\\*", - "M:TSSTACKED"=>"^\\*", - "N:STACKABLE"=>"^\\*", -); - -my %matchListKOPP_FC = ( - "1:Kopp_FC" => "^kr..................", - "8:HMS" => "^810e04....(1|5|9).a001", # CUNO OneWire HMS Emulation - "D:CUL_IR" => "^I............", - "H:STACKABLE_CC"=>"^\\*", - "M:TSSTACKED"=>"^\\*", - "N:STACKABLE"=>"^\\*", -); - -my %matchListBetty = ( - "8:HMS" => "^810e04....(1|5|9).a001", # CUNO OneWire HMS Emulation - "D:CUL_IR" => "^I............", - "H:STACKABLE_CC"=>"^\\*", - "M:TSSTACKED"=>"^\\*", - "N:STACKABLE"=>"^\\*", - "O:Betty" => "^y.*", -); - -sub -CUL_Initialize($) -{ - my ($hash) = @_; - - require "$attr{global}{modpath}/FHEM/DevIo.pm"; - -# Provider - $hash->{ReadFn} = "CUL_Read"; - $hash->{WriteFn} = "CUL_Write"; - $hash->{ReadyFn} = "CUL_Ready"; - -# Normal devices - $hash->{DefFn} = "CUL_Define"; - $hash->{FingerprintFn} = "CUL_FingerprintFn"; - $hash->{UndefFn} = "CUL_Undef"; - $hash->{GetFn} = "CUL_Get"; - $hash->{SetFn} = "CUL_Set"; - $hash->{AttrFn} = "CUL_Attr"; - no warnings 'qw'; - my @attrList = qw( - addvaltrigger - connectCommand - do_not_notify:1,0 - dummy:1,0 - hmId longids - hmProtocolEvents:0_off,1_dump,2_dumpFull,3_dumpTrigger - model:CUL,CUN,CUNO,SCC,nanoCUL - rfmode:SlowRF,HomeMatic,MAX,WMBus_T,WMBus_S,KOPP_FC,Betty - sendpool - showtime:1,0 - ); - use warnings 'qw'; - $hash->{AttrList} = join(" ", @attrList)." ".$readingFnAttributes; - $hash->{ShutdownFn} = "CUL_Shutdown"; -} - -sub -CUL_FingerprintFn($$) -{ - my ($name, $msg) = @_; - - # Store only the "relevant" part, as the CUL won't compute the checksum - $msg = substr($msg, 8) if($msg =~ m/^81/ && length($msg) > 8); - - return ($name, $msg); -} - -##################################### -sub -CUL_Define($$) -{ - my ($hash, $def) = @_; - my @a = split("[ \t][ \t]*", $def); - - if(@a < 4 || @a > 5) { - my $msg = "wrong syntax: define CUL {none | devicename[\@baudrate] ". - "| devicename\@directio | hostname:port} "; - Log3 undef, 2, $msg; - return $msg; - } - - DevIo_CloseDev($hash); - - my $name = $a[0]; - my $dev = $a[2]; - return "FHTID must be H1H2, with H1 and H2 hex and both smaller than 64" - if(uc($a[3]) !~ m/^[0-6][0-9A-F][0-6][0-9A-F]$/); - - if(uc($a[3]) =~ m/^([0-6][0-9A-F])/ && $1 ne "00") { - my $x = $1; - foreach my $d (keys %defs) { - next if($d eq $name); - if($defs{$d}{TYPE} =~ m/$culNameRe/) { - if(uc($defs{$d}{FHTID}) =~ m/^$x/) { - my $m = "$name: Cannot define multiple CULs with identical ". - "first two digits ($x)"; - Log3 $name, 1, $m; - return $m; - } - } - } - } - $hash->{FHTID} = uc($a[3]); - $hash->{initString} = "X21"; - $hash->{CMDS} = ""; - $hash->{Clients} = $clientsSlowRF; - $hash->{MatchList} = \%matchListSlowRF; - - if($dev eq "none") { - Log3 $name, 1, "$name device is none, commands will be echoed only"; - $attr{$name}{dummy} = 1; - return undef; - } - - $hash->{DeviceName} = $dev; - my $ret = DevIo_OpenDev($hash, 0, "CUL_DoInit"); - return $ret; -} - -##################################### -sub -CUL_Undef($$) -{ - my ($hash, $arg) = @_; - my $name = $hash->{NAME}; - - foreach my $d (sort keys %defs) { - if(defined($defs{$d}) && - defined($defs{$d}{IODev}) && - $defs{$d}{IODev} == $hash) - { - my $lev = ($reread_active ? 4 : 2); - Log3 $name, $lev, "deleting port for $d"; - delete $defs{$d}{IODev}; - } - } - - CUL_SimpleWrite($hash, "X00"); # Switch reception off, it may hang up the CUL - DevIo_CloseDev($hash); - return undef; -} - -##################################### -sub -CUL_Shutdown($) -{ - my ($hash) = @_; - CUL_SimpleWrite($hash, "X00"); - return undef; -} - -sub -CUL_RemoveHMPair($) -{ - my $hash = shift; - delete($hash->{hmPair}); -} - -##################################### -sub -CUL_Reopen($) -{ - my ($hash) = @_; - DevIo_CloseDev($hash); - DevIo_OpenDev($hash, 1, "CUL_DoInit"); -} - -##################################### -sub -CUL_Set($@) -{ - my ($hash, @a) = @_; - - return "\"set CUL\" needs at least one parameter" if(@a < 2); - return "Unknown argument $a[1], choose one of " . join(" ", sort keys %sets) - if(!defined($sets{$a[1]})); - - my $name = shift @a; - my $type = shift @a; - my $arg = join("", @a); - - return "This command is not valid in the current rfmode" - if($sets{$type} && $sets{$type} ne AttrVal($name, "rfmode", "SlowRF")); - - if($type eq "reopen") { - CUL_Reopen($hash); - - } elsif($type eq "hmPairForSec") { - return "Usage: set $name hmPairForSec " - if(!$arg || $arg !~ m/^\d+$/); - $hash->{hmPair} = 1; - InternalTimer(gettimeofday()+$arg, "CUL_RemoveHMPair", $hash, 1); - - } elsif($type eq "hmPairSerial") { - return "Usage: set $name hmPairSerial <10-character-serialnumber>" - if(!$arg || $arg !~ m/^.{10}$/); - - my $id = AttrVal($hash->{NAME}, "hmId", "F1".$hash->{FHTID}); - $hash->{HM_CMDNR} = $hash->{HM_CMDNR} ? ($hash->{HM_CMDNR}+1)%256 : 1; - CUL_SimpleWrite($hash, sprintf("As15%02x8401%s000000010A%s", - $hash->{HM_CMDNR}, $id, unpack('H*', $arg))); - $hash->{hmPairSerial} = $arg; - - } elsif($type eq "freq") { - - my $f = $arg/26*65536; - - my $f2 = sprintf("%02x", $f / 65536); - my $f1 = sprintf("%02x", int($f % 65536) / 256); - my $f0 = sprintf("%02x", $f % 256); - $arg = sprintf("%.3f", (hex($f2)*65536+hex($f1)*256+hex($f0))/65536*26); - Log3 $name, 3, "Setting FREQ2..0 (0D,0E,0F) to $f2 $f1 $f0 = $arg MHz"; - CUL_SimpleWrite($hash, "W0F$f2"); - CUL_SimpleWrite($hash, "W10$f1"); - CUL_SimpleWrite($hash, "W11$f0"); - CUL_WriteInit($hash); # Will reprogram the CC1101 - - } elsif($type eq "bWidth") { - my ($err, $ob); - if(!IsDummy($hash->{NAME})) { - CUL_SimpleWrite($hash, "C10"); - ($err, $ob) = CUL_ReadAnswer($hash, $type, 0, "^C10 = .*"); - return "Can't get old MDMCFG4 value" if($err || $ob !~ m,/ (.*)\r,); - $ob = $1 & 0x0f; - } - - my ($bits, $bw) = (0,0); - for (my $e = 0; $e < 4; $e++) { - for (my $m = 0; $m < 4; $m++) { - $bits = ($e<<6)+($m<<4); - $bw = int(26000/(8 * (4+$m) * (1 << $e))); # KHz - goto GOTBW if($arg >= $bw); - } - } - -GOTBW: - $ob = sprintf("%02x", $ob+$bits); - Log3 $name, 3, "Setting MDMCFG4 (10) to $ob = $bw KHz"; - CUL_SimpleWrite($hash, "W12$ob"); - CUL_WriteInit($hash); - - } elsif($type eq "rAmpl") { - return "a numerical value between 24 and 42 is expected" - if($arg !~ m/^\d+$/ || $arg < 24 || $arg > 42); - my ($v, $w); - for($v = 0; $v < @ampllist; $v++) { - last if($ampllist[$v] > $arg); - } - $v = sprintf("%02d", $v-1); - $w = $ampllist[$v]; - Log3 $name, 3, "Setting AGCCTRL2 (1B) to $v / $w dB"; - CUL_SimpleWrite($hash, "W1D$v"); - CUL_WriteInit($hash); - - } elsif($type eq "sens") { - return "a numerical value between 4 and 16 is expected" - if($arg !~ m/^\d+$/ || $arg < 4 || $arg > 16); - my $w = int($arg/4)*4; - my $v = sprintf("9%d",$arg/4-1); - Log3 $name, 3, "Setting AGCCTRL0 (1D) to $v / $w dB"; - CUL_SimpleWrite($hash, "W1F$v"); - CUL_WriteInit($hash); - - } elsif( $type eq "ITClock" ) { - my $clock = shift @a; - $clock=250 if($clock eq ""); - return "argument $arg is not numeric" if($clock !~ /^\d+$/); - Log3 $name, 3, "set $name $type $clock"; - $arg="ic$clock"; - CUL_SimpleWrite($hash, $arg); - - } else { - return "Expecting a 0-padded hex number" - if((length($arg)&1) == 1 && $type ne "raw"); - Log3 $name, 3, "set $name $type $arg"; - $arg = "l$arg" if($type eq "led"); - $arg = "x$arg" if($type eq "patable"); - CUL_SimpleWrite($hash, $arg); - - } - return undef; -} - -##################################### -sub -CUL_Get($@) -{ - my ($hash, @a) = @_; - my $type = $hash->{TYPE}; - - return "\"get $type\" needs at least one parameter" if(@a < 2); - if(!defined($gets{$a[1]})) { - my @cList = map { $_ =~ m/^(file|raw)$/ ? $_ : "$_:noArg" } sort keys %gets; - return "Unknown argument $a[1], choose one of " . join(" ", @cList); - } - - my $arg = ($a[2] ? $a[2] : ""); - my ($msg, $err); - my $name = $a[0]; - - return "No $a[1] for dummies" if(IsDummy($name)); - - if($a[1] eq "ccconf") { - - my %r = ( "0D"=>1,"0E"=>1,"0F"=>1,"10"=>1,"1B"=>1,"1D"=>1 ); - foreach my $a (sort keys %r) { - CUL_SimpleWrite($hash, "C$a"); - ($err, $msg) = CUL_ReadAnswer($hash, "C$a", 0, "^C.* = .*"); - return $err if($err); - my @answ = split(" ", $msg); - $r{$a} = $answ[4]; - } - $msg = sprintf("freq:%.3fMHz bWidth:%dKHz rAmpl:%ddB sens:%ddB", - 26*(($r{"0D"}*256+$r{"0E"})*256+$r{"0F"})/65536, #Freq - 26000/(8 * (4+(($r{"10"}>>4)&3)) * (1 << (($r{"10"}>>6)&3))), #Bw - $ampllist[$r{"1B"}&7], - 4+4*($r{"1D"}&3) #Sens - ); - - } else { - - CUL_SimpleWrite($hash, $gets{$a[1]}[0] . $arg); - my $mtch = defined($a[3]) ? $a[3] : $gets{$a[1]}[1]; # optional - ($err, $msg) = CUL_ReadAnswer($hash, $a[1], 0, $mtch); - if(!defined($msg)) { - DevIo_Disconnected($hash); - $msg = "No answer"; - - } elsif($a[1] eq "cmds") { # nice it up - $msg =~ s/.*Use one of//g; - - } elsif($a[1] eq "uptime") { # decode it - $msg =~ s/[\r\n]//g; - $msg = hex($msg)/125; - $msg = sprintf("%d %02d:%02d:%02d", - $msg/86400, ($msg%86400)/3600, ($msg%3600)/60, $msg%60); - } elsif($a[1] eq "credit10ms") { - ($msg) = ($msg =~ /^.. *(\d*)[\r\n]*$/); - } - - $msg =~ s/[\r\n]//g; - - } - - readingsSingleUpdate($hash, $a[1], $msg, 1); - - return "$a[0] $a[1] => $msg"; -} - -sub -CUL_Clear($) -{ - my $hash = shift; - - # Clear the pipe - $hash->{RA_Timeout} = 0.1; - for(;;) { - my ($err, undef) = CUL_ReadAnswer($hash, "Clear", 0, "wontmatch"); - last if($err); - } - delete($hash->{RA_Timeout}); - $hash->{PARTIAL} = ""; -} - -##################################### -sub -CUL_DoInit($) -{ - my $hash = shift; - my $name = $hash->{NAME}; - my $err; - my $msg = undef; - - CUL_Clear($hash); - my ($ver, $try) = ("", 0); - while($try++ < 3 && $ver !~ m/^V/) { - CUL_SimpleWrite($hash, "V"); - ($err, $ver) = CUL_ReadAnswer($hash, "Version", 0, "^V"); - return "$name: $err" if($err && ($err !~ m/Timeout/ || $try == 3)); - $ver = "" if(!$ver); - } - - if($ver !~ m/^V/) { - $attr{$name}{dummy} = 1; - $msg = "Not an CUL device, got for V: $ver"; - Log3 $name, 1, $msg; - return $msg; - } - $ver =~ s/[\r\n]//g; - $hash->{VERSION} = $ver; - - # Cmd-String feststellen - - my $cmds = CUL_Get($hash, $name, "cmds", 0); - $cmds =~ s/$name cmds =>//g; - $cmds =~ s/ //g; - $hash->{CMDS} = $cmds; - Log3 $name, 3, "$name: Possible commands: " . $hash->{CMDS}; - - CUL_WriteInit($hash); - - # FHTID - if(defined($hash->{FHTID})) { - my $fhtid; - CUL_SimpleWrite($hash, "T01"); - ($err, $fhtid) = CUL_ReadAnswer($hash, "FHTID", 0, undef); - return "$name: $err" if($err); - $fhtid =~ s/[\r\n]//g; - Log3 $name, 5, "GOT CUL fhtid: $fhtid"; - if(!defined($fhtid) || $fhtid ne $hash->{FHTID}) { - Log3 $name, 2, "Setting $name fhtid from $fhtid to " . $hash->{FHTID}; - CUL_SimpleWrite($hash, "T01" . $hash->{FHTID}); - } - } - - my $cc = AttrVal($name, "connectCommand", undef); - CUL_SimpleWrite($hash, $cc) if($cc); - - readingsSingleUpdate($hash, "state", "Initialized", 1); - - # Reset the counter - delete($hash->{XMIT_TIME}); - delete($hash->{NR_CMD_LAST_H}); - return undef; -} - -##################################### -# This is a direct read for commands like get -# Anydata is used by read file to get the filesize -sub -CUL_ReadAnswer($$$$) -{ - my ($hash, $arg, $anydata, $regexp) = @_; - my $ohash = $hash; - - while($hash && $hash->{TYPE} !~ m/$culNameRe/) { - $hash = $hash->{IODev}; - } - return ("No FD", undef) - if(!$hash || ($^O !~ /Win/ && !defined($hash->{FD}))); - - my ($mculdata, $rin) = ("", ''); - my $buf; - my $to = 3; # 3 seconds timeout - $mculdata = $hash->{PARTIAL} if(defined($hash->{PARTIAL})); - - $to = $ohash->{RA_Timeout} if($ohash->{RA_Timeout}); # ...or less - for(;;) { - - if($^O =~ m/Win/ && $hash->{USBDev}) { - $hash->{USBDev}->read_const_time($to*1000); # set timeout (ms) - # Read anstatt input sonst funzt read_const_time nicht. - $buf = $hash->{USBDev}->read(999); - return ("Timeout reading answer for get $arg", undef) - if(length($buf) == 0); - - } else { - return ("Device lost when reading answer for get $arg", undef) - if(!$hash->{FD}); - - vec($rin, $hash->{FD}, 1) = 1; - my $nfound = select($rin, undef, undef, $to); - if($nfound < 0) { - next if ($! == EAGAIN() || $! == EINTR() || $! == 0); - my $err = $!; - DevIo_Disconnected($hash); - return("CUL_ReadAnswer $arg: $err", undef); - } - return ("Timeout reading answer for get $arg", undef) - if($nfound == 0); - $buf = DevIo_SimpleRead($hash); - return ("No data", undef) if(!defined($buf)); - - } - - if(defined($buf)) { - Log3 $ohash->{NAME}, 5, "CUL/RAW (ReadAnswer): $buf"; - $mculdata .= $buf; - } - - # Dispatch data in the buffer before the proper answer. - while(($mculdata =~ m/^([^\n]*\n)(.*)/s) || $anydata) { - my $line = ($anydata ? $mculdata : $1); - $mculdata = $2; - $hash->{PARTIAL} = $mculdata; # for recursive calls - (undef, $line) = CUL_prefix(0, $ohash, $line); # Delete prefix - if($regexp && $line !~ m/$regexp/) { - $line =~ s/[\n\r]+//g; - CUL_Parse($ohash, $hash, $ohash->{NAME}, $line) if($init_done); - $mculdata = $hash->{PARTIAL}; - } else { - return (undef, $line); - } - } - } -} - -##################################### -# Check if the 1% limit is reached and trigger notifies -sub -CUL_XmitLimitCheck($$$) -{ - my ($hash,$fn,$now) = @_; - - if(!$hash->{XMIT_TIME}) { - $hash->{XMIT_TIME}[0] = $now; - $hash->{NR_CMD_LAST_H} = 1; - return; - } - - my $nowM1h = $now-3600; - my @b = grep { $_ > $nowM1h } @{$hash->{XMIT_TIME}}; - - # Maximum nr of transmissions per hour, but not for HM and MAX - if(@b > 163 && $fn !~ m/^[AZ]/) { - my $name = $hash->{NAME}; - Log3 $name, 2, "CUL TRANSMIT LIMIT EXCEEDED"; - DoTrigger($name, "TRANSMIT LIMIT EXCEEDED"); - - } else { - - push(@b, $now); - - } - $hash->{XMIT_TIME} = \@b; - $hash->{NR_CMD_LAST_H} = int(@b); -} - -sub -CUL_XmitDlyHM($$$) -{ - my ($hash,$fn,$now) = @_; - - my (undef,$mTy,undef,$id) = unpack 'A8A2A6A6',$fn if(length($fn)>19); - - if($id && - $modules{CUL_HM}{defptr}{$id} && - $modules{CUL_HM}{defptr}{$id}{helper}{io} && - $modules{CUL_HM}{defptr}{$id}{helper}{io}{nextSend}) { - my $dDly = $modules{CUL_HM}{defptr}{$id}{helper}{io}{nextSend} - $now; - #$dDly -= 0.04 if ($mTy eq "02");# while HM devices need a rest there are - # still some devices that need faster - # reactionfor ack. - # Mode needs to be determined - if ($dDly > 0.01){# wait less then 10 ms will not work - $dDly = 0.1 if($dDly > 0.1); - Log3 $hash->{NAME}, 5, "CUL $id dly:".int($dDly*1000)."ms"; - select(undef, undef, undef, $dDly); - } - } - shift(@{$hash->{helper}{$id}{QUEUE}}); - InternalTimer($now+0.1, "CUL_XmitDlyHMTo", "$hash->{NAME}:$id", 1) - if (scalar(@{$hash->{helper}{$id}{QUEUE}})); - return 0; -} - -sub -CUL_XmitDlyHMTo($) -{ # waited long enough - next send for this ID - my ($name,$id) = split(":",$_[0]); - CUL_SendFromQueue($defs{$name}, ${$defs{$name}{helper}{$id}{QUEUE}}[0]); -} - -##################################### -# Translate data prepared for an FHZ to CUL syntax, so we can reuse -# the FS20 and FHZ modules. -sub -CUL_WriteTranslate($$$) -{ - my ($hash,$fn,$msg) = @_; - - ################### - # Rewrite message from FHZ -> CUL - if(length($fn) <= 1) { # CUL Native - ; - - } elsif($fn eq "04" && substr($msg,0,6) eq "010101") { # FS20 - $fn = "F"; - AddDuplicate($hash->{NAME}, - "0101a001" . substr($msg, 6, 6) . "00" . substr($msg, 12)); - $msg = substr($msg,6); - - } elsif($fn eq "04" && substr($msg,0,6) eq "020183") { # FHT - $fn = "T"; - $msg = substr($msg,6,4) . substr($msg,10); - - } elsif($fn eq "cmd") { # internal command - if($msg eq "speed100") { - $fn = "AR"; - } elsif($msg eq "speed10") { - $fn = "Ar"; - } else { # by default rewrite init - $fn = $hash->{initString}; - } - $msg = ""; - - } else { - Log3 $hash, 2, "CUL cannot translate $fn $msg"; - return (undef, undef); - } - return ($fn, $msg); -} - -##################################### -sub -CUL_Write($$$) -{ - my ($hash,$fn,$msg) = @_; - - ($fn, $msg) = CUL_WriteTranslate($hash, $fn, $msg); - return if(!defined($fn)); - my $name = $hash->{NAME}; - Log3 $name, 5, "$hash->{NAME} sending $fn$msg"; - my $bstring = "$fn$msg"; - - if($fn eq "F" || # FS20 message - $bstring =~ m/^u....F/ || # FS20 messages sent over an RFR - ($fn eq "" && ($bstring =~ m/^A/ || $bstring =~ m/^Z/ ))) { # AskSin/BidCos/HomeMatic/MAX - - CUL_AddSendQueue($hash, $bstring); - - } else { - - CUL_SimpleWrite($hash, $bstring); - - } - -} - -sub -CUL_SendFromQueue($$) -{ - my ($hash, $bstring) = @_; - my $name = $hash->{NAME}; - my $hm = ($bstring =~ m/^A/); - my $to = ($hm ? 0.15 : 0.3); - my $now = gettimeofday(); - if($bstring ne "") { - my $sp = AttrVal($name, "sendpool", undef); - if($sp) { # Is one of the CUL-fellows sending data? - my @fellows = split(",", $sp); - foreach my $f (@fellows) { - if($f ne $name && - $defs{$f} && - $defs{$f}{QUEUE} && - $defs{$f}{QUEUE}->[0] ne ""){ - unshift(@{$hash->{QUEUE}}, ""); - InternalTimer($now+$to, "CUL_HandleWriteQueue", $hash, 1); - return; - } - } - } - - CUL_XmitLimitCheck($hash, $bstring, $now); - if($hm) { - CUL_SimpleWrite($hash, $bstring) if(!CUL_XmitDlyHM($hash,$bstring,$now)); - return; - } else { - CUL_SimpleWrite($hash, $bstring); - } - } - - ############## - # Write the next buffer not earlier than 0.23 seconds - # = 3* (12*0.8+1.2+1.0*5*9+0.8+10) = 226.8ms - # else it will be sent too early by the CUL, resulting in a collision - InternalTimer($now+$to, "CUL_HandleWriteQueue", $hash, 1); -} - -sub -CUL_AddSendQueue($$) -{ - my ($hash, $bstring) = @_; - my $qHash = $hash; - if ($bstring =~ m/^A/){ # HM device - my $id = substr($bstring,16,6);#get HMID destination - $qHash = $hash->{helper}{$id}; - } - if(!$qHash->{QUEUE} || 0 == scalar(@{$qHash->{QUEUE}})) { - $qHash->{QUEUE} = [ $bstring ]; - CUL_SendFromQueue($hash, $bstring); - } else { - push(@{$qHash->{QUEUE}}, $bstring); - } -} - -##################################### -sub -CUL_HandleWriteQueue($) -{ - my $hash = shift; - my $arr = $hash->{QUEUE}; - if(defined($arr) && @{$arr} > 0) { - shift(@{$arr}); - if(@{$arr} == 0) { - delete($hash->{QUEUE}); - return; - } - my $bstring = $arr->[0]; - if($bstring eq "") { - CUL_HandleWriteQueue($hash); - } else { - CUL_SendFromQueue($hash, $bstring); - } - } -} - -##################################### -# called from the global loop, when the select for hash->{FD} reports data -sub -CUL_Read($) -{ - my ($hash) = @_; - - my $buf = DevIo_SimpleRead($hash); - return "" if(!defined($buf)); - my $name = $hash->{NAME}; - - my $culdata = $hash->{PARTIAL}; - Log3 $name, 5, "CUL/RAW: $culdata/$buf"; - $culdata .= $buf; - - while($culdata =~ m/\n/) { - my $rmsg; - ($rmsg,$culdata) = split("\n", $culdata, 2); - $rmsg =~ s/\r//; - $hash->{PARTIAL} = $culdata; # for recursive calls - CUL_Parse($hash, $hash, $name, $rmsg) if($rmsg); - $culdata = $hash->{PARTIAL}; - } - $hash->{PARTIAL} = $culdata; -} - -sub -CUL_Parse($$$$@) -{ - my ($hash, $iohash, $name, $rmsg, $initstr) = @_; - - if($rmsg =~ m/^V/) { # CUN* keepalive - Log3 $name, 4, "CUL_Parse: $name $rmsg"; - return; - } - - my $rssi; - my $dmsg = $rmsg; - my $dmsgLog = (AttrVal($name,"rfmode","") eq "HomeMatic") - ? join(" ",(unpack'A1A2A2A4A6A6A*',$rmsg)) - :$dmsg; - if($dmsg =~ m/^[AFTKEHRStZriby]([A-F0-9][A-F0-9])+$/) { # RSSI - my $l = length($dmsg); - $rssi = hex(substr($dmsg, $l-2, 2)); - $dmsg = substr($dmsg, 0, $l-2); - $rssi = ($rssi>=128 ? (($rssi-256)/2-74) : ($rssi/2-74)); - Log3 $name, 4, "CUL_Parse: $name $dmsgLog $rssi"; - } else { - Log3 $name, 4, "CUL_Parse: $name $dmsgLog"; - } - - ########################################### - #Translate Message from CUL to FHZ - next if(!$dmsg || length($dmsg) < 1); # Bogus messages - - if ($dmsg eq 'SMODE' || $dmsg eq 'TMODE') { # brs/brt returns SMODE/TMODE - Log3 $name, 5, "CUL_Parse: switched to $dmsg"; - return; - } - - if($dmsg =~ m/^[0-9A-F]{4}U./) { # RF_ROUTER - Dispatch($hash, $dmsg, undef); - return; - } - - my $fn = substr($dmsg,0,1); - my $len = length($dmsg); - - if($fn eq "F" && $len >= 9) { # Reformat for 10_FS20.pm - CUL_AddSendQueue($iohash, ""); # Delay immediate replies - $dmsg = sprintf("81%02x04xx0101a001%s00%s", - $len/2+7, substr($dmsg,1,6), substr($dmsg,7)); - $dmsg = lc($dmsg); - - } elsif($fn eq "T") { - if ($len >= 11) { # Reformat for 11_FHT.pm - $dmsg = sprintf("81%02x04xx0909a001%s00%s", - $len/2+7, substr($dmsg,1,6), substr($dmsg,7)); - $dmsg = lc($dmsg); - } - - } elsif($fn eq "H" && $len >= 13) { # Reformat for 12_HMS.pm - my $type = hex(substr($dmsg,6,1)); - my $stat = $type > 1 ? hex(substr($dmsg,7,2)) : hex(substr($dmsg,5,2)); - my $prf = $type > 1 ? "02" : "05"; - my $bat = $type > 1 ? hex(substr($dmsg,5,1))+1 : 1; - my $HA = substr($dmsg,1,4); - my $values = $type > 1 ? "000000" : substr($dmsg,7); - $dmsg = sprintf("81%02x04xx%s%x%xa001%s0000%02x%s", - $len/2+8, # Packet-Length - $prf, $bat, $type, - $HA, # House-Code - $stat, - $values); # Values - $dmsg = lc($dmsg); - - } elsif($fn eq "K" && $len >= 5) { - if($len == 15) { # Reformat for 13_KS300.pm - my @a = split("", $dmsg); - $dmsg = sprintf("81%02x04xx4027a001", $len/2+6); - for(my $i = 1; $i < 14; $i+=2) { # Swap nibbles. - $dmsg .= $a[$i+1] . $a[$i]; - } - $dmsg = lc($dmsg); - } - # Other K... Messages ar sent to CUL_WS - } elsif($fn eq "r" && $len >= 23) { # Revolt - $dmsg = lc($dmsg); - } elsif($fn eq "i" && $len >= 7) { # IT - $dmsg = lc($dmsg); - } elsif($fn eq "A" && $len >= 20) { # AskSin/BidCos/HomeMatic - my $src = substr($dmsg,9,6); - if($modules{CUL_HM}{defptr}{$src}){ - $modules{CUL_HM}{defptr}{$src}{helper}{io}{nextSend} = - gettimeofday() + 0.100; - } - $dmsg .= "::$rssi:$name" if(defined($rssi)); - - } elsif($fn eq "Z" && $len >= 21) { # Moritz/Max - ; - } elsif($fn eq "b" && $len >= 24) { # Wireless M-Bus - $dmsg .= "::$rssi" if (defined($rssi)); - } elsif($fn eq "t" && $len >= 5) { # TX3 - $dmsg = "TX".substr($dmsg,1); # t.* is occupied by FHTTK - } - - $hash->{"${name}_MSGCNT"}++; - $hash->{"${name}_TIME"} = TimeNow(); - # showtime attribute - readingsSingleUpdate($hash, "state", $hash->{READINGS}{state}{VAL}, 0); - $hash->{RAWMSG} = $rmsg; - my %addvals = (RAWMSG => $dmsg); - if(defined($rssi)) { - $hash->{RSSI} = $rssi; - $addvals{RSSI} = $rssi; - } - Dispatch($hash, $dmsg, \%addvals); -} - - -##################################### -sub -CUL_Ready($) -{ - my ($hash) = @_; - - return DevIo_OpenDev($hash, 1, "CUL_DoInit") - if($hash->{STATE} eq "disconnected"); - - # This is relevant for windows/USB only - my $po = $hash->{USBDev}; - my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags); - if($po) { - ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $po->status; - } - return ($InBytes && $InBytes>0); -} - -######################## -# Needed for STACKABLE_CC -sub -CUL_WriteInit($) -{ - my ($hash) = @_; - foreach my $is (split("\n", $hash->{initString})) { - CUL_SimpleWrite($hash, $is); - } -} - -sub -CUL_SimpleWrite(@) -{ - my ($hash, $msg, $nonl) = @_; - return if(!$hash); - ($hash, $msg) = CUL_prefix(1, $hash, $msg); - DevIo_SimpleWrite($hash, $msg, 2, !$nonl); -} - -sub -CUL_Attr(@) -{ - my ($cmd,$name,$aName,$aVal) = @_; - my $hash = $defs{$name}; - - if($aName eq "rfmode") { - - - $aVal = "SlowRF" if(!$aVal || - ($aVal ne "HomeMatic" - && $aVal ne "MAX" - && $aVal ne "WMBus_T" - && $aVal ne "WMBus_S" - && $aVal ne "KOPP_FC" - && $aVal ne "Betty")); - my $msg = $hash->{NAME} . ": Mode $aVal not supported"; - - if($aVal eq "HomeMatic") { - return if($hash->{initString} =~ m/Ar/); - if($hash->{CMDS} =~ m/A/ || IsDummy($hash->{NAME}) || !$hash->{FD}) { - $hash->{Clients} = $clientsHomeMatic; - $hash->{MatchList} = \%matchListHomeMatic; - CUL_SimpleWrite($hash, "Zx") if ($hash->{CMDS} =~ m/Z/); # reset Moritz - $hash->{initString} = "X21\nAr"; # X21 is needed for RSSI reporting - CUL_WriteInit($hash); - - } else { - Log3 $name, 2, $msg; - return $msg; - } - - } elsif($aVal eq "MAX") { - return if($hash->{initString} =~ m/Zr/); - if($hash->{CMDS} =~ m/Z/ || IsDummy($hash->{NAME}) || !$hash->{FD}) { - $hash->{Clients} = $clientsMAX; - $hash->{MatchList} = \%matchListMAX; - CUL_SimpleWrite($hash, "Ax") if ($hash->{CMDS} =~ m/A/); # reset AskSin - $hash->{initString} = "X21\nZr"; # X21 is needed for RSSI reporting - CUL_WriteInit($hash); - - } else { - Log3 $name, 2, $msg; - return $msg; - } - - } elsif($aVal eq "WMBus_S") { - return if($hash->{initString} =~ m/brs/); - if($hash->{CMDS} =~ m/b/ || IsDummy($hash->{NAME}) || !$hash->{FD}) { - $hash->{Clients} = $clientsWMBus; - $hash->{MatchList} = \%matchListWMBus; - $hash->{initString} = "X21\nbrs"; # Use S-Mode - CUL_WriteInit($hash); - - } else { - Log3 $name, 2, $msg; - return $msg; - } - } elsif($aVal eq "WMBus_T") { - return if($hash->{initString} =~ m/brt/); - if($hash->{CMDS} =~ m/b/ || IsDummy($hash->{NAME}) || !$hash->{FD}) { - $hash->{Clients} = $clientsWMBus; - $hash->{MatchList} = \%matchListWMBus; - $hash->{initString} = "X21\nbrt"; # Use T-Mode - CUL_WriteInit($hash); - - } else { - Log3 $name, 2, $msg; - return $msg; - } - } elsif($aVal eq "KOPP_FC") { - if($hash->{CMDS} =~ m/k/ || IsDummy($hash->{NAME}) || !$hash->{FD}) { - $hash->{Clients} = $clientsKOPP_FC; - $hash->{MatchList} = \%matchListKOPP_FC; - $hash->{initString} = "krS"; # krS: start Kopp receive Mode - CUL_WriteInit($hash); - - } else { - Log3 $name, 2, $msg; - return $msg; - } - - } elsif($aVal eq "Betty") { - if($hash->{CMDS} =~ m/y/ || IsDummy($hash->{NAME}) || !$hash->{FD}) { - $hash->{Clients} = $clientsBetty; - $hash->{MatchList} = \%matchListBetty; - $hash->{initString} = "X21\nyr"; # krS: start Betty receive Mode - CUL_WriteInit($hash); - - } else { - Log3 $name, 2, $msg; - return $msg; - } - - } else { - return if($hash->{initString} eq "X21"); - $hash->{Clients} = $clientsSlowRF; - $hash->{MatchList} = \%matchListSlowRF; - $hash->{initString} = "X21"; - CUL_SimpleWrite($hash, "Ax") if ($hash->{CMDS} =~ m/A/); # reset AskSin - CUL_SimpleWrite($hash, "Zx") if ($hash->{CMDS} =~ m/Z/); # reset Moritz - CUL_SimpleWrite($hash, "brx") if ($hash->{CMDS} =~ m/b/); # reset WMBus - CUL_WriteInit($hash); - - } - - Log3 $name, 2, "Switched $name rfmode to $aVal"; - delete $hash->{".clientArray"}; - - } elsif($aName eq "hmId"){ - if($cmd eq "set") { - return "wrong syntax: hmId must be 6-digit-hex-code (3 byte)" - if($aVal !~ m/^[A-F0-9]{6}$/i); - } - - } elsif($aName eq "connectCommand"){ - CUL_SimpleWrite($hash, $aVal) if($cmd eq "set"); - - } - - return undef; -} - -sub -CUL_prefix($$$) -{ - my ($isadd, $hash, $msg) = @_; - while($hash && $hash->{TYPE} !~ m/$culNameRe/) { - $msg = CallFn($hash->{NAME}, $isadd ? "AddPrefix":"DelPrefix", $hash, $msg); - $hash = $hash->{IODev}; - last if(!$hash); - } - return ($hash, $msg); -} - -1; - -=pod -=item summary connect devices with the culfw Firmware, e.g. Busware CUL -=item summary_DE Anbindung von Geraeten mit dem culfw Firmware, z.Bsp. Busware CUL -=begin html - - -

CUL

-
    - - - -
    - The CUL/CUN(O) is a family of RF devices sold by busware.de. - - With the opensource firmware - culfw they are capable - to receive and send different 433/868 MHz protocols (FS20/FHT/S300/EM/HMS/MAX!). - It is even possible to use these devices as range extenders/routers, see the - CUL_RFR module for details. -

    - - Some protocols (FS20, FHT and KS300) are converted by this module so that - the same logical device can be used, irrespective if the radio telegram is - received by a CUL or an FHZ device.
    - Other protocols (S300/EM) need their - own modules. E.g. S300 devices are processed by the CUL_WS module if the - signals are received by the CUL, similarly EMWZ/EMGZ/EMEM is handled by the - CUL_EM module.

    - - It is possible to attach more than one device in order to get better - reception, FHEM will filter out duplicate messages.

    - - Note: This module may require the Device::SerialPort or - Win32::SerialPort module if you attach the device via USB - and the OS sets strange default parameters for serial devices.

    - -
    - -
    - - - Define -
      - define <name> CUL <device> <FHTID>
      -
      - USB-connected devices (CUL/CUN):
        - <device> specifies the serial port to communicate with the CUL. - The name of the serial-device depends on your distribution, under - linux the cdc_acm kernel module is responsible, and usually a - /dev/ttyACM0 device will be created. If your distribution does not have a - cdc_acm module, you can force usbserial to handle the CUL by the - following command: -
          - modprobe usbserial vendor=0x03eb product=0x204b -
        - In this case the device is most probably /dev/ttyUSB0.

        - - You can also specify a baudrate if the device name contains the @ - character, e.g.: /dev/ttyACM0@38400

        - - If the baudrate is "directio" (e.g.: /dev/ttyACM0@directio), then the - perl module Device::SerialPort is not needed, and FHEM - opens the device with simple file io. This might work if the operating - system uses sane defaults for the serial parameters, e.g. some Linux - distributions and OSX.

        - -
      - Network-connected devices (CUN(O)):
        - <device> specifies the host:port of the device, e.g. - 192.168.0.244:2323 -
      -
      - If the device is called none, then no device will be opened, so you - can experiment without hardware attached.
      - - The FHTID is a 4 digit hex number, and it is used when the CUL talks to - FHT devices or when CUL requests data. Set it to 0000 to avoid answering - any FHT80b request by the CUL. -
    -
    - - - Set -
      -
    • reopen
      - Reopens the connection to the device and reinitializes it. -

    • -
    • raw
      - Issue a CUL firmware command. See the this document - for details on CUL commands. -

    • - -
    • freq / bWidth / rAmpl / sens
      - SlowRF mode only.
      - Set the CUL frequency / bandwidth / receiver-amplitude / sensitivity
      - - Use it with care, it may destroy your hardware and it even may be - illegal to do so. Note: The parameters used for RFR transmission are - not affected.
      -
        -
      • freq sets both the reception and transmission frequency. Note: - Although the CC1101 can be set to frequencies between 315 and 915 - MHz, the antenna interface and the antenna of the CUL is tuned for - exactly one frequency. Default is 868.3 MHz (or 433 MHz)
      • -
      • bWidth can be set to values between 58 kHz and 812 kHz. Large values - are susceptible to interference, but make possible to receive - inaccurately calibrated transmitters. It affects tranmission too. - Default is 325 kHz.
      • -
      • rAmpl is receiver amplification, with values between 24 and 42 dB. - Bigger values allow reception of weak signals. Default is 42. -
      • -
      • sens is the decision boundary between the on and off values, and it - is 4, 8, 12 or 16 dB. Smaller values allow reception of less clear - signals. Default is 4 dB.
      • -
      -

    • - -
    • hmPairForSec
      - HomeMatic mode only.
      - Set the CUL in Pairing-Mode for the given seconds. Any HM device set into - pairing mode in this time will be paired with FHEM. -

    • - -
    • hmPairSerial
      - HomeMatic mode only.
      - Try to pair with the given device. The argument is a 10 character - string, usually starting with letters and ending with digits, printed on - the backside of the device. It is not necessary to put the given device - in learning mode if it is a receiver. -

    • - -
    • led
      - Set the CUL led off (00), on (01) or blinking (02). -

    • -
    • ITClock
      - Set the IT clock for Intertechno V1 protocol. Default 250. -

    • -
    - - - Get -
      -
    • version
      - returns the CUL firmware version -

    • -
    • uptime
      - returns the CUL uptime (time since CUL reset) -

    • -
    • raw
      - Issues a CUL firmware command, and waits for one line of data returned by - the CUL. See the CUL firmware README document for details on CUL - commands. -

    • -
    • fhtbuf
      - CUL has a message buffer for the FHT. If the buffer is full, then newly - issued commands will be dropped, and an "EOB" message is issued to the - FHEM log. - fhtbuf returns the free memory in this buffer (in hex), - an empty buffer in the CUL V2 is 74 bytes, in CUL V3/CUN(O) 200 Bytes. - A message occupies 3 + 2x(number of FHT commands) bytes, - this is the second reason why sending multiple FHT commands with one - set is a good idea. The first reason is, that - these FHT commands are sent at once to the FHT. -

    • - -
    • ccconf
      - Read some CUL radio-chip (cc1101) registers (frequency, bandwidth, etc.), - and display them in human readable form. -

    • - -
    • cmds
      - Depending on the firmware installed, CULs have a different set of - possible commands. Please refer to the README of the firmware of your - CUL to interpret the response of this command. See also the raw command. -

    • -
    • credit10ms
      - One may send for a duration of credit10ms*10 ms before the send limit - is reached and a LOVF is generated. -

    • -
    - - - Attributes -
      -
    • addvaltrigger
      - Create triggers for additional device values. Right now these are RSSI - and RAWMSG for the CUL family and RAWMSG for the FHZ. -

    • - -
    • connectCommand
      - raw culfw command sent to the CUL after a (re-)connect of the USB device, - and sending the usual initialization needed for the configured rfmode. -
    • - -
    • do_not_notify
    • -
    • dummy
    • -
    • hmId
      - Set the HomeMatic ID of this device. If this attribute is absent, the - ID will be F1<FHTID>. Note 1: After setting or changing this - attribute you have to relearn all your HomeMatic devices. Note 2: The - value must be a 6 digit hex number, and 000000 is not valid. FHEM - won't complain if it is not correct, but the communication won't work. -

    • - -
    • hmProtocolEvents
      - Generate events for HomeMatic protocol messages. These are normally - used for debugging, by activating "inform timer" in a telnet session, - or looking at the Event Monitor window in the FHEMWEB frontend.
      - Example: -
        - - 2012-05-17 09:44:22.515 CUL CULHM RCV L:0B N:81 CMD:A258 SRC:...... - DST:...... 0000 (TYPE=88,WAKEMEUP,BIDI,RPTEN) - -
      -

    • - -
    • longids
      - Comma separated list of device-types for CUL that should be handled - using long IDs. This additional ID allows it to differentiate some - weather sensors, if they are sending on the same channel. - Therefore a random generated id is added. If you choose to use longids, - then you'll have to define a different device after battery change. - Default is not to use long IDs.
      - Modules which are using this functionality are for e.g. : - 14_Hideki, 41_OREGON, 14_CUL_TCM97001, 14_SD_WS07.
      - - Examples:
      -
        - # Do not use any long IDs for any devices (this is default):
        - attr cul longids 0
        - # Use long IDs for all devices:
        - attr cul longids 1
        - # Use longids for SD_WS07 devices.
        - # Will generate devices names like SD_WS07_TH_3 for channel 3.
        - attr cul longids SD_WS07 -
      -

    • - -
    • model (CUL,CUN,etc)
    • -
    • sendpool
      - If using more than one CUL for covering a large area, sending - different events by the different CUL's might disturb each other. This - phenomenon is also known as the Palm-Beach-Resort effect. - Putting them in a common sendpool will serialize sending the events. - E.g. if you have three CUN's, you have to specify following - attributes:
      - attr CUN1 sendpool CUN1,CUN2,CUN3
      - attr CUN2 sendpool CUN1,CUN2,CUN3
      - attr CUN3 sendpool CUN1,CUN2,CUN3

      -

    • -
    • rfmode
      - Configure the RF Transceiver of the CUL (the CC1101). Available - arguments are: -
        -
      • SlowRF
        - To communicate with FS20/FHT/HMS/EM1010/S300/Hoermann devices @1 kHz - datarate. This is the default.
      • - -
      • HomeMatic
        - To communicate with HomeMatic type of devices @10 kHz datarate.
      • - -
      • MAX
        - To communicate with MAX! type of devices @10 kHz datarate.
      • - -
      • WMBus_S
      • -
      • WMBus_T
        - To communicate with Wireless M-Bus devices like water, gas or - electrical meters. Wireless M-Bus uses two different communication - modes, S-Mode and T-Mode. While in this mode, no reception of other - protocols like SlowRF or HomeMatic is possible. See also the WMBUS - FHEM Module. -
      • -
      -

    • -
    • showtime
    • - - -
    • readingFnAttributes
    • -
    -
    -
- -=end html - -=begin html_DE - - -

CUL

-
    - - - -
    - Der CUL/CUN(O) ist eine Familie von Funkempfängern, die von der Firma - Busware verkauft wird. - - Mit der OpenSource Firmware - culfw können sie verschiedene - 868 MHz Funkprotokolle empfangen bzw. senden (FS20/FHT/S300/EM/HMS/MAX!). - Man kann diese Geräte auch zur Reichweitenverlängerung, siehe - CUL_RFR einsetzen. -

    - - Einige Protokolle (FS20, FHT und KS300) werden von diesem Modul in das FHZ - Format konvertiert, daher kann dasselbe logische Gerät verwendet werden, - egal ob das Funktelegramm von einem CUL oder einem FHZ Gerät empfangen - wird.
    - - Andere Protokolle (S300/EM) benötigen ihre eigenen Module. S300 - Geräte werden vom Modul CUL_WS verarbeitet, wenn das Signal von einem - CUL empfangen wurde, ähnliches gilt für EMWZ/EMGZ/EMEM: diese - werden vom CUL_EM Modul verarbeitet.

    - - Es ist möglich mehr als ein Gerät zu verwenden, um einen besseren - Empfang zu erhalten, FHEM filtert doppelte Funktelegramme aus.

    - - Bemerkung: Dieses Modul benötigt unter Umständen das - Device::SerialPort bzw. Win32::SerialPort Modul, - wenn Sie das Gerät über USB anschließen und das - Betriebssystem unübliche Parameter für serielle Schnittstellen - setzt.

    - -
    - -
    - - - Define -
      - define <name> CUL <device> <FHTID>
      -
      - Geräte, die an USB angeschlossen sind (CUL/CUN):
      -
        - <device> gibt die serielle Schnittstelle an, mit der der CUL - kommuniziert. Der Name der seriellen Schnittstelle hängt von der - gewählten Distribution und USB-Treiber ab, unter Linux ist dies das - Kernel Modul cdc_acm und üblicherweise wird die Schnittstelle - /dev/ttyACM0 genannt. Wenn die Linux Distribution über kein Kernel - Modul cdc_acm verfügt, dann kann die Schnittstelle über - usbserial mit dem folgenden Befehl erzeugt werden: -
          - modprobe usbserial vendor=0x03eb product=0x204b -
        - In diesem Fall ist diese Schnittstelle dann wahrscheinlich - /dev/ttyUSB0.

        - - Wenn der Name der Schnittstelle ein @ enthält, kann nachfolgend die - verwendete Baudrate angegeben werden, z.B.: /dev/ttyACM0@38400.

        - - Wenn die Baudrate mit "directio" angegeben wird (z.B.: - /dev/ttyACM0@directio), wird das Perl Modul - Device::SerialPort nicht benötigt und FHEM öffnet - die Schnittstelle mit einfachem Dateizugriff. Dies sollte dann - funktionieren, wenn das Betriebssystem vernünftige Standardwerte - für die serielle Schnittstelle verwendet, wie z.B. einige Linux - Distributionen oder OSX.

        -
      - - Geräte, die mit dem Netzwerk verbunden sind (CUN(O)):
      -
        - <device> gibt die Hostadresse:Port des Gerätes an, z.B. - 192.168.0.244:2323 -
      -
      - - Wenn das Gerät mit none bezeichnet wird, wird keine Schnittstelle - geöffnet und man kann ohne angeschlossene Hardware - experimentieren.
      - - Die FHTID ist eine 4-stellige hexadezimale Zahl und wird verwendet, wenn - der CUL FHT Telegramme sendet bzw. Daten anfragt. Diese sollte als 0000 - gewählt werden, wenn man FHT80b Anfragen durch den CUL vermeiden will. -
    -
    - - - Set -
      -
    • reopen
      - Öffnet die Verbindung zum Gerät neu und initialisiert es. -

    • -
    • raw
      - Sendet einen CUL Firmware Befehl. Siehe auch - hier für - nähere Erläuterungen der CUL Befehle. -

    • - -
    • freq / bWidth / rAmpl / sens
      - Nur in der Betriebsart SlowRF.
      Bestimmt die - CUL Frequenz / Bandbreite / Empfänger Amplitude / - Empfindlichkeit
      - - Bitte mit Vorsicht verwenden, da es die verwendete Hardware - zerstören kann bzw. es zu illegalen Funkzuständen kommen - kann.
      Bemerkung: Die Parameter für die RFR Übermittlung - werden hierdurch nicht beeinflußt.
      -
        -
      • freq bestimmt sowohl die Empfangs- als auch die Sendefrequenz.
        - Bemerkung: Auch wenn der CC1101 zwischen den Frequenzen 315 und 915 - MHz eingestellt werden kann, ist die Antennenanbindung bzw. die - Antenne des CUL exakt auf eine Frequenz eingestellt. Standard ist - 868.3 MHz (bzw. 433 MHz).
      • - -
      • bWidth kann zwischen 58 kHz und 812 kHz variiert werden. - Große Werte sind empfindlicher gegen Interferencen, aber - machen es möglich, nicht genau kalbrierte Signale zu - empfangen. Die Einstellung beeinflusst ebenso die Übertragung. - Standardwert ist 325 kHz.
      • - -
      • rAmpl ist die Verstärkung des Empfängers mit Werten - zwischen 24 and 42 dB. Größere Werte erlauben den - Empfang von schwachen Signalen. Standardwert ist 42.
      • - -
      • sens ist die Entscheidungsgrenze zwischen "on" und "off" - Zuständen und kann 4, 8, 12 oder 16 dB sein. Kleinere Werte - erlauben den Empfang von undeutlicheren Signalen. Standard ist 4 - dB.
      • -
      -

    • - -
    • hmPairForSec
      - Nur in der Betriebsart HomeMatic.
      Versetzt den - CUL für die angegebene Zeit in Sekunden in den Anlern-Modus. Jedes - HM Gerät, das sich im Anlern-Modus befindet, wird an FHEM - angelernt.

    • - - -
    • hmPairSerial
      - Nur in der Betriebsart HomeMatic.
      - Versucht, das angegebene Gerät anzulernen (zu "pairen"). Der - Parameter ist eine 10-stellige Zeichenfolge, die normalerweise mit - Buchstaben beginnt und mit Ziffern endet; diese sind auf der - Rückseite der Geräte aufgedruckt. Wenn das Gerät ein - Empfänger ist, ist es nicht notwendig, das angegebene Gerät in - den Anlern-Modus zu versetzen.

    • - - -
    • led
      - Schaltet die LED des CUL: aus (00), an (01) oder blinkend (02). -

    • -
    • ITClock
      - Setzt die IT clock fü Intertechno V1 Protokoll. Default 250. -

    • -
    - - - Get -
      -
    • version
      - gibt die Version der CUL Firmware zurück -

    • -
    • uptime
      - gibt die Betriebszeit des CULs zurück (Zeit seit dem letzten Reset - des CULs)

    • - -
    • raw
      - Sendet einen CUL Firmware Befehl und wartet auf eine Rückgabe des - CULs. Siehe auch README der Firmware für nähere - Erläuterungen zu den CUL Befehlen.

    • - -
    • fhtbuf
      - Der CUL hat einen Puffer für Nachrichten für FHT. Wenn der - Puffer voll ist, werden neu empfangene Telegramme ignoriert und eine - "EOB" Meldung wird in die FHEM Logdatei geschrieben. - - fhtbuf gibt den freien Speicher dieses Puffers (in hex) - zurück, ein leerer Puffer im CUL V2 hat 74 Byte, im CUL V3/CUN(O) - hat 200 Byte. Eine Telegramm benötigt 3 + 2x(Anzahl der FHT - Befehle) Byte, dies ist ein Grund, warum man mehrere FHT Befehle mit - einem set senden sollte. Ein weiterer Grund ist, - dass diese FHT Befehle in einem "Paket" zum FHT Gerät gesendet werden. -

    • - -
    • ccconf
      - Liest einige CUL Register des CC1101 (Sende- und Empfängerchips) - aus (Frequenz, Bandbreite, etc.) und stellt diese in lesbarer Form dar. -

    • - -
    • cmds
      - In abhägigkeit der installierten Firmware hat der CUL/CUN(O) - unterschiedliche Befehlssätze. Nähere Informationen über - die Befehle bzw. deren Interpretation siehe README Datei der - verwendeten CUL Firmware. Siehe auch Anmerkungen beim raw Befehl. -

    • - -
    • credit10ms
      - Der Funkraum darf für eine Dauer von credit10ms*10 ms belegt - werden, bevor die gesetzliche 1% Grenze erreicht ist und eine - LOVF Meldung ausgegeben wird.

    - - - Attribute -
      -
    • addvaltrigger
      - Generiert Trigger für zusätzliche Werte. Momentan sind dies - RSSI und RAWMSG für die CUL Familie und RAWMSG für FHZ. -

    • - -
    • connectCommand
      - culfw Befehl, was nach dem Verbindungsaufbau mit dem USB-Gerät, nach - Senden der zum Initialisieren der konfigurierten rfmode benötigten - Befehle gesendet wird. -
    • - -
    • do_not_notify
    • -
    • dummy
    • - -
    • hmId
      - Setzt die HomeMatic ID des Gerätes. Wenn dieses Attribut fehlt, - wird die ID zu F1<FHTID> gesetzt. Bemerkung 1: Nach dem Setzen - bzw. Verändern dieses Attributes müssen alle HomeMatic - Geräte neu angelernt werden. Bemerkung 2: Der Wert muss - eine 6-stellige Hexadezimalzahl sein, 000000 ist ungültig. FHEM - überprüft nicht, ob die ID korrekt ist, im Zweifelsfall - funktioniert die Kommunikation nicht.

    • - -
    • hmProtocolEvents
      - Generiert Ereignisse für HomeMatic Telegramme. Diese werden - normalerweise für die Fehlersuche verwendet, z.B. durch Aktivieren - von inform timer in einer telnet Sitzung bzw. im - Event Monitor Fenster im FHEMWEB Frontend.
      - Beispiel: -
        - - 2012-05-17 09:44:22.515 CUL CULHM RCV L:0B N:81 CMD:A258 SRC:...... - DST:...... 0000 (TYPE=88,WAKEMEUP,BIDI,RPTEN) - -
      -

    • - -
    • longids
      - Durch Kommata getrennte Liste von Device-Typen für Empfang von - langen IDs mit den CUL. Diese zusätzliche ID erlaubt es - Wettersensoren, welche auf dem gleichen Kanal senden zu unterscheiden. - Hierzu wird eine zufällig generierte ID hinzugefügt. Wenn Sie - longids verwenden, dann wird in den meisten Fällen nach einem - Batteriewechsel ein neuer Sensor angelegt. - Standardmäßig werden keine langen IDs verwendet.
      - Folgende Module verwenden diese Funktionalität: - 14_Hideki, 41_OREGON, 14_CUL_TCM97001, 14_SD_WS07.
      - Beispiele: -
        - # Keine langen IDs verwenden (Default Einstellung):
        - attr cul longids 0
        - # Immer lange IDs verwenden:
        - attr cul longids 1
        - # Verwende lange IDs für SD_WS07 Devices.
        - # Device Namen sehen z.B. so aus: SD_WS07_TH_3 for channel 3.
        - attr cul longids SD_WS07 -
      -

    • - -
    • model (CUL,CUN)

    • - -
    • rfmode
      - Konfiguriert den RF Transceiver des CULs (CC1101). Verfügbare - Argumente sind: -
        -
      • SlowRF
        - Für die Kommunikation mit FS20/FHT/HMS/EM1010/S300/Hoermann - Geräten @1 kHz Datenrate (Standardeinstellung).
      • - -
      • HomeMatic
        - Für die Kommunikation mit HomeMatic Geräten @10 kHz - Datenrate.
      • - -
      • MAX
        - Für die Kommunikation mit MAX! Geräten @10 kHz - Datenrate.
      • -
      • WMBus_S
      • -
      • WMBus_T
        - Für die Kommunikation mit Wireless M-Bus Geräten wie - Wasser-, Gas- oder Elektrozählern. Wireless M-Bus verwendet - zwei unterschiedliche Kommunikationsarten, S-Mode und T-Mode. In - diesem Modus ist der Empfang von anderen Protokollen wie SlowRF - oder HomeMatic nicht möglich.
      • -
      -

    • - -
    • sendpool
      - Wenn mehr als ein CUL verwendet wird, um einen größeren - Bereich abzudecken, können diese sich gegenseitig - beeinflussen. Dieses Phänomen wird auch Palm-Beach-Resort Effekt - genannt. Wenn man diese zu einen gemeinsamen Sende"pool" - zusammenschließt, wird das Senden der einzelnen Telegramme - seriell (d.h. hintereinander) durchgeführt. - Wenn z.B. drei CUN's zur - Verfügung stehen, werden folgende Attribute gesetzt:
      - attr CUN1 sendpool CUN1,CUN2,CUN3
      - attr CUN2 sendpool CUN1,CUN2,CUN3
      - attr CUN3 sendpool CUN1,CUN2,CUN3

      -

    • - -
    • showtime
    • -
    • readingFnAttributes
    • -
    -
    -
- -=end html_DE -=cut diff --git a/FHEM/10_Betty.pm b/FHEM/10_Betty.pm deleted file mode 100644 index 9fe6b47..0000000 --- a/FHEM/10_Betty.pm +++ /dev/null @@ -1,176 +0,0 @@ -############################################## -# $Id: $ -package main; - -use strict; -use warnings; -use SetExtensions; - -my %sets = ( - "clear:noArg" => "", - "time:noArg" => "", - "raw" => "", -); - -sub -Betty_Initialize($) -{ - my ($hash) = @_; - - - $hash->{Match} = "^y.*"; - $hash->{SetFn} = "Betty_Set"; - $hash->{DefFn} = "Betty_Define"; - $hash->{ParseFn} = "Betty_Parse"; - $hash->{AttrList} = "IODev ". $readingFnAttributes; -} - - - -################################### -sub -Betty_Set($@) { - my ($hash, @a) = @_; - - return "set $hash->{NAME} needs at least one parameter" if(@a < 2); - - my $me = shift @a; - my $cmd = shift @a; - my $arg = shift @a; - my $arg2 = shift @a; - - return join(" ", sort keys %sets) if ($cmd eq "?"); - - if ($cmd eq "clear") { - my @cH = ($hash); - delete $_->{READINGS} foreach (@cH); - return undef; - - } elsif ($cmd eq "raw") { - my $msg = $arg; - #IOWrite( $hash, $msg ); - IOWrite( $hash, "y", $msg ); - return undef; - - } elsif ($cmd eq "time") { - my $address = $hash->{ADDRESS}; - - my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime; - - my $m = sprintf("%02d%02d%02d%02d",$mday,$wday,$month+1, $year-100); - my $n = sprintf("%02d%02d%02d",$sec, $min, $hour ); - - my $msg = "w".$address; - IOWrite( $hash, "y", $msg ); - $msg = "s0a".$address."0003".$m.$n; - IOWrite( $hash, "y", $msg ); - - return undef; - - } - - return "Unknown argument $cmd, choose one of ". join(" ", sort keys %sets); -} - - -############################# -sub -Betty_Define($$) -{ - my ($hash, $def) = @_; - my @a = split("[ \t][ \t]*", $def); - - return "wrong syntax: define Betty
" - if(int(@a) < 2 || int(@a) > 4); - - my $address = uc($a[2]); - $hash->{ADDRESS} = $address; - $modules{Betty}{defptr}{$address} = $hash; - AssignIoPort($hash); - - readingsSingleUpdate($hash, "state", "Initialized", 1); - - return undef; -} - - -sub -Betty_Parse($$) -{ - my ($hash,$msg) = @_; - - my ($len,$dest,$src,$service,$data) = unpack 'x1A2A2A2A2A*',$msg; - - my $def = $modules{Betty}{defptr}{$src}; - - if(!$def) { - DoTrigger("global","UNDEFINED Betty_$src Betty $src"); - $def = $modules{Betty}{defptr}{$src}; - if(!$def) { - Log3 $hash, 1, "Betty UNDEFINED, address $src"; - return "UNDEFINED Betty_$src Betty $src"; - } - } - - $hash = $def; - my $name = $hash->{NAME}; - - # packet_RFenc - if ($service eq '04') { - my ($addr,$key) = unpack 'A2A2',$data; - - if($hash->{helper}{lastkey } ne $key) { - $hash->{helper}{lastkey } = $key; - $key = sprintf "%02x", hex($key) & 0x7F; - readingsSingleUpdate($hash, "key", $addr."_".$key , 1); - } - - - # packet_test - } elsif ($service eq '01') { - - $data = latin1ToUtf8(pack("H*",$data)); - readingsSingleUpdate($hash, "test", $data , 1); - - # packet_time - } elsif ($service eq '03') { - - my ($request) = unpack 'A2',$data; - - if($request eq "FF") { - my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime; - - my $m = sprintf("%02d%02d%02d%02d",$mday,$wday,$month+1, $year-100); - my $n = sprintf("%02d%02d%02d",$sec, $min, $hour ); - - $msg = "s0a".$src."0003".$m.$n; - IOWrite( $hash, "y", $msg ); - } - - } else { - Log3 $hash, 4, "Betty UNKNOWN MESSAGE $service: $data"; - } - - return $name; -} - - - - -1; - -=pod -=item summary devices communicating with the Betty remote control -=item summary_DE Anbindung der Betty Fernbedienung -=begin html - - -

Betty

-
    - Todo -
- -=end html - - -=cut diff --git a/boop/Makefile b/boop/Makefile index 1f49ca1..8a4eaf4 100644 --- a/boop/Makefile +++ b/boop/Makefile @@ -55,7 +55,7 @@ ifeq ($(MAKECMDGOALS),debug) COMPILE += -D DEBUGMODE OPTFLAGS = -O0 else - OPTFLAGS = -Og + OPTFLAGS = -Os endif ifeq ($(MAKECMDGOALS),release) diff --git a/boop/audio/sid.c b/boop/audio/sid.c index 9ade33e..0128d39 100644 --- a/boop/audio/sid.c +++ b/boop/audio/sid.c @@ -157,7 +157,7 @@ void beep(unsigned char n) { SIDsetfrq(0,5001); break; } - //PWMPR = 0; + PWMPR = 0; switchSound(SOUND_ON); SID.flags |= SIDenable; SID.reg[REG_Control] |= GATE; diff --git a/boop/audio/sid.h b/boop/audio/sid.h index 05833b5..e67980f 100644 --- a/boop/audio/sid.h +++ b/boop/audio/sid.h @@ -101,12 +101,12 @@ struct SID_ { struct SID_ SID; -extern unsigned int playtone_cb; -extern unsigned char *playtone[3]; -extern unsigned char playstate; -extern unsigned char tonelen[3]; -extern unsigned short playcounter; -extern unsigned short playcountermax; +unsigned int playtone_cb; +unsigned char *playtone[3]; +unsigned char playstate; +unsigned char tonelen[3]; +unsigned short playcounter; +unsigned short playcountermax; void SIDsetfrq(unsigned char voice, unsigned short frq); void SIDsetadsr(unsigned char voice,unsigned char attack, unsigned char decay, unsigned char sustain, unsigned char release); diff --git a/boop/audio/sidfiles.h b/boop/audio/sidfiles.h index 6f10dde..0a4dccb 100644 --- a/boop/audio/sidfiles.h +++ b/boop/audio/sidfiles.h @@ -769,7 +769,6 @@ const unsigned char song1[] = { 0xa2,0x25,0x00,0x00,0x21,0x11,0x70,0xd2,0x0f,0x00,0x00,0x21,0x00,0x70, 0xa2,0x25,0x00,0x00,0x21,0x11,0x70,0xd2,0x0f,0x00,0x00,0x21,0x00,0x70, 0xa2,0x25,0x00,0x00,0x21,0x11,0x70,0xd2,0x0f,0x00,0x00,0x21,0x00,0x70, -/* 0x1f,0x15,0x00,0x00,0x21,0x11,0x70,0xc3,0x10,0x00,0x00,0x21,0x00,0x70, 0x1f,0x15,0x00,0x00,0x21,0x11,0x70,0xc3,0x10,0x00,0x00,0x21,0x00,0x70, 0x1f,0x15,0x00,0x00,0x21,0x11,0x70,0xc3,0x10,0x00,0x00,0x21,0x00,0x70, @@ -1002,5 +1001,4 @@ const unsigned char song1[] = { 0xc1,0x2c,0x00,0x00,0x21,0x11,0x70,0x31,0x1c,0x00,0x00,0x21,0x00,0x70, 0xc1,0x2c,0x00,0x00,0x21,0x11,0x70,0x31,0x1c,0x00,0x00,0x21,0x00,0x70, 0xc1,0x2c,0x00,0x00,0x21,0x11,0x70,0x31,0x1c,0x00,0x00,0x21,0x00,0x70 -*/ }; diff --git a/boop/audio/sound.c b/boop/audio/sound.c index 3eee98c..310ecbc 100644 --- a/boop/audio/sound.c +++ b/boop/audio/sound.c @@ -20,7 +20,6 @@ #include "sound.h" #include "soundirq.h" #include "lpc2220.h" -#include "pwm.h" #define AUTO_OFF_TIME 0x4000 @@ -38,7 +37,7 @@ unsigned char timeout; unsigned int auto_timeout; void startSoundIRQ(void) -{/* +{ timeout = 0; auto_timeout = 0; out1 = 0; @@ -58,7 +57,6 @@ void startSoundIRQ(void) //VICVectCntl0 = VIC_SLOT_EN | INT_SRC_PWM; VICIntSelect |= INT_PWM; VICIntEnable = INT_PWM; - */ } void initSound(void) @@ -69,18 +67,12 @@ void initSound(void) tval = 0; last_sample = 0; bl_val = 0x3F; - timeout = 0; - auto_timeout = 0; - out1 = 0; } void switchSound(unsigned char onoff) { if(onoff) { - - PWM_set_frequency(30864); - sound_shutdown = 0; PINSEL0 &= ~(3 << (2 * SND_PWM)); // IO PINSEL0 |= (2 << (2 * SND_PWM)); // PWM @@ -89,7 +81,6 @@ void switchSound(unsigned char onoff) FIODIR0 |= (1<= 63) + { + FIODIR0 |= (1<<4); // sck0/P0.4 + cmp_val -= 63; + } + else + { + FIODIR0 &= ~(1<<4); // sck0/P0.4 + } + } diff --git a/boop/betty.cfg b/boop/betty.cfg index ba49750..4ac8704 100644 --- a/boop/betty.cfg +++ b/boop/betty.cfg @@ -71,9 +71,9 @@ proc betty_init { } { # Memory Bank Configuration # BCFG0: 16bit, rble, 2wst - 30 mhz : Betty: FLASH 0 @ 0x80000000 - mww 0xffe00000 0x10001CA0 + mww 0xffe00000 0x10000420 # BCFG2: 16bit, rble, 2wst - 30 mhz : Betty: FLASH 1 @ 0x82000000 - mww 0xffe00008 0x10001CA0 + mww 0xffe00008 0x10000420 # BCFG1: 8 bit, 3 sram wst, rble, 5 wst 3 idcy : Betty: LCD @ 0x81000000 mww 0xffe00004 0x00000400 @@ -108,8 +108,8 @@ proc flash_boop {IMAGE} { flash erase_check 0 flash erase_sector 0 0 last flash erase_check 0 - flash write_bank 0 $IMAGE 0 - reset run + flash write_bank 0 $IMAGE 0 + reset run } proc start_debug {} { diff --git a/boop/boop_rom.bin b/boop/boop_rom.bin index 33ec32b..1ffe406 100644 Binary files a/boop/boop_rom.bin and b/boop/boop_rom.bin differ diff --git a/boop/cc1100/cc1100.c b/boop/cc1100/cc1100.c index 02b9c80..4874ca2 100644 --- a/boop/cc1100/cc1100.c +++ b/boop/cc1100/cc1100.c @@ -26,74 +26,58 @@ #include "cc1100.h" #include "irq.h" -// Deviation = 21.423340 -// Base frequency = 433.254913 -// Carrier frequency = 433.254913 -// Channel number = 0 -// Carrier frequency = 433.254913 -// Modulated = true -// Modulation format = GFSK -// Manchester enable = false -// Sync word qualifier mode = 30/32 sync word bits detected -// Preamble count = 4 -// Channel spacing = 184.982300 -// Carrier frequency = 433.254913 -// Data rate = 37.4908 -// RX filter BW = 210.937500 -// Data format = Normal mode -// CRC enable = true -// Whitening = false -// Device address = 1 -// Address config = Address check and 0 (0x00) broadcast -// CRC autoflush = true -// PA ramping = false -// TX power = 0 -// Rf settings for CC1101 -const unsigned char conf[] = { - 0x29, // IOCFG2 GDO2 Output Pin Configuration - 0x2E, // IOCFG1 GDO1 Output Pin Configuration - 0x06, // IOCFG0 GDO0 Output Pin Configuration - 0x47, // FIFOTHR RX FIFO and TX FIFO Thresholds - 0xD3, // SYNC1 Sync Word, High Byte - 0x91, // SYNC0 Sync Word, Low Byte - 0x3E, // PKTLEN Packet Length - 0x1A, // PKTCTRL1 Packet Automation Control - 0x05, // PKTCTRL0 Packet Automation Control - 0x01, // ADDR Device Address - 0x00, // CHANNR Channel Number - 0x06, // FSCTRL1 Frequency Synthesizer Control - 0x00, // FSCTRL0 Frequency Synthesizer Control - 0x10, // FREQ2 Frequency Control Word, High Byte - 0x0B, // FREQ1 Frequency Control Word, Middle Byte - 0xE6, // FREQ0 Frequency Control Word, Low Byte - 0x8A, // MDMCFG4 Modem Configuration - 0x6C, // MDMCFG3 Modem Configuration - 0x13, // MDMCFG2 Modem Configuration - 0x22, // MDMCFG1 Modem Configuration - 0xC1, // MDMCFG0 Modem Configuration - 0x35, // DEVIATN Modem Deviation Setting - 0x04, // MCSM2 Main Radio Control State Machine Configuration - 0x0C, // MCSM1 Main Radio Control State Machine Configuration - 0x38, // MCSM0 Main Radio Control State Machine Configuration - 0x16, // FOCCFG Frequency Offset Compensation Configuration - 0x6C, // BSCFG Bit Synchronization Configuration - 0x43, // AGCCTRL2 AGC Control - 0x40, // AGCCTRL1 AGC Control - 0x91, // AGCCTRL0 AGC Control - 0x46, // WOREVT1 High Byte Event0 Timeout - 0x50, // WOREVT0 Low Byte Event0 Timeout - 0x78, // WORCTRL Wake On Radio Control - 0x56, // FREND1 Front End RX Configuration - 0x10, // FREND0 Front End TX Configuration - 0xE9, // FSCAL3 Frequency Synthesizer Calibration - 0x2A, // FSCAL2 Frequency Synthesizer Calibration - 0x00, // FSCAL1 Frequency Synthesizer Calibration - 0x1F, // FSCAL0 Frequency Synthesizer Calibration - 0x41, // RCCTRL1 RC Oscillator Configuration - 0x00, // RCCTRL0 RC Oscillator Configuration +//setting 6_WOR +const unsigned char conf[0x2F] = { + 0x29, // IOCFG2 + 0x2E, // IOCFG1 + 0x06, // IOCFG0 + 0x47, // FIFOTHR + 0xD3, // SYNC1 + 0x91, // SYNC0 + 0x3E, // PKTLEN + 0x1A, // PKTCTRL1 + 0x45, // PKTCTRL0 + 0x01, // ADDR + 0x01, // CHANNR + 0x06, // FSCTRL1 + 0x00, // FSCTRL0 + 0x10, // FREQ2 # + 0x0B, // FREQ1 # + 0xDA, // FREQ0 # -> 433,249969 MHz + 0x8A, // MDMCFG4 + 0x75, // MDMCFG3 + 0x13, // MDMCFG2 + 0x22, // MDMCFG1 + 0xC1, // MDMCFG0 CHANSPC_M + 0x35, // DEVIATN + 0x04, // MCSM2 + 0x0C, // MCSM1 0c + 0x38, // MCSM0 + 0x16, // FOCCFG + 0x6C, // BSCFG + 0x43, // AGCCTRL2 + 0x40, // AGCCTRL1 + 0x91, // AGCCTRL0 + 0x46, // WOREVT1 + 0x50, // WOREVT0 + 0x78, // WORCTRL + 0x56, // FREND1 + 0x10, // FREND0 + 0xA9, // FSCAL3 + 0x0A, // FSCAL2 + 0x00, // FSCAL1 + 0x11, // FSCAL0 + 0x41, // RCCTRL1 + 0x00, // RCCTRL0 + 0x57, // FSTEST + 0x7F, // PTEST + 0x3F, // AGCTEST + 0x98, // TEST2 + 0x31, // TEST1 + 0x0B // TEST0 }; -const unsigned char confasync[] = { +const unsigned char confasync[0x2F] = { 0x0D, // IOCFG2 0x0D, // IOCFG1 0x2E, // IOCFG0 @@ -136,6 +120,12 @@ const unsigned char confasync[] = { 0x1F, // FSCAL0 0x41, // RCCTRL1 0x00, // RCCTRL0 + 0x59, // FSTEST + 0x7F, // PTEST + 0x3F, // AGCTEST + 0x81, // TEST2 + 0x35, // TEST1 + 0x09 // TEST0 }; void cc1100_init(void) { @@ -174,7 +164,7 @@ void cc1100_init(void) { while (SSPSR & (1<<4)); xx = SSPDR; - cc1100_write((0x00 | BURST ),(unsigned char*)conf,sizeof(conf)); + cc1100_write((0x00 | BURST ),(unsigned char*)conf,0x2f); cc1100_write1(PATABLE,0xC0); cc1100_strobe(SIDLE); cc1100_strobe(SPWD); diff --git a/boop/cc1100/cc1100.h b/boop/cc1100/cc1100.h index f4cc27a..3e0b3c7 100644 --- a/boop/cc1100/cc1100.h +++ b/boop/cc1100/cc1100.h @@ -118,8 +118,8 @@ #define MARCSTATE_IDLE 0x01 #define MARCSTATE_RX 0x0d -extern const unsigned char conf[]; //__attribute__((aligned(0x4))); -extern const unsigned char confasync[];// __attribute__((aligned(0x4))); +const unsigned char conf[0x2F] __attribute__((aligned(0x4))); +const unsigned char confasync[0x2F] __attribute__((aligned(0x4))); void cc1100_init(void); unsigned char cc1100_write(unsigned char addr, unsigned char* data, unsigned char length); diff --git a/boop/cc1100/rf.c b/boop/cc1100/rf.c index cc93c81..62ce2e2 100644 --- a/boop/cc1100/rf.c +++ b/boop/cc1100/rf.c @@ -485,14 +485,14 @@ void RFasyncmode(unsigned char on) { RF_changestate(RFidle); while(RF.state != RFidle); stopRFIRQ(); - cc1100_write((0x00 | BURST ),(unsigned char*)confasync,sizeof((unsigned char*)confasync)); + cc1100_write((0x00 | BURST ),(unsigned char*)confasync,0x2f); cc1100_write1(PATABLE,0xf0); PINSEL1 &= 0xfffffffc; // GDO0 as GPIO FIODIR0 |= GDO0; // output } else { PINSEL1 |= 1; // GDO0 as EINT0 - cc1100_write((0x00 | BURST ),(unsigned char*)conf,sizeof((unsigned char*)conf)); + cc1100_write((0x00 | BURST ),(unsigned char*)conf,0x2f); cc1100_write1(PATABLE,0xC0); cc1100_strobe(SIDLE); load_RF_setting(); diff --git a/boop/crt.s b/boop/crt.s index 34bf0dc..27636b6 100644 --- a/boop/crt.s +++ b/boop/crt.s @@ -182,7 +182,7 @@ Reset_Handler: /* --+--+-+-+-+-+--------+-----+-------+-+---- */ /* ldr r1, =0x10000400 /* 00|01|0|0|0|0|00000000|00000|1|00000|0|0000 16bit, rble, 3wst - 10 mhz*/ /* ldr r1, =0x10000420 /* 00|01|0|0|0|0|00000000|00000|1|00001|0|0000 16bit, rble, 4wst - 30 mhz*/ - ldr r1, =0x10001CA0 /* 00|01|0|0|0|0|00000000|00101|1|00101|0|0000 16bit, rble, 6wst - 60 mhz*/ + ldr r1, =0x100004A0 /* 00|01|0|0|0|0|00000000|00000|1|00101|0|0000 16bit, rble, 6wst - 60 mhz*/ str r1,[r0] /* set bcfg0 (flash) */ str r1,[r0,#0x08] /* set bcfg2 (flash) */ diff --git a/boop/gui/testmenu.c b/boop/gui/testmenu.c index ce4d331..e5af164 100644 --- a/boop/gui/testmenu.c +++ b/boop/gui/testmenu.c @@ -29,7 +29,6 @@ #include "ir_selector.h" #include "infrared.h" #include "sid.h" -#include "sidfiles.h" #include "timerfuncs.h" #include "sound.h" #include "lpc2220.h" @@ -862,35 +861,6 @@ void test_RF(void) { cur_ep->bufferlen = 3; cur_ep->flags |= EPenabled | EPoutput | EPnewdata | EPonce | EPsendwor; - RF_changestate(RFtx); - } else if(KEY_1) - { - struct RFendpoint_* cur_ep; - - cur_ep = openEP(0,0, packet_test); - if(cur_ep) { - cur_ep->dest = destAddr; - cur_ep->data[0] = 'X'; - cur_ep->data[1] = '1'; - cur_ep->data[2] = 0x00; - cur_ep->bufferlen = 3; - cur_ep->flags |= EPenabled | EPoutput | EPnewdata | EPonce; - - RF_changestate(RFtx); - } - } - else if(KEY_2) - { - struct RFendpoint_* cur_ep; - - cur_ep = openEP(0,0, packet_test); - cur_ep->dest = destAddr; - cur_ep->data[0] = 'X'; - cur_ep->data[1] = '2'; - cur_ep->data[2] = 0x00; - cur_ep->bufferlen = 3; - cur_ep->flags |= EPenabled | EPoutput | EPnewdata | EPonce ; - RF_changestate(RFtx); } } @@ -964,9 +934,6 @@ void test_sid(void) { draw_string (0, 95, "color keys", LCD_COLOR_B, DRAW_PUT); draw_string (0, 104, "set waveform", LCD_COLOR_B, DRAW_PUT); - draw_string (0, 120, "Mute", LCD_COLOR_B, DRAW_PUT); - draw_string (0, 129, "Raiders March", LCD_COLOR_B, DRAW_PUT); - sysInfo |= SYS_IR; SID.noise = 0xaa; playstate = 0x00; @@ -1085,20 +1052,6 @@ void test_sid(void) { playtone_cb = addTimerCB(SIDplaytone, 4); startCB(playtone_cb); } - } else if (KEY_Mute) - { - if (playstate == 0) - { - playstate = 1; - - playtone[0] = (unsigned char*)&song1[0]; - - playcounter = 0; - playcountermax = sizeof(song1)/14; - - playtone_cb = addTimerCB(SIDplaydump, 4); - startCB(playtone_cb); - } } } while (!KEY_Exit); sysInfo &= ~SYS_IR; diff --git a/boop/infrared/Make.conf b/boop/infrared/Make.conf index f6aed17..2a1fa32 100644 --- a/boop/infrared/Make.conf +++ b/boop/infrared/Make.conf @@ -1,5 +1,5 @@ -THUMBSRCS := infrared.c codes.c encoders.c ir_capture.c ir_selector.c -SRCS := infraredirq.c pwm.c +THUMBSRCS := infrared.c codes.c encoders.c ir_capture.c ir_selector.c +SRCS := infraredirq.c THUMBSRCSUNOPT := ir_itt.c ir_nrc17.c \ ir_raw.c ir_rc5.c ir_rc6.c ir_rca.c ir_rcmm.c ir_rec80.c ir_recs80.c ir_rf.c \ ir_sirc.c ir_spaceenc.c ir_lirc.c diff --git a/boop/infrared/codes.c b/boop/infrared/codes.c index 99a5f59..f30c7ad 100644 --- a/boop/infrared/codes.c +++ b/boop/infrared/codes.c @@ -222,7 +222,7 @@ const struct TABLES_N RAW = const struct TABLES_L LIRC = { - 10, + 9, { { #include "ir_codes/lirc/ufs922" @@ -259,10 +259,6 @@ const struct TABLES_L LIRC = { #include "ir_codes/lirc/samsung_ue46b6000" "Samsung TV" - }, - { - #include "ir_codes/lirc/beo4" - "bang & olufsen" - } + } } }; diff --git a/boop/infrared/infrared.c b/boop/infrared/infrared.c index 5e3aa45..e0ac240 100644 --- a/boop/infrared/infrared.c +++ b/boop/infrared/infrared.c @@ -25,7 +25,6 @@ #include "encoders.h" #include "codes.h" #include "ir_selector.h" -#include "pwm.h" volatile unsigned char mod_enable; volatile unsigned char hi_border; @@ -62,9 +61,9 @@ void startIrIRQ(void) // T1PR = 0x01; T1MCR = 0x03; - VICVectAddr1 = (unsigned long)&(irIRQ); - VICVectCntl1 = VIC_SLOT_EN | INT_SRC_TIMER1; - //VICIntSelect |= INT_TIMER1; + //VICVectAddr1 = (unsigned long)&(irIRQ); + //VICVectCntl1 = VIC_SLOT_EN | INT_SRC_TIMER1; + VICIntSelect |= INT_TIMER1; VICIntEnable = INT_TIMER1; } @@ -110,21 +109,11 @@ void defStopper(void) void runIR(void) { T1TCR = 0x01; - PWM_set_IR_duty_cycle(0); - -} - -void setIRspeed(struct irModule module) -{ - PWM_set_frequency(15000000 / (module.tval * module.lo_border)); - ir.duty_cycle =(module.hi_border * 100) / module.lo_border; } void stopIR(void) { T1TCR = 0x03; - PWM_set_IR_duty_cycle(0); - } void copyMapC(unsigned char *map) diff --git a/boop/infrared/infrared.h b/boop/infrared/infrared.h index 4e5665a..b10991e 100644 --- a/boop/infrared/infrared.h +++ b/boop/infrared/infrared.h @@ -63,8 +63,28 @@ struct IR_VARS_ { unsigned long actpre_data; unsigned long post_data; // data which the remote sends after actual keycode unsigned long actpost_data; - unsigned long cycles_counter; + unsigned short flags; // flags + unsigned short phead,shead; // header + unsigned short plead; // leading pulse + unsigned short ptrail; // trailing pulse + unsigned short pfoot,sfoot; // foot + unsigned short pre_p,pre_s; // signal between pre_data and keycode + unsigned short post_p,post_s; // signal between keycode and post_code + unsigned short gap; + unsigned short repeat_gap; + unsigned short prepeat,srepeat; + unsigned short cycles_counter; + unsigned char bits; // bits (length of code) + unsigned char pre_data_bits; // length of pre_data + unsigned char post_data_bits; // length of post_data + unsigned char rc6_bit; // doubles signal length of this bit (only used for RC-6) + unsigned char pthree,sthree; // 3 (only used for RC-MM) + unsigned char ptwo,stwo; // 2 (only used for RC-MM) + unsigned char pone,sone; // 1 + unsigned char pzero,szero; // 0 + unsigned char min_repeat; unsigned char bit; + unsigned char map; unsigned char stop; unsigned char repeats; } lirc; @@ -73,12 +93,11 @@ struct IR_VARS_ { unsigned int actcmd; unsigned char toggle; unsigned char state; - unsigned char duty_cycle; } ir; //#define setIRspeed( _m ) { if(sysInfo & 0x80) T1MR0 = _m.tval1; else T1MR0 = _m.tval; } -//#define setIRspeed( _m ) { T1MR0 = _m.tval; } +#define setIRspeed( _m ) { T1MR0 = _m.tval; } void __attribute__ ((section(".text.fastcode"))) defIR(void); void defSender(unsigned long cmd); @@ -90,7 +109,6 @@ void startIrIRQ(void); void setIR(struct irModule module); void runIR(void); void stopIR(void); -void setIRspeed(struct irModule module); unsigned long setEncoder( unsigned char _x, unsigned char _y ); diff --git a/boop/infrared/infraredirq.c b/boop/infrared/infraredirq.c index 2ae58f8..5fa7314 100644 --- a/boop/infrared/infraredirq.c +++ b/boop/infrared/infraredirq.c @@ -23,8 +23,9 @@ #include "keyboard.h" #include "rf.h" #include "cc1100.h" -#include "pwm.h" +static unsigned int c_cnt = 0; +static unsigned int b_len = 0; extern volatile unsigned char mod_enable; extern volatile unsigned char hi_border; extern volatile unsigned char lo_border; @@ -34,15 +35,33 @@ extern ir_fn irEncoder; void __attribute__ ((section(".text.fastcode"))) irIRQ(void) { - - irEncoder(); - - if(mod_enable) { - PWM_set_IR_duty_cycle(ir.duty_cycle); - } else { - PWM_set_IR_duty_cycle(0); + c_cnt++; + if(c_cnt <= hi_border) + { + FIOSET0 = (mod_enable<<21); + } + else + { + FIOCLR0 = (1<<21); + if(c_cnt >= lo_border) + { + c_cnt = 0; + b_len++; + if(b_len >= cycles) + { + irEncoder(); + b_len = 0; + + if(!hi_border) { //RF mode + if(mod_enable) + FIOCLR0 = GDO0; + else + FIOSET0 = GDO0; + } + } + } } T1IR = 1; - +// VICVectAddr = 0; } diff --git a/boop/infrared/ir_codes/lirc/beo4 b/boop/infrared/ir_codes/lirc/beo4 deleted file mode 100644 index 9869987..0000000 --- a/boop/infrared/ir_codes/lirc/beo4 +++ /dev/null @@ -1 +0,0 @@ -/* infrared codes for bang & olufsen Copyright (C) 2017 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 3 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 this program. If not, see . */ /*pre_data*/ 0x00000000, // 2. start bit /*post_data*/ 0x00000000, /*toggle_bit_mask*/ 0x00, /*gap*/ 18000, // final gap to prevent collision /*repeat_gap*/ 0, /*bits*/ 17, // last(4.) start bit logical low as first data bit ==> 1+16 data bits = 17 /*pre_data_bits*/ 1, // 2. start bit /*post_data_bits*/ 0, /*rc6_bit*/ 0, /*frequency*/ 455000, // regular freq is 455kHz but to get a valid result 454,5 is used /*flags*/ LIRC_BO, /*header*/ 200,3125, // 1. start bit /*three*/ 0,0, /*two*/ 0,0, /*one*/ 200,9375, /*zero*/ 200,3125, /*plead*/ 0, /*ptrail*/ 200, // stop bit /*foot*/ 0,0, /*pre*/ 200,15625, //3. start bit /*post*/ 200,12500, // post bit /*repeat*/ 0,0, /*min_repeat*/ 0, /*duty cycle*/ 30, { 0x0000, // A -> 0x0000, // B -> 0x0000, // C -> 0x0000, // D -> 0x0000, // Betty -> 0xB44B, // Exit -> Exit 0x06F9, // Up -> UP 0x8679, // Down -> Down 0xA659, // Left -> Left 0x46B9, // Right -> Right 0x16E9, // OK -> OK 0x0160, // Vol+ -> Vol+ 0x0164, // Vol- -> Vol- 0xF00F, // Mute -> Mute 0x48B7, // Prog+ -> Prog+ 0x48B7, // Prog- -> Prog- 0x0101, // 1 -> 1 0x0102, // 2 -> 2 0x609F, // 3 -> 3 0x10EF, // 4 -> 4 0x906F, // 5 -> 5 0x50AF, // 6 -> 6 0x30CF, // 7 -> 7 0xB04F, // 8 -> 8 0x708F, // 9 -> 9 0x8877, // 0 -> 0 0xF20D, // -/-- -> Guide 0x0181, // AV -> Source 0x0f0c, // Menu -> Menue 0xD22D, // PiP -> Tools 0x1AE5, // A/B -> Return 0x7C83, // 16:9 -> P.Size 0xF807, // Info -> Info 0xD629, // VTX1 -> Ch.List 0x0000, // VTX2 -> 0xC837, // VTX3 -> Pre-CH 0x6897, // Blue -> Blue 0xA857, // Yello -> Yellow 0x28D7, // Green -> Green 0x36C9, // Red -> Red 0xC23D, // TV -> TV/DTV 0x0f0C // Power -> Standby }, \ No newline at end of file diff --git a/boop/infrared/ir_itt.c b/boop/infrared/ir_itt.c index 1156947..6294cc4 100644 --- a/boop/infrared/ir_itt.c +++ b/boop/infrared/ir_itt.c @@ -126,7 +126,6 @@ void __attribute__ ((section(".text.fastcode"))) ITT_Encode (void) } break; } - T1MR0 = cycles * ITT2_Module.lo_border * ITT2_Module.tval; } void ITT_LoadMap(unsigned char map) diff --git a/boop/infrared/ir_lirc.c b/boop/infrared/ir_lirc.c index 2dc4204..7e34d60 100644 --- a/boop/infrared/ir_lirc.c +++ b/boop/infrared/ir_lirc.c @@ -25,16 +25,18 @@ #include "lcd.h" #include "rf.h" #include "cc1100.h" -#include "pwm.h" #include "global.h" extern volatile unsigned char mod_enable; extern volatile unsigned int cycles; +extern volatile unsigned long keyMap[42]; -struct CODE_TABLE_L *lirctable; - -unsigned int prev_cycles; /* needed for handling of b&o specific protocol added MN2017325 */ +/* +#define RAW_IDLE 0x00 +#define RAW_HI 0x01 +#define RAW_LO 0x02 +*/ #define LIRC_IDLE 0x00 #define LIRC_HEAD_P 0x01 @@ -71,7 +73,7 @@ const struct irModule LIRC_Module = unsigned char __attribute__ ((section(".text.fastcode"))) send_data (unsigned long data, unsigned char pulse) { - const unsigned short* bittimes[4] = {&(lirctable->pzero), &(lirctable->pone), &(lirctable->ptwo), &(lirctable->pthree)}; + const unsigned char* bittimes[4] = {&(ir.lirc.pzero), &(ir.lirc.pone), &(ir.lirc.ptwo), &(ir.lirc.pthree)}; unsigned char notpulse = 1; if(pulse) { @@ -110,7 +112,7 @@ unsigned char __attribute__ ((section(".text.fastcode"))) send_data (unsigned lo cycles = bittimes[0][notpulse]; mod_enable = pulse; } - if((ir.lirc.bit+1 == lirctable->rc6_bit)) + if((ir.lirc.bit+1 == ir.lirc.rc6_bit)) cycles <<= 1; } else { @@ -130,97 +132,86 @@ unsigned char __attribute__ ((section(".text.fastcode"))) send_data (unsigned lo } void __attribute__ ((section(".text.fastcode"))) LIRC_Encode (void) { - unsigned long gap; + unsigned short gap; ir.lirc.cycles_counter += cycles; switch(ir.state) { case LIRC_IDLE: - cycles = lirctable->pone; + cycles = ir.lirc.pone; mod_enable = 0; break; case LIRC_HEAD_P: ir.lirc.cycles_counter = 0; - if(has_header && (!ir.lirc.repeats || (!(lirctable->flags&LIRC_NO_HEAD_REP) && !has_repeat) || (lirctable->flags&LIRC_REPEAT_HEADER))) { // + if(has_header && (!ir.lirc.repeats || (!(ir.lirc.flags&LIRC_NO_HEAD_REP) && !has_repeat) || (ir.lirc.flags&LIRC_REPEAT_HEADER))) { // mod_enable = 1; - cycles = lirctable->phead; + cycles = ir.lirc.phead; ir.state++; break; case LIRC_HEAD_S: mod_enable = 0; - cycles = lirctable->shead; + cycles = ir.lirc.shead; ir.state++; break; } ir.state = LIRC_LEAD_P; case LIRC_LEAD_P: - if(lirctable->plead) { + if(ir.lirc.plead) { mod_enable = 1; - cycles = lirctable->plead; + cycles = ir.lirc.plead; ir.state++; break; } ir.state++; case LIRC_PRE_DAT_P: if(!has_repeat || !(ir.lirc.repeats)) { - if(lirctable->pre_data_bits) { + if(ir.lirc.pre_data_bits) { send_data(ir.lirc.pre_data,1); ir.state++; break; case LIRC_PRE_DAT_S: ir.lirc.pre_data <<= send_data(ir.lirc.pre_data,0); - if(ir.lirc.bit >= lirctable->pre_data_bits) + if(ir.lirc.bit >= ir.lirc.pre_data_bits) ir.state++; else ir.state--; break; case LIRC_PRE_P: - if(lirctable->pre_p && lirctable->pre_s) { + if(ir.lirc.pre_p && ir.lirc.pre_s) { mod_enable = 1; - cycles = lirctable->pre_p; + cycles = ir.lirc.pre_p; ir.state++; break; case LIRC_PRE_S: mod_enable = 0; - cycles = lirctable->pre_s; + cycles = ir.lirc.pre_s; ir.state++; break; } } - ir.state = LIRC_DATA_P; - prev_cycles = 0; + ir.state = LIRC_DATA_P; case LIRC_DATA_P: send_data(ir.cmd,1); ir.state++; break; case LIRC_DATA_S: ir.cmd <<= send_data(ir.cmd,0); - /* handling for b&o specific protocol added MN2017325 - special r-bit coding, if current bit is equal previous bit */ - if(is_BO) { - if (prev_cycles == cycles) { - prev_cycles = cycles; - cycles = lirctable->szero * 2 ; - } else { - prev_cycles = cycles; - } - } - if(ir.lirc.bit >= lirctable->pre_data_bits + lirctable->bits) + if(ir.lirc.bit >= ir.lirc.pre_data_bits + ir.lirc.bits) ir.state++; else ir.state--; break; case LIRC_POST_P: - if(lirctable->post_data_bits) { - if(lirctable->post_p && lirctable->post_s) { + if(ir.lirc.post_data_bits) { + if(ir.lirc.post_p && ir.lirc.post_s) { mod_enable = 1; - cycles = lirctable->post_p; + cycles = ir.lirc.post_p; ir.state++; break; case LIRC_POST_S: mod_enable = 0; - cycles = lirctable->post_s; + cycles = ir.lirc.post_s; ir.state++; break; } @@ -230,8 +221,8 @@ void __attribute__ ((section(".text.fastcode"))) LIRC_Encode (void) { ir.state++; break; case LIRC_POST_DAT_S: - ir.lirc.post_data <<= send_data(ir.lirc.post_data,0); - if(ir.lirc.bit >= lirctable->pre_data_bits + lirctable->bits + lirctable->post_data_bits) + ir.lirc.post_data <<= send_data(ir.lirc.post_data,0); + if(ir.lirc.bit >= ir.lirc.pre_data_bits + ir.lirc.bits +ir.lirc.post_data_bits) ir.state = LIRC_TRAIL_P; else ir.state--; @@ -242,33 +233,33 @@ void __attribute__ ((section(".text.fastcode"))) LIRC_Encode (void) { case LIRC_REPEAT_P: if(has_repeat && ir.lirc.repeats) { mod_enable = 1; - cycles = lirctable->prepeat; + cycles = ir.lirc.prepeat; ir.state++; break; case LIRC_REPEAT_S: mod_enable = 0; - cycles = lirctable->srepeat; + cycles = ir.lirc.srepeat; ir.state++; break; } ir.state = LIRC_TRAIL_P; case LIRC_TRAIL_P: - if(lirctable->ptrail) { + if(ir.lirc.ptrail) { mod_enable = 1; - cycles = lirctable->ptrail; + cycles = ir.lirc.ptrail; ir.state++; break; } ir.state++; case LIRC_FOOT_S: - if(has_foot && (!ir.lirc.repeats || !(lirctable->flags&LIRC_NO_FOOT_REP)) && (!has_repeat || !ir.lirc.repeats)) { + if(has_foot && (!ir.lirc.repeats || !(ir.lirc.flags&LIRC_NO_FOOT_REP)) && (!has_repeat || !ir.lirc.repeats)) { mod_enable = 0; - cycles = lirctable->sfoot; + cycles = ir.lirc.sfoot; ir.state++; break; case LIRC_FOOT_P: mod_enable = 1; - cycles = lirctable->pfoot; + cycles = ir.lirc.pfoot; ir.state++; break; } @@ -280,17 +271,17 @@ void __attribute__ ((section(".text.fastcode"))) LIRC_Encode (void) { ir.lirc.pre_data = ir.lirc.actpre_data; ir.lirc.post_data = ir.lirc.actpost_data; - if((lirctable->repeat_gap && has_repeat && ir.lirc.repeats) | (is_RF && (ir.lirc.repeats >= lirctable->min_repeat))) - gap = lirctable->repeat_gap; + if((ir.lirc.repeat_gap && has_repeat && ir.lirc.repeats) | (is_RF && (ir.lirc.repeats >= ir.lirc.min_repeat))) + gap = ir.lirc.repeat_gap; else - gap = lirctable->gap; + gap = ir.lirc.gap; if(is_const && (ir.lirc.cycles_counter < gap)) cycles = gap - ir.lirc.cycles_counter; else cycles = gap; - if((ir.lirc.repeats >= lirctable->min_repeat) && ir.lirc.stop) { + if((ir.lirc.repeats >= ir.lirc.min_repeat) && ir.lirc.stop) { ir.state = LIRC_IDLE; } else { @@ -299,14 +290,12 @@ void __attribute__ ((section(".text.fastcode"))) LIRC_Encode (void) { ir.state = LIRC_HEAD_P; } } - - T1MR0 = 15 * cycles; - } void LIRC_Init(unsigned char map) { unsigned long freq; + struct CODE_TABLE_L *lirctable; if(map < LIRC.num_tables) { @@ -316,32 +305,90 @@ void LIRC_Init(unsigned char map) setIR(LIRC_Module); if(lirctable->flags&LIRC_RF) { - ir.duty_cycle = 50; + hi_border = 0; + lo_border = 1; freq = 20000; } else { freq = lirctable->freq; if(!freq) freq = 38000; - - ir.duty_cycle = lirctable->duty_cycle; - if(!lirctable->duty_cycle) { //default 50% - ir.duty_cycle = 50; + + if(lirctable->duty_cycle == 0) { //default 50% + hi_border = 1; + lo_border = 2; + } + else if(lirctable->duty_cycle <= 25) { + hi_border = 1; + lo_border = 4; + } + else if(lirctable->duty_cycle <= 33) { + hi_border = 1; + lo_border = 3; + } + else if(lirctable->duty_cycle <= 50) { + hi_border = 1; + lo_border = 2; + } + else if(lirctable->duty_cycle <= 66) { + hi_border = 2; + lo_border = 3; + } + else { //75% + hi_border = 3; + lo_border = 4; } } - PWM_set_frequency(freq); - - T1MR0 = 15000000 / (freq); + T1MR0 = 15000000 / (freq * lo_border); + + ir.lirc.phead = (lirctable->phead * freq) / 1000000; + ir.lirc.shead = (lirctable->shead * freq) / 1000000; + + ir.lirc.plead = (lirctable->plead * freq) / 1000000; + ir.lirc.actpre_data = (lirctable->pre_data)<<(32-lirctable->pre_data_bits); + ir.lirc.pre_data_bits = lirctable->pre_data_bits; + ir.lirc.pre_p = (lirctable->pre_p * freq) / 1000000; + ir.lirc.pre_s = (lirctable->pre_s * freq) / 1000000; + + ir.lirc.post_p = (lirctable->post_p * freq) / 1000000; + ir.lirc.post_s = (lirctable->post_s * freq) / 1000000; ir.lirc.actpost_data = (lirctable->post_data)<<(32-lirctable->post_data_bits); - + ir.lirc.post_data_bits = lirctable->post_data_bits; + + ir.lirc.ptrail = (lirctable->ptrail * freq) / 1000000; + + ir.lirc.pfoot = (lirctable->pfoot * freq) / 1000000; + ir.lirc.sfoot = (lirctable->sfoot * freq) / 1000000; + + ir.lirc.prepeat = (lirctable->prepeat * freq) / 1000000; + ir.lirc.srepeat = (lirctable->srepeat * freq) / 1000000; + + ir.lirc.pzero = (lirctable->pzero * freq) / 1000000; + ir.lirc.szero = (lirctable->szero * freq) / 1000000; + ir.lirc.pone = (lirctable->pone * freq) / 1000000; + ir.lirc.sone = (lirctable->sone * freq) / 1000000; + ir.lirc.ptwo = (lirctable->ptwo * freq) / 1000000; + ir.lirc.stwo = (lirctable->stwo * freq) / 1000000; + ir.lirc.pthree = (lirctable->pthree * freq) / 1000000; + ir.lirc.sthree = (lirctable->sthree * freq) / 1000000; + + ir.lirc.gap = (lirctable->gap * freq) / 1000000; + ir.lirc.repeat_gap = (lirctable->repeat_gap * freq) / 1000000; + + ir.lirc.rc6_bit = lirctable->rc6_bit; + ir.lirc.flags = lirctable->flags; + ir.lirc.bits = lirctable->bits; + ir.lirc.min_repeat = lirctable->min_repeat; + ir.cmd = 0; ir.actcmd = 0; ir.lirc.stop = 0; ir.state = LIRC_IDLE; ir.lirc.bit = 0; + ir.lirc.map = map; } } @@ -352,19 +399,19 @@ void LIRC_Send(unsigned long cmd) if(cmd != 0x0000) { ir.lirc.pre_data = ir.lirc.actpre_data; - ir.actcmd = cmd<<(32-lirctable->bits); + ir.actcmd = cmd<<(32-ir.lirc.bits); ir.lirc.post_data = ir.lirc.actpost_data; ir.lirc.stop = 0; ir.lirc.repeats = 0; if(ir.toggle & 0x01) { - togglemask = (unsigned long)(lirctable->toggle_bit_mask) << (32-lirctable->post_data_bits); + togglemask = (unsigned long)(LIRC.table[ir.lirc.map].toggle_bit_mask) << (32-ir.lirc.post_data_bits); ir.lirc.post_data ^= togglemask; - togglemask = (unsigned long)(lirctable->toggle_bit_mask>>lirctable->post_data_bits) << (32-lirctable->bits); + togglemask = (unsigned long)(LIRC.table[ir.lirc.map].toggle_bit_mask>>ir.lirc.post_data_bits) << (32-ir.lirc.bits); ir.actcmd ^= togglemask; - togglemask = (unsigned long)(lirctable->toggle_bit_mask>>(lirctable->post_data_bits + lirctable->bits)) << (32-lirctable->pre_data_bits); + togglemask = (unsigned long)(LIRC.table[ir.lirc.map].toggle_bit_mask>>(ir.lirc.post_data_bits + ir.lirc.bits)) << (32-ir.lirc.pre_data_bits); ir.lirc.pre_data ^= togglemask; } @@ -374,9 +421,9 @@ void LIRC_Send(unsigned long cmd) ir.state++; if(is_RF) { RFasyncmode(true); - cc1100_write1(FREQ2,((lirctable->freq)>>16) & 0xFF); - cc1100_write1(FREQ1,((lirctable->freq)>>8) & 0xFF); - cc1100_write1(FREQ0,(lirctable->freq) & 0xFF); + cc1100_write1(FREQ2,((LIRC.table[ir.lirc.map].freq)>>16) & 0xFF); + cc1100_write1(FREQ1,((LIRC.table[ir.lirc.map].freq)>>8) & 0xFF); + cc1100_write1(FREQ0,(LIRC.table[ir.lirc.map].freq) & 0xFF); cc1100_strobe(STX); } runIR(); @@ -391,7 +438,7 @@ void LIRC_Repeat(void) { void LIRC_Stop(void) { ir.lirc.stop = 1; - if(lirctable->bits){ + if(ir.lirc.bits){ while(ir.state != LIRC_IDLE); } diff --git a/boop/infrared/ir_lirc.h b/boop/infrared/ir_lirc.h index 3541a87..2154aa9 100644 --- a/boop/infrared/ir_lirc.h +++ b/boop/infrared/ir_lirc.h @@ -28,10 +28,10 @@ //#define LIRC_SPACE_FIRST 0x0020 /* bits are encoded as space+pulse */ //#define LIRC_GOLDSTAR 0x0040 /* encoding found on Goldstar remote */ //#define LIRC_GRUNDIG 0x0080 /* encoding found on Grundig remote */ -#define LIRC_BO 0x0100 /* encoding found on Bang & Olufsen remote */ -#define LIRC_RF 0x0200 /* RF ASK/OOK modulator */ -//#define LIRC_SERIAL 0x0400 /* serial protocol */ -//#define LIRC_XMP 0x0800 /* XMP protocol */ +//#define LIRC_BO 0x0100 /* encoding found on Bang & Olufsen remote */ +#define LIRC_RF 0x0100 /* RF ASK/OOK modulator */ +//#define LIRC_SERIAL 0x0200 /* serial protocol */ +//#define LIRC_XMP 0x0400 /* XMP protocol */ /* additinal flags: can be orred together with protocol flag */ //#define REVERSE 0x0800 @@ -40,15 +40,14 @@ #define LIRC_CONST_LENGTH 0x4000 /* signal length+gap is always constant */ #define LIRC_REPEAT_HEADER 0x8000 /* header is also sent before repeat code */ -#define is_rc6 (lirctable->flags & LIRC_RC6) -#define is_biphase ((lirctable->flags & LIRC_RC5) || is_rc6) -#define is_rcmm (lirctable->flags & LIRC_RCMM) -#define is_const (lirctable->flags & LIRC_CONST_LENGTH) -#define is_RF (lirctable->flags & LIRC_RF) -#define is_BO (lirctable->flags & LIRC_BO) /* flag for b&o specific protocol MN2017325 */ -#define has_header (lirctable->phead && lirctable->shead) -#define has_foot (lirctable->pfoot && lirctable->sfoot) -#define has_repeat (lirctable->prepeat && lirctable->srepeat) +#define is_rc6 (ir.lirc.flags & LIRC_RC6) +#define is_biphase ((ir.lirc.flags & LIRC_RC5) || is_rc6) +#define is_rcmm (ir.lirc.flags & LIRC_RCMM) +#define is_const (ir.lirc.flags & LIRC_CONST_LENGTH) +#define is_RF (ir.lirc.flags & LIRC_RF) +#define has_header (ir.lirc.phead && ir.lirc.shead) +#define has_foot (ir.lirc.pfoot && ir.lirc.sfoot) +#define has_repeat (ir.lirc.prepeat && ir.lirc.srepeat) //FS20 Protocol description see http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol #define calcFS20pre(HC1,par1,HC2,par2) ((1<<18) | (HC1<<10) | (par1<<9) | (HC2<<1) | par2) diff --git a/boop/infrared/ir_nrc17.c b/boop/infrared/ir_nrc17.c index 229caf4..afbe81f 100644 --- a/boop/infrared/ir_nrc17.c +++ b/boop/infrared/ir_nrc17.c @@ -115,7 +115,6 @@ void __attribute__ ((section(".text.fastcode"))) NRC17_Encode(void) break; } - T1MR0 = cycles * NRC17_Module.lo_border * NRC17_Module.tval; } /* void NRC17_CopyMap(unsigned char xtra, unsigned short *map) diff --git a/boop/infrared/ir_rc5.c b/boop/infrared/ir_rc5.c index 624620f..8c6c6c1 100644 --- a/boop/infrared/ir_rc5.c +++ b/boop/infrared/ir_rc5.c @@ -98,7 +98,6 @@ void __attribute__ ((section(".text.fastcode"))) RC5_Encode (void) } break; } - T1MR0 = cycles * RC5_Module.lo_border * RC5_Module.tval; } void RC5_Init(unsigned char map) diff --git a/boop/infrared/ir_rc6.c b/boop/infrared/ir_rc6.c index 990fa08..d42b43a 100644 --- a/boop/infrared/ir_rc6.c +++ b/boop/infrared/ir_rc6.c @@ -148,7 +148,6 @@ void __attribute__ ((section(".text.fastcode"))) RC6_Encode (void) } break; } - T1MR0 = cycles * RC6_Module.lo_border * RC6_Module.tval; } void RC6_Init(unsigned char map) diff --git a/boop/infrared/ir_rca.c b/boop/infrared/ir_rca.c index 1ba24d7..84e95d5 100644 --- a/boop/infrared/ir_rca.c +++ b/boop/infrared/ir_rca.c @@ -120,7 +120,6 @@ void __attribute__ ((section(".text.fastcode"))) RCA_Encode (void) } break; } - T1MR0 = cycles * RCA_Module.lo_border * RCA_Module.tval; } void RCA_LoadMap(unsigned char map) diff --git a/boop/infrared/ir_rcmm.c b/boop/infrared/ir_rcmm.c index e477185..2424391 100644 --- a/boop/infrared/ir_rcmm.c +++ b/boop/infrared/ir_rcmm.c @@ -117,7 +117,6 @@ void __attribute__ ((section(".text.fastcode"))) RCMM_Encode (void) } - T1MR0 = cycles * RCMM_Module.lo_border * RCMM_Module.tval; } void RCMM_LoadMap(unsigned char map) diff --git a/boop/infrared/ir_rec80.c b/boop/infrared/ir_rec80.c index 02fb5f7..6f4f8b1 100644 --- a/boop/infrared/ir_rec80.c +++ b/boop/infrared/ir_rec80.c @@ -117,7 +117,6 @@ void __attribute__ ((section(".text.fastcode"))) REC80_Encode (void) } break; } - T1MR0 = cycles * REC80_Module.lo_border * REC80_Module.tval; } void REC80_LoadMap(unsigned char map) diff --git a/boop/infrared/ir_recs80.c b/boop/infrared/ir_recs80.c index cabd96b..d15dbd1 100644 --- a/boop/infrared/ir_recs80.c +++ b/boop/infrared/ir_recs80.c @@ -90,7 +90,6 @@ void __attribute__ ((section(".text.fastcode"))) RECS80_Encode (void) } break; } - T1MR0 = cycles * RECS80_Module.lo_border * RECS80_Module.tval; } void RECS80_Init(unsigned char map) diff --git a/boop/infrared/ir_rf.c b/boop/infrared/ir_rf.c index 8032b17..b1dcbe3 100644 --- a/boop/infrared/ir_rf.c +++ b/boop/infrared/ir_rf.c @@ -42,7 +42,7 @@ extern volatile unsigned long keyMap[42]; #define IRRF_WAIT 0x01 #define IRRF_BITTIME 40 -#define IRRF_WAITTIME 100 +#define IRRF_WAITTIME 125 void __attribute__ ((section(".text.fastcode"))) IRRF_Encode (void) { @@ -63,7 +63,6 @@ void __attribute__ ((section(".text.fastcode"))) IRRF_Encode (void) } break; } - T1MR0 = 15*1000; } void IRRF_Init(unsigned char map) @@ -101,10 +100,9 @@ void IRRF_Repeat(void) struct RFendpoint_* cur_ep; cur_ep = (struct RFendpoint_*)ir.general.trail; if((cur_ep) && !(cur_ep->flags & EPnewdata)) { - cur_ep->dest = 0; - cur_ep->data[1] = (ir.actcmd & 0x00ff); - cur_ep->data[0] = (ir.actcmd & 0xff00) >> 8; - cur_ep->bufferlen = 2; + cur_ep->dest = (ir.actcmd & 0xff00) >> 8; + cur_ep->data[0] = (ir.actcmd & 0x00ff); + cur_ep->bufferlen = 1; cur_ep->flags |= EPenabled | EPoutput | EPnewdata; RF_changestate(RFtx); diff --git a/boop/infrared/ir_sirc.c b/boop/infrared/ir_sirc.c index dd9e4b4..0bcfa8a 100644 --- a/boop/infrared/ir_sirc.c +++ b/boop/infrared/ir_sirc.c @@ -103,8 +103,6 @@ void __attribute__ ((section(".text.fastcode"))) SIRC_Encode (void) break; } - - T1MR0 = cycles * SIRC_Module.lo_border * SIRC_Module.tval; } void SIRC_Init(unsigned char map) diff --git a/boop/infrared/ir_spaceenc.c b/boop/infrared/ir_spaceenc.c index 73b0228..d6c0ccc 100644 --- a/boop/infrared/ir_spaceenc.c +++ b/boop/infrared/ir_spaceenc.c @@ -137,7 +137,6 @@ void __attribute__ ((section(".text.fastcode"))) SPACEENC_Encode (void) } break; } - T1MR0 = cycles * SPACEENC_Module.lo_border * SPACEENC_Module.tval; } void SPACEENC_LoadMap(unsigned char map) diff --git a/boop/infrared/pwm.c b/boop/infrared/pwm.c deleted file mode 100644 index 7c891c6..0000000 --- a/boop/infrared/pwm.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - pwm.c - pwm control - Copyright (C) 2017 - - 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 3 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 this program. If not, see . -*/ - -#include "global.h" -#include "lpc2220.h" -#include "irq.h" - -void PWM_init(void) -{ - //Set pin P0.21 IR_OUT as PWM - PINSEL1 &= ~(3 << (10)); // IO - PINSEL1 |= (1 << (10)); // PWM5 - - PWMTC = 0; //Timer Counter - PWMPR = 0; //Prescale Register - PWMPC = 0; //Prescale Counter - - PWMMR0 = 416; // pwm rate - PWMMR2 = 0x00; // pwm value sound - PWMMR5 = 0x00; // pwm value IR - - PWMLER = 0x26; //Latch Enable - PWMMCR = 0x03; //Match Control - PWMPCR |= (1<<13) | (1<<10); - PWMTCR = 0x03; - PWMTCR = 0x09; - - /* PWMTC = 0; - PWMPR = 7; - PWMMR0 = 0x1E6; // pwm rate - PWMMR2 = 0x00; // pwm value - PWMLER = 0x05; - PWMPCR = (1<<10); -*/ - - //VICVectAddr0 = (unsigned long)&(soundIRQ); - //VICVectCntl0 = VIC_SLOT_EN | INT_SRC_PWM; - VICIntSelect |= INT_PWM; - VICIntEnable = INT_PWM; - -} - -void PWM_set_frequency(unsigned long f) -{ - if(f<5000) { - PWMPR = 7; - PWMMR0 = 1875000 / f; - } else { - PWMPR = 0; - PWMMR0 = 15000000 / f; - } - PWMLER |= 0x01; //Latch Enable - - - if(f < 32000) { - PWMMCR = 0x03; - } else { - PWMMCR = 0x02; - } - -} - -void PWM_set_IR_duty_cycle(unsigned char d) { - PWMMR5 = (PWMMR0 * d) / 100; - PWMLER |= 0x20; -} - diff --git a/boop/infrared/pwm.h b/boop/infrared/pwm.h deleted file mode 100644 index 8d47ff6..0000000 --- a/boop/infrared/pwm.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - pwm.h - pwm control - Copyright (C) 2017 - - 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 3 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 this program. If not, see . -*/ - -#pragma once - - -void PWM_init(void); -void PWM_set_frequency(unsigned long f); -void PWM_set_IR_duty_cycle(unsigned char d); - - diff --git a/boop/interrupt/irq.c b/boop/interrupt/irq.c index 331fa55..9c8f965 100644 --- a/boop/interrupt/irq.c +++ b/boop/interrupt/irq.c @@ -71,12 +71,12 @@ unsigned restoreIRQ(unsigned oldCPSR) // (where's the vector? in lpc2220_rom.ld ?) void __attribute__ ((section(".text.fastcode"))) FIQ_Routine (void) { - //while ((PWMIR == 0x01)) + while ((PWMIR == 0x01) || (T1IR == 1)) { if (PWMIR == 0x01) soundIRQ(); // sound, backlight - //if (T1IR == 1) - // irIRQ(); // IR + if (T1IR == 1) + irIRQ(); // IR } } diff --git a/boop/main.c b/boop/main.c index 9744389..5f8fba8 100644 --- a/boop/main.c +++ b/boop/main.c @@ -31,7 +31,6 @@ //#include "sounds.h" //#include "sound3.h" #include "infrared.h" -#include "pwm.h" #include "codes.h" #include "encoders.h" #include "ir_selector.h" @@ -88,8 +87,8 @@ void setSpeed(unsigned char sp) VPBDIV = 0x00; - BCFG0 = 0x10001CA0; - BCFG2 = 0x10001CA0; + BCFG0 = 0x100004A0; + BCFG2 = 0x100004A0; BCFG1 = 0x00000C21; sysInfo |= SYS_TURBO; break; @@ -103,8 +102,8 @@ void setSpeed(unsigned char sp) VPBDIV = 0x02; - BCFG0 = 0x10000A20; - BCFG2 = 0x10000A20; + BCFG0 = 0x10000420; + BCFG2 = 0x10000420; BCFG1 = 0x00000400; sysInfo &= ~SYS_TURBO; break; @@ -199,8 +198,6 @@ void cpu_idle () if(U0SCR) return; - return; - /* only idle mode instead of power down when: * * backlight on * * IR transmission @@ -243,8 +240,7 @@ int main(void) FIOSET0 |= (1<<12); FIOCLR0 |= (1<<4); - setSpeed(SPEED_60); - BFS_Mount(); // flash file system + setSpeed(SPEED_30); lcd_init(0); serial_init(); @@ -255,13 +251,11 @@ int main(void) initKeys(); initSound(); - //startSoundIRQ(); + startSoundIRQ(); initIR(); startIrIRQ(); - PWM_init(); - RF_init(); load_RF_setting(); startRFIRQ(); @@ -285,8 +279,10 @@ int main(void) set_font(BOLDFONT); - load_setting(); // display settings + BFS_Mount(); // flash file system load_RC_setting(); // learned remote codes + load_setting(); // display settings + // recorded raw IR commands { diff --git a/boop/timer/timerfuncs.c b/boop/timer/timerfuncs.c index 7467050..f7749c1 100644 --- a/boop/timer/timerfuncs.c +++ b/boop/timer/timerfuncs.c @@ -42,7 +42,7 @@ void startTimerIRQ(void) T0TCR = 0x02; // reset timer T0TC = 1870; T0PR = 0x0e; // 15.000.000 Hz / 15 = 1.000.000 Hz --> PR = 15 - 1 = 0x0e - T0MR0 = 250; // 1.000.000 Hz / 250 = 4000 Hz = 0,25msec intervall time + T0MR0 = 5000; // 1.000.000 Hz / 5000 = 200 Hz = 5 msec intervall time T0MCR = 0x03; // reset and issue IRQ on TC == MR0 T0TCR = 0x01; // enable timer diff --git a/boop/timer/timerirq.c b/boop/timer/timerirq.c index 873274f..a19cfae 100644 --- a/boop/timer/timerirq.c +++ b/boop/timer/timerirq.c @@ -21,37 +21,14 @@ #include "timerfuncs.h" #include "lcd.h" -#define TIMER_PRESCALER 20 - struct CB callbacks[MAX_CB]; unsigned long* timeouts[MAX_TO]; -unsigned char timerPrescaler = TIMER_PRESCALER; -unsigned char bl_val, cmp_val; // backlight PWM -// wird alle 0.25 ms aufgerufen (s. startTimerIRQ() in timerfuncs) + +// wird alle 5 ms aufgerufen (s. startTimerIRQ() in timerfuncs) // bearbeitet eingetragene "timer" void __attribute__ ((section(".text.fastcode"))) timerIRQ(void) { - // backlight pwm - cmp_val += bl_val; - if (cmp_val >= 63) - { - FIODIR0 |= (1<<4); // sck0/P0.4 - cmp_val -= 63; - } - else - { - FIODIR0 &= ~(1<<4); // sck0/P0.4 - } - - - if(--timerPrescaler) { - T0IR = 1; - return; - } - timerPrescaler = TIMER_PRESCALER; - - //5 msec intervall time unsigned int cnt; struct CB *cur_cb;