Anders Blomdell / mbed-sdk-tools
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.3"
00030 
00031 ADD_DEVICE_IFDEF = 0
00032 ADD_QSPI_FEATURE = 1
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     for p in l:
00783         result = get_gpio_af_num(p[1], p[2])
00784         if result != 'NOTFOUND':
00785             CommentedLine = "  "
00786             if p[1] in PinLabel.keys():
00787                 if "STDIO_UART" in PinLabel[p[1]]:
00788                     CommentedLine = "//"
00789                 if "RCC_OSC" in PinLabel[p[1]]:
00790                     CommentedLine = "//"
00791             s1 = "%-16s" % (CommentedLine + "  {" + p[0] + ',')
00792             # p[2] : QUADSPI_BK1_IO3 / QUADSPI_CLK / QUADSPI_NCS
00793             s1 += "%-8s" % ('QSPI_1,')
00794             result = result.replace("GPIO_AF10_OTG_FS", "GPIO_AF10_QSPI")
00795             s1 += 'STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, ' + result +')},'
00796             s1 += '  // ' + p[2]
00797             if p[1] in PinLabel.keys():
00798                 s1 += ' // Connected to ' + PinLabel[p[1]]
00799             s1 += '\n'
00800             out_c_file.write(s1)
00801     out_c_file.write( """    {NC, NC, 0}
00802 };
00803 """)
00804     if ADD_DEVICE_IFDEF:
00805         out_c_file.write( "#endif\n" )
00806 
00807 def print_h_file(l, comment):
00808     if len(l) > 0:
00809         s = ("\n/**** %s pins ****/\n" % comment)
00810         out_h_file.write(s)
00811 
00812         prev_s = ''
00813         alt_index = 0
00814         for p in l:
00815             if p[2] == prev_s:
00816                 prev_s = p[2]
00817                 p[2] += '_ALT%d' % alt_index
00818                 alt_index += 1
00819             else:
00820                 prev_s = p[2]
00821                 alt_index = 0
00822             s1 = "    %s = %s,\n" % (p[2].replace("-", "_"), p[0])
00823             out_h_file.write(s1)
00824     # else:
00825     #     s = ("\n/**** No %s pins ***/\n" % comment)
00826     #     out_h_file.write(s)
00827 
00828 
00829 tokenize = re.compile(r'(\d+)|(\D+)').findall
00830 
00831 def natural_sortkey(list_2_elem):
00832     return tuple(int(num) if num else alpha for num, alpha in tokenize(list_2_elem[0]))
00833 
00834 def natural_sortkey2(list_2_elem):
00835     return tuple(int(num) if num else alpha for num, alpha in tokenize(list_2_elem[2]))
00836 
00837 def natural_sortkey_uart(list_2_elem):
00838     return tuple(int(num) if num else alpha for num, alpha in tokenize(list_2_elem[2].replace("USART", "UART").replace("LPUART", "ZUART")))
00839 
00840 def natural_sortkey_i2c(list_2_elem):
00841     return tuple(int(num) if num else alpha for num, alpha in tokenize(list_2_elem[2].replace("FMPI2C", "ZFMPI2C")))
00842 
00843 def sort_my_lists():
00844     adclist.sort(key=natural_sortkey)
00845     daclist.sort(key=natural_sortkey)
00846     i2cscl_list.sort(key=natural_sortkey_i2c) # first sort on name column
00847     i2csda_list.sort(key=natural_sortkey_i2c) # first sort on name column
00848     i2cscl_list.sort(key=natural_sortkey)
00849     i2csda_list.sort(key=natural_sortkey)
00850     pwm_list.sort(key=natural_sortkey2) # first sort on name column
00851     pwm_list.sort(key=natural_sortkey)
00852     uarttx_list.sort(key=natural_sortkey_uart) # first sort on name column
00853     uartrx_list.sort(key=natural_sortkey_uart) # first sort on name column
00854     uartcts_list.sort(key=natural_sortkey_uart) # first sort on name column
00855     uartrts_list.sort(key=natural_sortkey_uart) # first sort on name column
00856     uarttx_list.sort(key=natural_sortkey)
00857     uartrx_list.sort(key=natural_sortkey)
00858     uartcts_list.sort(key=natural_sortkey)
00859     uartrts_list.sort(key=natural_sortkey)
00860     spimosi_list.sort(key=natural_sortkey)
00861     spimiso_list.sort(key=natural_sortkey)
00862     spissel_list.sort(key=natural_sortkey)
00863     spisclk_list.sort(key=natural_sortkey)
00864     cantd_list.sort(key=natural_sortkey)
00865     canrd_list.sort(key=natural_sortkey)
00866     eth_list.sort(key=natural_sortkey2)
00867     quadspidata_list.sort(key=natural_sortkey)
00868     quadspisclk_list.sort(key=natural_sortkey)
00869     quadspissel_list.sort(key=natural_sortkey)
00870     usb_list.sort(key=natural_sortkey2)
00871     osc_list.sort(key=natural_sortkey2)
00872     sys_list.sort(key=natural_sortkey2)
00873 
00874 def clean_all_lists():
00875     del io_list[:]
00876     del adclist[:]
00877     del daclist[:]
00878     del i2cscl_list[:]
00879     del i2csda_list[:]
00880     del pwm_list[:]
00881     del uarttx_list[:]
00882     del uartrx_list[:]
00883     del uartcts_list[:]
00884     del uartrts_list[:]
00885     del spimosi_list[:]
00886     del spimiso_list[:]
00887     del spissel_list[:]
00888     del spisclk_list[:]
00889     del cantd_list[:]
00890     del canrd_list[:]
00891     del eth_list[:]
00892     del quadspidata_list[:]
00893     del quadspisclk_list[:]
00894     del quadspissel_list[:]
00895     del usb_list[:]
00896     del osc_list[:]
00897     del sys_list[:]
00898 
00899 def parse_pins():
00900     # print (" * Getting pins per Ips...")
00901     pinregex=r'^(P[A-Z][0-9][0-5]?)'
00902     itemlist = xml_mcu.getElementsByTagName('Pin')
00903     for s in itemlist:
00904         m = re.match(pinregex, s.attributes['Name'].value)
00905         if m:
00906             pin = m.group(0)[:2] + '_' + m.group(0)[2:] # pin formatted P<port>_<number>: PF_O
00907             name = s.attributes['Name'].value.strip()   # full name: "PF0 / OSC_IN"
00908             if s.attributes['Type'].value == "I/O":
00909                 store_pin(pin, name)
00910             else:
00911                 continue
00912             siglist = s.getElementsByTagName('Signal')
00913             for a in siglist:
00914                 sig = a.attributes['Name'].value.strip()
00915                 if "ADC" in sig:
00916                     store_adc(pin, name, sig)
00917                 if all(["DAC" in sig, "_OUT" in sig]):
00918                     store_dac(pin, name, sig)
00919                 if "I2C" in sig:
00920                     store_i2c(pin, name, sig)
00921                 if re.match('^TIM', sig) is not None: #ignore HRTIM
00922                     store_pwm(pin, name, sig)
00923                 if re.match('^(LPU|US|U)ART', sig) is not None:
00924                     store_uart(pin, name, sig)
00925                 if "SPI" in sig:
00926                     store_spi(pin, name, sig)
00927                 if "CAN" in sig:
00928                     store_can(pin, name, sig)
00929                 if "ETH" in sig:
00930                     store_eth(pin, name, sig)
00931                 if "QUADSPI" in sig:
00932                     store_qspi(pin, name, sig)
00933                 if "USB" in sig:
00934                     store_usb(pin, name, sig)
00935                 if "RCC_OSC" in sig:
00936                     store_osc(pin, name, sig)
00937                 if "SYS_" in sig:
00938                     store_sys(pin, name, sig)
00939 
00940 PinData = {}
00941 PinLabel = {}
00942 
00943 def parse_BoardFile(fileName):
00944     print(" * Board file: '%s'" % (fileName))
00945     board_file = open(board_file_name, "r")
00946     # IOC_PIN_pattern = re.compile(r'(P[A-I][\d]*).*\.([\w]*)=(.*)')
00947     IOC_PIN_pattern = re.compile(r'(.*)\.([\w]*)=(.*)')
00948     for line in board_file.readlines():
00949         IOC_PIN = re.match(IOC_PIN_pattern, line)
00950         if IOC_PIN:
00951             if IOC_PIN.groups()[0] in PinData.keys():
00952                 PinData[IOC_PIN.groups()[0]][IOC_PIN.groups()[1]] = IOC_PIN.groups()[2]
00953             else:
00954                 PinData[IOC_PIN.groups()[0]] = {}
00955                 PinData[IOC_PIN.groups()[0]][IOC_PIN.groups()[1]] = IOC_PIN.groups()[2]
00956         # IOC_MCU = re.match(r'Mcu\.UserName=(.*)', line)
00957         IOC_MCU = re.match(r'Mcu\.Name=(.*)', line)
00958         if IOC_MCU:
00959             mcu_list.append("%s.xml" % IOC_MCU.groups()[0])
00960 
00961     board_file.close()
00962 
00963     for EachPin in PinData:
00964         try:
00965             PinLabel[EachPin] = PinData[EachPin]["Signal"]
00966         except:
00967             pass
00968 
00969         try:
00970             PinLabel[EachPin] = PinData[EachPin]["GPIO_Label"]
00971 
00972             if "STLK_RX" in PinLabel[EachPin] or "STLK_TX" in PinLabel[EachPin]:
00973                 # Patch waiting for CubeMX correction
00974                 if "RX" in PinData[EachPin]["Signal"]:
00975                     PinLabel[EachPin] = "STDIO_UART_RX"
00976                 else:
00977                     PinLabel[EachPin] = "STDIO_UART_TX"
00978             elif "USART_RX" in PinLabel[EachPin]:
00979                 PinLabel[EachPin] = "STDIO_UART_RX"
00980             elif "USART_TX" in PinLabel[EachPin]:
00981                 PinLabel[EachPin] = "STDIO_UART_TX"
00982             elif "VCP_RX" in PinLabel[EachPin]:
00983                 PinLabel[EachPin] = "STDIO_UART_RX"
00984             elif "VCP_TX" in PinLabel[EachPin]:
00985                 PinLabel[EachPin] = "STDIO_UART_TX"
00986             elif "ST_LINK_UART1_RX" in PinLabel[EachPin]:
00987                 PinLabel[EachPin] = "STDIO_UART_RX"
00988             elif "ST_LINK_UART1_TX" in PinLabel[EachPin]:
00989                 PinLabel[EachPin] = "STDIO_UART_TX"
00990             elif "USART2_RX" in PinLabel[EachPin]:
00991                 PinLabel[EachPin] = "STDIO_UART_RX"
00992             elif "USART2_TX" in PinLabel[EachPin]:
00993                 PinLabel[EachPin] = "STDIO_UART_TX"
00994             elif "STLINK_RX" in PinLabel[EachPin] or "STLINK_TX" in PinLabel[EachPin]:
00995                 # Patch waiting for CubeMX correction
00996                 if "RX" in PinData[EachPin]["Signal"]:
00997                     PinLabel[EachPin] = "STDIO_UART_RX"
00998                 else:
00999                     PinLabel[EachPin] = "STDIO_UART_TX"
01000         except:
01001             pass
01002 
01003 # main
01004 print ("\nScript version %s" % GENPINMAP_VERSION)
01005 cur_dir = os.getcwd()
01006 PeripheralPins_c_filename = 'PeripheralPins.c'
01007 PinNames_h_filename = 'PinNames.h'
01008 config_filename = 'cube_path.json'
01009 
01010 try:
01011     config_file = open(config_filename, "r")
01012 except IOError:
01013     print("Please set your configuration in '%s' file" % config_filename)
01014     config_file = open(config_filename, "w")
01015     if sys.platform.startswith('win32'):
01016         print("Platform is Windows")
01017         cubemxdir = 'C:\\Program Files (x86)\\STMicroelectronics\\STM32Cube\\STM32CubeMX'
01018     elif sys.platform.startswith('linux'):
01019         print("Platform is Linux")
01020         cubemxdir = os.getenv("HOME")+'/STM32CubeMX'
01021     elif sys.platform.startswith('darwin'):
01022         print("Platform is Mac OSX")
01023         cubemxdir = '/Applications/STMicroelectronics/STM32CubeMX.app/Contents/Resources'
01024     else:
01025         print("Platform unknown")
01026         cubemxdir = '<Set CubeMX install directory>'
01027     config_file.write(json.dumps({"CUBEMX_DIRECTORY":cubemxdir}))
01028     config_file.close()
01029     exit(1)
01030 
01031 config = json.load(config_file)
01032 config_file.close()
01033 cubemxdir = config["CUBEMX_DIRECTORY"]
01034 
01035 parser = argparse.ArgumentParser(
01036     description=textwrap.dedent('''\
01037 Script will generate %s thanks to the xml files description available in
01038 STM32CubeMX directory defined in '%s':
01039 \t%s''' % (PeripheralPins_c_filename, config_filename, cubemxdir)),
01040     epilog=textwrap.dedent('''\
01041 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, ...)
01042 '''),
01043     formatter_class=RawTextHelpFormatter)
01044 group = parser.add_mutually_exclusive_group()
01045 
01046 group.add_argument("-l", "--list", help="list available mcu xml files description in STM32CubeMX", action="store_true")
01047 
01048 group.add_argument("-b", "--boards", help="list available boards description in STM32CubeMX", action="store_true")
01049 
01050 group.add_argument("-m", "--mcu", metavar='xml', help=textwrap.dedent('''\
01051 specify the mcu xml file description in STM32CubeMX to use (use double quotes).
01052    Parameter can be a filter like L496 if you want to parse all L496 chips (-m STM32 to parse all).
01053 '''))
01054 
01055 group.add_argument("-t", "--target", metavar='HW', help=textwrap.dedent('''\
01056 specify the board file description in STM32CubeMX to use (use double quotes).
01057    Parameter can be a filter like L496 (only the first file found will be parsed).
01058 '''))
01059 
01060 args = parser.parse_args()
01061 
01062 if not(os.path.isdir(cubemxdir)):
01063     print ("\n ! ! ! Cube Mx seems not to be installed or not at the requested location")
01064     print ("\n ! ! ! please check the value you set for 'CUBEMX_DIRECTORY' in '%s' file" % config_filename)
01065     quit()
01066 
01067 cubemxdirMCU = os.path.join(cubemxdir, 'db', 'mcu')
01068 cubemxdirIP = os.path.join(cubemxdir, 'db', 'mcu', 'IP')
01069 cubemxdirBOARDS = os.path.join(cubemxdir, 'db', 'plugins', 'boardmanager', 'boards')
01070 
01071 version_file = os.path.join(cubemxdir, 'db', 'package.xml')
01072 try:
01073     xml_file = parse(version_file)
01074     PackDescription_item = xml_file.getElementsByTagName('PackDescription')
01075     for item in PackDescription_item:
01076         CUBEMX_DB_VERSION = item.attributes['Release'].value
01077 except:
01078     CUBEMX_DB_VERSION = "NOT_FOUND"
01079 print ("CubeMX DB version %s\n" % CUBEMX_DB_VERSION)
01080 
01081 if args.list:
01082     FileCount = 0
01083     for f in fnmatch.filter(os.listdir(cubemxdirMCU), 'STM32*.xml'):
01084         print(f)
01085         FileCount += 1
01086     print
01087     print("%i available xml files description" % FileCount)
01088     quit()
01089 
01090 if args.boards:
01091     NucleoFileCount = 0
01092     DiscoFileCount = 0
01093     for f in fnmatch.filter(os.listdir(cubemxdirBOARDS), '*AllConfig.ioc'):
01094         print(f)
01095         if "Nucleo" in f:
01096             NucleoFileCount += 1
01097         elif "Discovery" in f:
01098             DiscoFileCount += 1
01099     print
01100     print("%2i available Nucleo files description" % NucleoFileCount)
01101     print("%2i available Disco  files description" % DiscoFileCount)
01102     quit()
01103 
01104 if args.mcu:
01105     #check input file exists
01106     if os.path.isfile(os.path.join(cubemxdirMCU, args.mcu)):
01107         mcu_list.append(args.mcu)
01108     else:
01109         mcu_list = fnmatch.filter(os.listdir(cubemxdirMCU), '*%s*' % args.mcu)
01110         if len(mcu_list) == 0:
01111             print (" ! ! ! " + args.mcu + " file not found")
01112             print (" ! ! ! Check in " + cubemxdirMCU + " the correct name of this file")
01113             print (" ! ! ! You may use double quotes for this file if it contains special characters")
01114             quit()
01115 
01116 if args.target:
01117     board_file_name = os.path.join(cubemxdirBOARDS, args.target)
01118     if not(os.path.isfile(board_file_name)):
01119         board_list = fnmatch.filter(os.listdir(cubemxdirBOARDS), '*%s*AllConfig.ioc' % args.target)
01120         if len(board_list) == 0:
01121             print (" ! ! ! No file contains " + args.target)
01122             print (" ! ! ! Check in " + cubemxdirBOARDS + " the correct filter to apply")
01123             quit()
01124         elif len(board_list) > 1:
01125             print (" ! ! ! Multiple files contains " + args.target)
01126             for board_elem in board_list: print (board_elem)
01127             print (" ! ! ! Only the first one will be parsed\n")
01128         board_file_name = os.path.join(cubemxdirBOARDS,board_list[0])
01129         if not (os.path.isfile(board_file_name)):
01130             print (" ! ! ! " + args.target + " file not found")
01131             print (" ! ! ! Check in " + cubemxdirBOARDS + " the correct name of this file")
01132             print (" ! ! ! You may use double quotes for this file if it contains special characters")
01133             quit()
01134     parse_BoardFile(board_file_name)
01135     TargetName = ""
01136     if "Nucleo" in board_file_name:
01137         TargetName += "NUCLEO_"
01138     elif "Discovery" in board_file_name:
01139         TargetName += "DISCO_"
01140     elif "Evaluation" in board_file_name:
01141         TargetName += "EVAL_"
01142     m = re.search(r'STM32([\w][\dR]{3}[\w]{0,2})[\w]*_Board', board_file_name)
01143     if m:
01144         TargetName += "%s" % m.group(1)
01145         # specific case
01146         if "-P" in args.target:
01147             TargetName += "_P"
01148         if TargetName == "DISCO_L072":
01149             TargetName += "CZ_LRWAN1"
01150         if TargetName == "DISCO_L475V":
01151             TargetName += "G_IOT01A"
01152     else:
01153         quit()
01154 
01155 for mcu_file in mcu_list:
01156     if args.mcu:
01157         TargetName = os.path.splitext(mcu_file)[0]
01158     out_path = os.path.join(cur_dir, '%s' % TargetName)
01159     print(" * Output directory: %s" % (out_path))
01160     print(" * Generating %s and %s with '%s'" % (PeripheralPins_c_filename, PinNames_h_filename, mcu_file))
01161     input_file_name = os.path.join(cubemxdirMCU, mcu_file)
01162     output_cfilename = os.path.join(out_path, PeripheralPins_c_filename)
01163     output_hfilename = os.path.join(out_path, PinNames_h_filename)
01164     if not(os.path.isdir(out_path)):
01165         os.makedirs(out_path)
01166 
01167     if (os.path.isfile(output_cfilename)):
01168         # print (" * Requested %s file already exists and will be overwritten" % PeripheralPins_c_filename)
01169         os.remove(output_cfilename)
01170     out_c_file = open(output_cfilename, 'w')
01171     out_h_file = open(output_hfilename, 'w')
01172 
01173     #open input file
01174     try:
01175         xml_mcu = parse(input_file_name)
01176     except:
01177         # Patch waiting for CubeMX correction
01178         if "STM32F042K6Tx" in input_file_name:
01179             input_file_name = os.path.join(cubemxdirMCU, "STM32F042K(4-6)Tx.xml")
01180             xml_mcu = parse(input_file_name)
01181         elif "STM32F429Z" in input_file_name:
01182             input_file_name = os.path.join(cubemxdirMCU, "STM32F429ZITx.xml")
01183             xml_mcu = parse(input_file_name)
01184         elif "STM32F746Z" in input_file_name:
01185             input_file_name = os.path.join(cubemxdirMCU, "STM32F746ZGTx.xml")
01186             xml_mcu = parse(input_file_name)
01187         elif "STM32F767Z" in input_file_name:
01188             input_file_name = os.path.join(cubemxdirMCU, "STM32F767ZGTx.xml")
01189             xml_mcu = parse(input_file_name)
01190 
01191         elif "STM32L011K4Tx" in input_file_name:
01192             input_file_name = os.path.join(cubemxdirMCU, "STM32L011K(3-4)Tx.xml")
01193             xml_mcu = parse(input_file_name)
01194         elif "STM32L432KCUx" in input_file_name:
01195             input_file_name = os.path.join(cubemxdirMCU, "STM32L432K(B-C)Ux.xml")
01196             xml_mcu = parse(input_file_name)
01197         elif "STM32F746N" in input_file_name:
01198             input_file_name = os.path.join(cubemxdirMCU, "STM32F746NGHx.xml")
01199             xml_mcu = parse(input_file_name)
01200         else:
01201             print ("\n ! ! ! Error in CubeMX file. File " + input_file_name + " doesn't exist")
01202             print (" ! ! ! Check in " + cubemxdirMCU)
01203             quit()
01204     gpiofile = find_gpio_file()
01205     if gpiofile == 'ERROR':
01206         print("Could not find GPIO file")
01207         quit()
01208     xml_gpio = parse(os.path.join(cubemxdirIP, 'GPIO-' + gpiofile + '_Modes.xml'))
01209     print (" * GPIO file: " + os.path.join(cubemxdirIP, 'GPIO-' + gpiofile + '_Modes.xml'))
01210 
01211     parse_pins()
01212     sort_my_lists()
01213     print_header()
01214     print_all_lists()
01215     print_footer()
01216 
01217     nb_pin = (len(io_list))
01218     nb_connected_pin = len(PinLabel)
01219     print (" * I/O pins found: %i connected: %i\n" % (nb_pin, nb_connected_pin))
01220     clean_all_lists()
01221 
01222     out_c_file.close()
01223     out_h_file.close()