123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653 |
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <!-- Awlsim project file generated by awlsim-0.72.0-pre -->
- <awlsim_project date_create="2018-02-09 21:25:51.784572"
- date_modify="2020-02-22 15:04:58.426727"
- format_version="1">
- <!-- CPU core configuration -->
- <cpu>
- <!-- CPU core feature specification -->
- <specs call_stack_size="256"
- nr_accus="2"
- nr_counters="256"
- nr_flags="2048"
- nr_inputs="128"
- nr_localbytes="1024"
- nr_outputs="128"
- nr_timers="256"
- parenthesis_stack_size="7" />
- <!-- CPU core configuration -->
- <config clock_memory_byte="-1"
- cycle_time_limit_us="1000000"
- cycle_time_target_us="0"
- ext_insns_enable="1"
- mnemonics="0"
- ob_startinfo_enable="0"
- run_time_limit_us="-1" />
- </cpu>
- <!-- AWL/STL language configuration -->
- <language_awl>
- <!-- AWL/STL source code -->
- <source enabled="1"
- name="OB 1"
- type="0"><![CDATA[
- ORGANIZATION_BLOCK OB 1
- VAR_TEMP
- OB1_EV_CLASS : BYTE; // Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
- OB1_SCAN_1 : BYTE; // 1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
- OB1_PRIORITY : BYTE; // Priority of OB execution
- OB1_OB_NUMBR : BYTE; // 1 (Organization block 1, OB 1)
- OB1_RESERVED_1 : BYTE;
- OB1_RESERVED_2 : BYTE;
- OB1_PREV_CYCLE : INT; // Cycle time of previous OB 1 scan (milliseconds)
- OB1_MIN_CYCLE : INT; // Minimum cycle time of OB 1 (milliseconds)
- OB1_MAX_CYCLE : INT; // Maximum cycle time of OB 1 (milliseconds)
- OB1_DATE_TIME : DATE_AND_TIME; // Date and time OB 1 started
- END_VAR
- BEGIN
-
- // Run the music player
- CALL "FB_musicPlayer", DB 10 (
- volume := 15,
- base_speed := T#2000ms,
- song_DB := "DB_song",
- )
-
- END_ORGANIZATION_BLOCK
- DATA_BLOCK DB 10
- "FB_musicPlayer"
- BEGIN
- END_DATA_BLOCK
- ]]></source>
- <!-- AWL/STL source code -->
- <source enabled="1"
- name="player"
- type="0"><![CDATA[
- FUNCTION_BLOCK "FB_musicPlayer"
- TITLE = PWM based music player
- AUTHOR : Michael Buesch <m@bues.ch>
- // License : GNU/GPL 2+
- VAR_INPUT
- volume : INT;
- base_speed : TIME;
- song_DB : BLOCK_DB;
- END_VAR
- VAR
- notes_index : INT;
- octave_shift : INT;
- sharp : BOOL;
- tie : BOOL;
- wait_time_active : BOOL;
- wait_timestamp : TIME;
- prev_note_id : BYTE;
- prev_note_value : BYTE;
- END_VAR
- VAR_TEMP
- cur_note : BYTE;
- cur_note_id : BYTE;
- cur_note_value : BYTE;
- base_freq : DINT;
- deci_hz : INT;
- period : WORD;
- remaining_ms : TIME;
- now : TIME;
- END_VAR
- BEGIN
- // Get the current time
- CALL SFC 64 (
- RET_VAL := #now
- )
- // Check if we need to wait
- U #wait_time_active
- SPBN NWAI
- L #now
- L #wait_timestamp
- -D
- SLD 1 // sign extension
- SSD 1 // sign extension
- L 0
- <D
- BEB
- CLR
- = #wait_time_active
- NWAI: NOP 0
- // Open the song we are playing
- AUF #song_DB
- // Get current note
- L #notes_index
- SLW 3
- LAR1
- L DBB [AR1, P#0.0]
- T #cur_note
- // End of note table?
- L #cur_note
- L B#16#FF
- <>I
- SPB NEND
- L 0
- T #notes_index
- L DBB 0
- T #cur_note
- NEND: NOP 0
- // Extract note ID
- L #cur_note
- UW W#16#0F
- T #cur_note_id
- // Extract note value
- L #cur_note
- UW W#16#70
- SRW 4
- T #cur_note_value
- // If this is a special note, handle it.
- L #cur_note_id
- L W#16#F
- ==I
- SPB SPEC
- // Check if the current note is equal to the previous note.
- L #cur_note_id
- L #prev_note_id
- ==I
- SPB SAME
- // Tune the note.
- // Get the note frequency in deci-Hz.
- TUNE: AUF "DB_notes"
- U #sharp
- SPBN NOSH
- AUF "DB_notes_sharp"
- NOSH: L #cur_note_id
- SLW 4
- LAR1
- L DBW [AR1, P#0.0]
- T #deci_hz
- // Octave shift the frequency.
- L #octave_shift
- L 0
- >=I
- SPB POSO
- // Negative octave shift
- L #octave_shift
- NEGI
- L #deci_hz
- SRW
- SPA OCTE
- // Positive octave shift
- POSO: L #octave_shift
- L #deci_hz
- SLW
- OCTE: T #deci_hz
- // Calculate the PWM period from the frequency.
- L #deci_hz
- L 0
- ==I
- SPB NPER
- L L#20000000 // pwm_baseFreqHz * 10
- L #deci_hz
- /D
- NPER: T #period
- // Write period to PWM output hardware
- CALL "FC_setPWM" (
- period := #period,
- volume := #volume,
- )
- // Calculate the wait timestamp from the current note value.
- CALL "FC_calcWaitTime" (
- now := #now,
- note_value := #cur_note_value,
- base_speed := #base_speed,
- wait_timestamp := #wait_timestamp,
- wait_time_active := #wait_time_active,
- )
- // We are done with this note.
- // Reset all flags.
- CLR
- = #sharp
- = #tie
- L #cur_note_id
- T #prev_note_id
- L #cur_note_value
- T #prev_note_value
- SPA NEXT
- // If this is a special flags note, handle it.
- SPEC: L #cur_note_value
- SPL INVA // Invalid
- SPA SHRP // Activate "sharp" (Kreuz)
- SPA DOT // Activate "dot" (Punktierung)
- SPA TIE // Activate "tie" (Haltebogen)
- SPA SHUP // Shift one octave up
- SPA SHDN // Shift one octave down
- SPA INVA // Invalid
- SPA INVA // Invalid
- SPA INVA // Invalid
- INVA: BEA
- // Activate "sharp" (Kreuz)
- SHRP: SET
- = #sharp
- SPA NEXT
- // Activate "dot" (Punktierung)
- // Get the value of the previous note (that is the currenly tuned one)
- // and wait for half its time.
- DOT: L #prev_note_value
- + 1 // Decrease value by 50%
- T #prev_note_value
- CALL "FC_calcWaitTime" (
- now := #now,
- note_value := #prev_note_value,
- base_speed := #base_speed,
- wait_timestamp := #wait_timestamp,
- wait_time_active := #wait_time_active,
- )
- SPA NEXT
- // Activate "tie" (Haltebogen)
- TIE: SET
- = #tie
- SPA NEXT
- // Shift one octave up
- SHUP: L #octave_shift
- + 1
- T #octave_shift
- SPA NEXT
- // Shift one octave down
- SHDN: L #octave_shift
- + -1
- T #octave_shift
- SPA NEXT
- // The current note is the same as the previous one.
- // If "tie" is not active, deactivate the PWM and wait
- // a tiny amount of time. Then re-activate the note.
- // If "tie" is active, tune the note.
- SAME: U #tie
- SPB TUNE
- CALL "FC_setPWM" (
- period := W#16#0,
- volume := #volume,
- )
- L #now
- L T#30ms
- +D
- UD DW#16#7FFFFFFF
- T #wait_timestamp
- SET
- = #wait_time_active
- // Set "tie" to re-activate the note
- // after the wait time has passed.
- SET
- = #tie
- SPB NINC
- // Increment notes index
- NEXT: L #notes_index
- + 1
- T #notes_index
- NINC: BE
- END_FUNCTION_BLOCK
- FUNCTION "FC_setPWM" : VOID
- VAR_INPUT
- period : WORD;
- volume : INT;
- END_VAR
- VAR_TEMP
- volume_shift : INT;
- END_VAR
- BEGIN
- // Calculate the duty cycle shift from the volume.
- // #volume can be 0-15
- L 15
- L #volume
- -I
- + 1
- T #volume_shift
- // Write period to PWM output hardware
- L #period
- T "pwm_period"
- // Write duty cycle to PWM output hardware
- L #volume_shift
- L #period
- SRW
- T "pwm0"
- END_FUNCTION
- FUNCTION "FC_calcWaitTime" : VOID
- VAR_INPUT
- now : TIME;
- note_value : BYTE;
- base_speed : TIME;
- END_VAR
- VAR_OUTPUT
- wait_timestamp : TIME;
- wait_time_active : BOOL;
- END_VAR
- VAR_TEMP
- remaining_ms : TIME;
- END_VAR
- BEGIN
- // Calculate the remaining time from the note value.
- L #note_value
- L #base_speed // base speed, in milliseconds
- SRW
- T #remaining_ms
- // Calculate the next timestamp to wait for.
- L #now
- L #remaining_ms
- +D
- UD DW#16#7FFFFFFF
- T #wait_timestamp
- SET
- = #wait_time_active
- END_FUNCTION
- ]]></source>
- <!-- AWL/STL source code -->
- <source enabled="1"
- name="notes"
- type="0"><![CDATA[
- // Note frequencies in 0.1 Hz
- DATA_BLOCK "DB_notes"
- STRUCT
- note_freqs : ARRAY [0 .. 14] OF INT;
- END_STRUCT;
- BEGIN
- note_freqs[0] := 0;
- note_freqs[1] := 2616; // c'
- note_freqs[2] := 2937; // d'
- note_freqs[3] := 3296; // e'
- note_freqs[4] := 3492; // f'
- note_freqs[5] := 3919; // g'
- note_freqs[6] := 4400; // a'
- note_freqs[7] := 4939; // h'
- note_freqs[8] := 5233; // c''
- note_freqs[9] := 5873; // d''
- note_freqs[10] := 6593; // e''
- note_freqs[11] := 6985; // f''
- note_freqs[12] := 7840; // g''
- note_freqs[13] := 8800; // a''
- note_freqs[14] := 9878; // h''
- END_DATA_BLOCK
- // Sharp note frequencies in 0.1 Hz
- DATA_BLOCK "DB_notes_sharp"
- STRUCT
- note_freqs : ARRAY [0 .. 14] OF INT;
- END_STRUCT;
- BEGIN
- note_freqs[0] := 0;
- note_freqs[1] := 2772; // cis'
- note_freqs[2] := 3111; // dis'
- note_freqs[3] := 3296; // e'
- note_freqs[4] := 3700; // fis'
- note_freqs[5] := 4153; // gis'
- note_freqs[6] := 4662; // ais'
- note_freqs[7] := 4939; // h'
- note_freqs[8] := 5544; // cis''
- note_freqs[9] := 6223; // dis''
- note_freqs[10] := 6593; // e''
- note_freqs[11] := 7400; // fis''
- note_freqs[12] := 8306; // gis''
- note_freqs[13] := 9323; // ais''
- note_freqs[14] := 9878; // h''
- END_DATA_BLOCK
- ]]></source>
- <!-- AWL/STL source code -->
- <source enabled="1"
- name="song"
- type="0"><![CDATA[
- // The Free Software Song
- // Sadi moma bela loza (Bulgarian folk song)
- // Words by Richard Stallman, the Free Software Foundation http://fsf.org/
- // Richard Stallman and the Free Software Foundation claim no copyright on this song.
- // The official homepage for this song is http://www.gnu.org/music/free-software-song.html
- DATA_BLOCK "DB_song"
- STRUCT
- SONG : ARRAY [0 .. 57] OF BYTE;
- END_STRUCT;
- BEGIN
- SONG[0] := B#16#29;
- SONG[1] := B#16#38;
- SONG[2] := B#16#27;
- SONG[3] := B#16#26;
- SONG[4] := B#16#27;
- SONG[5] := B#16#38;
- SONG[6] := B#16#37;
- SONG[7] := B#16#2F;
- SONG[8] := B#16#36;
- SONG[9] := B#16#25;
- SONG[10] := B#16#25;
- SONG[11] := B#16#1F;
- SONG[12] := B#16#26;
- SONG[13] := B#16#1F;
- SONG[14] := B#16#2F;
- SONG[15] := B#16#37;
- SONG[16] := B#16#28;
- SONG[17] := B#16#1F;
- SONG[18] := B#16#27;
- SONG[19] := B#16#37;
- SONG[20] := B#16#29;
- SONG[21] := B#16#26;
- SONG[22] := B#16#1F;
- SONG[23] := B#16#16;
- SONG[24] := B#16#29;
- SONG[25] := B#16#2F;
- SONG[26] := B#16#38;
- SONG[27] := B#16#2F;
- SONG[28] := B#16#17;
- SONG[29] := B#16#29;
- SONG[30] := B#16#38;
- SONG[31] := B#16#27;
- SONG[32] := B#16#26;
- SONG[33] := B#16#27;
- SONG[34] := B#16#38;
- SONG[35] := B#16#37;
- SONG[36] := B#16#2F;
- SONG[37] := B#16#36;
- SONG[38] := B#16#25;
- SONG[39] := B#16#25;
- SONG[40] := B#16#1F;
- SONG[41] := B#16#26;
- SONG[42] := B#16#1F;
- SONG[43] := B#16#2F;
- SONG[44] := B#16#37;
- SONG[45] := B#16#28;
- SONG[46] := B#16#1F;
- SONG[47] := B#16#27;
- SONG[48] := B#16#37;
- SONG[49] := B#16#29;
- SONG[50] := B#16#26;
- SONG[51] := B#16#1F;
- SONG[52] := B#16#16;
- SONG[53] := B#16#26;
- SONG[54] := B#16#1F;
- SONG[55] := B#16#2F;
- SONG[56] := B#16#16;
- SONG[57] := B#16#FF;
- END_DATA_BLOCK
- ]]></source>
- </language_awl>
- <!-- Symbol table configuration -->
- <symbols>
- <!-- symbol table source code -->
- <source enabled="1"
- name="Main table"
- type="3"><![CDATA[
- 126,pwm_period AW 0 WORD
- 126,pwm0 AW 2 WORD
- 126,DB_notes DB 100 DB 100
- 126,DB_notes_sharp DB 101 DB 101
- 126,DB_song DB 1 DB 1
- 126,FB_musicPlayer FB 1 FB 1
- 126,FC_setPWM FC 1 FC 1
- 126,FC_calcWaitTime FC 2 FC 2
- ]]></source>
- </symbols>
- <!-- Core server link configuration -->
- <core_link>
- <!-- Locally spawned core server -->
- <spawn_local enable="0"
- interpreters="$DEFAULT"
- port_range_begin="4183"
- port_range_end="8278" />
- <!-- Remote server connection -->
- <connect host="pilc"
- port="4151"
- timeout_ms="3000" />
- <!-- Transport tunnel -->
- <tunnel local_port="-1"
- type="1">
- <ssh executable="ssh"
- port="22"
- user="pi" />
- </tunnel>
- </core_link>
- <!-- Hardware modules configuration -->
- <hardware>
- <!-- Loaded hardware module -->
- <module name="pixtend">
- <params>
- <param name="analogIn0_10V"
- value="True" />
- <param name="analogIn0_addr" />
- <param name="analogIn0_nos"
- value="10" />
- <param name="analogIn1_10V"
- value="True" />
- <param name="analogIn1_addr" />
- <param name="analogIn1_nos"
- value="10" />
- <param name="analogIn2_addr" />
- <param name="analogIn2_nos"
- value="10" />
- <param name="analogIn3_addr" />
- <param name="analogIn3_nos"
- value="10" />
- <param name="analogIn_kHz"
- value="125" />
- <param name="analogOut0_addr" />
- <param name="analogOut1_addr" />
- <param name="boardType"
- value="auto" />
- <param name="digitalIn0_addr" />
- <param name="digitalIn1_addr" />
- <param name="digitalIn2_addr" />
- <param name="digitalIn3_addr" />
- <param name="digitalIn4_addr" />
- <param name="digitalIn5_addr" />
- <param name="digitalIn6_addr" />
- <param name="digitalIn7_addr" />
- <param name="digitalOut0_addr" />
- <param name="digitalOut1_addr" />
- <param name="digitalOut2_addr" />
- <param name="digitalOut3_addr" />
- <param name="digitalOut4_addr" />
- <param name="digitalOut5_addr" />
- <param name="enabled"
- value="True" />
- <param name="gpio0_addr" />
- <param name="gpio0_pullup"
- value="False" />
- <param name="gpio1_addr" />
- <param name="gpio1_pullup"
- value="False" />
- <param name="gpio2_addr" />
- <param name="gpio2_pullup"
- value="False" />
- <param name="gpio3_addr" />
- <param name="gpio3_pullup"
- value="False" />
- <param name="inputAddressBase"
- value="0" />
- <param name="outputAddressBase"
- value="0" />
- <param name="pollIntMs"
- value="25" />
- <param name="pwm0A_addr"
- value="AW 2" />
- <param name="pwm0B_addr" />
- <param name="pwm0_baseFreqHz"
- value="2000000" />
- <param name="pwm0_mode"
- value="dutycycle" />
- <param name="pwm0_period"
- value="AW 0" />
- <param name="pwm1A_addr" />
- <param name="pwm1B_addr" />
- <param name="pwm1_baseFreqHz"
- value="0" />
- <param name="pwm1_mode"
- value="dutycycle" />
- <param name="pwm1_period" />
- <param name="relay0_addr" />
- <param name="relay1_addr" />
- <param name="relay2_addr" />
- <param name="relay3_addr" />
- <param name="rs485"
- value="False" />
- </params>
- </module>
- </hardware>
- <!-- Graphical user interface configuration -->
- <gui>
- <!-- Core interaction settings -->
- <core pre_download_validation="1" />
- <!-- AWL editor settings -->
- <editor autoindent="1"
- paste_autoindent="1"
- validation="1" />
- </gui>
- </awlsim_project>
|