Kaynağa Gözat

Updates to support 16Mhz and reading from register memory from picadae_shell.py.

master
kevin.larke 4 yıl önce
ebeveyn
işleme
6dc45c0127

+ 110
- 73
control/app/picadae_api.py Dosyayı Görüntüle

@@ -5,49 +5,62 @@ from multiprocessing import Process, Pipe
5 5
 # Message header id's for messages passed between the application
6 6
 # process and the microcontroller and video processes
7 7
 
8
-TinyOpD = {
9
-    'setPwmOp':     0,
10
-    'noteOnVelOp':  1,
11
-    'noteOnUsecOp': 2,
12
-    'noteOffOp':    3,
13
-    'readOp':       4,
14
-    'writeOp':      5
15
-}
8
+class TinyOp(Enum):
9
+    setPwmOp     = 0
10
+    noteOnVelOp  = 1
11
+    noteOnUsecOp = 2
12
+    noteOffOp    = 3
13
+    setReadAddr  = 4
14
+    writeOp      = 5
15
+    
16 16
 
17 17
 class TinyRegAddr(Enum):
18
-    kRdRegAddrAddr   =  0,
19
-    kRdTableAddrAddr =  1,
20
-    kRdEEAddrAddr    =  2,
21
-    kRdSrcAddr       =  3,
22
-    kWrRegAddrAddr   =  4,
23
-    kWrTableAddrAddr =  5,
24
-    kWrEEAddrAddr    =  6,
25
-    kWrDstAddr       =  7,
26
-    kTmrCoarseAddr   =  8,
27
-    kTmrFineAddr     =  9,
28
-    kTmrPrescaleAddr = 10, 
29
-    kPwmEnableAddr   = 11,
30
-    kPwmDutyAddr     = 12,
31
-    kPwmFreqAddr     = 13,
32
-    kModeAddr        = 14,
33
-    kStateAddr       = 15,
34
-    kErrorCodeAddr   = 16
18
+    kRdRegAddrAddr   =  0
19
+    kRdTableAddrAddr =  1
20
+    kRdEEAddrAddr    =  2
21
+    kRdSrcAddr       =  3
22
+    kWrRegAddrAddr   =  4
23
+    kWrTableAddrAddr =  5
24
+    kWrEEAddrAddr    =  6
25
+    kWrDstAddr       =  7
26
+    kTmrCoarseAddr   =  8
27
+    kTmrFineAddr     =  9
28
+    kTmrPrescaleAddr = 10 
29
+    kPwmDutyAddr     = 11
30
+    kPwmFreqAddr     = 12
31
+    kModeAddr        = 13
32
+    kStateAddr       = 14
33
+    kErrorCodeAddr   = 15
35 34
 
36 35
 class TinyConst(Enum):
37
-    kRdRegSrcId    = TinyRegAddr.kRdRegAddrAddr,    # 0
38
-    kRdTableSrcId  = TinyRegAddr.kRdTableAddrAddr,  # 1
39
-    kRdEESrcId     = TinyRegAddr.kRdEEAddrAddr      # 2
36
+    kRdRegSrcId    = TinyRegAddr.kRdRegAddrAddr    # 0
37
+    kRdTableSrcId  = TinyRegAddr.kRdTableAddrAddr  # 1
38
+    kRdEESrcId     = TinyRegAddr.kRdEEAddrAddr     # 2
40 39
     
41
-    kWrRegDstId    = TinyRegAddr.kWrRegAddrAddr,    # 4
42
-    kWrTableDstId  = TinyRegAddr.kWrTableAddrAddr,  # 5
43
-    kWrEEDstId     = TinyRegAddr.kWrEEAddrAddr,     # 6
44
-    kWrAddrFl      = 0x08,                          # first avail bit above kWrEEAddr
40
+    kWrRegDstId    = TinyRegAddr.kWrRegAddrAddr    # 4
41
+    kWrTableDstId  = TinyRegAddr.kWrTableAddrAddr  # 5
42
+    kWrEEDstId     = TinyRegAddr.kWrEEAddrAddr     # 6
43
+    kWrAddrFl      = 0x08                          # first avail bit above kWrEEAddr
45 44
     
46 45
 class SerialMsgId(Enum):
47 46
     QUIT_MSG   = 0xffff   
48 47
     DATA_MSG   = 0xfffe
49 48
 
49
+class Result(object):
50
+    def __init__( self, value=None, msg=None ):
51
+        self.value = value
52
+        self.msg   = msg
50 53
 
54
+    def set_error( self, msg ):
55
+        if self.msg is None:
56
+            self.msg = ""
57
+            
58
+        self.msg += " " + msg
59
+        
60
+    def __bool__( self ):
61
+        return self.msg is  None
62
+
63
+    
51 64
 def _serial_process_func( serial_dev, baud, pipe ):
52 65
 
53 66
     reset_N     = 0
@@ -100,7 +113,8 @@ class SerialProcess(Process):
100 113
         self.parent_end, child_end = Pipe()
101 114
         super(SerialProcess, self).__init__(target=_serial_process_func, name="Serial", args=(serial_dev,serial_baud,child_end,))
102 115
         self.doneFl    = False
103
-        
116
+
117
+
104 118
     def quit(self):
105 119
         # send quit msg to the child process
106 120
         self.parent_end.send((SerialMsgId.QUIT_MSG,0))
@@ -108,6 +122,7 @@ class SerialProcess(Process):
108 122
     def send(self,msg_id,value):
109 123
         # send a msg to the child process
110 124
         self.parent_end.send((msg_id,value))
125
+        return Result()
111 126
 
112 127
     def recv(self):
113 128
         # 
@@ -127,7 +142,7 @@ class SerialProcess(Process):
127 142
         
128 143
 
129 144
 class Picadae:
130
-    def __init__( self, key_mapL, i2c_base_addr=1, serial_dev='/dev/ttyACM0', serial_baud=38400 ):
145
+    def __init__( self, key_mapL, i2c_base_addr=21, serial_dev='/dev/ttyACM0', serial_baud=38400, prescaler_usec=16 ):
131 146
         """
132 147
         key_mapL      = [{ index, board, ch, type, midi, class }]  
133 148
         serial_dev    = /dev/ttyACM0
@@ -137,65 +152,86 @@ class Picadae:
137 152
         self.serialProc     = SerialProcess( serial_dev, serial_baud )
138 153
         self.keyMapD        = { d['midi']:d for d in key_mapL }
139 154
         self.i2c_base_addr  = i2c_base_addr
140
-        self.prescaler_usec = 32
155
+        self.prescaler_usec = prescaler_usec
141 156
         
142 157
         self.serialProc.start()
143 158
         
144 159
     def close( self ):
145 160
         self.serialProc.quit()
146 161
         
147
-    def write( self, i2c_addr, reg_addr, byteL ):
148
-        return self._send( 'w', i2c_addr, reg_addr, [ len(byteL) ] + byteL )
149
-
150
-    def set_read_addr( self, i2c_addr, src, addr ):
151
-        return self. write(i2c_addr, TinyOpD['readOp'], src, addr )
152
-            
153
-    def set_reg_read_addr( self, i2c_addr, addr ):
154
-        return self.set_read_addr(i2c_addr, TinyRegAddr.kRdRegAddrAddr, addr )
162
+    def wait_for_serial_sync(self, timeoutMs=10000):
155 163
 
156
-    def set_table_read_addr( self, i2c_addr, addr ):
157
-        return self.set_read_addr(i2c_addr, TinyRegAddr.kRdTableAddrAddr, addr )
158
-    
159
-    def set_eeprom_read_addr( self, i2c_addr, addr ):
160
-        return self.set_read_addr(i2c_addr, TinyRegAddr.kRdEEAddrAddr, addr )
161
-    
162
-    def read_request( self, i2c_addr, reg_addr, argL ):
163
-        return self._send( 'r', i2c_addr, reg_addr,    [  byteOutN, len(argL) ] + argL )
164
+        # wait for the letter 'a' to come back from the serial port
165
+        result = self.block_on_serial_read(1,timeoutMs)
164 166
 
165
-    def read_poll( self ):
166
-        return self.serialProc.recv()
167
+        if result and len(result.value)>0 and result.value[0] == ord('a'):
168
+            pass
169
+        else:
170
+            result.set_error("Serial sync failed.")
167 171
 
168
-    def read_block( self, i2c_addr, reg_addr, argL, byteOutN, time_out_ms ):
172
+        return result
169 173
         
170
-        self.read_request( self, i2c_addr, reg_addr, argL, byteOutN )
174
+    def write( self, i2c_addr, reg_addr, byteL ):
175
+        return self._send( 'w', i2c_addr, reg_addr, [ len(byteL) ] + byteL )
171 176
 
172
-        ts = datetime.datetime.now() + datetime.timeDelta(milliseconds=time_out_ms)
177
+    def set_read_addr( self, i2c_addr, mem_id, addr ):
178
+        return self. write(i2c_addr, TinyOp.setReadAddr.value,[ mem_id, addr ])
179
+                
180
+    def read_request( self, i2c_addr, reg_addr, byteOutN ):
181
+        return self._send( 'r', i2c_addr, reg_addr,[ byteOutN ] )
173 182
 
183
+    def block_on_serial_read( self, byteOutN, time_out_ms=250 ):
184
+        
185
+        ts   = datetime.datetime.now() + datetime.timedelta(milliseconds=time_out_ms)
174 186
         retL = []
187
+        
175 188
         while datetime.datetime.now() < ts and len(retL) < byteOutN:
176
-            
189
+
190
+            # If a value is available at the serial port return is otherwise return None.
177 191
             x = self.serialProc.recv()
178
-            if x is not None:
179
-                retL.append(x)
192
+            
193
+            if x is not None and x[0] == SerialMsgId.DATA_MSG:
194
+                for b in x[1]:
195
+                    retL.append(int(b))
180 196
             
181 197
             time.sleep(0.01)
182
-        
183
-        return retL
198
+
199
+        result = Result(value=retL)
200
+            
201
+        if len(retL) < byteOutN:
202
+            result.set_error("Serial port time out on read.")
203
+
204
+        return result
205
+            
206
+            
207
+
208
+    def block_on_picadae_read( self, i2c_addr, mem_id, reg_addr, argL, byteOutN, time_out_ms ):
209
+
210
+        result = self.set_read_addr( i2c_addr, mem_id, reg_addr )
211
+
212
+        if result:
213
+            result = self.read_request( i2c_addr, TinyOp.setReadAddr.value, byteOutN )
214
+
215
+            if result:
216
+                result = self.block_on_serial_read( byteOutN, time_out_ms )
217
+                
218
+        return result
184 219
         
185 220
 
186 221
     def note_on_vel( self, midi_pitch, midi_vel ):
187 222
         return self.write( self._pitch_to_i2c_addr( midi_pitch ),
188
-                           TinyOpD['noteOnVelOp'],
223
+                           TinyOp.noteOnVelOp.value,
189 224
                            [self._validate_vel(midi_vel)] )
190 225
     
191 226
     def note_on_us( self, midi_pitch, pulse_usec ):
192 227
         return self.write( self._pitch_to_i2c_addr( midi_pitch ),
193
-                           TinyOpD['noteOnUsecOp'],
228
+                           TinyOp.noteOnUsecOp.value,
194 229
                            list(self._usec_to_coarse_and_fine(pulse_usec)) )
195 230
 
196 231
     def note_off( self, midi_pitch ):
197 232
         return self.write( self._pitch_to_i2c_addr( midi_pitch ),
198
-                           TinyOpD['noteOffOp'],[0] )  # TODO: sending a dummy byte because we can handle sending a command with no data bytes.
233
+                           TinyOp.noteOffOp.value,
234
+                           [0] )  # TODO: sending a dummy byte because we can't handle sending a command with no data bytes.
199 235
 
200 236
     def set_velocity_map( self, midi_pitch, midi_vel, pulse_usec ):
201 237
         pass
@@ -203,14 +239,15 @@ class Picadae:
203 239
     def get_velocity_map( self, midi_pitch, midi_vel, time_out_ms=250 ):
204 240
         pass
205 241
     
206
-    def set_pwm_duty( self, midi_pitch, duty_cycle_pct, enableFl=True ):
242
+    def set_pwm_duty( self, midi_pitch, duty_cycle_pct ):
207 243
         return self.write( self._pitch_to_i2c_addr( midi_pitch ),
208
-                           TinyOpD['setPwmOp'],
209
-                           [enableFl, int( duty_cycle_pct * 255.0 /100.0 )])
244
+                           TinyOp.setPwmOp.value,
245
+                           [ int( duty_cycle_pct * 255.0 /100.0 )])
210 246
 
211 247
     def get_pwm_duty( self, midi_pitch, time_out_ms=250 ):
212
-        return self.read_block( self._pitch_to_i2c_addr( midi_pitch ),
213
-                                TinyRegAddr.kPwmDutyAddr,
248
+        return self.block_on_picadae_read( self._pitch_to_i2c_addr( midi_pitch ),
249
+                                TinyRegAddr.kRdRegAddrAddr.value,
250
+                                TinyRegAddr.kPwmDutyAddr.value,
214 251
                                 [], 1, time_out_ms )
215 252
     
216 253
     def set_pwm_freq( self, midi_pitch, freq_div_id ):
@@ -219,13 +256,14 @@ class Picadae:
219 256
         pass
220 257
     
221 258
     def get_pwm_freq( self, midi_pitch, time_out_ms=250 ):
222
-        return self.read_block( self._pitch_to_i2c_addr( midi_pitch ),
223
-                                TinyRegAddr.kPwmFreqAddr,
259
+        return self.block_on_picadae_read( self._pitch_to_i2c_addr( midi_pitch ),
260
+                                TinyRegAddr.kRdRegAddrAddr.value,
261
+                                TinyRegAddr.kPwmFreqAddr.value,
224 262
                                 [], 1, time_out_ms )
225 263
 
226 264
     def set_flags( self, midi_pitch, flags ):
227 265
         return self.write( self._pitch_to_i2c_addr( midi_pitch ),                           
228
-                           TinyOpD['writeOp'],
266
+                           TinyOp.writeOp.value,
229 267
                            [ 12, 14, flags ])
230 268
 
231 269
     def make_note( self, midi_pitch, atk_us, dur_ms ):
@@ -245,7 +283,6 @@ class Picadae:
245 283
         coarse = int( usec / (self.prescaler_usec*255))
246 284
         fine   = int((usec - coarse*self.prescaler_usec*255) / self.prescaler_usec)
247 285
 
248
-        print(coarse,fine)
249 286
         assert( coarse <= 255 )
250 287
         assert( fine <= 255)
251 288
 

+ 5
- 0
control/app/picadae_cmd.py Dosyayı Görüntüle

@@ -275,6 +275,11 @@ class App:
275 275
             
276 276
         # form the command into a byte array
277 277
         cmd_bV = bytearray( [ ord(op_code), i2c_addr, reg_addr, op_byteN ] + dataL )
278
+
279
+        # s = ""
280
+        # for i in range(len(cmd_bV)):
281
+        #    s += "%i " % (cmd_bV[i])
282
+        # print(s)
278 283
         
279 284
         return (cmd_bV,None)
280 285
 

+ 2
- 1
control/app/picadae_cmd.yml Dosyayı Görüntüle

@@ -4,7 +4,8 @@
4 4
      serial_dev: "/dev/ttyACM0",
5 5
      serial_baud: 38400,
6 6
      i2c_base_addr: 21,
7
-     prescaler_usec: 32,
7
+     prescaler_usec: 16,
8
+     serial_sync_timeout_ms: 10000,
8 9
      
9 10
      key_mapL: [
10 11
 

+ 34
- 20
control/app/picadae_shell.py Dosyayı Görüntüle

@@ -1,6 +1,7 @@
1 1
 import os,sys,argparse,yaml,types,select,serial,logging,time
2 2
 
3 3
 from picadae_api import Picadae
4
+from picadae_api import Result
4 5
 
5 6
 class PicadaeShell:
6 7
     def __init__( self, cfg ):
@@ -27,6 +28,7 @@ class PicadaeShell:
27 28
         for k,d in self.parseD.items():
28 29
             s = "{} = {}".format( k, d['help'] )
29 30
             print(s)
31
+        return Result()
30 32
 
31 33
     def _do_write( self, argL ):
32 34
         return self.p.write(argL[0], argL[1], argL[2:])
@@ -69,7 +71,7 @@ class PicadaeShell:
69 71
         
70 72
     def _syntaxError( self, msg ):
71 73
         print("Syntax Error: " + msg )
72
-        return None
74
+        return Result()
73 75
             
74 76
     def _exec_cmd( self, tokL ):
75 77
         if len(tokL) <= 0:
@@ -95,36 +97,48 @@ class PicadaeShell:
95 97
             if  d['varN'] != -1 and len(argL) != d['varN']:                
96 98
                 return self._syntaxError("Argument mismatch {} != {}.".format(len(argL),d['varN']))
97 99
             
98
-            result = func(argL) 
100
+            result = func(argL)
101
+            
99 102
 
100
-        return None
103
+        return result
101 104
     
102 105
     def run( self ):
103 106
 
104 107
         # create the API object
105
-        self.p = Picadae( cfg.key_mapL, cfg.i2c_base_addr, cfg.serial_dev, cfg.serial_baud )
108
+        self.p = Picadae( cfg.key_mapL, cfg.i2c_base_addr, cfg.serial_dev, cfg.serial_baud, cfg.prescaler_usec )
106 109
 
107
-        print("'q'=quit '?'=help")
108
-        time_out_secs = 1
109
-        
110
-        while True:
110
+        # wait for the letter 'a' to come back from the serial port
111
+        result = self.p.wait_for_serial_sync(timeoutMs=cfg.serial_sync_timeout_ms)
112
+
113
+        if not result:
114
+            print("Serial port sync failed.")
115
+        else:
116
+            print(result.value)
117
+            
118
+            print("'q'=quit '?'=help")
119
+            time_out_secs = 1
120
+
121
+            while True:
122
+
123
+                # wait for keyboard activity
124
+                i, o, e = select.select( [sys.stdin], [], [], time_out_secs )
111 125
 
112
-            # wait for keyboard activity
113
-            i, o, e = select.select( [sys.stdin], [], [], time_out_secs )
126
+                if (i):
127
+                    # read the command
128
+                    s = sys.stdin.readline().strip() 
114 129
 
115
-            if (i):
116
-                # read the command
117
-                s = sys.stdin.readline().strip() 
130
+                    # tokenize the command
131
+                    tokL = s.split(' ')
118 132
 
119
-                # tokenize the command
120
-                tokL = s.split(' ')
133
+                    # if this is the 'quit' command
134
+                    if tokL[0] == 'q':
135
+                        break
121 136
 
122
-                # if this is the 'quit' command
123
-                if tokL[0] == 'q':
124
-                    break
137
+                    # execute the command
138
+                    result = self._exec_cmd( tokL )
125 139
 
126
-                # execute the command
127
-                self._exec_cmd( tokL )
140
+                    if result.value:
141
+                        print(result.value)
128 142
                 
129 143
                 
130 144
         self.p.close()

+ 4
- 1
control/tiny/Makefile Dosyayı Görüntüle

@@ -21,12 +21,15 @@ AVRDUDE=avrdude
21 21
 # /usr/bin/avrdude -C/etc/avrdude/avrdude.conf -v -pattiny85 -cstk500v1 -P/dev/ttyACM0 -b19200 -Uflash:w:/tmp/arduino_build_108059/i2c.ino.hex:i 
22 22
 # 	
23 23
 
24
+# lfuse=0xe2 =  8 Mghz
25
+# lfuse=0xe1 = 16 Mghz
26
+
24 27
 all:
25 28
 	$(CC) $(CFLAGS) $(TARGET).c usiTwiSlave.c -o$(TARGET)
26 29
 	$(OBJ2HEX) -R .eeprom -O ihex $(TARGET) $(TARGET).hex
27 30
 
28 31
 burn:
29
-	$(AVRDUDE) -p $(MCU) -P $(TTY)  -C/etc/avrdude/avrdude.conf -v -c avrisp -b 19200 -U flash:w:$(TARGET).hex -U lfuse:w:0xe2:m -U hfuse:w:0xdd:m -U efuse:w:0xff:m
32
+	$(AVRDUDE) -p $(MCU) -P $(TTY)  -C/etc/avrdude/avrdude.conf -v -c avrisp -b 19200 -U flash:w:$(TARGET).hex -U lfuse:w:0xe1:m -U hfuse:w:0xdd:m -U efuse:w:0xff:m
30 33
 clean:
31 34
 	rm -f *.hex *.obj *.o
32 35
 

+ 51
- 43
control/tiny/i2c_timer_pwm.c Dosyayı Görüntüle

@@ -15,7 +15,7 @@
15 15
 
16 16
 
17 17
 // This program acts as the device (slave) for the control program i2c/a2a/c_ctl
18
-#define F_CPU 8000000L
18
+#define F_CPU 16000000L
19 19
 
20 20
 #include <stdio.h>
21 21
 #include <avr/io.h>
@@ -35,13 +35,15 @@
35 35
 // Opcodes
36 36
 enum
37 37
 { 
38
- kSetPwm_Op         =  0,  // Set PWM registers  0 {<enable> {<duty> {<freq>}}}
38
+ kSetPwm_Op         =  0,  // Set PWM registers  0 {<duty> {<freq>}}
39 39
  kNoteOnVel_Op      =  1,  // Turn on note       1 {<vel>}
40 40
  kNoteOnUsec_Op     =  2,  // Turn on note       2 {<coarse> {<fine> {<prescale>}}}
41 41
  kNoteOff_Op        =  3,  // Turn off note      3
42
- kRead_Op           =  4,  // Read a value       4 {<src>} {<addr>} }  src: 0=reg 1=table 2=eeprom
43
- kWrite_Op          =  5,  // Set write          5 {<addrfl|src> {addr}  {<value0> ... {<valueN>}} 
44
- kInvalid_Op        =  6   //                      addrFl:0x80  src: 4=reg 5=table 6=eeprom                       
42
+ kSetReadAddr_Op    =  4,  // Set a read addr.   4 {<src>} {<addr>} }  src: 0=reg 1=table 2=eeprom
43
+ kWrite_Op          =  5,  // Set write          5 {<addrfl|src> {addr}  {<value0> ... {<valueN>}}  addrFl:0x80  src: 4=reg 5=table 6=eeprom
44
+ kSetMode_Op        =  6,  // Set the mode flags 6 {<mode>}  1=repeat 2=pwm
45
+ 
46
+ kInvalid_Op        =  7   //                                             
45 47
 };
46 48
 
47 49
 
@@ -59,26 +61,29 @@ enum
59 61
  
60 62
  kTmr_Coarse_idx     =  8,  //  
61 63
  kTmr_Fine_idx       =  9,  // 
62
- kTmr_Prescale_idx   = 10,  // Timer 0 clock divider: 1=1,2=8,3=64,4=256,5=1024  Default: 8 (32us)
64
+ kTmr_Prescale_idx   = 10,  // Timer 0 clock divider: 1=1,2=8,3=64,4=256,5=1024  Default: 8 (16us)
63 65
  
64
- kPwm_Enable_idx     = 11,  // 
65
- kPwm_Duty_idx       = 12,  // 
66
- kPwm_Freq_idx       = 13,  //
66
+ kPwm_Duty_idx       = 11,  // 
67
+ kPwm_Freq_idx       = 12,  //
67 68
 
68
- kMode_idx          = 14, // 1=repeat 2=pwm
69
- kState_idx          = 15, // 1=attk 2=hold
70
- kError_Code_idx     = 16,  // Error Code
69
+ kMode_idx           = 13, // 1=repeat 2=pwm
70
+ kState_idx          = 14, // 1=attk 2=hold
71
+ kError_Code_idx     = 15, // Error Code
71 72
  kMax_idx
72 73
 };
73 74
 
74 75
 enum
75 76
 {
76
- kTmr_Repeat_Fl= 1,
77
- kTmr_Pwm_Fl   = 2,
78
- kAttk_Fl      = 1,
79
- kHold_Fl      = 2
77
+ kMode_Repeat_Fl = 1,
78
+ kMode_Pwm_Fl    = 2,
79
+ kAttk_Fl        = 1,
80
+ kHold_Fl        = 2
80 81
 };
81 82
 
83
+
84
+#define isInRepeatMode() ctl_regs[ kMode_idx ] & kMode_Repeat_Fl
85
+#define isInPwmMode()    ctl_regs[ kMode_idx ] & kMode_Pwm_Fl
86
+
82 87
 // Flags:
83 88
 // 1=Repeat: 1=Timer and PWM are free running. This allows testing with LED's. 0=Timer triggers does not reset on time out. 
84 89
 // 2=PWM:  On timer timeout  1=PWM HOLD 0=Set HOLD 
@@ -93,15 +98,14 @@ volatile uint8_t ctl_regs[] =
93 98
    0,                //  5 (0-255)          Table Write Addr
94 99
    0,                //  6 (0-255)          EE Write Addr     
95 100
    kReg_Wr_Addr_idx, //  7 (0-2)    Write source
96
- 123,                //  8 (0-255)  Timer 0 Coarse Value 
97
-   8,                //  9 (0-255)  Timer 0 Fine Value
98
-   4,                // 10 (1-5)    4=32us per tick
99
-   1,                // 11 (0-1)    Pwm Enable Flag
100
- 127,                // 12 (0-255)  Pwm Duty cycle
101
- 254,                // 13 (0-255)  Pwm Frequency  (123 hz)
102
-   0,                // 14 mode flags  1=Repeat 2=PWM
103
-   0,                // 15 state flags 1=attk 2=hold
104
-   0,                // 16 (0-255)  Error bit field
101
+ 245,                //  8 (0-255)  Timer 0 Coarse Value 
102
+  25,                //  9 (0-255)  Timer 0 Fine Value
103
+   4,                // 10 (1-5)    4=16us per tick
104
+ 127,                // 11 (0-255)  Pwm Duty cycle
105
+ 254,                // 12 (0-255)  Pwm Frequency  (123 hz)
106
+   kMode_Repeat_Fl,  // 13 mode flags  1=Repeat 2=PWM
107
+   0,                // 14 state flags 1=attk   2=hold
108
+   0,                // 15 (0-255)  Error bit field
105 109
 };
106 110
 
107 111
 #define tableN 256
@@ -251,7 +255,7 @@ ISR(TIMER0_COMPA_vect)
251 255
       // fine mode
252 256
 
253 257
       // If in repeat mode
254
-      if(ctl_regs[kMode_idx] & kTmr_Repeat_Fl)
258
+      if(ctl_regs[kMode_idx] & kMode_Repeat_Fl)
255 259
       {
256 260
         uint8_t fl = ctl_regs[kState_idx] & kAttk_Fl;
257 261
         
@@ -271,7 +275,7 @@ ISR(TIMER0_COMPA_vect)
271 275
       {
272 276
         clear_attack();
273 277
         
274
-        if( ctl_regs[kMode_idx] & kTmr_Pwm_Fl)
278
+        if( ctl_regs[kMode_idx] & kMode_Pwm_Fl)
275 279
         {
276 280
           TIMSK  |= _BV(OCIE1B) + _BV(TOIE1);    // PWM interupt Enable interrupts          
277 281
         }
@@ -289,17 +293,13 @@ ISR(TIMER0_COMPA_vect)
289 293
 }
290 294
 
291 295
 
292
-void timer0_init()
296
+void tmr0_init()
293 297
 {
294 298
   TIMSK  &= ~_BV(OCIE0A);    // Disable interrupt TIMER1_OVF
295 299
   TCCR0A  |=  0x02;           // CTC mode
296 300
   TCCR0B  |= ctl_regs[kTmr_Prescale_idx]; // set the prescaler
297 301
 
298
-  GTCCR  |= _BV(PSR0);      // Set the pre-scaler to the selected value
299
-  
300
-  //tmr0_reset();              // set the timers starting state
301
-
302
-
302
+  GTCCR   |= _BV(PSR0);      // Set the pre-scaler to the selected value
303 303
 }
304 304
 
305 305
 
@@ -341,7 +341,7 @@ void pwm1_init()
341 341
   // set on TCNT1 == 0     // happens when TCNT1 matches OCR1C
342 342
   // clr on OCR1B == TCNT  // happens when TCNT1 matches OCR1B
343 343
   //                       // COM1B1=1 COM1B0=0 (enable output on ~OC1B)
344
-  TCCR1  |= 9;             // 32us period (256 divider) prescaler
344
+  TCCR1  |= 10;            // 32us period (512 divider) prescaler
345 345
   GTCCR  |= _BV(PWM1B);    // Enable PWM B and disconnect output pins
346 346
   GTCCR  |= _BV(PSR1);     // Set the pre-scaler to the selected value
347 347
 
@@ -485,13 +485,13 @@ void on_receive( uint8_t byteN )
485 485
   switch( op_id )
486 486
   {
487 487
     case kSetPwm_Op:
488
-      for(i=0; i<stack_idx; ++i)
489
-        ctl_regs[ kPwm_Enable_idx + i ] = stack[i];
488
+      for(i=0; i<stack_idx && i<2; ++i)
489
+        ctl_regs[ kPwm_Duty_idx + i ] = stack[i];
490 490
       pwm1_update();
491 491
       break;
492 492
       
493 493
     case kNoteOnUsec_Op:
494
-      for(i=0; i<stack_idx; ++i)
494
+      for(i=0; i<stack_idx && i<3; ++i)
495 495
         ctl_regs[ kTmr_Coarse_idx + i ] = stack[i];
496 496
       tmr0_reset();
497 497
       break;
@@ -501,8 +501,7 @@ void on_receive( uint8_t byteN )
501 501
       PORTB  &= ~_BV(HOLD_PIN);              // clear the HOLD pin          
502 502
       break;
503 503
 
504
-
505
-    case kRead_Op:
504
+    case kSetReadAddr_Op:
506 505
       if( stack_idx > 0 )
507 506
       {
508 507
         ctl_regs[ kRead_Src_idx ] = stack[0];
@@ -515,6 +514,15 @@ void on_receive( uint8_t byteN )
515 514
     case kWrite_Op:
516 515
       _write_op( stack, stack_idx );
517 516
       break;
517
+
518
+    case kSetMode_Op:
519
+      if( stack_idx > 0)
520
+      {
521
+        ctl_regs[ kMode_idx ] = stack[0];
522
+        tmr0_reset();
523
+      }
524
+      
525
+      break;
518 526
   }
519 527
 }
520 528
 
@@ -523,12 +531,10 @@ int main(void)
523 531
 {
524 532
   cli();        // mask all interupts
525 533
 
526
-
527 534
   DDRB  |=   _BV(ATTK_DIR)  + _BV(HOLD_DIR)  + _BV(LED_DIR);  // setup PB4,PB3,PB1 as output  
528 535
   PORTB &= ~(_BV(ATTK_PIN)  + _BV(HOLD_PIN)  + _BV(LED_PIN)); // clear output pins
529
-
530 536
   
531
-  timer0_init();
537
+  tmr0_init();
532 538
   pwm1_init();
533 539
   
534 540
   // setup i2c library
@@ -542,10 +548,12 @@ int main(void)
542 548
   _delay_ms(1000);  
543 549
   PINB = _BV(LED_PIN);  // writes to PINB toggle the pins
544 550
 
551
+  // if in repeat mode
552
+  if( ctl_regs[ kMode_idx ] & kMode_Repeat_Fl)
553
+    tmr0_reset();
545 554
   
546 555
   while(1)
547 556
   {
548
-    //_delay_ms(1000);
549 557
 
550 558
     if (!usi_onReceiverPtr)
551 559
     {

Loading…
İptal
Kaydet