A metronome using the FRDM K64F board

Committer:
ram54288
Date:
Sun May 14 18:40:18 2017 +0000
Revision:
0:a7a43371b306
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:a7a43371b306 1 # -----------------------------------------------------------------------
ram54288 0:a7a43371b306 2 # Copyright (c) 2016 ARM Limited. All rights reserved.
ram54288 0:a7a43371b306 3 # SPDX-License-Identifier: Apache-2.0
ram54288 0:a7a43371b306 4 # Licensed under the Apache License, Version 2.0 (the License); you may
ram54288 0:a7a43371b306 5 # not use this file except in compliance with the License.
ram54288 0:a7a43371b306 6 # You may obtain a copy of the License at
ram54288 0:a7a43371b306 7 #
ram54288 0:a7a43371b306 8 # http://www.apache.org/licenses/LICENSE-2.0
ram54288 0:a7a43371b306 9 #
ram54288 0:a7a43371b306 10 # Unless required by applicable law or agreed to in writing, software
ram54288 0:a7a43371b306 11 # distributed under the License is distributed on an AS IS BASIS, WITHOUT
ram54288 0:a7a43371b306 12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ram54288 0:a7a43371b306 13 # See the License for the specific language governing permissions and
ram54288 0:a7a43371b306 14 # limitations under the License.
ram54288 0:a7a43371b306 15 # -----------------------------------------------------------------------
ram54288 0:a7a43371b306 16
ram54288 0:a7a43371b306 17 import os
ram54288 0:a7a43371b306 18 import shutil
ram54288 0:a7a43371b306 19 from time import sleep, strftime
ram54288 0:a7a43371b306 20 import serial
ram54288 0:a7a43371b306 21 import re
ram54288 0:a7a43371b306 22 import sys
ram54288 0:a7a43371b306 23
ram54288 0:a7a43371b306 24
ram54288 0:a7a43371b306 25 class MbedDeviceManager:
ram54288 0:a7a43371b306 26 def __init__(self):
ram54288 0:a7a43371b306 27 try:
ram54288 0:a7a43371b306 28 import mbed_lstools
ram54288 0:a7a43371b306 29 except ImportError, e:
ram54288 0:a7a43371b306 30 print("Error: Can't import 'mbed_lstools' module: %s"% e)
ram54288 0:a7a43371b306 31 mbed = mbed_lstools.create()
ram54288 0:a7a43371b306 32 self.mbed_list = mbed.list_mbeds()
ram54288 0:a7a43371b306 33 for dev in self.mbed_list:
ram54288 0:a7a43371b306 34 dev['Available'] = True
ram54288 0:a7a43371b306 35 # part. structure:{'mount_point': 'D:','serial_port': u'COM3','platform_name': 'LPC1768','Available'=True}
ram54288 0:a7a43371b306 36
ram54288 0:a7a43371b306 37 def dump_all_devices(self):
ram54288 0:a7a43371b306 38 print("dump Devices:")
ram54288 0:a7a43371b306 39 print(self.mbed_list)
ram54288 0:a7a43371b306 40
ram54288 0:a7a43371b306 41
ram54288 0:a7a43371b306 42 def get_device(self, platform_type):
ram54288 0:a7a43371b306 43 found = False
ram54288 0:a7a43371b306 44 index = int(-1)
ram54288 0:a7a43371b306 45 mount_point = None
ram54288 0:a7a43371b306 46 serial_port = None
ram54288 0:a7a43371b306 47 print(platform_type)
ram54288 0:a7a43371b306 48 for idx,dev in enumerate(self.mbed_list):
ram54288 0:a7a43371b306 49 if dev['platform_name'] == platform_type:
ram54288 0:a7a43371b306 50 found = True
ram54288 0:a7a43371b306 51 if dev['platform_name'] == platform_type and dev['Available']:
ram54288 0:a7a43371b306 52 mount_point = dev['mount_point']
ram54288 0:a7a43371b306 53 serial_port = dev['serial_port']
ram54288 0:a7a43371b306 54 print('Detected %s. Mount point %s Serial port %s index %s.'
ram54288 0:a7a43371b306 55 % (platform_type, mount_point, serial_port, idx))
ram54288 0:a7a43371b306 56 dev['Available'] = False
ram54288 0:a7a43371b306 57 return idx, mount_point, serial_port
ram54288 0:a7a43371b306 58 if found:
ram54288 0:a7a43371b306 59 print('Device %s is not available already in use.' %platform_type)
ram54288 0:a7a43371b306 60 else:
ram54288 0:a7a43371b306 61 print('Device %s is not found.' %platform_type)
ram54288 0:a7a43371b306 62 return index, mount_point, serial_port
ram54288 0:a7a43371b306 63
ram54288 0:a7a43371b306 64 def free_device(self, index):
ram54288 0:a7a43371b306 65 dev = self.mbed_list[index]
ram54288 0:a7a43371b306 66 if not dev['Available']:
ram54288 0:a7a43371b306 67 dev['Available'] = True
ram54288 0:a7a43371b306 68 print('Release Device %s : %s .' % (index, dev['platform_name']))
ram54288 0:a7a43371b306 69 else:
ram54288 0:a7a43371b306 70 print('Error: Device %s : %s is already free.' % (index, dev['platform_name']), )
ram54288 0:a7a43371b306 71
ram54288 0:a7a43371b306 72 mbed_manager = MbedDeviceManager()
ram54288 0:a7a43371b306 73
ram54288 0:a7a43371b306 74 class MBED:
ram54288 0:a7a43371b306 75 def __init__(self,platform_type):
ram54288 0:a7a43371b306 76 self.manager = mbed_manager
ram54288 0:a7a43371b306 77 self.platform_type = platform_type
ram54288 0:a7a43371b306 78 self.mount_point = None
ram54288 0:a7a43371b306 79 self.serial_port = None
ram54288 0:a7a43371b306 80 self.index = -1
ram54288 0:a7a43371b306 81 self.running = False
ram54288 0:a7a43371b306 82
ram54288 0:a7a43371b306 83 def detect(self):
ram54288 0:a7a43371b306 84 self.index, self.mount_point, self.serial_port = self.manager.get_device(self.platform_type)
ram54288 0:a7a43371b306 85 if self.index >= 0:
ram54288 0:a7a43371b306 86 return True
ram54288 0:a7a43371b306 87 else:
ram54288 0:a7a43371b306 88 return False
ram54288 0:a7a43371b306 89
ram54288 0:a7a43371b306 90 def generic_mbed_copy_win(self, source, destination):
ram54288 0:a7a43371b306 91
ram54288 0:a7a43371b306 92
ram54288 0:a7a43371b306 93 from win32com.shell import shell, shellcon
ram54288 0:a7a43371b306 94 import pythoncom
ram54288 0:a7a43371b306 95 from os.path import abspath, join
ram54288 0:a7a43371b306 96 from glob import glob
ram54288 0:a7a43371b306 97
ram54288 0:a7a43371b306 98 for f in glob(join(destination, '*.bin')):
ram54288 0:a7a43371b306 99 os.unlink(f)
ram54288 0:a7a43371b306 100
ram54288 0:a7a43371b306 101 src = shell.SHCreateItemFromParsingName(source, None, shell.IID_IShellItem)
ram54288 0:a7a43371b306 102 dest_dir = shell.SHCreateItemFromParsingName(
ram54288 0:a7a43371b306 103 abspath(destination),
ram54288 0:a7a43371b306 104 None,
ram54288 0:a7a43371b306 105 shell.IID_IShellItem
ram54288 0:a7a43371b306 106 )
ram54288 0:a7a43371b306 107 pfo = pythoncom.CoCreateInstance(
ram54288 0:a7a43371b306 108 shell.CLSID_FileOperation,
ram54288 0:a7a43371b306 109 None,
ram54288 0:a7a43371b306 110 pythoncom.CLSCTX_ALL,
ram54288 0:a7a43371b306 111 shell.IID_IFileOperation
ram54288 0:a7a43371b306 112 )
ram54288 0:a7a43371b306 113 pfo.SetOperationFlags(shellcon.FOF_NO_UI)
ram54288 0:a7a43371b306 114 pfo.CopyItem(src, dest_dir, None, None)
ram54288 0:a7a43371b306 115 pfo.PerformOperations()
ram54288 0:a7a43371b306 116
ram54288 0:a7a43371b306 117 return True
ram54288 0:a7a43371b306 118
ram54288 0:a7a43371b306 119 def install_bin(self,bin_file_name):
ram54288 0:a7a43371b306 120 bin_on_mbed = os.path.join(self.mount_point,os.path.basename(bin_file_name))
ram54288 0:a7a43371b306 121 print('%s Copying %s --> %s' %(strftime('%H:%M:%S'),bin_file_name,bin_on_mbed))
ram54288 0:a7a43371b306 122 if 'win' in sys.platform:
ram54288 0:a7a43371b306 123 self.generic_mbed_copy_win(os.path.abspath(bin_file_name), os.path.abspath(self.mount_point))
ram54288 0:a7a43371b306 124 else:
ram54288 0:a7a43371b306 125 shutil.copyfile(bin_file_name,bin_on_mbed)
ram54288 0:a7a43371b306 126 self.wait_for_file_system()
ram54288 0:a7a43371b306 127 print('%s Bin installation complete' %strftime('%H:%M:%S'))
ram54288 0:a7a43371b306 128
ram54288 0:a7a43371b306 129 def run(self,serial_capture_file_name,baud=9600,read_timeout=10,stop_on_serial_read_timeout=False):
ram54288 0:a7a43371b306 130 if serial_capture_file_name is not None:
ram54288 0:a7a43371b306 131 self.stop_on_serial_read_timeout = stop_on_serial_read_timeout
ram54288 0:a7a43371b306 132 from multiprocessing import Process, Event, Pipe
ram54288 0:a7a43371b306 133 self.event = Event()
ram54288 0:a7a43371b306 134 parent_conn, child_conn = Pipe()
ram54288 0:a7a43371b306 135 print('Start serial capture process')
ram54288 0:a7a43371b306 136 process_args=(self.serial_port,baud,read_timeout,serial_capture_file_name,stop_on_serial_read_timeout,self.event,child_conn)
ram54288 0:a7a43371b306 137 self.capture_process = Process(target=capture_serial,args=process_args)
ram54288 0:a7a43371b306 138 self.capture_process.start()
ram54288 0:a7a43371b306 139 print('Waiting for pipe input from subprocess')
ram54288 0:a7a43371b306 140 self.ip,self.port = parent_conn.recv()
ram54288 0:a7a43371b306 141 if not self.port or not self.ip :
ram54288 0:a7a43371b306 142 return 1
ram54288 0:a7a43371b306 143
ram54288 0:a7a43371b306 144 print('Received IP %s port %s'%(self.ip,self.port))
ram54288 0:a7a43371b306 145 else:
ram54288 0:a7a43371b306 146 print('Running without serial capture')
ram54288 0:a7a43371b306 147 self.ip,self.port = run_no_capture(self.serial_port,baud,read_timeout)
ram54288 0:a7a43371b306 148 print('%s IP %s port %s' % (self.platform_type, self.ip, self.port))
ram54288 0:a7a43371b306 149 self.running = True
ram54288 0:a7a43371b306 150
ram54288 0:a7a43371b306 151 def end_run(self, delete_binaries=True, release_manager=True):
ram54288 0:a7a43371b306 152 print('MBED end_run')
ram54288 0:a7a43371b306 153 if self.running:
ram54288 0:a7a43371b306 154 if not self.stop_on_serial_read_timeout:
ram54288 0:a7a43371b306 155 self.event.set() # the thread does not stop on its own. send stop signal
ram54288 0:a7a43371b306 156 print('MBED end_run waiting for subprocess to terminate')
ram54288 0:a7a43371b306 157 self.capture_process.join() # wait for completion
ram54288 0:a7a43371b306 158 print('MBED end_run subprocess terminated')
ram54288 0:a7a43371b306 159 if delete_binaries:
ram54288 0:a7a43371b306 160 print('MBED end_run deleting binaries')
ram54288 0:a7a43371b306 161 # delete all binaries on MBED
ram54288 0:a7a43371b306 162 filelist = [ f for f in os.listdir(self.mount_point) if f.endswith(".bin") ]
ram54288 0:a7a43371b306 163 for f in filelist:
ram54288 0:a7a43371b306 164 print('MBED end_run delete %s',f)
ram54288 0:a7a43371b306 165 os.remove(os.path.join(self.mount_point,f))
ram54288 0:a7a43371b306 166 self.wait_for_file_system()
ram54288 0:a7a43371b306 167 print('MBED end_run binary delete completed')
ram54288 0:a7a43371b306 168 self.running = False
ram54288 0:a7a43371b306 169 if release_manager:
ram54288 0:a7a43371b306 170 self.manager.free_device(self.index)
ram54288 0:a7a43371b306 171
ram54288 0:a7a43371b306 172 def run_and_capture_till_timeout(self,serial_capture_file_name,baud=9600,read_timeout=10,endOfData=None):
ram54288 0:a7a43371b306 173 try:
ram54288 0:a7a43371b306 174 print('[%s run_and_capture_till_timeout] Start' %strftime('%H:%M:%S'))
ram54288 0:a7a43371b306 175 ser = serial.Serial(self.serial_port,baudrate=baud,timeout=read_timeout)
ram54288 0:a7a43371b306 176 if ser == None:
ram54288 0:a7a43371b306 177 print(' serial.Serial returned None..')
ram54288 0:a7a43371b306 178 capture_file = open(serial_capture_file_name,'w')
ram54288 0:a7a43371b306 179 read_size = 1000
ram54288 0:a7a43371b306 180 cont = True
ram54288 0:a7a43371b306 181 print('[%s run_and_capture_till_timeout] Reseting device..' %strftime('%H:%M:%S'))
ram54288 0:a7a43371b306 182 c = reset_mbed(ser)
ram54288 0:a7a43371b306 183 if c == None:
ram54288 0:a7a43371b306 184 cont = False
ram54288 0:a7a43371b306 185 else:
ram54288 0:a7a43371b306 186 capture_file.write(c)
ram54288 0:a7a43371b306 187 print('[%s run_and_capture_till_timeout] capturing to file...' %strftime('%H:%M:%S'))
ram54288 0:a7a43371b306 188 while cont:
ram54288 0:a7a43371b306 189 c = ser.read(read_size)
ram54288 0:a7a43371b306 190 # Look for the end of test data string and terminate if it is found.
ram54288 0:a7a43371b306 191 if endOfData != None:
ram54288 0:a7a43371b306 192 endPos = c.find(endOfData)
ram54288 0:a7a43371b306 193 # Clip off the termination string and anything afterwards
ram54288 0:a7a43371b306 194 if endPos != -1:
ram54288 0:a7a43371b306 195 c = c[:(endPos + len(endOfData))]
ram54288 0:a7a43371b306 196 capture_file.write(c)
ram54288 0:a7a43371b306 197 if endPos != -1:
ram54288 0:a7a43371b306 198 break
ram54288 0:a7a43371b306 199 if len(c) < read_size:
ram54288 0:a7a43371b306 200 print('[%s run_and_capture_till_timeout] serial read timeout. Stopping subprocess' %strftime('%H:%M:%S'))
ram54288 0:a7a43371b306 201 print ("exit last Buffsize " + str(len(c)) + "<32" )
ram54288 0:a7a43371b306 202 cont = False
ram54288 0:a7a43371b306 203 print('[%s run_and_capture_till_timeout] closing capture file' %strftime('%H:%M:%S'))
ram54288 0:a7a43371b306 204 capture_file.close()
ram54288 0:a7a43371b306 205 print('[%s run_and_capture_till_timeout] closing serial port' %strftime('%H:%M:%S'))
ram54288 0:a7a43371b306 206 ser.flushInput()
ram54288 0:a7a43371b306 207 ser.flushOutput()
ram54288 0:a7a43371b306 208 ser.close()
ram54288 0:a7a43371b306 209 print('[%s run_and_capture_till_timeout] done' %strftime('%H:%M:%S'))
ram54288 0:a7a43371b306 210 return True
ram54288 0:a7a43371b306 211 except serial.SerialException as e:
ram54288 0:a7a43371b306 212 print('[run_and_capture_till_timeout] serial exception',e)
ram54288 0:a7a43371b306 213 return False
ram54288 0:a7a43371b306 214
ram54288 0:a7a43371b306 215 def wait_for_file_system(self):
ram54288 0:a7a43371b306 216 #sleep(25) #MBED file system takes some 'settling' time after it is wrirtten to
ram54288 0:a7a43371b306 217 sleep(3) #MBED file system takes some 'settling' time after it is wrirtten to
ram54288 0:a7a43371b306 218
ram54288 0:a7a43371b306 219 def reset_mbed(ser):
ram54288 0:a7a43371b306 220 for loop in range(5):
ram54288 0:a7a43371b306 221 # reset called after open port
ram54288 0:a7a43371b306 222 # add sleep for port ready (we saw that sometimes read failed...)
ram54288 0:a7a43371b306 223 delay = 5
ram54288 0:a7a43371b306 224 print('[%s reset_mbed] loop=%d , delay=%d' %(strftime('%H:%M:%S'), loop, delay))
ram54288 0:a7a43371b306 225 sleep(delay)
ram54288 0:a7a43371b306 226 try:
ram54288 0:a7a43371b306 227 ser.sendBreak()
ram54288 0:a7a43371b306 228 except Exception:
ram54288 0:a7a43371b306 229 # In linux a termios.error is raised in sendBreak and in
ram54288 0:a7a43371b306 230 # setBreak. The following setBreak() is needed to release
ram54288 0:a7a43371b306 231 # the reset signal on the target mcu.
ram54288 0:a7a43371b306 232 try:
ram54288 0:a7a43371b306 233 ser.setBreak(False)
ram54288 0:a7a43371b306 234 except:
ram54288 0:a7a43371b306 235 pass
ram54288 0:a7a43371b306 236 c = ser.read(1)
ram54288 0:a7a43371b306 237 if len(c) == 1:
ram54288 0:a7a43371b306 238 return c
ram54288 0:a7a43371b306 239 print ("Error reading from serial port" )
ram54288 0:a7a43371b306 240 return None
ram54288 0:a7a43371b306 241
ram54288 0:a7a43371b306 242 def is_valid_ip(ip):
ram54288 0:a7a43371b306 243 return re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",ip)
ram54288 0:a7a43371b306 244
ram54288 0:a7a43371b306 245 def capture_serial(port,baud,read_timeout,capture_file_name,stop_on_serial_read_timeout,event,pipe_conn):
ram54288 0:a7a43371b306 246 try:
ram54288 0:a7a43371b306 247 print('[capture_serial subprocess] starting..')
ram54288 0:a7a43371b306 248 ser = serial.Serial(port,baudrate=baud,timeout=read_timeout)
ram54288 0:a7a43371b306 249 capture_file = open(capture_file_name,'w')
ram54288 0:a7a43371b306 250 read_size = 32
ram54288 0:a7a43371b306 251 cont = True
ram54288 0:a7a43371b306 252 print('[capture_serial subprocess] Reseting device..')
ram54288 0:a7a43371b306 253 c = reset_mbed(ser)
ram54288 0:a7a43371b306 254 if c == None:
ram54288 0:a7a43371b306 255 print('[capture_serial subprocess] Reseting device failed')
ram54288 0:a7a43371b306 256
ram54288 0:a7a43371b306 257 if c == None:
ram54288 0:a7a43371b306 258 cont = False
ram54288 0:a7a43371b306 259 print('[capture_serial subprocess] Failed to get IP from device... exiting ')
ram54288 0:a7a43371b306 260 pipe_conn.send([None,None]) # send IP and port
ram54288 0:a7a43371b306 261 pipe_conn.close()
ram54288 0:a7a43371b306 262 capture_file.close()
ram54288 0:a7a43371b306 263 ser.flushInput()
ram54288 0:a7a43371b306 264 ser.flushOutput()
ram54288 0:a7a43371b306 265 ser.close()
ram54288 0:a7a43371b306 266 return
ram54288 0:a7a43371b306 267 else:
ram54288 0:a7a43371b306 268 # parse the first received string for IP and port
ram54288 0:a7a43371b306 269 ip_str = c.split(':')
ram54288 0:a7a43371b306 270 if is_valid_ip(ip_str[1]) :
ram54288 0:a7a43371b306 271 pipe_conn.send([ip_str[1],ip_str[2]]) # send IP and port
ram54288 0:a7a43371b306 272 print('[capture_serial subprocess] Sending IP to main process %s:%s'%(ip_str[1],ip_str[2]))
ram54288 0:a7a43371b306 273 print('[capture_serial subprocess] capturing to file...')
ram54288 0:a7a43371b306 274 else:
ram54288 0:a7a43371b306 275 print('[capture_serial subprocess] No valid IP address')
ram54288 0:a7a43371b306 276 pipe_conn.send([None,None]) # send IP and port
ram54288 0:a7a43371b306 277 cont = False
ram54288 0:a7a43371b306 278 capture_file.write(c)
ram54288 0:a7a43371b306 279 pipe_conn.close()
ram54288 0:a7a43371b306 280
ram54288 0:a7a43371b306 281 while cont:
ram54288 0:a7a43371b306 282 c = ser.read(read_size)
ram54288 0:a7a43371b306 283 capture_file.write(c)
ram54288 0:a7a43371b306 284 if stop_on_serial_read_timeout:
ram54288 0:a7a43371b306 285 if len(c) < read_size:
ram54288 0:a7a43371b306 286 print('[capture_serial subprocess] serial read timeout. Stopping subprocess')
ram54288 0:a7a43371b306 287 cont = False
ram54288 0:a7a43371b306 288 else:
ram54288 0:a7a43371b306 289 if event.is_set():
ram54288 0:a7a43371b306 290 print('[capture_serial subprocess] event is set. Stopping subprocess')
ram54288 0:a7a43371b306 291 cont = False
ram54288 0:a7a43371b306 292
ram54288 0:a7a43371b306 293 print('[capture_serial subprocess] closing capture file')
ram54288 0:a7a43371b306 294 capture_file.close()
ram54288 0:a7a43371b306 295 print('[capture_serial subprocess] closing serial port')
ram54288 0:a7a43371b306 296 ser.flushInput()
ram54288 0:a7a43371b306 297 ser.flushOutput()
ram54288 0:a7a43371b306 298 ser.close()
ram54288 0:a7a43371b306 299 print('[capture_serial subprocess] Subprocess exiting')
ram54288 0:a7a43371b306 300 except serial.SerialException as e:
ram54288 0:a7a43371b306 301 print('[capture_serial subprocess] serial exception',e)
ram54288 0:a7a43371b306 302
ram54288 0:a7a43371b306 303 def run_no_capture(port,baud,read_timeout):
ram54288 0:a7a43371b306 304 try:
ram54288 0:a7a43371b306 305 ser = serial.Serial(port,baudrate=baud,timeout=read_timeout)
ram54288 0:a7a43371b306 306 ip = None
ram54288 0:a7a43371b306 307 port = None
ram54288 0:a7a43371b306 308 c = reset_mbed(ser)
ram54288 0:a7a43371b306 309 if c:
ram54288 0:a7a43371b306 310 # parse the first received string for IP and port
ram54288 0:a7a43371b306 311 ip_str = c.split(':')
ram54288 0:a7a43371b306 312 if is_valid_ip(ip_str[1]) != None:
ram54288 0:a7a43371b306 313 ip = ip_str[1]
ram54288 0:a7a43371b306 314 port = ip_str[2]
ram54288 0:a7a43371b306 315 ser.flushInput()
ram54288 0:a7a43371b306 316 ser.flushOutput()
ram54288 0:a7a43371b306 317 ser.close()
ram54288 0:a7a43371b306 318 return ip,port
ram54288 0:a7a43371b306 319 except serial.SerialException as e:
ram54288 0:a7a43371b306 320 print e
ram54288 0:a7a43371b306 321
ram54288 0:a7a43371b306 322
ram54288 0:a7a43371b306 323 class MBED_DEVICE(MBED):
ram54288 0:a7a43371b306 324 def __init__(self,platform_type):
ram54288 0:a7a43371b306 325 print('MBED Device:' + platform_type)
ram54288 0:a7a43371b306 326 MBED.__init__(self, platform_type)
ram54288 0:a7a43371b306 327
ram54288 0:a7a43371b306 328