commit f6d6bfa45cd41f2d040dec1a0c02f5d647b37f9f
Author: zavok <an2qzavok@gmail.com>
Date: Sun, 26 Feb 2017 18:18:48 +0300
YES
Diffstat:
A | Makefile | | | 11 | +++++++++++ |
A | firmware.c | | | 215 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | firmware.hex | | | 129 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | firmware.o | | | 0 | |
4 files changed, 355 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,11 @@
+all: firmware.o firmware.hex
+.PHONY: flash clean
+firmware.o: firmware.c
+ avr-gcc -Wall -g3 -gdwarf-2 -mmcu="atmega328p" -Os firmware.c -o firmware.o
+firmware.hex: firmware.o
+ avr-objcopy -j .text -j .data -O ihex firmware.o firmware.hex
+clean:
+ rm firmware.hex firmware.o
+flash:
+ avrdude -p atmega328p -c arduino -P /dev/ttyACM0 -U flash:w:firmware.hex:i
+
diff --git a/firmware.c b/firmware.c
@@ -0,0 +1,215 @@
+#define F_CPU 16000000UL
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/sleep.h>
+#include <util/delay.h>
+
+#define LENGTH(X) sizeof(X)/sizeof(*X)
+
+#define BLOCK 100
+#define BPS 62500
+
+enum state {
+ INACTIVE = 0,
+ ATTACK = 1,
+ DECAY = 2,
+ SUSTAIN = 3,
+ RELEASE = 4
+};
+
+struct voice {
+ enum state state;
+ unsigned int time;
+ unsigned int freq;
+ unsigned int phase;
+ unsigned int dV;
+};
+
+float
+tri(unsigned int ph)
+{
+ double p = (double)((ph%BPS)*2 - BPS);
+ return p < 0 ? -p/(double)BPS : p/(double)BPS;
+}
+
+float
+saw(unsigned int ph)
+{
+ return (float)ph/(float)BPS;
+}
+
+float
+sqr(unsigned int ph)
+{
+ return ph%BPS>BPS/2? 0.0 : 1.0;
+}
+
+float (*wave[])(unsigned int) = { &tri, &sqr, &saw};
+
+struct voice voices[1];
+unsigned int ADSR[4];
+unsigned int waveform = 1;
+unsigned int c = 0;
+
+unsigned int
+adsr(struct voice *v)
+{
+ unsigned int v1=0, v2=255, t, T;
+ switch (v->state){
+ case INACTIVE:
+ return 0;
+ case ATTACK:
+ break;
+ case DECAY:
+ v1 = 255;
+ v2 = ADSR[2];
+ break;
+ case SUSTAIN:
+ return ADSR[2];
+ case RELEASE:
+ v1 = ADSR[2];
+ v2 = 0;
+ break;
+ default:
+ break;
+ }
+ t = v->time;
+ T = ADSR[v->state-1];
+ return (v1*(T-t) + v2*t)/T;
+}
+
+void
+init_pwm()
+{
+ DDRD |= _BV(PD6);
+ TCCR0A |= _BV(COM0A1) | _BV(WGM01) | _BV(WGM00);
+ TCCR0B |= _BV(CS00);
+}
+
+void
+init_interrupt()
+{
+ TIFR0 =_BV(TOV0);
+ TIMSK0=_BV(TOIE0);
+ sei();
+}
+
+void
+init()
+{
+ //TEMPORARY
+ ADSR[0] = 8;
+ ADSR[1] = 32;
+ ADSR[2] = 128;
+ voices[0].state = ATTACK;
+ voices[0].freq = 440;
+ //voices[2].state = ATTACK;
+ //voices[2].freq = 550;
+ //---------
+ set_sleep_mode(0);
+ init_pwm();
+ init_interrupt();
+}
+
+void
+scan_keys()
+{
+ int i,j;
+ int row = 1;
+ int col = 1;
+ for(i=0; i<7; ++i){
+ row = row << 1;
+ for(j=0; j<6; ++j){
+ col = col << 1;
+ //woop
+ }
+ }
+}
+
+void
+scan_knobs()
+{
+}
+
+void
+update_phase(struct voice *v)
+{
+ if (v->state == INACTIVE) return;
+ v->phase = (v->phase+(v->freq))%BPS;
+}
+
+void
+update_voice(struct voice *v)
+{
+ if (v->state == INACTIVE) return;
+ v->dV = adsr(v);
+ if (v->state == SUSTAIN) return;
+ v->time++;
+ if (v->time > ADSR[v->state-1]){
+ v->time = 0;
+ v->state = (v->state+1)%5;
+ }
+}
+
+void
+update_synth()
+{
+ int i;
+ for(i=0; i<LENGTH(voices); ++i) update_voice(&voices[i]);
+}
+
+unsigned int
+get_voice(struct voice *v)
+{
+ unsigned int amp;
+ if (v->state == INACTIVE) return 0;
+ amp = (*wave[waveform])(v->phase) * v->dV;
+ return amp;
+}
+
+void
+drive_pwm()
+{
+ unsigned int p = 0;
+ int i;
+ for (i=0; i<LENGTH(voices); ++i) {
+ update_phase(&voices[i]);
+ p += get_voice(&voices[i])/8;
+ }
+ OCR0A = p;
+}
+
+/*void
+loop()
+{
+ scan_keys();
+ scan_knobs();
+ update_synth();
+ int i;
+ for (i=0; i<BLOCK; ++i) {
+ drive_pwm();
+ _delay_us(1000000/BPS);
+ }
+}*/
+
+ISR(TIMER0_OVF_vect)
+{
+ c++;
+ drive_pwm();
+ if (c >= BLOCK) {
+ c = 0;
+ scan_keys();
+ scan_knobs();
+ update_synth();
+ }
+
+}
+
+int
+main ()
+{
+ init();
+ for(;;) sleep_mode();
+ return 0;
+}
+
diff --git a/firmware.hex b/firmware.hex
@@ -0,0 +1,129 @@
+:100000000C9434000C9451000C9451000C94510049
+:100010000C9451000C9451000C9451000C9451001C
+:100020000C9451000C9451000C9451000C9451000C
+:100030000C9451000C9451000C9451000C945100FC
+:100040000C94D4010C9451000C9451000C94510068
+:100050000C9451000C9451000C9451000C945100DC
+:100060000C9451000C94510011241FBECFEFD8E026
+:10007000DEBFCDBF11E0A0E0B1E0E6EEF7E002C0E8
+:1000800005900D92A830B107D9F721E0A8E0B1E0C2
+:1000900001C01D92AC31B207E1F70E940E020C9430
+:1000A000F1030C940000CF92DF92EF92FF9221E0D7
+:1000B00030E0843244EF940710F420E030E064E252
+:1000C00074EF269FA001279F500D369F500D1124DD
+:1000D000841B950BBC0180E090E062517A47810956
+:1000E0009109660F771F881F991F0E94D4026B0128
+:1000F0007C0120E030E0A9010E942C0287FF0EC0A5
+:10010000C701B601905820E034E244E757E40E946A
+:100110003102FF90EF90DF90CF90089520E034E21D
+:1001200044E757E4C701B601F2CFBC0180E090E09C
+:100130000E94D20220E034E244E757E40E943102F8
+:10014000089521E030E0843244EF940710F420E079
+:1001500030E064E274EF269FA001279F500D369F88
+:10016000500D1124841B950B83319A4728F460E0CD
+:1001700070E080E89FE3089560E070E0CB010895AF
+:10018000CF93DF93FC012081318122303105B9F01A
+:1001900048F42115310509F440C04FEF50E0A0E0CC
+:1001A000B0E013C02330310589F124303105A9F7BF
+:1001B000A0910E01B0910F0140E050E006C04091C7
+:1001C0000E0150910F01AFEFB0E0FC01C281D3816D
+:1001D000220F331FF901E85FFE4F608171819B019F
+:1001E0002C1B3D0B2A9FC0012B9F900D3A9F900D19
+:1001F00011244C9F90014D9F300D5C9F300D1124B8
+:10020000820F931F0E941802CB0104C080910E013F
+:1002100090910F01DF91CF91089580E090E0FACFA7
+:10022000569A84B5836884BD85B5816085BD08957F
+:1002300081E085BB80936E0078940895EAE0F1E058
+:1002400088E090E09183808380E290E093838283D2
+:1002500080E890E095838483E2E1F1E081E090E042
+:100260009183808388EB91E09583848383B7817F3A
+:1002700083BF0E9410010C94180108950895FC0199
+:1002800080819181892BD9F0268137818481958164
+:10029000280F391F81E090E0243244EF340710F436
+:1002A00080E090E064E274EF869FA001879F500D8C
+:1002B000969F500D1124241B350B378326830895F8
+:1002C0000F931F93CF93DF93EC01088119810115E0
+:1002D000110501F10E94C00099878887033011053C
+:1002E000C9F08A819B8101969B838A83F801EE0F76
+:1002F000FF1FE85FFE4F208131812817390750F436
+:100300001B821A82C801019665E070E00E94180203
+:1003100099838883DF91CF911F910F91089582E196
+:1003200091E00C946001CF92DF92EF92FF92CF9315
+:10033000DF93EC0188819981892B21F1E091000103
+:10034000F0910101EE0FFF1FEE5FFE4F0190F08173
+:10035000E02D8E819F8109956B017C0168857985EF
+:1003600080E090E00E94D202A70196010E948403DF
+:100370000E94A302CB01DF91CF91FF90EF90DF901D
+:10038000CF90089580E090E0F6CF82E191E00E9466
+:100390003F0182E191E00E94930123E096958795C9
+:1003A0002A95E1F787BD08951F920F920FB60F921D
+:1003B00011242F933F934F935F936F937F938F936A
+:1003C0009F93AF93BF93EF93FF9380910801909118
+:1003D0000901019690930901809308010E94C501CB
+:1003E00080910801909109018436910530F01092B6
+:1003F0000901109208010E948F01FF91EF91BF91B6
+:10040000AF919F918F917F916F915F914F913F91AC
+:100410002F910F900FBE0F901F9018950E941E01F4
+:1004200083B7816083BF889583B78E7F83BFF8CF02
+:10043000AA1BBB1B51E107C0AA1FBB1FA617B7070A
+:1004400010F0A61BB70B881F991F5A95A9F7809526
+:100450009095BC01CD0108950E940F0308F481E03E
+:1004600008950E9445020C944A030E94430358F0E9
+:100470000E943C0340F029F45F3F29F00C943303C1
+:1004800051110C947E030C9439030E945B0368F3B2
+:100490009923B1F3552391F3951B550BBB27AA273D
+:1004A00062177307840738F09F5F5F4F220F331F77
+:1004B000441FAA1FA9F335D00E2E3AF0E0E832D03F
+:1004C00091505040E695001CCAF72BD0FE2F29D042
+:1004D000660F771F881FBB1F261737074807AB0714
+:1004E000B0E809F0BB0B802DBF01FF2793585F4F89
+:1004F0003AF09E3F510578F00C9433030C947E0340
+:100500005F3FE4F3983ED4F3869577956795B7956A
+:10051000F7959F5FC9F7880F911D9695879597F975
+:100520000895E1E0660F771F881FBB1F62177307EE
+:100530008407BA0720F0621B730B840BBA0BEE1F03
+:1005400088F7E09508950E94630388F09F5798F01C
+:10055000B92F9927B751B0F0E1F0660F771F881FC8
+:10056000991F1AF0BA95C9F714C0B13091F00E94E2
+:100570007D03B1E008950C947D03672F782F8827C1
+:10058000B85F39F0B93FCCF3869577956795B39509
+:10059000D9F73EF490958095709561957F4F8F4F78
+:1005A0009F4F0895E89409C097FB3EF4909580957D
+:1005B000709561957F4F8F4F9F4F9923A9F0F92F29
+:1005C00096E9BB279395F695879577956795B795A7
+:1005D000F111F8CFFAF4BB0F11F460FF1BC06F5F8D
+:1005E0007F4F8F4F9F4F16C0882311F096E911C09F
+:1005F000772321F09EE8872F762F05C0662371F0C0
+:1006000096E8862F70E060E02AF09A95660F771FD3
+:10061000881FDAF7880F9695879597F90895990FAF
+:100620000008550FAA0BE0E8FEEF16161706E807BC
+:10063000F907C0F012161306E407F50798F0621BDD
+:10064000730B840B950B39F40A2661F0232B242BB2
+:10065000252B21F408950A2609F4A140A6958FEFD1
+:10066000811D811D089597F99F6780E870E060E023
+:1006700008959FEF80EC089500240A94161617063B
+:1006800018060906089500240A9412161306140683
+:1006900005060895092E0394000C11F4882352F0E6
+:1006A000BB0F40F4BF2B11F460FF04C06F5F7F4F9E
+:1006B0008F4F9F4F089557FD9058440F551F59F085
+:1006C0005F3F71F04795880F97FB991F61F09F3F3F
+:1006D00079F087950895121613061406551FF2CF68
+:1006E0004695F1DF08C0161617061806991FF1CFB8
+:1006F00086957105610508940895E894BB276627DF
+:100700007727CB0197F908950E9497030C944A0329
+:100710000E943C0338F00E94430320F0952311F01F
+:100720000C9433030C94390311240C947E030E941F
+:100730005B0370F3959FC1F3950F50E0551F629FC7
+:10074000F001729FBB27F00DB11D639FAA27F00D2A
+:10075000B11DAA1F649F6627B00DA11D661F829F51
+:100760002227B00DA11D621F739FB00DA11D621F36
+:10077000839FA00D611D221F749F3327A00D611D53
+:10078000231F849F600D211D822F762F6A2F112435
+:100790009F5750409AF0F1F088234AF0EE0FFF1F68
+:1007A000BB1F661F771F881F91505040A9F79E3FBF
+:1007B000510580F00C9433030C947E035F3FE4F307
+:1007C000983ED4F3869577956795B795F795E79515
+:1007D0009F5FC1F7FE2B880F911D9695879597F91E
+:0607E0000895F894FFCF1C
+:0807E60001005300A100950081
+:00000001FF
diff --git a/firmware.o b/firmware.o
Binary files differ.