diff --git a/flash/administra/admflash.spin b/flash/administra/admflash.spin index 3e49ac2..a7e9831 100644 --- a/flash/administra/admflash.spin +++ b/flash/administra/admflash.spin @@ -80,6 +80,7 @@ COG's : MANAGMENT 1 COG SIDCog's 2 COG's DMP/Tracker 1 COG (dynamisch) NET 2 COG + DCF receiver 1 COG Defines : __ADM_FAT enable FAT engine (sd card handling) __ADM_HSS enable HSS synthesizer @@ -89,6 +90,8 @@ Defines : __ADM_FAT enable FAT engine (sd card handling) __ADM_LAN enable LAN functions __ADM_RTC enable RTC functions (FAT engine inherits it also) __ADM_PLX enable plexbus + __ADM_DCF enable DCF77 receiver + __ADM_BLT enable Bluetooth __ADM_COM enable serial port __ADM_AYS enable AYS player @@ -159,17 +162,20 @@ Notizen : CON ''default defines (please anable to compile from GUI) -'#define __ADM_FAT +#define __ADM_FAT '#define __ADM_HSS '#define __ADM_HSS_PLAY '#define __ADM_WAV -'#define __ADM_RTC +#define __ADM_RTC '#define __ADM_COM ''other defines '#define __ADM_LAN -'#define __ADM_SID +#define __ADM_SID '#define __ADM_AYS +#define __ADM_PLX +#define __ADM_DCF +#define __ADM_BLT _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 @@ -243,7 +249,19 @@ CHIP_SPEC_AYS = gc#A_AYS CHIP_SPEC_AYS = 0 #endif -CHIP_SPEC = CHIP_SPEC_FAT|CHIP_SPEC_LDR|CHIP_SPEC_HSS|CHIP_SPEC_WAV|CHIP_SPEC_SID|CHIP_SPEC_LAN|CHIP_SPEC_RTC|CHIP_SPEC_PLX|CHIP_SPEC_COM|CHIP_SPEC_AYS +#ifdef __ADM_DCF +CHIP_SPEC_DCF = gc#A_DCF +#else +CHIP_SPEC_DCF = 0 +#endif + +#ifdef __ADM_BLT +CHIP_SPEC_BLT = gc#A_BLT +#else +CHIP_SPEC_BLT = 0 +#endif + +CHIP_SPEC = CHIP_SPEC_FAT|CHIP_SPEC_LDR|CHIP_SPEC_HSS|CHIP_SPEC_WAV|CHIP_SPEC_SID|CHIP_SPEC_LAN|CHIP_SPEC_RTC|CHIP_SPEC_PLX|CHIP_SPEC_COM|CHIP_SPEC_AYS|CHIP_SPEC_DCF|CHIP_SPEC_BLT ' ' hbeat --------+ ' clk -------+| @@ -330,6 +348,12 @@ OBJ sock : "driver_socket" 'LAN num : "glob-numbers" 'Number Engine #endif +#ifdef __ADM_PLX + com : "adm-plx" 'PlexBux +#endif +#ifdef __ADM_DCF + dcf : "adm-dcf" 'DCF-77 +#endif gc : "glob-con" 'globale konstanten @@ -339,6 +363,9 @@ VAR byte tbuf2[20] byte fl_syssnd '1 = systemtöne an byte st_sound '0 = aus, 1 = hss, 2 = wav +#ifdef __ADM_DCF + byte dcfon 'DCF-Betriebsmerker +#endif CON ''------------------------------------------------- ADMINISTRA @@ -350,6 +377,12 @@ PUB main | cmd,err 'chip: kommandointerpret init_chip 'bus/vga/keyboard/maus initialisieren repeat +#ifdef __ADM_DCF + if dcfon + if dcf.GetInSync==1 + if dcf.GetBitNumber==59 'Zeittelegramm gültig?, dann RTC synchronisieren (jedes gültige Telegramm) + dcf_updateRTC +#endif '__ADM_DCF cmd := bus_getchar 'kommandocode empfangen err := 0 case cmd @@ -396,8 +429,15 @@ PUB main | cmd,err 'chip: kommandointerpret gc#a_comRx: com_rx #endif '__ADM_COM +' ---------------------------------------------- Bluetooth-FUNKTIONEN +#ifdef __ADM_BLT + gc#a_bltCommand_On: blt_setCommandMode + gc#a_bltCommand_Off: blt_setNormalMode +#endif '__ADM_BLT + ' ---------------------------------------------- RTC-FUNKTIONEN #ifdef __ADM_RTC + gc#a_rtcTest: rtc_test 'Test if RTC Chip is available gc#a_rtcGetSeconds: rtc_getSeconds 'Returns the current second (0 - 59) from the real time clock. gc#a_rtcGetMinutes: rtc_getMinutes 'Returns the current minute (0 - 59) from the real time clock. gc#a_rtcGetHours: rtc_getHours 'Returns the current hour (0 - 23) from the real time clock. @@ -416,9 +456,31 @@ PUB main | cmd,err 'chip: kommandointerpret gc#a_rtcGetNVSRAM: rtc_getNVSRAM 'Gets the selected NVSRAM value at the index (0 - 55). gc#a_rtcPauseForSec: rtc_pauseForSeconds 'Pauses execution for a number of seconds. Returns a puesdo random value derived from the current clock frequency and the time when called. Number - Number of seconds to pause for between 0 and 2,147,483,647. gc#a_rtcPauseForMSec: rtc_pauseForMilliseconds 'Pauses execution for a number of milliseconds. Returns a puesdo random value derived from the current clock frequency and the time when called. Number - Number of milliseconds to pause for between 0 and 2,147,483,647. - gc#a_rtcTest: rtc_test 'Test if RTC Chip is available + gc#a_rtcGetTime: rtc_getTime 'Returns the current hour, minute and second from the real time clock. #endif '__ADM_RTC +' ---------------------------------------------- DCF77-FUNKTIONEN +#ifdef __ADM_DCF + gc#a_dcfGetInSync: dcf_getInSync 'Sync-Status senden + gc#a_dcfUpdateRTC: dcf_updateRTC 'RTC Synchronisieren + gc#a_dcfGetBitError: dcf_getBitError + gc#a_dcfGetDataCount: dcf_getDataCount + gc#a_dcfGetBitNumber: dcf_getBitNumber + gc#a_dcfGetBitLevel: dcf_getBitLevel + gc#a_dcfGetTimeZone: dcf_getTimeZone + gc#a_dcfGetActiveSet: dcf_getActiveSet + gc#a_dcfStart: dcf_start 'DCF-Empfang starten + gc#a_dcfStop: dcf_stop 'DCF-Empfang stoppen + gc#a_dcfState: dcf_state 'Status des DCF-Empfängers + gc#a_dcfGetSeconds: dcf_getSeconds + gc#a_dcfGetMinutes: dcf_getMinutes + gc#a_dcfGetHours: dcf_getHours + gc#a_dcfGetWeekDay: dcf_getWeekDay + gc#a_dcfGetDay: dcf_getDay + gc#a_dcfGetMonth: dcf_getMonth + gc#a_dcfGetYear: dcf_getYear +#endif '__ADM_DCF + ' ---------------------------------------------- LAN-FUNKTIONEN #ifdef __ADM_LAN gc#a_lanStart: lan_start 'Start Network @@ -593,7 +655,7 @@ PRI init_chip | err,i,j 'chip: initialisierung d #ifdef __ADM_COM 'serielle schnittstelle starten com_baud := 9600 - com.start(gc#SER_RX,gc#SER_TX,0,com_baud) ' start the default serial interface + com.start(gc#SER_RX,gc#SER_TX,0,com_baud) 'start the default serial interface #endif '__ADM_COM #ifdef __ADM_LAN @@ -601,6 +663,11 @@ PRI init_chip | err,i,j 'chip: initialisierung d lan_started := false 'LAN noch nicht gestartet #endif '__ADM_LAN +#ifdef __ADM_DCF + 'DCF-77 + dcfon:=0 +#endif '__ADM_DCF + PRI bus_putchar(zeichen) 'chip: ein byte über bus ausgeben ''funktionsgruppe : chip ''funktion : senderoutine für ein byte zu regnatix über den systembus @@ -1398,6 +1465,22 @@ CON ''------------------------------------------------- End of COM FUNCTIONS #endif ' __ADM_COM +CON ''------------------------------------------------- Bluetooth FUNCTIONS + +#ifdef __ADM_BLT + +PRI blt_setCommandMode + dira[gc#A_Bluetooth_Line]:=1 + outa[gc#A_Bluetooth_Line]:=1 + +PRI blt_setNormalMode + outa[gc#A_Bluetooth_Line]:=0 + dira[gc#A_Bluetooth_Line]:=0 + +CON ''------------------------------------------------- End of Bluetooth FUNCTIONS + +#endif ' __ADM_BLT + CON ''------------------------------------------------- HSS-FUNKTIONEN #ifdef __ADM_HSS @@ -2055,10 +2138,108 @@ PRI rtc_test 'rtc: Test if RTC Chip i '' : Returns TRUE if RTC is available, otherwise FALSE bus_putchar(probeRTC) +PRI rtc_getTime + + sub_putlong(rtc.getHours) + sub_putlong(rtc.getMinutes) + sub_putlong(rtc.getSeconds) + CON ''------------------------------------------------- End of RTC FUNCTIONS #endif ' __ADM_RTC +CON ''------------------------------------------------- DCF77-FUNKTIONEN + +#ifdef __ADM_DCF + +VAR + +PRI dcf_getInSync 'dcf: Sync-Status senden + + bus_putchar(dcf.GetInSync) + +PRI dcf_updateRTC 'dcf: RTC Synchronisieren + +#ifdef __ADM_RTC + rtc.setHours(dcf.GetHours) + rtc.setMinutes(dcf.GetMinutes) + rtc.setSeconds(dcf.GetSeconds) + rtc.setYear(dcf.GetYear) + rtc.setMonth(dcf.GetMonth) + rtc.setDate(dcf.GetDay) + rtc.setDay(dcf.GetWeekDay) +#endif ' __ADM_RTC + +PRI dcf_getBitError + + bus_putchar(dcf.GetBitError) + +PRI dcf_getDataCount + + bus_putchar(dcf.GetDatacount) + +PRI dcf_getBitNumber + + bus_putchar(dcf.GetBitNumber) + +PRI dcf_getBitLevel + + bus_putchar(dcf.GetBitLevel) + +PRI dcf_getTimeZone + + bus_putchar(dcf.GetTimeZone) + +PRI dcf_getActiveSet + + bus_putchar(dcf.GetActiveSet) + +PRI dcf_start 'dcf: DCF-Empfang starten + + dcf.start + dcfon:=1 + +PRI dcf_stop 'dcf: DCF-Empfang stoppen + + dcf.stop + dcfon:=0 + +PRI dcf_state 'dcf: Status des DCF-Empfängers + + bus_putchar(dcfon) + +PRI dcf_getSeconds + + bus_putchar(dcf.GetSeconds) + +PRI dcf_getMinutes + + bus_putchar(dcf.GetMinutes) + +PRI dcf_getHours + + bus_putchar(dcf.GetHours) + +PRI dcf_getWeekDay + + bus_putchar(dcf.GetWeekDay) + +PRI dcf_getDay + + bus_putchar(dcf.GetDay) + +PRI dcf_getMonth + + bus_putchar(dcf.GetMonth) + +PRI dcf_getYear + + sub_putword(dcf.GetYear) + +CON ''------------------------------------------------- End of DCF77 FUNCTIONS + +#endif ' __ADM_DCF + CON ''------------------------------------------------- LAN-FUNKTIONEN #ifdef __ADM_LAN diff --git a/lib/adm-dcf.spin b/lib/adm-dcf.spin new file mode 100644 index 0000000..7744477 --- /dev/null +++ b/lib/adm-dcf.spin @@ -0,0 +1,524 @@ +{{******************************************************************************} +{ FileName............: Dcf77.spin } +{ Project.............: } +{ Author(s)...........: MM } +{ Version.............: 1.00 } +{------------------------------------------------------------------------------} +{ DCF77 (clock) control } +{ } +{ Copyright (C) 2006-2007 M.Majoor } +{ } +{ This program is free software; you can redistribute it and/or } +{ modify it under the terms of the GNU General Public License } +{ as published by the Free Software Foundation; either version 2 } +{ of the License, or (at your option) any later version. } +{ } +{ This program is distributed in the hope that it will be useful, } +{ but WITHOUT ANY WARRANTY; without even the implied warranty of } +{ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the } +{ GNU General Public License for more details. } +{ } +{ You should have received a copy of the GNU General Public License } +{ along with this program; if not, write to the Free Software } +{ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. } +{ } +{------------------------------------------------------------------------------} +{ } +{ Version Date Comment } +{ 1.00 20070727 - Initial release } +{******************************************************************************} + +{------------------------------------------------------------------------------} + DCF77 is a time signal being transmitted by 'radio'. The time signal being + transmitted is based on an atomic clock. + This code assumes we have a DCF77 receiver with a digital output. This output + is connected to one of the available input pins. + The output pin of the DCF77 receiver changes it output according to the + received radio signal. This radio signal is an amplitude modulated signal. + The amplitude level is converted into a digital signal by the DCF77 receiver. + A typical output signal of a DCF77 receiver is: + + ┌──┐ ┌──┐ ┌─┐ + │ │ │ │ │ │ + │ │ │ │ │ │ + │ │ │ │ │ │ + ┘ └─────────────────┘ └───────────────────┘ └────────────────── + + The spacing of these pulses is 1 second. Every second the amplitude signal is + being lowered for a small duration (0.1 s or 0.2 s). This lowered amplitude + is being output as a pulse here. + The duration of the pulse defines whether it represents a digital '0' or a + digital '1'. + These digital '0' and '1' together form a digital representation of the time. + This digital stream of bits is being transmitted within one minute. The next + minute a new digital stream starts. + For synchronization purposes there will be no pulse when the 59's digital signal + is being transmitted. This is used to indicate the start of the next digital + stream (and the next minute). + The pulse length is converted into a binary signal according to its length: + 0.1s --> '0' + 0.2s --> '1' + + The digital stream format is (with the first received bit at the right): + + 5 555555555 44444 444 443333 3333332 22222222 211111 11111 + Sec 9 876543210 98765 432 109876 5432109 87654321 098765 432109876543210 + + D P84218421 18421 421 218421 P218421 P4218421 SAZZAR + 30000 0 00 200 1000 2211 + + + + R = Call bit (irregularities in DCF77 control facilities) + + A1 = '1' Imminent change-over of time from CET <-> CEST + Transmitted 1 hour prior to change (refelected in Z1/Z2) + Z1 = Zone time bit 0 '10' = CET ; UTC + 1 hour + Z2 = Zone time bit 1 '01' = CEST; DST ; dayligt saving time, UTC + 2 hours + A2 = '1' Imminent change-over of leap second + Transmitted 1 hour prior to change (January 1/July 1) + + S = Startbit coded time information (always '1') + + 1 = Minute (BCD) + 2 = ,, + 4 = ,, + 8 = ,, + 10 = ,, + 20 = ,, + 40 = ,, + P1 = Parity bit preceeding 7 bits (all bits including parity equals even number) + + 1 = Hour (BDC) + 2 = ,, + 4 = ,, + 8 = ,, + 10 = ,, + 20 = ,, + P2 = Parity bit preceeding 6 bits (all bits including parity equals even number) + + 1 = Calendar day (BCD) + 2 = ,, + 4 = ,, + 8 = ,, + 10 = ,, + 20 = ,, + + 1 = Day of the week (BCD) 1 = Monday + 2 = ,, + 4 = ,, + + 1 = Month (BCD) + 2 = ,, + 4 = ,, + 8 = ,, + 10 = ,, + + 1 = Year (BCD) + 2 = ,, + 4 = ,, + 8 = ,, + 10 = ,, + 20 = ,, + 40 = ,, + 80 = ,, + + P3 = Parity bit preceeding 22 bits (all bits including parity equals even number) + + D = No pulse here except for leap second ('0' pulse) -> the next (leap) second + then has no pulse. + The pulse following the 'no pulse' indicates start of next minute/data stream. + + + The DCF device is connected as follows: + 3V3 + ┌────────┐  + R │ DCF │ 10k + 3V3 ──┳──┳──┤ ├─┻── Input + C  │ device │ + ┌────┻──┻──┤ │ +  └────────┘ + + R = 1kΩ + C = 1uF + 1nF + + The resistor here has one major purpose: filtering out any noise from the 3V3 + power supply, which is typically connected directly to the Propeller device. + Since the DCF signal itself is a low frequency (77.5 kHz), it falls within + the frequency range of the Propeller chip itself, which can lead to problems. + Without this resistor the DCF device was unable to function properly. The + resistor has very little impact on the voltage available to the DCF device. + Because the DCF device draws very little current, the voltage drop over the + resistor is very low (0.08V here). +{------------------------------------------------------------------------------}} + + +CON + CDcfIn = 22 ' Input pin for DCF77 _>Hive ADM-Port 1 ->Expansionsbus B17 + CDcfOut = 24 ' Output pin for DCF77 signal (debug/visualization) ->Hive-Administra-LED + CDcfLevel = 1 ' Level for '1' signal + CNoSync = 0 ' Not in sync (never sync data received) + CInSync = 1 ' In sync (no error since last sync) + CInSyncWithError = 2 ' Not in sync (error since last sync), but time is up to date + CCest = 1 ' CEST timezone (daylight saving time) + CCet = 2 ' CET timezone + CAm = 0 ' AM + CPm = 1 ' PM + +VAR + byte Cog ' Active cog + long Stack[26] ' Stack for cog + byte Bits[8] ' Current detection of pulses (bit access) + long BitLevel ' Current bit level (NOT the signal level!) + long BitError ' Current bit status + byte BitNumber ' Current index of bit (== seconds) + + ' Time settings + byte DataCount ' Incremented when data below updated + byte TimeIndex ' Indicates the active index for the time settings + ' Typically the background writes in one of the registers + ' and if they all check out it makes them available by + ' changing the TimeIndex. + byte InSync ' Synchronization indication + + byte TimeZone[2] + byte Seconds[2] + byte Minutes[2] + byte Hours[2] ' 0..23 hour indication + byte HoursAmPm[2] ' 1..12 hour indication (used with AM/PM) + byte AmPm[2] + byte WeekDay[2] + byte Day[2] + byte Month[2] + word Year[2] + + +{{------------------------------------------------------------------------------ + Params : - + Returns : TRUE if cog available + + Descript: Start DCF acquisition + Notes : + ------------------------------------------------------------------------------}} + +PUB Start: Success +{ + DIRA[dcfstart]~~ + outa[dcfstart]:=1 + waitcnt((clkfreq * 2)+ cnt) + outa[dcfstart]:=0 + } + result := Cog := cognew(DcfReceive, @Stack) + + +{{------------------------------------------------------------------------------ + Params : - + Returns : - + + Descript: Stop cog and DCF acquisition + Notes : + ------------------------------------------------------------------------------}} +PUB Stop + if Cog == 0 ' Only if cog is active + return + cogstop(Cog) ' Stop the cog + + +{{------------------------------------------------------------------------------ + Params : - + Returns : - + + Descript: Interfaces to variables + Notes : + ------------------------------------------------------------------------------}} +PUB GetActiveSet: Value + result := TimeIndex + +PUB GetInSync: Value + result := InSync + +PUB GetTimeZone: Value + result := TimeZone[TimeIndex] + +PUB GetSeconds: Value + result := Seconds[TimeIndex] + +PUB GetMinutes: Value + result := Minutes[TimeIndex] + +PUB GetHours: Value + result := Hours[TimeIndex] + +PUB GetWeekDay: Value + result := WeekDay[TimeIndex] + +PUB GetDay: Value + result := Day[TimeIndex] + +PUB GetMonth: Value + result := Month[TimeIndex] + +PUB GetYear: Value + result := Year[TimeIndex] + +PUB GetBit(Index): Value + result := Bits[Index] + +PUB GetDataCount: Value + result := DataCount + +PUB GetBitNumber: Value + result := BitNumber + +PUB GetBitLevel: Value + result := BitLevel + +PUB GetBitError: Value + result := BitError + + +{{------------------------------------------------------------------------------ + Params : - + Returns : - + + Descript: Handle DCF reception + Notes : At fixed intervals the DCF input is polled. Every second the + data is checked and the data updated. + This code does not compensate for a leap second. However, this + is handled by a resynchronization. + We use a state machine so we can divide everything up. + Digital output: + On : In sync (no error) + 1 Hz : In sync with DCF77 signal (rising edge is start second) + 3 Hz : In sync with DCF77 signal (59th second) + Active in first 0.5 second + 10 Hz : Previous bit had error + Active in first 0.5 second + 20 Hz : Resyncing (waiting for pulse, max 1 s); followed by bit + error signal + This is the only variable in length (time) signal + The last 100 ms of the 2nd 0.5 second contains a small 40 ms pulse + when a binary '1' has been detected (for a '0' no pulse is generated) + If no signal is being received then the following output is + repeatedly generated: 20 Hz (1s), 10 Hz (0.5s), no signal (0.5s) + ------------------------------------------------------------------------------}} +PUB DcfReceive | LLocalTime, LIntervalCounts, LState, LWaitInterval, LBitNumber, LBitError, LLevels, LBitLevel, LIndex, LAccu, LParity, LError, LNewData + DIRA[CDcfIn]~ + DIRA[CDcfOut]~~ + DataCount := 0 + LLocalTime := 0 + InSync := CNoSync + LNewData := FALSE + LWaitInterval := CNT ' Get current system counter + LState := 99 ' Last state == initiates new state + LIntervalCounts := (CLKFREQ / (1000 / 10)) #>381 ' Interval counts + TimeIndex := 0 + LIndex := 1 + repeat + + ' The state machine consists of 100 equal steps + ' Each of these steps have a time span of 10 ms, getting to a total + ' of 1 second + waitcnt(LWaitInterval += LIntervalCounts) ' Wait for next interval + + ' We keep the local time running independent from the received DCF signal + ' because that might need synchronization. Only when synchronization has taken place + ' the local time is synchronized with the DCF. This only happens every minute, when + ' the received data checks out correctly + LLocalTime++ + case LLocalTime + 001: ' Update local time + ' Note: the date is not adjusted + if Seconds[TimeIndex] == 59 + Seconds[TimeIndex] := 0 + if Minutes[TimeIndex] == 59 + Minutes[TimeIndex] := 0 + if HoursAmPm[TimeIndex] == 12 + HoursAmPm[TimeIndex] := 1 + if AmPm[TimeIndex] == CAm + AmPm[TimeIndex] := CPm + else + AmPm[TimeIndex] := CAm + else + HoursAmPm[TimeIndex]++ + if Hours[TimeIndex] == 23 + Hours[TimeIndex] := 0 + if WeekDay[TimeIndex] == 7 + WeekDay[TimeIndex] := 1 + else + WeekDay[TimeIndex]++ + else + Hours[TimeIndex]++ + else + Minutes[TimeIndex]++ + else + Seconds[TimeIndex]++ + 100: LLocalTime := 0 + + ' Handling the 0/1 detection + ' We allow a 10% margin of error: + ' 0 .. 0.3s 0/1 signal detection + ' 0.3 .. 0.9s signal must be 0 + ' 0.9 .. 1 s not checked + ' 1 .. 2 s only when resync active + LState++ + case LState + 01..30 : if INA[CDcfIn] == CDcfLevel + LLevels++ ' We only need to check one level + 31..90 : if INA[CDcfIn] == CDcfLevel + LBitError := TRUE ' Any signal here is an error + 101..200: if INA[CDcfIn] == CDcfLevel + LState := 0 ' Restart state machine + + ' We divide the second up into several parts, including handling data of the + ' previous second. + ' In the last state (100) data from the current second are copied to the data + ' which is handled the next second + case LState + 091: if (LLevels => 15) ' Decide if we detected a binary '0' or '1' + LBitLevel := TRUE + Bits[LBitNumber / 8] |= (1 << (LBitNumber // 8)) + else + LBitLevel := FALSE + Bits[LBitNumber / 8] &= !(1 << (LBitNumber // 8)) + 092: ' Check for illogical data (this might also be the missing pulse occuring every minute) + if LBitNumber <> 59 + LBitError := LBitError | (LLevels =< 5) | (LLevels => 25) + 093: ' We can check the received data immediately + ' The background operates on the inactive settings + if LBitLevel + LParity++ + case LBitNumber + 0 : if LNewData ' If new data, switch over to new data set + Seconds[LIndex] := 0 ' Synchronize seconds + ' Note: we can not synchronize in the + ' 59th seconds because the 'local time' + ' state machine adjusts the minutes/hours + ' when the seconds reaches '60' + LLocalTime := 0 ' Synchronize the 'local time' state machine + if TimeIndex == 0 ' Switch to different active set + TimeIndex := 1 + LIndex := 0 + else + TimeIndex := 0 + LIndex := 1 + InSync := CInSync + OUTA[CDcfOut]~~ ' Output on + LNewData := FALSE + LError := FALSE + 15 : ' R = Call bit (irregularities in DCF77 control facilities) + 16 : ' A1 = '1' Imminent change-over of time from CET <-> CEST + ' Transmitted 1 hour prior to change (refelected in Z1/Z2) + 19 : ' A2 = '1' Imminent change-over of leap second + ' Transmitted 1 hour prior to change (January 1/July 1) + 20 : if !LBitLevel ' S = Startbit coded time information (always '1') + LError := TRUE + 17, 42, 45, 50 : if LBitLevel ' Start new data + LAccu := 1 + else + LAccu := 0 + 21, 29, 36 : if LBitLevel ' Start new data and parity controlled data + LAccu := 1 + LParity := 1 + else + LAccu := 0 + LParity := 0 + 18, 22, 30, 37, 43, 46, 51: if LBitLevel ' 2 + LAccu += 2 + case LBitNumber + 18: TimeZone[LIndex] := LAccu + if (LAccu == %00) or (LAccu == %11) + LError := TRUE + 23, 31, 38, 44, 47, 52 : if LBitLevel ' 4 + LAccu += 4 + case LBitNumber + 44: WeekDay[LIndex] := LAccu + 24, 32, 39, 48, 53 : if LBitLevel ' 8 + LAccu += 8 + 25, 33, 40, 49, 54 : if LBitLevel ' 10 + LAccu += 10 + case LBitNumber + 49: Month[LIndex] := LAccu + 26, 34, 41, 55 : if LBitLevel ' 20 + LAccu += 20 + case LBitNumber + 34: Hours[LIndex] := LAccu + if LAccu > 11 ' 1..12 Hour + AM/PM + AmPm[LIndex] := CPm + else + AmPm[LIndex] := CAm + if LAccu > 12 + HoursAmPm[LIndex] := LAccu - 12 + else + if LAccu == 0 + HoursAmPm[LIndex] := 12 + else + HoursAmPm[LIndex] := LAccu + 41: Day[LIndex] := LAccu + 27, 56 : if LBitLevel ' 40 + LAccu += 40 + case LBitNumber + 27: Minutes[Lindex] := LAccu + 57 : if LBitLevel ' 80 + LAccu += 80 + Year[LIndex] := 2000 + LAccu + 28, 35, 58 : if (LParity & %1) <> 0 + LError := TRUE + + 59 : ' D = No pulse here except for leap second ('0' pulse) -> the next (leap) second + ' then has no pulse. + ' The pulse following the 'no pulse' indicates start of next minute/data stream. + if !LError + LNewData := TRUE + + + 100: ' Copy current second data to data we will be handling the next second + ' and (re)set data for next second + if !LBitError ' An error switches to the next state (resync) + LState := 0 ' otherwise restart state machine + BitLevel := LBitLevel + LBitLevel := FALSE + BitError := LBitError + LBitError := FALSE + BitNumber := LBitNumber ' Last to change because foreground might check this one + ' to read others + LLevels := 0 + if BitError ' A sync error resets the second counter + LBitNumber := 0 + if InSync == CInSync + InSync := CInSyncWithError ' 'Out of sync' if we were 'in sync' + else + LBitNumber++ ' Next second + if LBitNumber == 60 ' We could check for leap second here, but ... + LBitNumber := 0 + DataCount++ ' Adjust data indicator for foreground + 201: LState := 0 ' Resync failed: restart state machine + + + ' Output + ' time out biterror sec59 level Note: 'biterror' and 'sec59' never active at same time + ' 1 1 1 1 1 + ' 10 0 + ' 17 0 + ' 20 1 + ' 30 0 + ' 34 1 + ' 40 1 + ' 50 0 0 0 0 + ' 75 1 + ' 91 1 + ' 95 0 0 0 0 + ' 101 1 1 1 1 + ' .. t t t t + ' 195 0 0 0 0 + if InSync <> CInSync ' Only control the output when not in sync + case LState + 001 : OUTA[CDcfOut]~~ ' Always on + 010, 020, 030, 040: if BitError ' 10 Hz signal (bit error) + !OUTA[CDcfOut] + 017, 034, 075 : if !BitError AND (LBitNumber == 59) ' 3 Hz signal (in sync and 59th second) + !OUTA[CDcfOut] + 091 : if LBitLevel ' Bit is '1' + !OUTA[CDcfOut] ' Always off + 050, 095 : OUTA[CDcfOut]~ + 101, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195: !OUTA[CDcfOut] diff --git a/lib/adm-plx.spin b/lib/adm-plx.spin index d0820fb..60b36e0 100644 --- a/lib/adm-plx.spin +++ b/lib/adm-plx.spin @@ -1,131 +1,272 @@ -''******************************************************************* -''* Simple Asynchronous Serial Driver v1.3 * -''* Authors: Chip Gracey, Phil Pilgrim, Jon Williams, Jeff Martin * -''* Copyright (c) 2006 Parallax, Inc. * -''* See end of file for terms of use. * -''******************************************************************* -'' -'' Performs asynchronous serial input/output at low baud rates (~19.2K or lower) using high-level code -'' in a blocking fashion (ie: single-cog (serial-process) rather than multi-cog (parallel-process)). -'' -'' To perform asynchronous serial communication as a parallel process, use the FullDuplexSerial object instead. -'' -'' -'' v1.3 - May 7, 2009 - Updated by Jeff Martin to fix rx method bug, noted by Mike Green and others, where uninitialized -'' variable would mangle received byte. -'' v1.2 - March 26, 2008 - Updated by Jeff Martin to conform to Propeller object initialization standards and compress by 11 longs. -'' v1.1 - April 29, 2006 - Updated by Jon Williams for consistency. -'' -'' -'' The init method MUST be called before the first use of this object. -'' Optionally call finalize after final use to release transmit pin. -'' -'' Tested to 19.2 kbaud with clkfreq of 80 MHz (5 MHz crystal, 16x PLL) +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@gmail.com +System : mental +Name : I2C/PlexBus-Objekt +Chip : Administra +Typ : + +Funktion : + + +COG's : + +Logbuch : + + +Notizen : + +}} + + + +OBJ + gc : "m-glob-con" + + +CON + + SCL = gc#adm_scl + SDA = gc#adm_sda +' VNX = gc#adm_int1 +' portadressen sepia + + 'pcf8574 %0100_ABC_0 + PORT1 = %0100_000 '$20 + PORT2 = %0100_001 '$21 + PORT3 = %0100_010 '$22 +{ + 'pcf8574a %0111_ABC_0 + PORT1 = %0111_000 '$38 + PORT2 = %0111_001 '$39 + PORT3 = %0111_010 '$3A +} +' ad/da-wandler-adresse + + 'pcf8591 %1001_ABC_R + ADDA0 = %1001_000 + ADDA0_WR = %1001_000_0 + ADDA0_RD = %1001_000_1 + +' +' +------------- 0 +' | +----------- 1 = analog output enable +' | | +-------- 00 - four single endet input +' | | | 01 - three differential inputs +' | | | 10 - single ended and differential mixed +' | | | 11 - two differential inputs +' | | | +------ 0 +' | | | | +---- 1 = auto-increment +' | | | | | +- 00 - channel 0 +' | | | | | | 01 - channel 1 +' | | | | | | 10 - channel 2 +' | | | | | | 11 - channel 3 +' | | -+ | | -+ + ADDA0_INIT = %0_1_00_0_0_00 + ADDA0_SCAN = %0_1_00_0_1_00 + ADDA0_CH0 = %0_1_00_0_0_00 + ADDA0_CH1 = %0_1_00_0_0_01 + ADDA0_CH2 = %0_1_00_0_0_10 + ADDA0_CH3 = %0_1_00_0_0_11 + +' index der register + R_PAD0 = 0 + R_PAD1 = 1 + R_PAD2 = 2 + R_PAD3 = 3 + R_INP0 = 4 + R_INP1 = 5 + R_INP2 = 6 +' R_VNX = 7 VAR - long sin, sout, inverted, bitTime, rxOkay, txOkay + byte joy0 + byte pad0 + byte plxreg[16] + long plxstack[16] + long plxcogid -PUB init(rxPin, txPin, baud): Okay -{{Call this method before first use of object to initialize pins and baud rate. + byte plxback + byte plxlock - • For true mode (start bit = 0), use positive baud value. Ex: serial.init(0, 1, 9600) - For inverted mode (start bit = 1), use negative baud value. Ex: serial.init(0, 1, -9600) - • Specify -1 for "unused" rxPin or txPin if only one-way communication desired. - • Specify same value for rxPin and txPin for bi-directional communication on that pin and connect a pull-up/pull-down resistor - to that pin (depending on true/inverted mode) since pin will set it to hi-z (input) at the end of transmission to avoid - electrical conflicts. See "Same-Pin (Bi-Directional)" examples, below. + byte adr_adda 'adresse adda (poller) + byte adr_port 'adresse ports (poller) - EXAMPLES: - - Standard Two-Pin Bi-Directional True/Inverted Modes Standard One-Pin Uni-Directional True/Inverted Mode - Ex: serial.init(0, 1, ±9600) Ex: serial.init(0, -1, ±9600) -or- serial.init(-1, 0, ±9600) - ┌────────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐ - │Propeller P0├─────────────┤I/O Device│ │Propeller P0├───────────────┤I/O Device│ - │ P1├─────────────┤ │ └────────────┘ └──────────┘ - └────────────┘ └──────────┘ +PUB init 'plx: io-system initialisieren - + outa[SCL] := 1 'SCL = 1 + dira[SCL] := 1 'SCL = ausgang + dira[SDA] := 0 'SDA = eingang - Same-Pin (Bi-Directional) True Mode Same-Pin (Bi-Directional) Inverted Mode - Ex: serial.init(0, 0, 9600) Ex: serial.init(0, 0, -9600) -  ┌────────────┐ ┌──────────┐ - │ │Propeller P0├─────┳─────┤I/O Device│ -  4.7 kΩ └────────────┘ │ └──────────┘ - ┌────────────┐ │ ┌──────────┐  4.7 kΩ - │Propeller P0├─────┻─────┤I/O Device│ │ - └────────────┘ └──────────┘  -}} + adr_adda := ADDA0 + adr_port := PORT1 - finalize ' clean-up if restart - - rxOkay := rxPin > -1 ' receiving? - txOkay := txPin > -1 ' transmitting? + 'ad/da-wandler initialisieren + ad_init(ADDA0) - sin := rxPin & $1F ' set rx pin - sout := txPin & $1F ' set tx pin + 'semaphore anfordern + 'plxlock := 2 'mental + plxlock := locknew 'trios - inverted := baud < 0 ' set inverted flag - bitTime := clkfreq / ||baud ' calculate serial bit time - - return rxOkay | TxOkay - + 'pollcog starten + plxcogid := cognew(poller,@plxstack) +pub plxstop -PUB finalize -{{Call this method after final use of object to release transmit pin.}} - - if txOkay ' if tx enabled - dira[sout]~ ' float tx pin - rxOkay := txOkay := false + if(plxcogid) + cogstop(plxcogid~ - 1) + lockret(-1 + plxlock~) +PRI poller 'plx: pollcog + repeat + 'semaphore setzen + repeat until not lockset(plxlock) 'auf freien bus warten -PUB rx: rxByte | t -{{ Receive a byte; blocks caller until byte received. }} + 'analoge eingänge pollen + plxreg[R_PAD0] := ad_ch(adr_adda,0) + plxreg[R_PAD1] := ad_ch(adr_adda,1) + lockclr(plxlock) 'bus freigeben - if rxOkay - dira[sin]~ ' make rx pin an input - waitpeq(inverted & |< sin, |< sin, 0) ' wait for start bit - t := cnt + bitTime >> 1 ' sync + 1/2 bit - repeat 8 - waitcnt(t += bitTime) ' wait for middle of bit - rxByte := ina[sin] << 7 | rxByte >> 1 ' sample bit - waitcnt(t + bitTime) ' allow for stop bit + repeat until not lockset(plxlock) 'auf freien bus warten + plxreg[R_PAD2] := ad_ch(adr_adda,2) + plxreg[R_PAD3] := ad_ch(adr_adda,3) + lockclr(plxlock) 'bus freigeben - rxByte := (rxByte ^ inverted) & $FF ' adjust for mode and strip off high bits + repeat until not lockset(plxlock) 'auf freien bus warten + 'digitale eingabeports pollen + plxreg[R_INP0] := in(adr_port ) + plxreg[R_INP1] := in(adr_port+1) + plxreg[R_INP2] := in(adr_port+2) + 'semaphore freigeben + lockclr(plxlock) 'bus freigeben +PUB run 'plx: polling aktivieren -PUB tx(txByte) | t -{{ Transmit a byte; blocks caller until byte transmitted. }} + lockclr(plxlock) 'bus freigeben - if txOkay - outa[sout] := !inverted ' set idle state - dira[sout]~~ ' make tx pin an output - txByte := ((txByte | $100) << 2) ^ inverted ' add stop bit, set mode - t := cnt ' sync - repeat 10 ' start + eight data bits + stop - waitcnt(t += bitTime) ' wait bit time - outa[sout] := (txByte >>= 1) & 1 ' output bit (true mode) - - if sout == sin - dira[sout]~ ' release to pull-up/pull-down +PUB halt 'plx: polling stoppen - -PUB str(strAddr) -{{ Transmit z-string at strAddr; blocks caller until string transmitted. }} + repeat until not lockset(plxlock) 'auf freien bus warten - if txOkay - repeat strsize(strAddr) ' for each character in string - tx(byte[strAddr++]) ' write the character +CON 'Devices: PORTS, AD/DA-WANDLER + +PUB in(adr):data | ack 'plx: port lesen + + start + ack := write((adr << 1) + 1) + ifnot ack + data := read(0) + stop + +PUB out(adr,data):ack 'plx: port schreiben + + start + ack := write(adr << 1) + ack := (ack << 1) | write(data) + stop + +PUB ad_init(adr) 'plx: ad-wandler initialisieren + + start + write(adr << 1) + write(ADDA0_INIT) + write(0) + stop + +PUB ad_ch(adr,ch): wert 'plx: ad-wandler wert auslesen + + start + write(adr << 1) + write(ADDA0_CH0 + ch) + write(0) + stop + repeat 2 'erste messung verwerfen! + start 'da diese das ergebnis + write((adr << 1) + 1) 'der letzten messung + wert := read(1) 'liefert! + stop + +PUB getreg(regnr):wert 'plx: register lesen + + wert := plxreg[regnr & $0F] + +PUB setreg(regnr,wert) 'plx: register schreiben + + plxreg[regnr & $0F] := wert + +PUB ping(adr):ack 'plx: device anpingen + + start + ack := write(adr<<1) + stop + +PUB setadr(adradda,adrport) + + 'halt + adr_adda := adradda + adr_port := adrport + ad_init(adr_adda) + 'run + +CON 'I2C-FUNKTIONEN + +PUB start 'i2c: dialog starten + + outa[SCL]~~ + dira[SCL]~~ + outa[SDA]~~ + dira[SDA]~~ + outa[SDA]~ + outa[SCL]~ + +PUB stop 'i2c: dialog beenden + outa[SCL]~~ + outa[SDA]~~ + dira[SCL]~ + dira[SDA]~ + +PUB write(data):ack 'i2c: byte senden + + ack := 0 + data <<= 24 + repeat 8 + outa[SDA] := (data <-= 1) & 1 + outa[SCL]~~ + outa[SCL]~ + dira[SDA]~ + outa[SCL]~~ + ack := ina[SDA] + outa[SCL]~ + outa[SDA]~ + dira[SDA]~~ + +PUB read(ack):data 'i2c: byte empfangen + + dira[SDA]~ + repeat 8 + outa[SCL]~~ + data := (data << 1) | ina[SDA] + outa[SCL]~ + outa[SDA] := ack + dira[SDA]~~ + outa[SCL]~~ + outa[SCL]~ + outa[SDA]~ {{ - - ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ TERMS OF USE: MIT License │ +│ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ -│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ │is furnished to do so, subject to the following conditions: │ @@ -137,4 +278,5 @@ PUB str(strAddr) │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -}} +}} + diff --git a/lib/glob-con.spin b/lib/glob-con.spin index 3644620..012e26e 100644 --- a/lib/glob-con.spin +++ b/lib/glob-con.spin @@ -44,6 +44,7 @@ CON 'Signaldefinitionen -------------------------------------------------------- #8, A_SOUNDL,A_SOUNDR 'sound (stereo 2 pin) #10, A_SDD0,A_SDCLK,A_SDCMD,A_SDD3 'sd-cardreader (4 pin) +#21, A_Bluetooth_Line 'Key-Line des HC05-Bluetooth-Moduls #23, A_SELECT 'administra-auswahlsignal CON 'KEY_CODES ------------------------------------------------------------------------------------- @@ -82,16 +83,18 @@ KEY_F12 = 219 CON 'ADMINISTRA-FUNKTIONEN -------------------------------------------------------------------------- -' +----------- ays -' |+---------- com -' || +-------- plexbus -' || |+------- rtc -' || ||+------ lan -' || |||+----- sid -' || ||||+---- wav -' || |||||+--- hss -' || ||||||+-- chiploader -' || |||||||+- dateisystem +' +------------- bluetooth +' |+------------ dfc77 receiver +' ||+----------- ays +' |||+---------- com +' |||| +-------- plexbus +' |||| |+------- rtc +' |||| ||+------ lan +' |||| |||+----- sid +' |||| ||||+---- wav +' |||| |||||+--- hss +' |||| ||||||+-- chiploader +' |||| |||||||+- dateisystem A_FAT = %00000000_00000000_00000000_00000001 A_LDR = %00000000_00000000_00000000_00000010 A_HSS = %00000000_00000000_00000000_00000100 @@ -102,6 +105,8 @@ A_RTC = %00000000_00000000_00000000_01000000 A_PLX = %00000000_00000000_00000000_10000000 A_COM = %00000000_00000000_00000001_00000000 A_AYS = %00000000_00000000_00000010_00000000 +A_DCF = %00000000_00000000_00000100_00000000 +A_BLT = %00000000_00000000_00001000_00000000 ' | ' ym @@ -141,10 +146,15 @@ A_AYS = %00000000_00000000_00000010_00000000 ' ---------------------------------------------- COM-FUNKTIONEN #31, a_comInit a_comTx - a_comRx '33 + a_comRx '33 + +' ---------------------------------------------- Bluetooth-Funktionen +#35, a_bltCommand_On + a_bltCommand_Off '36 ' ---------------------------------------------- RTC-FUNKTIONEN -#41, a_rtcGetSeconds 'Returns the current second (0 - 59) from the real time clock. +#40, a_rtcTest 'Test if RTC Chip is available + a_rtcGetSeconds 'Returns the current second (0 - 59) from the real time clock. a_rtcGetMinutes 'Returns the current minute (0 - 59) from the real time clock. a_rtcGetHours 'Returns the current hour (0 - 23) from the real time clock. a_rtcGetDay 'Returns the current day (1 - 7) from the real time clock. @@ -162,10 +172,30 @@ A_AYS = %00000000_00000000_00000010_00000000 a_rtcGetNVSRAM 'Gets the selected NVSRAM value at the index (0 - 55). a_rtcPauseForSec 'Pauses execution for a number of seconds. Returns a puesdo random value derived from the current clock frequency and the time when called. Number - Number of seconds to pause for between 0 and 2,147,483,647. a_rtcPauseForMSec 'Pauses execution for a number of milliseconds. Returns a puesdo random value derived from the current clock frequency and the time when called. Number - Number of milliseconds to pause for between 0 and 2,147,483,647. - a_rtcTest '59 'Test if RTC Chip is available + a_rtcGetTime '59 'Returns the current hour, minute and second from the real time clock. + +' ---------------------------------------------- DCF77-FUNKTIONEN +#60, a_dcfGetInSync 'Sync-Status senden + a_dcfUpdateRTC 'RTC Synchronisieren + a_dcfGetBitError + a_dcfGetDataCount + a_dcfGetBitNumber + a_dcfGetBitLevel + a_dcfGetTimeZone + a_dcfGetActiveSet + a_dcfStart 'DCF-Empfang starten + a_dcfStop 'DCF-Empfang stoppen + a_dcfState 'Status des DCF-Empfängers + a_dcfGetSeconds + a_dcfGetMinutes + a_dcfGetHours + a_dcfGetWeekDay + a_dcfGetDay + a_dcfGetMonth + a_dcfGetYear '77 ' ---------------------------------------------- LAN-FUNKTIONEN -#71, a_lanStart 'Start Network +#81, a_lanStart 'Start Network a_lanStop 'Stop Network a_lanConnect 'ausgehende TCP-Verbindung öffnen a_lanListen 'auf eingehende TCP-Verbindung lauschen @@ -175,7 +205,7 @@ A_AYS = %00000000_00000000_00000010_00000000 a_lanRXData 'Daten aus Empfangspuffer lesen a_lanTXData 'Daten senden a_lanRXByte 'wenn vorhanden, Byte aus Empfangspuffer lesen - a_lanIsConnected '81 'TRUE, wenn Socket verbunden, sonst FALSE + a_lanIsConnected '91 'TRUE, wenn Socket verbunden, sonst FALSE ' ---------------------------------------------- CHIP-MANAGMENT #92, a_mgrSetSound 'soundsubsysteme verwalten @@ -200,6 +230,27 @@ A_AYS = %00000000_00000000_00000010_00000000 a_sfxKeyOff a_sfxStop '110 +' ---------------------------------------------- PLX-Funktionen +#120, a_plxRun 'plx-bus freigeben + a_plxHalt 'plx-bus anfordern + a_plxIn 'port einlesen + a_plxOut 'port ausgeben + a_plxCh 'ad-wandler auslesen + a_plxGetReg 'poller-register lesen + a_plxSetReg 'poller-register setzen + a_plxStart 'i2c-dialog starten + a_plxStop 'i2c-dialog beenden + a_plxWrite 'i2c byte senden + a_plxRead 'i2c byte empfangen + a_plxPing 'abfrage ob device vorhanden ist + a_plxSetAdr 'adressen adda/ports für poller setzen +' ---------------------------------------------- GAMEDEVICES + a_Joy 'Joystick abfragen (1 x 8bit Port) + a_Paddle 'Paddle abfragen (1 x 8bit Port 1 x Analog) + a_Pad 'Pad abfragen (1 x 8bit Port 2 x Analog) + a_SetJoy 'Port für Joystick setzen + a_SetPad '137 'Chan für Pad setzen + ' ---------------------------------------------- WAV-FUNKTIONEN #150, a_sdwStart 'spielt wav-datei direkt von sd-card ab a_sdwStop 'stopt wav-cog @@ -209,11 +260,6 @@ A_AYS = %00000000_00000000_00000010_00000000 a_sdwPause 'player pause/weiter-modus a_sdwPosition '156 -' ---------------------------------------------- AY-SOUNDFUNKTIONEN -#200, a_ayStart - a_ayStop - a_ayUpdateRegisters - ' ---------------------------------------------- SIDCog: DMP-Player-Funktionen (SIDCog2) #157, a_s_mdmpplay 'dmp-file mono auf sid2 abspielen a_s_sdmpplay 'dmp-file stereo auf beiden sids abspielen @@ -262,6 +308,11 @@ A_AYS = %00000000_00000000_00000010_00000000 ' ---------------------------------------------- Zusatzfunktionen a_s_dmpreg '196 'soundinformationen senden +' ---------------------------------------------- AY-SOUNDFUNKTIONEN +#200, a_ayStart + a_ayStop + a_ayUpdateRegisters + CON 'BELLATRIX-FUNKTIONEN -------------------------------------------------------------------------- ' +----------