diff --git a/stmhal/boards/make-pins.py b/stmhal/boards/make-pins.py index afb594e412..e7f16108bf 100755 --- a/stmhal/boards/make-pins.py +++ b/stmhal/boards/make-pins.py @@ -11,11 +11,21 @@ SUPPORTED_FN = { 'TIM' : ['CH1', 'CH2', 'CH3', 'CH4', 'CH1N', 'CH2N', 'CH3N', 'CH1_ETR', 'ETR', 'BKIN'], 'I2C' : ['SDA', 'SCL'], + 'I2S' : ['CK', 'MCK', 'SD', 'WS', 'EXTSD'], 'USART' : ['RX', 'TX', 'CTS', 'RTS', 'CK'], 'UART' : ['RX', 'TX', 'CTS', 'RTS'], 'SPI' : ['NSS', 'SCK', 'MISO', 'MOSI'] } +CONDITIONAL_VAR = { + 'I2C' : 'MICROPY_HW_I2C{num}_SCL', + 'I2S' : 'MICROPY_HW_ENABLE_I2S{num}', + 'SPI' : 'MICROPY_HW_ENABLE_SPI{num}', + 'UART' : 'MICROPY_HW_UART{num}_PORT', + 'UART5' : 'MICROPY_HW_UART5_TX_PORT', + 'USART' : 'MICROPY_HW_UART{num}_PORT', +} + def parse_port_pin(name_str): """Parses a string and returns a (port-num, pin-num) tuple.""" if len(name_str) < 3: @@ -41,12 +51,39 @@ def split_name_num(name_num): break return name, num +def conditional_var(name_num): + # Try the specific instance first. For example, if name_num is UART4_RX + # then try UART4 first, and then try UART second. + name, num = split_name_num(name_num) + var = None + if name_num in CONDITIONAL_VAR: + var = CONDITIONAL_VAR[name_num] + elif name in CONDITIONAL_VAR: + var = CONDITIONAL_VAR[name] + if var: + return var.format(num=num) + +def print_conditional_if(cond_var, file=None): + if cond_var: + if cond_var.find('ENABLE') >= 0: + print('#if defined({0}) && {0}'.format(cond_var), file=file) + else: + print('#if defined({0})'.format(cond_var), file=file) + +def print_conditional_endif(cond_var, file=None): + if cond_var: + print('#endif', file=file) + class AlternateFunction(object): """Holds the information associated with a pins alternate function.""" def __init__(self, idx, af_str): self.idx = idx + # Special case. We change I2S2ext_SD into I2S2_EXTSD so that it parses + # the same way the other peripherals do. + af_str = af_str.replace('ext_', '_EXT') + self.af_str = af_str self.func = '' @@ -77,7 +114,10 @@ class AlternateFunction(object): def print(self): """Prints the C representation of this AF.""" + cond_var = None if self.supported: + cond_var = conditional_var('{}{}'.format(self.func, self.fn_num)) + print_conditional_if(cond_var) print(' AF', end='') else: print(' //', end='') @@ -86,6 +126,7 @@ class AlternateFunction(object): fn_num = 0 print('({:2d}, {:8s}, {:2d}, {:10s}, {:8s}), // {:s}'.format(self.idx, self.func, fn_num, self.pin_type, self.ptr(), self.af_str)) + print_conditional_endif(cond_var) def qstr_list(self): return [self.mux_name()] @@ -163,9 +204,9 @@ class Pin(object): print("// ", end='') print('};') print('') - print('const pin_obj_t pin_{:s} = PIN({:s}, {:d}, {:d}, {:s}, {:s}, {:d});'.format( + print('const pin_obj_t pin_{:s} = PIN({:s}, {:d}, {:s}, {:s}, {:d});'.format( self.cpu_pin_name(), self.port_letter(), self.pin, - self.alt_fn_count, self.alt_fn_name(null_if_0=True), + self.alt_fn_name(null_if_0=True), self.adc_num_str(), self.adc_channel)) print('') @@ -297,7 +338,13 @@ class Pins(object): for named_pin in self.board_pins: qstr_set |= set([named_pin.name()]) for qstr in sorted(qstr_set): + cond_var = None + if qstr.startswith('AF'): + af_words = qstr.split('_') + cond_var = conditional_var(af_words[1]) + print_conditional_if(cond_var, file=qstr_file) print('Q({})'.format(qstr), file=qstr_file) + print_conditional_endif(cond_var, file=qstr_file) def print_af_hdr(self, af_const_filename): with open(af_const_filename, 'wt') as af_const_file: @@ -313,10 +360,14 @@ class Pins(object): if len(mux_name) > mux_name_width: mux_name_width = len(mux_name) for mux_name in sorted(af_hdr_set): + af_words = mux_name.split('_') # ex mux_name: AF9_I2C2 + cond_var = conditional_var(af_words[1]) + print_conditional_if(cond_var, file=af_const_file) key = 'MP_OBJ_NEW_QSTR(MP_QSTR_{}),'.format(mux_name) val = 'MP_OBJ_NEW_SMALL_INT(GPIO_{})'.format(mux_name) print(' { %-*s %s },' % (mux_name_width + 26, key, val), file=af_const_file) + print_conditional_endif(cond_var, file=af_const_file) def print_af_py(self, af_py_filename): with open(af_py_filename, 'wt') as af_py_file: diff --git a/stmhal/boards/stm32f4xx_prefix.c b/stmhal/boards/stm32f4xx_prefix.c index d22bfacadf..f47394277f 100644 --- a/stmhal/boards/stm32f4xx_prefix.c +++ b/stmhal/boards/stm32f4xx_prefix.c @@ -17,13 +17,13 @@ .af_fn = (af_ptr) \ } -#define PIN(p_port, p_pin, p_num_af, p_af, p_adc_num, p_adc_channel) \ +#define PIN(p_port, p_pin, p_af, p_adc_num, p_adc_channel) \ { \ { &pin_type }, \ .name = MP_QSTR_ ## p_port ## p_pin, \ .port = PORT_ ## p_port, \ .pin = (p_pin), \ - .num_af = (p_num_af), \ + .num_af = (sizeof(p_af) / sizeof(pin_obj_t)), \ .pin_mask = (1 << ((p_pin) & 0x0f)), \ .gpio = GPIO ## p_port, \ .af = p_af, \ diff --git a/stmhal/pin_defs_stmhal.h b/stmhal/pin_defs_stmhal.h index 2b6d9da0e7..05b62532db 100644 --- a/stmhal/pin_defs_stmhal.h +++ b/stmhal/pin_defs_stmhal.h @@ -45,7 +45,8 @@ enum { AF_FN_I2C, AF_FN_USART, AF_FN_UART = AF_FN_USART, - AF_FN_SPI + AF_FN_SPI, + AF_FN_I2S, }; enum { @@ -77,20 +78,43 @@ enum { AF_PIN_TYPE_SPI_MISO, AF_PIN_TYPE_SPI_SCK, AF_PIN_TYPE_SPI_NSS, + + AF_PIN_TYPE_I2S_CK = 0, + AF_PIN_TYPE_I2S_MCK, + AF_PIN_TYPE_I2S_SD, + AF_PIN_TYPE_I2S_WS, + AF_PIN_TYPE_I2S_EXTSD, }; +// The HAL uses a slightly different naming than we chose, so we provide +// some #defines to massage things. Also I2S and SPI share the same +// peripheral. + +#define GPIO_AF5_I2S2 GPIO_AF5_SPI2 +#define GPIO_AF5_I2S3 GPIO_AF5_I2S3ext +#define GPIO_AF6_I2S2 GPIO_AF6_I2S2ext +#define GPIO_AF6_I2S3 GPIO_AF6_SPI3 +#define GPIO_AF7_I2S2 GPIO_AF7_SPI2 +#define GPIO_AF7_I2S3 GPIO_AF7_I2S3ext + +#define I2S2 SPI2 +#define I2S3 SPI3 + enum { PIN_ADC1 = (1 << 0), PIN_ADC2 = (1 << 1), PIN_ADC3 = (1 << 2), }; +// Note that SPI and I2S are really the same peripheral as far as the HAL +// is concerned, so there is no I2S_TypeDef. #define PIN_DEFS_PORT_AF_UNION \ TIM_TypeDef *TIM; \ I2C_TypeDef *I2C; \ USART_TypeDef *USART; \ USART_TypeDef *UART; \ - SPI_TypeDef *SPI; + SPI_TypeDef *SPI;\ + SPI_TypeDef *I2S; typedef GPIO_TypeDef pin_gpio_t;