Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers STM32_gen_PeripheralPins.py Source File

STM32_gen_PeripheralPins.py

00001 """
00002 * mbed Microcontroller Library
00003 * Copyright (c) 2006-2018 ARM Limited
00004 *
00005 * Licensed under the Apache License, Version 2.0 (the "License");
00006 * you may not use this file except in compliance with the License.
00007 * You may obtain a copy of the License at
00008 *
00009 *     http://www.apache.org/licenses/LICENSE-2.0
00010 *
00011 * Unless required by applicable law or agreed to in writing, software
00012 * distributed under the License is distributed on an "AS IS" BASIS,
00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014 * See the License for the specific language governing permissions and
00015 * limitations under the License.
00016 """
00017 
00018 import argparse
00019 import datetime
00020 import fnmatch
00021 import json
00022 import os
00023 import re
00024 import sys
00025 import textwrap
00026 from xml.dom.minidom import parse, Node
00027 from argparse import RawTextHelpFormatter
00028 
00029 GENPINMAP_VERSION = "1.2"
00030 
00031 ADD_DEVICE_IFDEF = 0
00032 ADD_QSPI_FEATURE = 0
00033 
00034 mcu_file=""
00035 mcu_list = []       #'name'
00036 io_list = []        #'PIN','name'
00037 adclist = []        #'PIN','name','ADCSignal'
00038 daclist = []        #'PIN','name','DACSignal'
00039 i2cscl_list = []    #'PIN','name','I2CSCLSignal'
00040 i2csda_list = []    #'PIN','name','I2CSDASignal'
00041 pwm_list = []       #'PIN','name','PWM'
00042 uarttx_list = []    #'PIN','name','UARTtx'
00043 uartrx_list = []    #'PIN','name','UARTrx'
00044 uartcts_list = []   #'PIN','name','UARTcts'
00045 uartrts_list = []   #'PIN','name','UARTrts'
00046 spimosi_list = []   #'PIN','name','SPIMOSI'
00047 spimiso_list = []   #'PIN','name','SPIMISO'
00048 spissel_list = []   #'PIN','name','SPISSEL'
00049 spisclk_list = []   #'PIN','name','SPISCLK'
00050 cantd_list = []     #'PIN','name','CANTD'
00051 canrd_list = []     #'PIN','name','CANRD'
00052 eth_list = []       #'PIN','name','ETH'
00053 quadspidata_list = []      #'PIN','name','QUADSPIDATA'
00054 quadspisclk_list = []      #'PIN','name','QUADSPISCLK'
00055 quadspissel_list = []      #'PIN','name','QUADSPISSEL'
00056 usb_list = []      #'PIN','name','USB'
00057 osc_list = []      #'PIN','name','OSC'
00058 sys_list = []      #'PIN','name','SYS'
00059 
00060 TIM_MST_LIST = { # Timer used for us ticker is hardcoded in this script
00061 "NUCLEO_F030R8":"TIM1",
00062 "NUCLEO_F072RB":"TIM2",
00063 "NUCLEO_F091RC":"TIM2",
00064 "NUCLEO_F070RB":"TIM1",
00065 "NUCLEO_F042K6":"TIM2",
00066 "NUCLEO_F031K6":"TIM2",
00067 "NUCLEO_F103RB":"TIM4",
00068 "NUCLEO_F207ZG":"TIM5",
00069 "NUCLEO_F302R8":"TIM2",
00070 "NUCLEO_F334R8":"TIM2",
00071 "NUCLEO_F303RE":"TIM2",
00072 "NUCLEO_F303K8":"TIM2",
00073 "NUCLEO_F303ZE":"TIM2",
00074 "NUCLEO_F401RE":"TIM5",
00075 "NUCLEO_F411RE":"TIM5",
00076 "NUCLEO_F446RE":"TIM5",
00077 "NUCLEO_F410RB":"TIM5",
00078 "NUCLEO_F429ZI":"TIM5",
00079 "NUCLEO_F446ZE":"TIM5",
00080 "NUCLEO_F412ZG":"TIM5",
00081 "NUCLEO_F413ZH":"TIM5",
00082 "NUCLEO_F746ZG":"TIM5",
00083 "NUCLEO_F767ZI":"TIM5",
00084 "NUCLEO_F722ZE":"TIM5",
00085 "NUCLEO_H743ZI":"TIM5",
00086 "NUCLEO_L053R8":"TIM21",
00087 "NUCLEO_L073RZ":"TIM21",
00088 "NUCLEO_L031K6":"TIM21",
00089 "NUCLEO_L011K4":"TIM21",
00090 "NUCLEO_L152RE":"TIM5",
00091 "NUCLEO_L476RG":"TIM5",
00092 "NUCLEO_L432KC":"TIM2",
00093 "NUCLEO_L496ZG":"TIM5",
00094 "NUCLEO_L496ZG_P":"TIM5",
00095 "NUCLEO_L433RC_P":"TIM2",
00096 
00097 "DISCO_F051R8":"TIM1",
00098 "DISCO_F100RB":"TIM4",
00099 "DISCO_F303VC":"TIM2",
00100 "DISCO_F334C8":"TIM2",
00101 "DISCO_F401VC":"TIM5",
00102 "DISCO_F407VG":"TIM5",
00103 "DISCO_F413ZH":"TIM5",
00104 "DISCO_F429ZI":"TIM5",
00105 "DISCO_F469NI":"TIM5",
00106 "DISCO_F769NI":"TIM5",
00107 "DISCO_F746NG":"TIM5",
00108 "DISCO_L053C8":"TIM21",
00109 "DISCO_L072CZ_LRWAN1":"TIM21",
00110 "DISCO_L475VG_IOT01A":"TIM5",
00111 "DISCO_L476VG":"TIM5",
00112 "DISCO_L496AG":"TIM5"
00113 }
00114 
00115 
00116 def find_gpio_file():
00117     res = 'ERROR'
00118     itemlist = xml_mcu.getElementsByTagName('IP')
00119     for s in itemlist:
00120         a = s.attributes['Name'].value
00121         if "GPIO" in a:
00122             res = s.attributes['Version'].value
00123     return res
00124 
00125 def get_gpio_af_num(pintofind, iptofind):
00126     if 'STM32F10' in mcu_file:
00127         return get_gpio_af_numF1(pintofind, iptofind)
00128     #DBG print ('pin to find ' + pintofind)
00129     i=0
00130     mygpioaf = 'NOTFOUND'
00131     for n in  xml_gpio.documentElement.childNodes:
00132         i += 1
00133         j = 0
00134         if n.nodeType == Node.ELEMENT_NODE:
00135             for firstlevel in n.attributes.items():
00136 #                if 'PB7' in firstlevel:
00137                 if pintofind ==  firstlevel[1]:
00138                     #DBG print (i , firstlevel)
00139                     #n = pin node found
00140                     for m in n.childNodes:
00141                         j += 1
00142                         k = 0
00143                         if m.nodeType == Node.ELEMENT_NODE:
00144                             for secondlevel in  m.attributes.items():
00145                                 k += 1
00146 #                                if 'I2C1_SDA' in secondlevel:
00147                                 if iptofind in secondlevel:
00148                                     #DBG print (i, j,  m.attributes.items())
00149                                     # m = IP node found
00150                                     for p in m.childNodes:
00151                                         if p.nodeType == Node.ELEMENT_NODE:
00152                                             #p node of 'Specific parameter'
00153                                             #DBG print (i,j,k,p.attributes.items())
00154                                             for myc in p.childNodes:
00155                                                 #DBG print (myc)
00156                                                 if myc.nodeType == Node.ELEMENT_NODE:
00157                                                     #myc = node of ALTERNATE
00158                                                     for mygpioaflist in myc.childNodes:
00159                                                         mygpioaf += ' ' + mygpioaflist.data
00160                                                         #print (mygpioaf)
00161     if mygpioaf == 'NOTFOUND':
00162         print ('GPIO AF not found in ' + gpiofile + ' for ' + pintofind + ' and the IP ' + iptofind)
00163         #quit()
00164     return mygpioaf.replace('NOTFOUND ', '')
00165 
00166 def get_gpio_af_numF1(pintofind, iptofind):
00167     #print ('pin to find ' + pintofind + ' ip to find ' + iptofind)
00168     i=0
00169     mygpioaf = 'NOTFOUND'
00170     for n in  xml_gpio.documentElement.childNodes:
00171         i += 1
00172         j = 0
00173         if n.nodeType == Node.ELEMENT_NODE:
00174             for firstlevel in n.attributes.items():
00175                 #print ('firstlevel ' , firstlevel)
00176 #                if 'PB7' in firstlevel:
00177                 if pintofind ==  firstlevel[1]:
00178                     #print ('firstlevel ' , i , firstlevel)
00179                     #n = pin node found
00180                     for m in n.childNodes:
00181                         j += 1
00182                         k = 0
00183                         if m.nodeType == Node.ELEMENT_NODE:
00184                             for secondlevel in  m.attributes.items():
00185                                 #print ('secondlevel ' , i, j, k , secondlevel)
00186                                 k += 1
00187 #                                if 'I2C1_SDA' in secondlevel:
00188                                 if iptofind in secondlevel:
00189                                     # m = IP node found
00190                                     #print (i, j,  m.attributes.items())
00191                                     for p in m.childNodes:
00192                                         #p node 'RemapBlock'
00193                                         if p.nodeType == Node.ELEMENT_NODE and p.hasChildNodes() == False:
00194                                             mygpioaf += ' AFIO_NONE'
00195                                         else:
00196                                             for s in p.childNodes:
00197                                                 if s.nodeType == Node.ELEMENT_NODE:
00198                                                     #s node 'Specific parameter'
00199                                                     #DBG print (i,j,k,p.attributes.items())
00200                                                     for myc in s.childNodes:
00201                                                         #DBG print (myc)
00202                                                         if myc.nodeType == Node.ELEMENT_NODE:
00203                                                             #myc = AF value
00204                                                             for mygpioaflist in myc.childNodes:
00205                                                                 mygpioaf += ' ' + mygpioaflist.data.replace("__HAL_", "").replace("_REMAP", "")
00206                                                                 #print mygpioaf
00207     if mygpioaf == 'NOTFOUND':
00208         print ('GPIO AF not found in ' + gpiofile + ' for ' + pintofind + ' and the IP ' + iptofind + ' set as AFIO_NONE')
00209         mygpioaf = 'AFIO_NONE'
00210     return mygpioaf.replace('NOTFOUND ', '')\
00211         .replace("AFIO_NONE", "0")\
00212         .replace("AFIO_SPI1_ENABLE", "1")\
00213         .replace("AFIO_I2C1_ENABLE", "2")\
00214         .replace("AFIO_USART1_ENABLE", "3")\
00215         .replace("AFIO_USART3_PARTIAL", "5")\
00216         .replace("AFIO_TIM1_PARTIAL", "6")\
00217         .replace("AFIO_TIM3_PARTIAL", "7")\
00218         .replace("AFIO_TIM2_ENABLE", "8")\
00219         .replace("AFIO_TIM3_ENABLE", "9")\
00220         .replace("AFIO_CAN1_2", "10")
00221 
00222 #function to store I/O pin
00223 def store_pin (pin, name):
00224     p = [pin, name]
00225     io_list.append(p)
00226 
00227 #function to store ADC list
00228 def store_adc (pin, name, signal):
00229     adclist.append([pin,name,signal])
00230 
00231 #function to store DAC list
00232 def store_dac (pin, name, signal):
00233     daclist.append([pin,name,signal])
00234 
00235 #function to store I2C list
00236 def store_i2c (pin, name, signal):
00237     #is it SDA or SCL ?
00238     if "_SCL" in signal:
00239         i2cscl_list.append([pin,name,signal])
00240     if "_SDA" in signal:
00241         i2csda_list.append([pin,name,signal])
00242 
00243 #function to store timers
00244 def store_pwm(pin, name, signal):
00245     if "_CH" in signal:
00246         pwm_list.append([pin,name,signal])
00247 
00248 #function to store Uart pins
00249 def store_uart(pin, name, signal):
00250     if "_TX" in signal:
00251         uarttx_list.append([pin,name,signal])
00252     if "_RX" in signal:
00253         uartrx_list.append([pin,name,signal])
00254     if "_CTS" in signal:
00255         uartcts_list.append([pin,name,signal])
00256     if "_RTS" in signal:
00257         uartrts_list.append([pin,name,signal])
00258 
00259 #function to store SPI pins
00260 def store_spi(pin, name, signal):
00261     if "_MISO" in signal:
00262         spimiso_list.append([pin,name,signal])
00263     if "_MOSI" in signal:
00264         spimosi_list.append([pin,name,signal])
00265     if "_SCK" in signal:
00266         spisclk_list.append([pin,name,signal])
00267     if "_NSS" in signal:
00268         spissel_list.append([pin,name,signal])
00269 
00270 #function to store CAN pins
00271 def store_can(pin, name, signal):
00272     if "_RX" in signal:
00273         canrd_list.append([pin,name,signal])
00274     if "_TX" in signal:
00275         cantd_list.append([pin,name,signal])
00276 
00277 #function to store ETH list
00278 def store_eth (pin, name, signal):
00279     eth_list.append([pin,name,signal])
00280 
00281 #function to store QSPI pins
00282 def store_qspi (pin, name, signal):
00283     if "_BK" in signal:
00284         quadspidata_list.append([pin,name,signal])
00285     if "_CLK" in signal:
00286         quadspisclk_list.append([pin,name,signal])
00287     if "_NCS" in signal:
00288         quadspissel_list.append([pin,name,signal])
00289 
00290 #function to store USB pins
00291 def store_usb (pin, name, signal):
00292     usb_list.append([pin,name,signal])
00293 
00294 #function to store OSC pins
00295 def store_osc (pin, name, signal):
00296     osc_list.append([pin,name,signal])
00297 
00298 #function to store SYS pins
00299 def store_sys (pin, name, signal):
00300     sys_list.append([pin,name,signal])
00301 
00302 def print_header():
00303     s =  ("""/* mbed Microcontroller Library
00304  *******************************************************************************
00305  * Copyright (c) %i, STMicroelectronics
00306  * All rights reserved.
00307  *
00308  * Redistribution and use in source and binary forms, with or without
00309  * modification, are permitted provided that the following conditions are met:
00310  *
00311  * 1. Redistributions of source code must retain the above copyright notice,
00312  *    this list of conditions and the following disclaimer.
00313  * 2. Redistributions in binary form must reproduce the above copyright notice,
00314  *    this list of conditions and the following disclaimer in the documentation
00315  *    and/or other materials provided with the distribution.
00316  * 3. Neither the name of STMicroelectronics nor the names of its contributors
00317  *    may be used to endorse or promote products derived from this software
00318  *    without specific prior written permission.
00319  *
00320  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00321  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00322  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00323  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00324  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00325  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00326  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00327  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00328  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00329  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00330  *******************************************************************************
00331  *
00332  * Automatically generated from %s
00333  */
00334 
00335 #include "PeripheralPins.h"
00336 #include "mbed_toolchain.h"
00337 
00338 //==============================================================================
00339 // Notes
00340 //
00341 // - The pins mentioned Px_y_ALTz are alternative possibilities which use other
00342 //   HW peripheral instances. You can use them the same way as any other "normal"
00343 //   pin (i.e. PwmOut pwm(PA_7_ALT0);). These pins are not displayed on the board
00344 //   pinout image on mbed.org.
00345 //
00346 // - The pins which are connected to other components present on the board have
00347 //   the comment "Connected to xxx". The pin function may not work properly in this
00348 //   case. These pins may not be displayed on the board pinout image on mbed.org.
00349 //   Please read the board reference manual and schematic for more information.
00350 //
00351 // - Warning: pins connected to the default STDIO_UART_TX and STDIO_UART_RX pins are commented
00352 //   See https://os.mbed.com/teams/ST/wiki/STDIO for more information.
00353 //
00354 //==============================================================================
00355 
00356 """ % (datetime.datetime.now().year, os.path.basename(input_file_name)))
00357     out_c_file.write( s )
00358 
00359     s =  ("""/* mbed Microcontroller Library
00360  *******************************************************************************
00361  * Copyright (c) %i, STMicroelectronics
00362  * All rights reserved.
00363  *
00364  * Redistribution and use in source and binary forms, with or without
00365  * modification, are permitted provided that the following conditions are met:
00366  *
00367  * 1. Redistributions of source code must retain the above copyright notice,
00368  *    this list of conditions and the following disclaimer.
00369  * 2. Redistributions in binary form must reproduce the above copyright notice,
00370  *    this list of conditions and the following disclaimer in the documentation
00371  *    and/or other materials provided with the distribution.
00372  * 3. Neither the name of STMicroelectronics nor the names of its contributors
00373  *    may be used to endorse or promote products derived from this software
00374  *    without specific prior written permission.
00375  *
00376  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00377  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00378  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00379  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00380  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00381  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00382  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00383  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00384  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00385  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00386  *******************************************************************************
00387  *
00388  * Automatically generated from %s
00389  */
00390 
00391 #ifndef MBED_PINNAMES_H
00392 #define MBED_PINNAMES_H
00393 
00394 #include "cmsis.h"
00395 #include "PinNamesTypes.h"
00396 
00397 #ifdef __cplusplus
00398 extern "C" {
00399 #endif
00400 
00401 typedef enum {
00402     ALT0  = 0x100,
00403     ALT1  = 0x200,
00404     ALT2  = 0x300,
00405     ALT3  = 0x400
00406 } ALTx;
00407 
00408 typedef enum {
00409 
00410 """ % (datetime.datetime.now().year, os.path.basename(input_file_name)))
00411     out_h_file.write( s )
00412 
00413 
00414 def print_footer():
00415     s = ("""
00416     // Not connected
00417     NC = (int)0xFFFFFFFF
00418 } PinName;
00419 
00420 #ifdef __cplusplus
00421 }
00422 #endif
00423 
00424 #endif
00425 """)
00426     out_h_file.write(s)
00427 
00428 
00429 def print_all_lists():
00430     if print_list_header("ADC", "ADC", adclist, "ANALOGIN"):
00431         print_adc()
00432     if print_list_header("DAC", "DAC", daclist, "ANALOGOUT"):
00433         print_dac()
00434     if print_list_header("I2C", "I2C_SDA", i2csda_list, "I2C"):
00435         print_i2c(i2csda_list)
00436     if print_list_header("", "I2C_SCL", i2cscl_list, "I2C"):
00437         print_i2c(i2cscl_list)
00438     if print_list_header("PWM", "PWM", pwm_list, "PWMOUT"):
00439         print_pwm()
00440     if print_list_header("SERIAL", "UART_TX", uarttx_list, "SERIAL"):
00441         print_uart(uarttx_list)
00442     if print_list_header("", "UART_RX", uartrx_list, "SERIAL"):
00443         print_uart(uartrx_list)
00444     if print_list_header("", "UART_RTS", uartrts_list, "SERIAL"):
00445         print_uart(uartrts_list)
00446     if print_list_header("", "UART_CTS", uartcts_list, "SERIAL"):
00447         print_uart(uartcts_list)
00448     if print_list_header("SPI", "SPI_MOSI", spimosi_list, "SPI"):
00449         print_spi(spimosi_list)
00450     if print_list_header("", "SPI_MISO", spimiso_list, "SPI"):
00451         print_spi(spimiso_list)
00452     if print_list_header("", "SPI_SCLK", spisclk_list, "SPI"):
00453         print_spi(spisclk_list)
00454     if print_list_header("", "SPI_SSEL", spissel_list, "SPI"):
00455         print_spi(spissel_list)
00456     if print_list_header("CAN", "CAN_RD", canrd_list, "CAN"):
00457         print_can(canrd_list)
00458     if print_list_header("", "CAN_TD", cantd_list, "CAN"):
00459         print_can(cantd_list)
00460     if ADD_QSPI_FEATURE:
00461         if print_list_header("QUADSPI", "QSPI_DATA", quadspidata_list, "QSPI"):
00462             print_qspi(quadspidata_list)
00463         if print_list_header("", "QSPI_SCLK", quadspisclk_list, "QSPI"):
00464             print_qspi(quadspisclk_list)
00465         if print_list_header("", "QSPI_SSEL", quadspissel_list, "QSPI"):
00466             print_qspi(quadspissel_list)
00467     print_h_file(usb_list, "USB")
00468     print_h_file(eth_list, "ETHERNET")
00469     print_h_file(osc_list, "OSCILLATOR")
00470     print_h_file(sys_list, "DEBUG")
00471 
00472 def print_list_header(comment, name, l, switch):
00473     s = ""
00474     if len(l)>0:
00475         if comment:
00476             s += "\n//*** %s ***\n" % comment
00477 
00478         s += "\n"
00479 
00480         if name == "PWM":
00481             if TargetName in TIM_MST_LIST.keys():
00482                 s += "// %s cannot be used because already used by the us_ticker\n" % TIM_MST_LIST[TargetName]
00483             else:
00484                 s += "// TIM<x> cannot be used because already used by the us_ticker\n"
00485                 s += "// You have to comment all PWM using TIM_MST defined in hal_tick.h file\n"
00486                 s += "//  or update python script (check TIM_MST_LIST) and re-run it\n"
00487 
00488         if ADD_DEVICE_IFDEF:
00489             s += "#ifdef DEVICE_%s\n" % switch
00490 
00491         s += "MBED_WEAK const PinMap PinMap_%s[] = {\n" % name
00492 
00493     # else:
00494     #     if comment:
00495     #         s += "\n//*** No %s ***\n" % comment
00496 
00497     out_c_file.write(s)
00498     return len(l)
00499 
00500 def print_adc():
00501     s_pin_data = 'STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, '
00502     prev_p = ''
00503     alt_index = 0
00504     for p in adclist:
00505         if "IN" in p[2]:
00506             CommentedLine = "  "
00507             if p[1] in PinLabel.keys():
00508                 if "STDIO_UART" in PinLabel[p[1]]:
00509                     CommentedLine = "//"
00510                 if "RCC_OSC" in PinLabel[p[1]]:
00511                     CommentedLine = "//"
00512             if CommentedLine != "//":
00513                 if p[0] == prev_p:
00514                     prev_p = p[0]
00515                     p[0] += '_ALT%d' % alt_index
00516                     alt_index += 1
00517                 else:
00518                     prev_p = p[0]
00519                     alt_index = 0
00520             s1 = "%-17s" % (CommentedLine + "  {" + p[0] + ',')
00521             a = p[2].split('_')
00522             inst = a[0].replace("ADC", "")
00523             if len(inst) == 0:
00524                 inst = '1' #single ADC for this product
00525             s1 += "%-7s" % ('ADC_' + inst + ',')
00526             chan = re.sub('IN[N|P]?', '', a[1])
00527             s1 += s_pin_data + chan
00528             s1 += ', 0)}, // ' + p[2]
00529             if p[1] in PinLabel.keys():
00530                 s1 += ' // Connected to ' + PinLabel[p[1]]
00531             s1 += '\n'
00532             out_c_file.write(s1)
00533     out_c_file.write( """    {NC, NC, 0}
00534 };
00535 
00536 // !!! SECTION TO BE CHECKED WITH DEVICE REFERENCE MANUAL
00537 MBED_WEAK const PinMap PinMap_ADC_Internal[] = {
00538     {ADC_TEMP,   ADC_1,    STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 16, 0)},
00539     {ADC_VREF,   ADC_1,    STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 17, 0)},
00540     {ADC_VBAT,   ADC_1,    STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 18, 0)},
00541     {NC, NC, 0}
00542 };
00543 """)
00544     if ADD_DEVICE_IFDEF:
00545         out_c_file.write( "#endif\n" )
00546 
00547 def print_dac():
00548     for p in daclist:
00549         CommentedLine = "  "
00550         if p[1] in PinLabel.keys():
00551             if "STDIO_UART" in PinLabel[p[1]]:
00552                 CommentedLine = "//"
00553             if "RCC_OSC" in PinLabel[p[1]]:
00554                 CommentedLine = "//"
00555         s1 = "%-17s" % (CommentedLine + "  {" + p[0] + ',')
00556         #p[2] : DAC_OUT1 / DAC1_OUT1
00557         a = p[2].split('_')
00558         inst = a[0].replace("DAC", "")
00559         b = a[1].replace("OUT", "")
00560         if len(inst) == 0:
00561             inst = '1'  # single DAC for this product
00562         s1 += "%-7s" % ('DAC_' + inst + ',')
00563         s1 += 'STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, ' + b + ', 0)}, // ' + p[2]
00564         if p[1] in PinLabel.keys():
00565             s1 += ' // Connected to ' + PinLabel[p[1]]
00566         s1 += '\n'
00567         out_c_file.write(s1)
00568     out_c_file.write( """    {NC, NC, 0}
00569 };
00570 """)
00571     if ADD_DEVICE_IFDEF:
00572         out_c_file.write( "#endif\n" )
00573 
00574 def print_i2c(l):
00575     prev_p = ''
00576     alt_index = 0
00577     for p in l:
00578         result = get_gpio_af_num(p[1], p[2])
00579         if result != 'NOTFOUND':
00580             CommentedLine = "  "
00581             if p[1] in PinLabel.keys():
00582                 if "STDIO_UART" in PinLabel[p[1]]:
00583                     CommentedLine = "//"
00584                 if "RCC_OSC" in PinLabel[p[1]]:
00585                     CommentedLine = "//"
00586             if CommentedLine != "//":
00587                 if p[0] == prev_p:
00588                     prev_p = p[0]
00589                     p[0] += '_ALT%d' % alt_index
00590                     alt_index += 1
00591                 else:
00592                     prev_p = p[0]
00593                     alt_index = 0
00594             s1 = "%-17s" % (CommentedLine + "  {" + p[0] + ',')
00595             # p[2] : I2C1_SDA / FMPI2C1_SDA
00596             if "FMP" in p[2]:
00597                 inst = p[2].split('_')[0].replace("FMPI2C", "")
00598                 s1 += "%-10s" % ('FMPI2C_' + inst + ',')
00599             else:
00600                 inst = p[2].split('_')[0].replace("I2C", "")
00601                 s1 += "%-7s" % ('I2C_' + inst + ',')
00602             s1 += 'STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, '
00603             r = result.split(' ')
00604             for af in r:
00605                 s2 = s1 + af  + ')},'
00606                 if p[1] in PinLabel.keys():
00607                     s2 += ' // Connected to ' + PinLabel[p[1]]
00608                 s2 += '\n'
00609                 out_c_file.write(s2)
00610     out_c_file.write( """    {NC, NC, 0}
00611 };
00612 """)
00613     if ADD_DEVICE_IFDEF:
00614         out_c_file.write( "#endif\n" )
00615 
00616 def print_pwm():
00617     prev_p = ''
00618     alt_index = 0
00619     TIM_MST = "NOT_KNOWN"
00620     if TargetName in TIM_MST_LIST.keys():
00621         TIM_MST = TIM_MST_LIST[TargetName]
00622     for p in pwm_list:
00623         result = get_gpio_af_num(p[1], p[2])
00624         if result != 'NOTFOUND':
00625             CommentedLine = "  "
00626             if p[1] in PinLabel.keys():
00627                 if "STDIO_UART" in PinLabel[p[1]]:
00628                     CommentedLine = "//"
00629                 if "RCC_OSC" in PinLabel[p[1]]:
00630                     CommentedLine = "//"
00631             if "%s_" % TIM_MST in p[2]:
00632                 CommentedLine = "//"
00633             if CommentedLine != "//":
00634                 if p[0] == prev_p:
00635                     prev_p = p[0]
00636                     p[0] += '_ALT%d' % alt_index
00637                     alt_index += 1
00638                 else:
00639                     prev_p = p[0]
00640                     alt_index = 0
00641             s1 = "%-17s" % (CommentedLine + "  {" + p[0] + ',')
00642             # p[2] : TIM2_CH1 / TIM15_CH1N
00643             a = p[2].split('_')
00644             inst = a[0].replace("TIM", "PWM_")
00645             # if len(inst) == 3:
00646             #     inst += '1'
00647             s1 += "%-8s" % (inst + ',')
00648             chan = a[1].replace("CH", "")
00649             if chan.endswith('N'):
00650                 neg = ', 1'
00651                 chan = chan.strip('N')
00652             else:
00653                 neg = ', 0'
00654             s1 += 'STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, '
00655             r = result.split(' ')
00656             for af in r:
00657                 s2 = s1 + af + ', ' + chan + neg + ')}, // ' + p[2]
00658                 if p[1] in PinLabel.keys():
00659                     s2 += ' // Connected to ' + PinLabel[p[1]]
00660                 s2 += '\n'
00661                 out_c_file.write(s2)
00662     out_c_file.write( """    {NC, NC, 0}
00663 };
00664 """)
00665     if ADD_DEVICE_IFDEF:
00666         out_c_file.write( "#endif\n" )
00667 
00668 def print_uart(l):
00669     prev_p = ''
00670     alt_index = 0
00671     for p in l:
00672         result = get_gpio_af_num(p[1], p[2])
00673         if result != 'NOTFOUND':
00674             CommentedLine = "  "
00675             if p[1] in PinLabel.keys():
00676                 if "RCC_OSC" in PinLabel[p[1]]:
00677                     CommentedLine = "//"
00678             if CommentedLine != "//":
00679                 if p[0] == prev_p:
00680                     prev_p = p[0]
00681                     p[0] += '_ALT%d' % alt_index
00682                     alt_index += 1
00683                 else:
00684                     prev_p = p[0]
00685                     alt_index = 0
00686             s1 = "%-17s" % (CommentedLine + "  {" + p[0] + ',')
00687             # p[2] : USART2_RX
00688             b=p[2].split('_')[0]
00689             b = b.replace("UART", "UART_")
00690             b = b.replace("USART", "UART_")
00691             s1 += "%-9s" % (b[:len(b)-1] +  b[len(b)-1:] + ',')
00692             if 'STM32F10' in mcu_file and l == uartrx_list:
00693                 s1 += 'STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, '
00694             else:
00695                 s1 += 'STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, '
00696             r = result.split(' ')
00697             for af in r:
00698                 s2 = s1 + af  + ')},'
00699                 if p[1] in PinLabel.keys():
00700                     s2 += ' // Connected to ' + PinLabel[p[1]]
00701                 s2 += '\n'
00702                 out_c_file.write(s2)
00703     out_c_file.write( """    {NC, NC, 0}
00704 };
00705 """)
00706     if ADD_DEVICE_IFDEF:
00707         out_c_file.write( "#endif\n" )
00708 
00709 def print_spi(l):
00710     prev_p = ''
00711     alt_index = 0
00712     for p in l:
00713         result = get_gpio_af_num(p[1], p[2])
00714         if result != 'NOTFOUND':
00715             CommentedLine = "  "
00716             if p[1] in PinLabel.keys():
00717                 if "STDIO_UART" in PinLabel[p[1]]:
00718                     CommentedLine = "//"
00719                 if "RCC_OSC" in PinLabel[p[1]]:
00720                     CommentedLine = "//"
00721             if CommentedLine != "//":
00722                 if p[0] == prev_p:
00723                     prev_p = p[0]
00724                     p[0] += '_ALT%d' % alt_index
00725                     alt_index += 1
00726                 else:
00727                     prev_p = p[0]
00728                     alt_index = 0
00729             s1 = "%-17s" % (CommentedLine + "  {" + p[0] + ',')
00730             # p[2] : SPI1_MISO
00731             instance=p[2].split('_')[0].replace("SPI", "")
00732             s1 += "%-7s" % ('SPI_' + instance + ',')
00733             s1 += 'STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, '
00734             r = result.split(' ')
00735             for af in r:
00736                 s2 = s1 + af  + ')},'
00737                 if p[1] in PinLabel.keys():
00738                     s2 += ' // Connected to ' + PinLabel[p[1]]
00739                 s2 += '\n'
00740                 out_c_file.write(s2)
00741     out_c_file.write( """    {NC, NC, 0}
00742 };
00743 """)
00744     if ADD_DEVICE_IFDEF:
00745         out_c_file.write( "#endif\n" )
00746 
00747 def print_can(l):
00748     for p in l:
00749         result = get_gpio_af_num(p[1], p[2])
00750         if result != 'NOTFOUND':
00751             CommentedLine = "  "
00752             if p[1] in PinLabel.keys():
00753                 if "STDIO_UART" in PinLabel[p[1]]:
00754                     CommentedLine = "//"
00755                 if "RCC_OSC" in PinLabel[p[1]]:
00756                     CommentedLine = "//"
00757             s1 = "%-17s" % (CommentedLine + "  {" + p[0] + ',')
00758             # p[2] : CAN_RX / CAN1_RX
00759             p[2] = p[2].replace("FD", "")
00760             instance = p[2].split('_')[0].replace("CAN", "")
00761             if len(instance) == 0:
00762                 instance = '1'
00763             s1 += "%-7s" % ('CAN_' + instance + ',')
00764             if 'STM32F10' in mcu_file and l == canrd_list:
00765                 s1 += 'STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, '
00766             else:
00767                 s1 += 'STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, '
00768             r = result.split(' ')
00769             for af in r:
00770                 s2 = s1 + af  + ')},'
00771                 if p[1] in PinLabel.keys():
00772                     s2 += ' // Connected to ' + PinLabel[p[1]]
00773                 s2 += '\n'
00774                 out_c_file.write(s2)
00775     out_c_file.write( """    {NC, NC, 0}
00776 };
00777 """)
00778     if ADD_DEVICE_IFDEF:
00779         out_c_file.write( "#endif\n" )
00780 
00781 def print_qspi(l):
00782     prev_s = ''
00783     for p in l:
00784         result = get_gpio_af_num(p[1], p[2])
00785         if result != 'NOTFOUND':
00786             CommentedLine = "  "
00787             if p[1] in PinLabel.keys():
00788                 if "STDIO_UART" in PinLabel[p[1]]:
00789                     CommentedLine = "//"
00790                 if "RCC_OSC" in PinLabel[p[1]]:
00791                     CommentedLine = "//"
00792             s1 = "%-17s" % (CommentedLine + "    {" + p[0] + ',')
00793             # p[2] : QUADSPI_BK1_IO3 / QUADSPI_CLK / QUADSPI_NCS
00794             instance = p[2].split('_')[1].replace("BK", "")
00795             instance = instance.replace("CLK", "1")
00796             instance = instance.replace("NCS", "1")
00797             s1 += "%-7s" % ('QSPI_' + instance + ',')
00798             s1 += 'STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, ' + result +')},'
00799             #check duplicated lines, only signal differs
00800             if (prev_s == s1):
00801                 s1 = '|' + p[2]
00802             else:
00803                 if len(prev_s)>0:
00804                     out_c_file.write('\n')
00805                 prev_s = s1
00806                 s1 += '  // ' + p[2]
00807             if p[1] in PinLabel.keys():
00808                 s1 += ' // Connected to ' + PinLabel[p[1]]
00809             s1 += '\n'
00810             out_c_file.write(s1)
00811     out_c_file.write( """    {NC, NC, 0}
00812 };
00813 """)
00814     if ADD_DEVICE_IFDEF:
00815         out_c_file.write( "#endif\n" )
00816 
00817 def print_h_file(l, comment):
00818     if len(l) > 0:
00819         s = ("\n/**** %s pins ****/\n" % comment)
00820         out_h_file.write(s)
00821 
00822         prev_s = ''
00823         alt_index = 0
00824         for p in l:
00825             if p[2] == prev_s:
00826                 prev_s = p[2]
00827                 p[2] += '_ALT%d' % alt_index
00828                 alt_index += 1
00829             else:
00830                 prev_s = p[2]
00831                 alt_index = 0
00832             s1 = "    %s = %s,\n" % (p[2].replace("-", "_"), p[0])
00833             out_h_file.write(s1)
00834     # else:
00835     #     s = ("\n/**** No %s pins ***/\n" % comment)
00836     #     out_h_file.write(s)
00837 
00838 
00839 tokenize = re.compile(r'(\d+)|(\D+)').findall
00840 
00841 def natural_sortkey(list_2_elem):
00842     return tuple(int(num) if num else alpha for num, alpha in tokenize(list_2_elem[0]))
00843 
00844 def natural_sortkey2(list_2_elem):
00845     return tuple(int(num) if num else alpha for num, alpha in tokenize(list_2_elem[2]))
00846 
00847 def natural_sortkey_uart(list_2_elem):
00848     return tuple(int(num) if num else alpha for num, alpha in tokenize(list_2_elem[2].replace("USART", "UART").replace("LPUART", "ZUART")))
00849 
00850 def natural_sortkey_i2c(list_2_elem):
00851     return tuple(int(num) if num else alpha for num, alpha in tokenize(list_2_elem[2].replace("FMPI2C", "ZFMPI2C")))
00852 
00853 def sort_my_lists():
00854     adclist.sort(key=natural_sortkey)
00855     daclist.sort(key=natural_sortkey)
00856     i2cscl_list.sort(key=natural_sortkey_i2c) # first sort on name column
00857     i2csda_list.sort(key=natural_sortkey_i2c) # first sort on name column
00858     i2cscl_list.sort(key=natural_sortkey)
00859     i2csda_list.sort(key=natural_sortkey)
00860     pwm_list.sort(key=natural_sortkey2) # first sort on name column
00861     pwm_list.sort(key=natural_sortkey)
00862     uarttx_list.sort(key=natural_sortkey_uart) # first sort on name column
00863     uartrx_list.sort(key=natural_sortkey_uart) # first sort on name column
00864     uartcts_list.sort(key=natural_sortkey_uart) # first sort on name column
00865     uartrts_list.sort(key=natural_sortkey_uart) # first sort on name column
00866     uarttx_list.sort(key=natural_sortkey)
00867     uartrx_list.sort(key=natural_sortkey)
00868     uartcts_list.sort(key=natural_sortkey)
00869     uartrts_list.sort(key=natural_sortkey)
00870     spimosi_list.sort(key=natural_sortkey)
00871     spimiso_list.sort(key=natural_sortkey)
00872     spissel_list.sort(key=natural_sortkey)
00873     spisclk_list.sort(key=natural_sortkey)
00874     cantd_list.sort(key=natural_sortkey)
00875     canrd_list.sort(key=natural_sortkey)
00876     eth_list.sort(key=natural_sortkey2)
00877     quadspidata_list.sort(key=natural_sortkey)
00878     quadspisclk_list.sort(key=natural_sortkey)
00879     quadspissel_list.sort(key=natural_sortkey)
00880     usb_list.sort(key=natural_sortkey2)
00881     osc_list.sort(key=natural_sortkey2)
00882     sys_list.sort(key=natural_sortkey2)
00883 
00884 def clean_all_lists():
00885     del io_list[:]
00886     del adclist[:]
00887     del daclist[:]
00888     del i2cscl_list[:]
00889     del i2csda_list[:]
00890     del pwm_list[:]
00891     del uarttx_list[:]
00892     del uartrx_list[:]
00893     del uartcts_list[:]
00894     del uartrts_list[:]
00895     del spimosi_list[:]
00896     del spimiso_list[:]
00897     del spissel_list[:]
00898     del spisclk_list[:]
00899     del cantd_list[:]
00900     del canrd_list[:]
00901     del eth_list[:]
00902     del quadspidata_list[:]
00903     del quadspisclk_list[:]
00904     del quadspissel_list[:]
00905     del usb_list[:]
00906     del osc_list[:]
00907     del sys_list[:]
00908 
00909 def parse_pins():
00910     # print (" * Getting pins per Ips...")
00911     pinregex=r'^(P[A-Z][0-9][0-5]?)'
00912     itemlist = xml_mcu.getElementsByTagName('Pin')
00913     for s in itemlist:
00914         m = re.match(pinregex, s.attributes['Name'].value)
00915         if m:
00916             pin = m.group(0)[:2] + '_' + m.group(0)[2:] # pin formatted P<port>_<number>: PF_O
00917             name = s.attributes['Name'].value.strip()   # full name: "PF0 / OSC_IN"
00918             if s.attributes['Type'].value == "I/O":
00919                 store_pin(pin, name)
00920             else:
00921                 continue
00922             siglist = s.getElementsByTagName('Signal')
00923             for a in siglist:
00924                 sig = a.attributes['Name'].value.strip()
00925                 if "ADC" in sig:
00926                     store_adc(pin, name, sig)
00927                 if all(["DAC" in sig, "_OUT" in sig]):
00928                     store_dac(pin, name, sig)
00929                 if "I2C" in sig:
00930                     store_i2c(pin, name, sig)
00931                 if re.match('^TIM', sig) is not None: #ignore HRTIM
00932                     store_pwm(pin, name, sig)
00933                 if re.match('^(LPU|US|U)ART', sig) is not None:
00934                     store_uart(pin, name, sig)
00935                 if "SPI" in sig:
00936                     store_spi(pin, name, sig)
00937                 if "CAN" in sig:
00938                     store_can(pin, name, sig)
00939                 if "ETH" in sig:
00940                     store_eth(pin, name, sig)
00941                 if "QUADSPI" in sig:
00942                     store_qspi(pin, name, sig)
00943                 if "USB" in sig:
00944                     store_usb(pin, name, sig)
00945                 if "RCC_OSC" in sig:
00946                     store_osc(pin, name, sig)
00947                 if "SYS_" in sig:
00948                     store_sys(pin, name, sig)
00949 
00950 PinData = {}
00951 PinLabel = {}
00952 
00953 def parse_BoardFile(fileName):
00954     print(" * Board file: '%s'" % (fileName))
00955     board_file = open(board_file_name, "r")
00956     # IOC_PIN_pattern = re.compile(r'(P[A-I][\d]*).*\.([\w]*)=(.*)')
00957     IOC_PIN_pattern = re.compile(r'(.*)\.([\w]*)=(.*)')
00958     for line in board_file.readlines():
00959         IOC_PIN = re.match(IOC_PIN_pattern, line)
00960         if IOC_PIN:
00961             if IOC_PIN.groups()[0] in PinData.keys():
00962                 PinData[IOC_PIN.groups()[0]][IOC_PIN.groups()[1]] = IOC_PIN.groups()[2]
00963             else:
00964                 PinData[IOC_PIN.groups()[0]] = {}
00965                 PinData[IOC_PIN.groups()[0]][IOC_PIN.groups()[1]] = IOC_PIN.groups()[2]
00966         # IOC_MCU = re.match(r'Mcu\.UserName=(.*)', line)
00967         IOC_MCU = re.match(r'Mcu\.Name=(.*)', line)
00968         if IOC_MCU:
00969             mcu_list.append("%s.xml" % IOC_MCU.groups()[0])
00970 
00971     board_file.close()
00972 
00973     for EachPin in PinData:
00974         try:
00975             PinLabel[EachPin] = PinData[EachPin]["Signal"]
00976         except:
00977             pass
00978 
00979         try:
00980             PinLabel[EachPin] = PinData[EachPin]["GPIO_Label"]
00981 
00982             if "STLK_RX" in PinLabel[EachPin] or "STLK_TX" in PinLabel[EachPin]:
00983                 if "RX" in PinData[EachPin]["Signal"]:
00984                     PinLabel[EachPin] = "STDIO_UART_RX"
00985                 else:
00986                     PinLabel[EachPin] = "STDIO_UART_TX"
00987             elif "USART_RX" in PinLabel[EachPin]:
00988                 PinLabel[EachPin] = "STDIO_UART_RX"
00989             elif "USART_TX" in PinLabel[EachPin]:
00990                 PinLabel[EachPin] = "STDIO_UART_TX"
00991             elif "VCP_RX" in PinLabel[EachPin]:
00992                 PinLabel[EachPin] = "STDIO_UART_RX"
00993             elif "VCP_TX" in PinLabel[EachPin]:
00994                 PinLabel[EachPin] = "STDIO_UART_TX"
00995             elif "ST_LINK_UART1_RX" in PinLabel[EachPin]:
00996                 PinLabel[EachPin] = "STDIO_UART_RX"
00997             elif "ST_LINK_UART1_TX" in PinLabel[EachPin]:
00998                 PinLabel[EachPin] = "STDIO_UART_TX"
00999             elif "USART2_RX" in PinLabel[EachPin]:
01000                 PinLabel[EachPin] = "STDIO_UART_RX"
01001             elif "USART2_TX" in PinLabel[EachPin]:
01002                 PinLabel[EachPin] = "STDIO_UART_TX"
01003             elif "STLINK_RX" in PinLabel[EachPin] or "STLINK_TX" in PinLabel[EachPin]:
01004                 if "RX" in PinData[EachPin]["Signal"]:
01005                     PinLabel[EachPin] = "STDIO_UART_RX"
01006                 else:
01007                     PinLabel[EachPin] = "STDIO_UART_TX"
01008         except:
01009             pass
01010 
01011 # main
01012 print ("\nScript version %s" % GENPINMAP_VERSION)
01013 cur_dir = os.getcwd()
01014 PeripheralPins_c_filename = 'PeripheralPins.c'
01015 PinNames_h_filename = 'PinNames.h'
01016 config_filename = 'cube_path.json'
01017 
01018 try:
01019     config_file = open(config_filename, "r")
01020 except IOError:
01021     print("Please set your configuration in '%s' file" % config_filename)
01022     config_file = open(config_filename, "w")
01023     if sys.platform.startswith('win32'):
01024         print("Platform is Windows")
01025         cubemxdir = 'C:\\Program Files (x86)\\STMicroelectronics\\STM32Cube\\STM32CubeMX'
01026     elif sys.platform.startswith('linux'):
01027         print("Platform is Linux")
01028         cubemxdir = os.getenv("HOME")+'/STM32CubeMX'
01029     elif sys.platform.startswith('darwin'):
01030         print("Platform is Mac OSX")
01031         cubemxdir = '/Applications/STMicroelectronics/STM32CubeMX.app/Contents/Resources'
01032     else:
01033         print("Platform unknown")
01034         cubemxdir = '<Set CubeMX install directory>'
01035     config_file.write(json.dumps({"CUBEMX_DIRECTORY":cubemxdir}))
01036     config_file.close()
01037     exit(1)
01038 
01039 config = json.load(config_file)
01040 config_file.close()
01041 cubemxdir = config["CUBEMX_DIRECTORY"]
01042 
01043 parser = argparse.ArgumentParser(
01044     description=textwrap.dedent('''\
01045 Script will generate %s thanks to the xml files description available in
01046 STM32CubeMX directory defined in '%s':
01047 \t%s''' % (PeripheralPins_c_filename, config_filename, cubemxdir)),
01048     epilog=textwrap.dedent('''\
01049 Once generated, you have to check and comment pins that can not be used (specific HW, internal ADC channels, remove PWM using us ticker timer, ...)
01050 '''),
01051     formatter_class=RawTextHelpFormatter)
01052 group = parser.add_mutually_exclusive_group()
01053 
01054 group.add_argument("-l", "--list", help="list available mcu xml files description in STM32CubeMX", action="store_true")
01055 
01056 group.add_argument("-b", "--boards", help="list available boards description in STM32CubeMX", action="store_true")
01057 
01058 group.add_argument("-m", "--mcu", metavar='xml', help=textwrap.dedent('''\
01059 specify the mcu xml file description in STM32CubeMX to use (use double quotes).
01060    Parameter can be a filter like L496 if you want to parse all L496 chips (-m STM32 to parse all).
01061 '''))
01062 
01063 group.add_argument("-t", "--target", metavar='HW', help=textwrap.dedent('''\
01064 specify the board file description in STM32CubeMX to use (use double quotes).
01065    Parameter can be a filter like L496 (only the first file found will be parsed).
01066 '''))
01067 
01068 args = parser.parse_args()
01069 
01070 if not(os.path.isdir(cubemxdir)):
01071     print ("\n ! ! ! Cube Mx seems not to be installed or not at the requested location")
01072     print ("\n ! ! ! please check the value you set for 'CUBEMX_DIRECTORY' in '%s' file" % config_filename)
01073     quit()
01074 
01075 cubemxdirMCU = os.path.join(cubemxdir, 'db', 'mcu')
01076 cubemxdirIP = os.path.join(cubemxdir, 'db', 'mcu', 'IP')
01077 cubemxdirBOARDS = os.path.join(cubemxdir, 'db', 'plugins', 'boardmanager', 'boards')
01078 
01079 version_file = os.path.join(cubemxdir, 'db', 'package.xml')
01080 try:
01081     xml_file = parse(version_file)
01082     PackDescription_item = xml_file.getElementsByTagName('PackDescription')
01083     for item in PackDescription_item:
01084         CUBEMX_DB_VERSION = item.attributes['Release'].value
01085 except:
01086     CUBEMX_DB_VERSION = "NOT_FOUND"
01087 print ("CubeMX DB version %s\n" % CUBEMX_DB_VERSION)
01088 
01089 if args.list:
01090     FileCount = 0
01091     for f in fnmatch.filter(os.listdir(cubemxdirMCU), 'STM32*.xml'):
01092         print(f)
01093         FileCount += 1
01094     print
01095     print("%i available xml files description" % FileCount)
01096     quit()
01097 
01098 if args.boards:
01099     NucleoFileCount = 0
01100     DiscoFileCount = 0
01101     for f in fnmatch.filter(os.listdir(cubemxdirBOARDS), '*AllConfig.ioc'):
01102         print(f)
01103         if "Nucleo" in f:
01104             NucleoFileCount += 1
01105         elif "Discovery" in f:
01106             DiscoFileCount += 1
01107     print
01108     print("%2i available Nucleo files description" % NucleoFileCount)
01109     print("%2i available Disco  files description" % DiscoFileCount)
01110     quit()
01111 
01112 if args.mcu:
01113     #check input file exists
01114     if os.path.isfile(os.path.join(cubemxdirMCU, args.mcu)):
01115         mcu_list.append(args.mcu)
01116     else:
01117         mcu_list = fnmatch.filter(os.listdir(cubemxdirMCU), '*%s*' % args.mcu)
01118         if len(mcu_list) == 0:
01119             print (" ! ! ! " + args.mcu + " file not found")
01120             print (" ! ! ! Check in " + cubemxdirMCU + " the correct name of this file")
01121             print (" ! ! ! You may use double quotes for this file if it contains special characters")
01122             quit()
01123 
01124 if args.target:
01125     board_file_name = os.path.join(cubemxdirBOARDS, args.target)
01126     if not(os.path.isfile(board_file_name)):
01127         board_list = fnmatch.filter(os.listdir(cubemxdirBOARDS), '*%s*AllConfig.ioc' % args.target)
01128         if len(board_list) == 0:
01129             print (" ! ! ! No file contains " + args.target)
01130             print (" ! ! ! Check in " + cubemxdirBOARDS + " the correct filter to apply")
01131             quit()
01132         elif len(board_list) > 1:
01133             print (" ! ! ! Multiple files contains " + args.target)
01134             for board_elem in board_list: print (board_elem)
01135             print (" ! ! ! Only the first one will be parsed\n")
01136         board_file_name = os.path.join(cubemxdirBOARDS,board_list[0])
01137         if not (os.path.isfile(board_file_name)):
01138             print (" ! ! ! " + args.target + " file not found")
01139             print (" ! ! ! Check in " + cubemxdirBOARDS + " the correct name of this file")
01140             print (" ! ! ! You may use double quotes for this file if it contains special characters")
01141             quit()
01142     parse_BoardFile(board_file_name)
01143     TargetName = ""
01144     if "Nucleo" in board_file_name:
01145         TargetName += "NUCLEO_"
01146     elif "Discovery" in board_file_name:
01147         TargetName += "DISCO_"
01148     elif "Evaluation" in board_file_name:
01149         TargetName += "EVAL_"
01150     m = re.search(r'STM32([\w][\dR]{3}[\w]{0,2})[\w]*_Board', board_file_name)
01151     if m:
01152         TargetName += "%s" % m.group(1)
01153         # specific case
01154         if "-P" in args.target:
01155             TargetName += "_P"
01156         if TargetName == "DISCO_L072":
01157             TargetName += "CZ_LRWAN1"
01158         if TargetName == "DISCO_L475V":
01159             TargetName += "G_IOT01A"
01160     else:
01161         quit()
01162 
01163 for mcu_file in mcu_list:
01164     if args.mcu:
01165         TargetName = os.path.splitext(mcu_file)[0]
01166     out_path = os.path.join(cur_dir, '%s' % TargetName)
01167     print(" * Output directory: %s" % (out_path))
01168     print(" * Generating %s and %s with '%s'" % (PeripheralPins_c_filename, PinNames_h_filename, mcu_file))
01169     input_file_name = os.path.join(cubemxdirMCU, mcu_file)
01170     output_cfilename = os.path.join(out_path, PeripheralPins_c_filename)
01171     output_hfilename = os.path.join(out_path, PinNames_h_filename)
01172     if not(os.path.isdir(out_path)):
01173         os.makedirs(out_path)
01174 
01175     if (os.path.isfile(output_cfilename)):
01176         # print (" * Requested %s file already exists and will be overwritten" % PeripheralPins_c_filename)
01177         os.remove(output_cfilename)
01178     out_c_file = open(output_cfilename, 'w')
01179     out_h_file = open(output_hfilename, 'w')
01180 
01181     #open input file
01182     try:
01183         xml_mcu = parse(input_file_name)
01184     except:
01185         # Patch waiting for CubeMX correction
01186         if "STM32F042K6Tx" in input_file_name:
01187             input_file_name = os.path.join(cubemxdirMCU, "STM32F042K(4-6)Tx.xml")
01188             xml_mcu = parse(input_file_name)
01189         elif "STM32F429Z" in input_file_name:
01190             input_file_name = os.path.join(cubemxdirMCU, "STM32F429ZITx.xml")
01191             xml_mcu = parse(input_file_name)
01192         elif "STM32F746Z" in input_file_name:
01193             input_file_name = os.path.join(cubemxdirMCU, "STM32F746ZGTx.xml")
01194             xml_mcu = parse(input_file_name)
01195         elif "STM32F767Z" in input_file_name:
01196             input_file_name = os.path.join(cubemxdirMCU, "STM32F767ZGTx.xml")
01197             xml_mcu = parse(input_file_name)
01198 
01199         elif "STM32L011K4Tx" in input_file_name:
01200             input_file_name = os.path.join(cubemxdirMCU, "STM32L011K(3-4)Tx.xml")
01201             xml_mcu = parse(input_file_name)
01202         elif "STM32L432KCUx" in input_file_name:
01203             input_file_name = os.path.join(cubemxdirMCU, "STM32L432K(B-C)Ux.xml")
01204             xml_mcu = parse(input_file_name)
01205         elif "STM32F746N" in input_file_name:
01206             input_file_name = os.path.join(cubemxdirMCU, "STM32F746NGHx.xml")
01207             xml_mcu = parse(input_file_name)
01208         else:
01209             print ("\n ! ! ! Error in CubeMX file. File " + input_file_name + " doesn't exist")
01210             print (" ! ! ! Check in " + cubemxdirMCU)
01211             quit()
01212     gpiofile = find_gpio_file()
01213     if gpiofile == 'ERROR':
01214         print("Could not find GPIO file")
01215         quit()
01216     xml_gpio = parse(os.path.join(cubemxdirIP, 'GPIO-' + gpiofile + '_Modes.xml'))
01217     print (" * GPIO file: " + os.path.join(cubemxdirIP, 'GPIO-' + gpiofile + '_Modes.xml'))
01218 
01219     parse_pins()
01220     sort_my_lists()
01221     print_header()
01222     print_all_lists()
01223     print_footer()
01224 
01225     nb_pin = (len(io_list))
01226     nb_connected_pin = len(PinLabel)
01227     print (" * I/O pins found: %i connected: %i\n" % (nb_pin, nb_connected_pin))
01228     clean_all_lists()
01229 
01230     out_c_file.close()
01231     out_h_file.close()