Updates to support 16Mhz and reading from register memory from picadae_shell.py.
This commit is contained in:
parent
de586ca2e3
commit
6dc45c0127
@ -5,48 +5,61 @@ from multiprocessing import Process, Pipe
|
||||
# Message header id's for messages passed between the application
|
||||
# process and the microcontroller and video processes
|
||||
|
||||
TinyOpD = {
|
||||
'setPwmOp': 0,
|
||||
'noteOnVelOp': 1,
|
||||
'noteOnUsecOp': 2,
|
||||
'noteOffOp': 3,
|
||||
'readOp': 4,
|
||||
'writeOp': 5
|
||||
}
|
||||
class TinyOp(Enum):
|
||||
setPwmOp = 0
|
||||
noteOnVelOp = 1
|
||||
noteOnUsecOp = 2
|
||||
noteOffOp = 3
|
||||
setReadAddr = 4
|
||||
writeOp = 5
|
||||
|
||||
|
||||
class TinyRegAddr(Enum):
|
||||
kRdRegAddrAddr = 0,
|
||||
kRdTableAddrAddr = 1,
|
||||
kRdEEAddrAddr = 2,
|
||||
kRdSrcAddr = 3,
|
||||
kWrRegAddrAddr = 4,
|
||||
kWrTableAddrAddr = 5,
|
||||
kWrEEAddrAddr = 6,
|
||||
kWrDstAddr = 7,
|
||||
kTmrCoarseAddr = 8,
|
||||
kTmrFineAddr = 9,
|
||||
kTmrPrescaleAddr = 10,
|
||||
kPwmEnableAddr = 11,
|
||||
kPwmDutyAddr = 12,
|
||||
kPwmFreqAddr = 13,
|
||||
kModeAddr = 14,
|
||||
kStateAddr = 15,
|
||||
kErrorCodeAddr = 16
|
||||
kRdRegAddrAddr = 0
|
||||
kRdTableAddrAddr = 1
|
||||
kRdEEAddrAddr = 2
|
||||
kRdSrcAddr = 3
|
||||
kWrRegAddrAddr = 4
|
||||
kWrTableAddrAddr = 5
|
||||
kWrEEAddrAddr = 6
|
||||
kWrDstAddr = 7
|
||||
kTmrCoarseAddr = 8
|
||||
kTmrFineAddr = 9
|
||||
kTmrPrescaleAddr = 10
|
||||
kPwmDutyAddr = 11
|
||||
kPwmFreqAddr = 12
|
||||
kModeAddr = 13
|
||||
kStateAddr = 14
|
||||
kErrorCodeAddr = 15
|
||||
|
||||
class TinyConst(Enum):
|
||||
kRdRegSrcId = TinyRegAddr.kRdRegAddrAddr, # 0
|
||||
kRdTableSrcId = TinyRegAddr.kRdTableAddrAddr, # 1
|
||||
kRdEESrcId = TinyRegAddr.kRdEEAddrAddr # 2
|
||||
kRdRegSrcId = TinyRegAddr.kRdRegAddrAddr # 0
|
||||
kRdTableSrcId = TinyRegAddr.kRdTableAddrAddr # 1
|
||||
kRdEESrcId = TinyRegAddr.kRdEEAddrAddr # 2
|
||||
|
||||
kWrRegDstId = TinyRegAddr.kWrRegAddrAddr, # 4
|
||||
kWrTableDstId = TinyRegAddr.kWrTableAddrAddr, # 5
|
||||
kWrEEDstId = TinyRegAddr.kWrEEAddrAddr, # 6
|
||||
kWrAddrFl = 0x08, # first avail bit above kWrEEAddr
|
||||
kWrRegDstId = TinyRegAddr.kWrRegAddrAddr # 4
|
||||
kWrTableDstId = TinyRegAddr.kWrTableAddrAddr # 5
|
||||
kWrEEDstId = TinyRegAddr.kWrEEAddrAddr # 6
|
||||
kWrAddrFl = 0x08 # first avail bit above kWrEEAddr
|
||||
|
||||
class SerialMsgId(Enum):
|
||||
QUIT_MSG = 0xffff
|
||||
DATA_MSG = 0xfffe
|
||||
|
||||
class Result(object):
|
||||
def __init__( self, value=None, msg=None ):
|
||||
self.value = value
|
||||
self.msg = msg
|
||||
|
||||
def set_error( self, msg ):
|
||||
if self.msg is None:
|
||||
self.msg = ""
|
||||
|
||||
self.msg += " " + msg
|
||||
|
||||
def __bool__( self ):
|
||||
return self.msg is None
|
||||
|
||||
|
||||
def _serial_process_func( serial_dev, baud, pipe ):
|
||||
|
||||
@ -101,6 +114,7 @@ class SerialProcess(Process):
|
||||
super(SerialProcess, self).__init__(target=_serial_process_func, name="Serial", args=(serial_dev,serial_baud,child_end,))
|
||||
self.doneFl = False
|
||||
|
||||
|
||||
def quit(self):
|
||||
# send quit msg to the child process
|
||||
self.parent_end.send((SerialMsgId.QUIT_MSG,0))
|
||||
@ -108,6 +122,7 @@ class SerialProcess(Process):
|
||||
def send(self,msg_id,value):
|
||||
# send a msg to the child process
|
||||
self.parent_end.send((msg_id,value))
|
||||
return Result()
|
||||
|
||||
def recv(self):
|
||||
#
|
||||
@ -127,7 +142,7 @@ class SerialProcess(Process):
|
||||
|
||||
|
||||
class Picadae:
|
||||
def __init__( self, key_mapL, i2c_base_addr=1, serial_dev='/dev/ttyACM0', serial_baud=38400 ):
|
||||
def __init__( self, key_mapL, i2c_base_addr=21, serial_dev='/dev/ttyACM0', serial_baud=38400, prescaler_usec=16 ):
|
||||
"""
|
||||
key_mapL = [{ index, board, ch, type, midi, class }]
|
||||
serial_dev = /dev/ttyACM0
|
||||
@ -137,65 +152,86 @@ class Picadae:
|
||||
self.serialProc = SerialProcess( serial_dev, serial_baud )
|
||||
self.keyMapD = { d['midi']:d for d in key_mapL }
|
||||
self.i2c_base_addr = i2c_base_addr
|
||||
self.prescaler_usec = 32
|
||||
self.prescaler_usec = prescaler_usec
|
||||
|
||||
self.serialProc.start()
|
||||
|
||||
def close( self ):
|
||||
self.serialProc.quit()
|
||||
|
||||
def wait_for_serial_sync(self, timeoutMs=10000):
|
||||
|
||||
# wait for the letter 'a' to come back from the serial port
|
||||
result = self.block_on_serial_read(1,timeoutMs)
|
||||
|
||||
if result and len(result.value)>0 and result.value[0] == ord('a'):
|
||||
pass
|
||||
else:
|
||||
result.set_error("Serial sync failed.")
|
||||
|
||||
return result
|
||||
|
||||
def write( self, i2c_addr, reg_addr, byteL ):
|
||||
return self._send( 'w', i2c_addr, reg_addr, [ len(byteL) ] + byteL )
|
||||
|
||||
def set_read_addr( self, i2c_addr, src, addr ):
|
||||
return self. write(i2c_addr, TinyOpD['readOp'], src, addr )
|
||||
def set_read_addr( self, i2c_addr, mem_id, addr ):
|
||||
return self. write(i2c_addr, TinyOp.setReadAddr.value,[ mem_id, addr ])
|
||||
|
||||
def set_reg_read_addr( self, i2c_addr, addr ):
|
||||
return self.set_read_addr(i2c_addr, TinyRegAddr.kRdRegAddrAddr, addr )
|
||||
def read_request( self, i2c_addr, reg_addr, byteOutN ):
|
||||
return self._send( 'r', i2c_addr, reg_addr,[ byteOutN ] )
|
||||
|
||||
def set_table_read_addr( self, i2c_addr, addr ):
|
||||
return self.set_read_addr(i2c_addr, TinyRegAddr.kRdTableAddrAddr, addr )
|
||||
|
||||
def set_eeprom_read_addr( self, i2c_addr, addr ):
|
||||
return self.set_read_addr(i2c_addr, TinyRegAddr.kRdEEAddrAddr, addr )
|
||||
|
||||
def read_request( self, i2c_addr, reg_addr, argL ):
|
||||
return self._send( 'r', i2c_addr, reg_addr, [ byteOutN, len(argL) ] + argL )
|
||||
|
||||
def read_poll( self ):
|
||||
return self.serialProc.recv()
|
||||
|
||||
def read_block( self, i2c_addr, reg_addr, argL, byteOutN, time_out_ms ):
|
||||
|
||||
self.read_request( self, i2c_addr, reg_addr, argL, byteOutN )
|
||||
|
||||
ts = datetime.datetime.now() + datetime.timeDelta(milliseconds=time_out_ms)
|
||||
def block_on_serial_read( self, byteOutN, time_out_ms=250 ):
|
||||
|
||||
ts = datetime.datetime.now() + datetime.timedelta(milliseconds=time_out_ms)
|
||||
retL = []
|
||||
|
||||
while datetime.datetime.now() < ts and len(retL) < byteOutN:
|
||||
|
||||
# If a value is available at the serial port return is otherwise return None.
|
||||
x = self.serialProc.recv()
|
||||
if x is not None:
|
||||
retL.append(x)
|
||||
|
||||
if x is not None and x[0] == SerialMsgId.DATA_MSG:
|
||||
for b in x[1]:
|
||||
retL.append(int(b))
|
||||
|
||||
time.sleep(0.01)
|
||||
|
||||
return retL
|
||||
result = Result(value=retL)
|
||||
|
||||
if len(retL) < byteOutN:
|
||||
result.set_error("Serial port time out on read.")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def block_on_picadae_read( self, i2c_addr, mem_id, reg_addr, argL, byteOutN, time_out_ms ):
|
||||
|
||||
result = self.set_read_addr( i2c_addr, mem_id, reg_addr )
|
||||
|
||||
if result:
|
||||
result = self.read_request( i2c_addr, TinyOp.setReadAddr.value, byteOutN )
|
||||
|
||||
if result:
|
||||
result = self.block_on_serial_read( byteOutN, time_out_ms )
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def note_on_vel( self, midi_pitch, midi_vel ):
|
||||
return self.write( self._pitch_to_i2c_addr( midi_pitch ),
|
||||
TinyOpD['noteOnVelOp'],
|
||||
TinyOp.noteOnVelOp.value,
|
||||
[self._validate_vel(midi_vel)] )
|
||||
|
||||
def note_on_us( self, midi_pitch, pulse_usec ):
|
||||
return self.write( self._pitch_to_i2c_addr( midi_pitch ),
|
||||
TinyOpD['noteOnUsecOp'],
|
||||
TinyOp.noteOnUsecOp.value,
|
||||
list(self._usec_to_coarse_and_fine(pulse_usec)) )
|
||||
|
||||
def note_off( self, midi_pitch ):
|
||||
return self.write( self._pitch_to_i2c_addr( midi_pitch ),
|
||||
TinyOpD['noteOffOp'],[0] ) # TODO: sending a dummy byte because we can handle sending a command with no data bytes.
|
||||
TinyOp.noteOffOp.value,
|
||||
[0] ) # TODO: sending a dummy byte because we can't handle sending a command with no data bytes.
|
||||
|
||||
def set_velocity_map( self, midi_pitch, midi_vel, pulse_usec ):
|
||||
pass
|
||||
@ -203,14 +239,15 @@ class Picadae:
|
||||
def get_velocity_map( self, midi_pitch, midi_vel, time_out_ms=250 ):
|
||||
pass
|
||||
|
||||
def set_pwm_duty( self, midi_pitch, duty_cycle_pct, enableFl=True ):
|
||||
def set_pwm_duty( self, midi_pitch, duty_cycle_pct ):
|
||||
return self.write( self._pitch_to_i2c_addr( midi_pitch ),
|
||||
TinyOpD['setPwmOp'],
|
||||
[enableFl, int( duty_cycle_pct * 255.0 /100.0 )])
|
||||
TinyOp.setPwmOp.value,
|
||||
[ int( duty_cycle_pct * 255.0 /100.0 )])
|
||||
|
||||
def get_pwm_duty( self, midi_pitch, time_out_ms=250 ):
|
||||
return self.read_block( self._pitch_to_i2c_addr( midi_pitch ),
|
||||
TinyRegAddr.kPwmDutyAddr,
|
||||
return self.block_on_picadae_read( self._pitch_to_i2c_addr( midi_pitch ),
|
||||
TinyRegAddr.kRdRegAddrAddr.value,
|
||||
TinyRegAddr.kPwmDutyAddr.value,
|
||||
[], 1, time_out_ms )
|
||||
|
||||
def set_pwm_freq( self, midi_pitch, freq_div_id ):
|
||||
@ -219,13 +256,14 @@ class Picadae:
|
||||
pass
|
||||
|
||||
def get_pwm_freq( self, midi_pitch, time_out_ms=250 ):
|
||||
return self.read_block( self._pitch_to_i2c_addr( midi_pitch ),
|
||||
TinyRegAddr.kPwmFreqAddr,
|
||||
return self.block_on_picadae_read( self._pitch_to_i2c_addr( midi_pitch ),
|
||||
TinyRegAddr.kRdRegAddrAddr.value,
|
||||
TinyRegAddr.kPwmFreqAddr.value,
|
||||
[], 1, time_out_ms )
|
||||
|
||||
def set_flags( self, midi_pitch, flags ):
|
||||
return self.write( self._pitch_to_i2c_addr( midi_pitch ),
|
||||
TinyOpD['writeOp'],
|
||||
TinyOp.writeOp.value,
|
||||
[ 12, 14, flags ])
|
||||
|
||||
def make_note( self, midi_pitch, atk_us, dur_ms ):
|
||||
@ -245,7 +283,6 @@ class Picadae:
|
||||
coarse = int( usec / (self.prescaler_usec*255))
|
||||
fine = int((usec - coarse*self.prescaler_usec*255) / self.prescaler_usec)
|
||||
|
||||
print(coarse,fine)
|
||||
assert( coarse <= 255 )
|
||||
assert( fine <= 255)
|
||||
|
||||
|
@ -276,6 +276,11 @@ class App:
|
||||
# form the command into a byte array
|
||||
cmd_bV = bytearray( [ ord(op_code), i2c_addr, reg_addr, op_byteN ] + dataL )
|
||||
|
||||
# s = ""
|
||||
# for i in range(len(cmd_bV)):
|
||||
# s += "%i " % (cmd_bV[i])
|
||||
# print(s)
|
||||
|
||||
return (cmd_bV,None)
|
||||
|
||||
|
||||
|
@ -4,7 +4,8 @@
|
||||
serial_dev: "/dev/ttyACM0",
|
||||
serial_baud: 38400,
|
||||
i2c_base_addr: 21,
|
||||
prescaler_usec: 32,
|
||||
prescaler_usec: 16,
|
||||
serial_sync_timeout_ms: 10000,
|
||||
|
||||
key_mapL: [
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import os,sys,argparse,yaml,types,select,serial,logging,time
|
||||
|
||||
from picadae_api import Picadae
|
||||
from picadae_api import Result
|
||||
|
||||
class PicadaeShell:
|
||||
def __init__( self, cfg ):
|
||||
@ -27,6 +28,7 @@ class PicadaeShell:
|
||||
for k,d in self.parseD.items():
|
||||
s = "{} = {}".format( k, d['help'] )
|
||||
print(s)
|
||||
return Result()
|
||||
|
||||
def _do_write( self, argL ):
|
||||
return self.p.write(argL[0], argL[1], argL[2:])
|
||||
@ -69,7 +71,7 @@ class PicadaeShell:
|
||||
|
||||
def _syntaxError( self, msg ):
|
||||
print("Syntax Error: " + msg )
|
||||
return None
|
||||
return Result()
|
||||
|
||||
def _exec_cmd( self, tokL ):
|
||||
if len(tokL) <= 0:
|
||||
@ -97,34 +99,46 @@ class PicadaeShell:
|
||||
|
||||
result = func(argL)
|
||||
|
||||
return None
|
||||
|
||||
return result
|
||||
|
||||
def run( self ):
|
||||
|
||||
# create the API object
|
||||
self.p = Picadae( cfg.key_mapL, cfg.i2c_base_addr, cfg.serial_dev, cfg.serial_baud )
|
||||
self.p = Picadae( cfg.key_mapL, cfg.i2c_base_addr, cfg.serial_dev, cfg.serial_baud, cfg.prescaler_usec )
|
||||
|
||||
print("'q'=quit '?'=help")
|
||||
time_out_secs = 1
|
||||
# wait for the letter 'a' to come back from the serial port
|
||||
result = self.p.wait_for_serial_sync(timeoutMs=cfg.serial_sync_timeout_ms)
|
||||
|
||||
while True:
|
||||
if not result:
|
||||
print("Serial port sync failed.")
|
||||
else:
|
||||
print(result.value)
|
||||
|
||||
# wait for keyboard activity
|
||||
i, o, e = select.select( [sys.stdin], [], [], time_out_secs )
|
||||
print("'q'=quit '?'=help")
|
||||
time_out_secs = 1
|
||||
|
||||
if (i):
|
||||
# read the command
|
||||
s = sys.stdin.readline().strip()
|
||||
while True:
|
||||
|
||||
# tokenize the command
|
||||
tokL = s.split(' ')
|
||||
# wait for keyboard activity
|
||||
i, o, e = select.select( [sys.stdin], [], [], time_out_secs )
|
||||
|
||||
# if this is the 'quit' command
|
||||
if tokL[0] == 'q':
|
||||
break
|
||||
if (i):
|
||||
# read the command
|
||||
s = sys.stdin.readline().strip()
|
||||
|
||||
# execute the command
|
||||
self._exec_cmd( tokL )
|
||||
# tokenize the command
|
||||
tokL = s.split(' ')
|
||||
|
||||
# if this is the 'quit' command
|
||||
if tokL[0] == 'q':
|
||||
break
|
||||
|
||||
# execute the command
|
||||
result = self._exec_cmd( tokL )
|
||||
|
||||
if result.value:
|
||||
print(result.value)
|
||||
|
||||
|
||||
self.p.close()
|
||||
|
@ -21,12 +21,15 @@ AVRDUDE=avrdude
|
||||
# /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
|
||||
#
|
||||
|
||||
# lfuse=0xe2 = 8 Mghz
|
||||
# lfuse=0xe1 = 16 Mghz
|
||||
|
||||
all:
|
||||
$(CC) $(CFLAGS) $(TARGET).c usiTwiSlave.c -o$(TARGET)
|
||||
$(OBJ2HEX) -R .eeprom -O ihex $(TARGET) $(TARGET).hex
|
||||
|
||||
burn:
|
||||
$(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
|
||||
$(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
|
||||
clean:
|
||||
rm -f *.hex *.obj *.o
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
|
||||
// This program acts as the device (slave) for the control program i2c/a2a/c_ctl
|
||||
#define F_CPU 8000000L
|
||||
#define F_CPU 16000000L
|
||||
|
||||
#include <stdio.h>
|
||||
#include <avr/io.h>
|
||||
@ -35,13 +35,15 @@
|
||||
// Opcodes
|
||||
enum
|
||||
{
|
||||
kSetPwm_Op = 0, // Set PWM registers 0 {<enable> {<duty> {<freq>}}}
|
||||
kSetPwm_Op = 0, // Set PWM registers 0 {<duty> {<freq>}}
|
||||
kNoteOnVel_Op = 1, // Turn on note 1 {<vel>}
|
||||
kNoteOnUsec_Op = 2, // Turn on note 2 {<coarse> {<fine> {<prescale>}}}
|
||||
kNoteOff_Op = 3, // Turn off note 3
|
||||
kRead_Op = 4, // Read a value 4 {<src>} {<addr>} } src: 0=reg 1=table 2=eeprom
|
||||
kWrite_Op = 5, // Set write 5 {<addrfl|src> {addr} {<value0> ... {<valueN>}}
|
||||
kInvalid_Op = 6 // addrFl:0x80 src: 4=reg 5=table 6=eeprom
|
||||
kSetReadAddr_Op = 4, // Set a read addr. 4 {<src>} {<addr>} } src: 0=reg 1=table 2=eeprom
|
||||
kWrite_Op = 5, // Set write 5 {<addrfl|src> {addr} {<value0> ... {<valueN>}} addrFl:0x80 src: 4=reg 5=table 6=eeprom
|
||||
kSetMode_Op = 6, // Set the mode flags 6 {<mode>} 1=repeat 2=pwm
|
||||
|
||||
kInvalid_Op = 7 //
|
||||
};
|
||||
|
||||
|
||||
@ -59,26 +61,29 @@ enum
|
||||
|
||||
kTmr_Coarse_idx = 8, //
|
||||
kTmr_Fine_idx = 9, //
|
||||
kTmr_Prescale_idx = 10, // Timer 0 clock divider: 1=1,2=8,3=64,4=256,5=1024 Default: 8 (32us)
|
||||
kTmr_Prescale_idx = 10, // Timer 0 clock divider: 1=1,2=8,3=64,4=256,5=1024 Default: 8 (16us)
|
||||
|
||||
kPwm_Enable_idx = 11, //
|
||||
kPwm_Duty_idx = 12, //
|
||||
kPwm_Freq_idx = 13, //
|
||||
kPwm_Duty_idx = 11, //
|
||||
kPwm_Freq_idx = 12, //
|
||||
|
||||
kMode_idx = 14, // 1=repeat 2=pwm
|
||||
kState_idx = 15, // 1=attk 2=hold
|
||||
kError_Code_idx = 16, // Error Code
|
||||
kMode_idx = 13, // 1=repeat 2=pwm
|
||||
kState_idx = 14, // 1=attk 2=hold
|
||||
kError_Code_idx = 15, // Error Code
|
||||
kMax_idx
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kTmr_Repeat_Fl= 1,
|
||||
kTmr_Pwm_Fl = 2,
|
||||
kAttk_Fl = 1,
|
||||
kHold_Fl = 2
|
||||
kMode_Repeat_Fl = 1,
|
||||
kMode_Pwm_Fl = 2,
|
||||
kAttk_Fl = 1,
|
||||
kHold_Fl = 2
|
||||
};
|
||||
|
||||
|
||||
#define isInRepeatMode() ctl_regs[ kMode_idx ] & kMode_Repeat_Fl
|
||||
#define isInPwmMode() ctl_regs[ kMode_idx ] & kMode_Pwm_Fl
|
||||
|
||||
// Flags:
|
||||
// 1=Repeat: 1=Timer and PWM are free running. This allows testing with LED's. 0=Timer triggers does not reset on time out.
|
||||
// 2=PWM: On timer timeout 1=PWM HOLD 0=Set HOLD
|
||||
@ -93,15 +98,14 @@ volatile uint8_t ctl_regs[] =
|
||||
0, // 5 (0-255) Table Write Addr
|
||||
0, // 6 (0-255) EE Write Addr
|
||||
kReg_Wr_Addr_idx, // 7 (0-2) Write source
|
||||
123, // 8 (0-255) Timer 0 Coarse Value
|
||||
8, // 9 (0-255) Timer 0 Fine Value
|
||||
4, // 10 (1-5) 4=32us per tick
|
||||
1, // 11 (0-1) Pwm Enable Flag
|
||||
127, // 12 (0-255) Pwm Duty cycle
|
||||
254, // 13 (0-255) Pwm Frequency (123 hz)
|
||||
0, // 14 mode flags 1=Repeat 2=PWM
|
||||
0, // 15 state flags 1=attk 2=hold
|
||||
0, // 16 (0-255) Error bit field
|
||||
245, // 8 (0-255) Timer 0 Coarse Value
|
||||
25, // 9 (0-255) Timer 0 Fine Value
|
||||
4, // 10 (1-5) 4=16us per tick
|
||||
127, // 11 (0-255) Pwm Duty cycle
|
||||
254, // 12 (0-255) Pwm Frequency (123 hz)
|
||||
kMode_Repeat_Fl, // 13 mode flags 1=Repeat 2=PWM
|
||||
0, // 14 state flags 1=attk 2=hold
|
||||
0, // 15 (0-255) Error bit field
|
||||
};
|
||||
|
||||
#define tableN 256
|
||||
@ -251,7 +255,7 @@ ISR(TIMER0_COMPA_vect)
|
||||
// fine mode
|
||||
|
||||
// If in repeat mode
|
||||
if(ctl_regs[kMode_idx] & kTmr_Repeat_Fl)
|
||||
if(ctl_regs[kMode_idx] & kMode_Repeat_Fl)
|
||||
{
|
||||
uint8_t fl = ctl_regs[kState_idx] & kAttk_Fl;
|
||||
|
||||
@ -271,7 +275,7 @@ ISR(TIMER0_COMPA_vect)
|
||||
{
|
||||
clear_attack();
|
||||
|
||||
if( ctl_regs[kMode_idx] & kTmr_Pwm_Fl)
|
||||
if( ctl_regs[kMode_idx] & kMode_Pwm_Fl)
|
||||
{
|
||||
TIMSK |= _BV(OCIE1B) + _BV(TOIE1); // PWM interupt Enable interrupts
|
||||
}
|
||||
@ -289,17 +293,13 @@ ISR(TIMER0_COMPA_vect)
|
||||
}
|
||||
|
||||
|
||||
void timer0_init()
|
||||
void tmr0_init()
|
||||
{
|
||||
TIMSK &= ~_BV(OCIE0A); // Disable interrupt TIMER1_OVF
|
||||
TCCR0A |= 0x02; // CTC mode
|
||||
TCCR0B |= ctl_regs[kTmr_Prescale_idx]; // set the prescaler
|
||||
|
||||
GTCCR |= _BV(PSR0); // Set the pre-scaler to the selected value
|
||||
|
||||
//tmr0_reset(); // set the timers starting state
|
||||
|
||||
|
||||
GTCCR |= _BV(PSR0); // Set the pre-scaler to the selected value
|
||||
}
|
||||
|
||||
|
||||
@ -341,7 +341,7 @@ void pwm1_init()
|
||||
// set on TCNT1 == 0 // happens when TCNT1 matches OCR1C
|
||||
// clr on OCR1B == TCNT // happens when TCNT1 matches OCR1B
|
||||
// // COM1B1=1 COM1B0=0 (enable output on ~OC1B)
|
||||
TCCR1 |= 9; // 32us period (256 divider) prescaler
|
||||
TCCR1 |= 10; // 32us period (512 divider) prescaler
|
||||
GTCCR |= _BV(PWM1B); // Enable PWM B and disconnect output pins
|
||||
GTCCR |= _BV(PSR1); // Set the pre-scaler to the selected value
|
||||
|
||||
@ -485,13 +485,13 @@ void on_receive( uint8_t byteN )
|
||||
switch( op_id )
|
||||
{
|
||||
case kSetPwm_Op:
|
||||
for(i=0; i<stack_idx; ++i)
|
||||
ctl_regs[ kPwm_Enable_idx + i ] = stack[i];
|
||||
for(i=0; i<stack_idx && i<2; ++i)
|
||||
ctl_regs[ kPwm_Duty_idx + i ] = stack[i];
|
||||
pwm1_update();
|
||||
break;
|
||||
|
||||
case kNoteOnUsec_Op:
|
||||
for(i=0; i<stack_idx; ++i)
|
||||
for(i=0; i<stack_idx && i<3; ++i)
|
||||
ctl_regs[ kTmr_Coarse_idx + i ] = stack[i];
|
||||
tmr0_reset();
|
||||
break;
|
||||
@ -501,8 +501,7 @@ void on_receive( uint8_t byteN )
|
||||
PORTB &= ~_BV(HOLD_PIN); // clear the HOLD pin
|
||||
break;
|
||||
|
||||
|
||||
case kRead_Op:
|
||||
case kSetReadAddr_Op:
|
||||
if( stack_idx > 0 )
|
||||
{
|
||||
ctl_regs[ kRead_Src_idx ] = stack[0];
|
||||
@ -515,6 +514,15 @@ void on_receive( uint8_t byteN )
|
||||
case kWrite_Op:
|
||||
_write_op( stack, stack_idx );
|
||||
break;
|
||||
|
||||
case kSetMode_Op:
|
||||
if( stack_idx > 0)
|
||||
{
|
||||
ctl_regs[ kMode_idx ] = stack[0];
|
||||
tmr0_reset();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -523,12 +531,10 @@ int main(void)
|
||||
{
|
||||
cli(); // mask all interupts
|
||||
|
||||
|
||||
DDRB |= _BV(ATTK_DIR) + _BV(HOLD_DIR) + _BV(LED_DIR); // setup PB4,PB3,PB1 as output
|
||||
PORTB &= ~(_BV(ATTK_PIN) + _BV(HOLD_PIN) + _BV(LED_PIN)); // clear output pins
|
||||
|
||||
|
||||
timer0_init();
|
||||
tmr0_init();
|
||||
pwm1_init();
|
||||
|
||||
// setup i2c library
|
||||
@ -542,10 +548,12 @@ int main(void)
|
||||
_delay_ms(1000);
|
||||
PINB = _BV(LED_PIN); // writes to PINB toggle the pins
|
||||
|
||||
// if in repeat mode
|
||||
if( ctl_regs[ kMode_idx ] & kMode_Repeat_Fl)
|
||||
tmr0_reset();
|
||||
|
||||
while(1)
|
||||
{
|
||||
//_delay_ms(1000);
|
||||
|
||||
if (!usi_onReceiverPtr)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user