From 9a5df6d1f77a11f93c39a4aeee2af23f823ef256 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 14 Mar 2018 11:28:14 +1100 Subject: [PATCH] HAL_ChibiOS: auto-generate DMA channels for RCIN and add DMA channels for TIMx_UP ready for DMAR based DShot support --- .../hwdef/scripts/chibios_hwdef.py | 27 +++++++++------ .../hwdef/scripts/dma_resolver.py | 34 ++++++++++++------- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/libraries/AP_HAL_ChibiOS/hwdef/scripts/chibios_hwdef.py b/libraries/AP_HAL_ChibiOS/hwdef/scripts/chibios_hwdef.py index 043f886597..a6f4895889 100755 --- a/libraries/AP_HAL_ChibiOS/hwdef/scripts/chibios_hwdef.py +++ b/libraries/AP_HAL_ChibiOS/hwdef/scripts/chibios_hwdef.py @@ -101,6 +101,7 @@ def get_alt_function(mcu, pin, function): return alt_map[s] return None + def have_type_prefix(ptype): '''return True if we have a peripheral starting with the given peripheral type''' for t in bytype.keys(): @@ -589,15 +590,13 @@ def write_PWM_config(f): error( "Bad channel number, only channel 1 and 2 supported for RCIN") n = int(a[0][3:]) - dma_chan_str = rc_in.extra_prefix('DMA_CH')[6:] - dma_chan = int(dma_chan_str) f.write('// RC input config\n') f.write('#define HAL_USE_ICU TRUE\n') f.write('#define STM32_ICU_USE_TIM%u TRUE\n' % n) f.write('#define RCIN_ICU_TIMER ICUD%u\n' % n) - f.write( - '#define RCIN_ICU_CHANNEL ICU_CHANNEL_%u\n' % int(chan_str)) - f.write('#define STM32_RCIN_DMA_CHANNEL %u' % dma_chan) + f.write('#define RCIN_ICU_CHANNEL ICU_CHANNEL_%u\n' % int(chan_str)) + f.write('#define STM32_RCIN_DMA_STREAM STM32_TIM_TIM%u_CH%u_DMA_STREAM\n' % (n, int(chan_str))) + f.write('#define STM32_RCIN_DMA_CHANNEL STM32_TIM_TIM%u_CH%u_DMA_CHAN\n' % (n, int(chan_str))) f.write('\n') if alarm is not None: @@ -833,7 +832,7 @@ def write_hwdef_header(outfilename): dma_resolver.write_dma_header(f, periph_list, mcu_type, dma_exclude=get_dma_exclude(periph_list), - dma_priority=get_config('DMA_PRIORITY',default=''), + dma_priority=get_config('DMA_PRIORITY',default='TIM* SPI*'), dma_noshare=get_config('DMA_NOSHARE',default='')) write_UART_config(f) @@ -915,11 +914,17 @@ def build_peripheral_list(): peripherals.append(type) if type.startswith('SDIO'): peripherals.append(type) - if type.startswith('TIM') and p.has_extra('RCIN'): - label = p.label - if label[-1] == 'N': - label = label[:-1] - peripherals.append(label) + if type.startswith('TIM'): + if p.has_extra('RCIN'): + label = p.label + if label[-1] == 'N': + label = label[:-1] + peripherals.append(label) + else: + # get the TIMn_UP DMA channels for DShot + label = type + '_UP' + if not label in peripherals: + peripherals.append(label) done.add(type) return peripherals diff --git a/libraries/AP_HAL_ChibiOS/hwdef/scripts/dma_resolver.py b/libraries/AP_HAL_ChibiOS/hwdef/scripts/dma_resolver.py index 4936b8910e..e1b6e4da3a 100755 --- a/libraries/AP_HAL_ChibiOS/hwdef/scripts/dma_resolver.py +++ b/libraries/AP_HAL_ChibiOS/hwdef/scripts/dma_resolver.py @@ -4,7 +4,7 @@ import sys, fnmatch import importlib # peripheral types that can be shared, wildcard patterns -SHARED_MAP = ["I2C*", "USART*_TX", "UART*_TX", "SPI*"] +SHARED_MAP = ["I2C*", "USART*_TX", "UART*_TX", "SPI*", "TIM*_UP"] ignore_list = [] dma_map = None @@ -28,7 +28,8 @@ def check_possibility(periph, dma_stream, curr_dict, dma_map, check_list): if debug: print("Trying to Resolve Conflict: ", check_str) #check if we can resolve by swapping with other periphs - for stream in dma_map[other_periph]: + for streamchan in dma_map[other_periph]: + stream = (streamchan[0], streamchan[1]) if stream != curr_dict[other_periph] and \ check_possibility(other_periph, stream, curr_dict, dma_map, check_list): curr_dict[other_periph] = stream @@ -52,19 +53,19 @@ def can_share(periph, noshare_list): def chibios_dma_define_name(key): '''return define name needed for board.h for ChibiOS''' if key.startswith('ADC'): - return 'STM32_ADC_%s_DMA_STREAM' % key + return 'STM32_ADC_%s_DMA_' % key elif key.startswith('SPI'): - return 'STM32_SPI_%s_DMA_STREAM' % key + return 'STM32_SPI_%s_DMA_' % key elif key.startswith('I2C'): - return 'STM32_I2C_%s_DMA_STREAM' % key + return 'STM32_I2C_%s_DMA_' % key elif key.startswith('USART'): - return 'STM32_UART_%s_DMA_STREAM' % key + return 'STM32_UART_%s_DMA_' % key elif key.startswith('UART'): - return 'STM32_UART_%s_DMA_STREAM' % key + return 'STM32_UART_%s_DMA_' % key elif key.startswith('SDIO'): - return 'STM32_SDC_%s_DMA_STREAM' % key + return 'STM32_SDC_%s_DMA_' % key elif key.startswith('TIM'): - return 'STM32_RCIN_DMA_STREAM' + return 'STM32_TIM_%s_DMA_' % key else: print("Error: Unknown key type %s" % key) sys.exit(1) @@ -121,7 +122,8 @@ def write_dma_header(f, peripheral_list, mcu_type, dma_exclude=[], print("Unknown peripheral function %s in DMA map for %s" % (periph, mcu_type)) sys.exit(1) - for stream in dma_map[periph]: + for streamchan in dma_map[periph]: + stream = (streamchan[0], streamchan[1]) if check_possibility(periph, stream, curr_dict, dma_map, check_list): curr_dict[periph] = stream @@ -138,7 +140,8 @@ def write_dma_header(f, peripheral_list, mcu_type, dma_exclude=[], unassigned_new = unassigned[:] for periph in unassigned: share_possibility = [] - for stream in dma_map[periph]: + for streamchan in dma_map[periph]: + stream = (streamchan[0], streamchan[1]) share_ok = True for periph2 in stream_assign[stream]: if not can_share(periph, noshare_list) or not can_share(periph2, noshare_list): @@ -158,7 +161,7 @@ def write_dma_header(f, peripheral_list, mcu_type, dma_exclude=[], unassigned_new.remove(periph) unassigned = unassigned_new - f.write("// auto-generated DMA mapping from dma_resolver.py\n") + f.write("\n\n// auto-generated DMA mapping from dma_resolver.py\n") if unassigned: f.write( @@ -171,8 +174,13 @@ def write_dma_header(f, peripheral_list, mcu_type, dma_exclude=[], if len(stream_assign[stream]) > 1: shared = ' // shared %s' % ','.join(stream_assign[stream]) f.write("#define %-30s STM32_DMA_STREAM_ID(%u, %u)%s\n" % - (chibios_dma_define_name(key), curr_dict[key][0], + (chibios_dma_define_name(key)+'STREAM', curr_dict[key][0], curr_dict[key][1], shared)) + for streamchan in dma_map[key]: + if stream == (streamchan[0], streamchan[1]): + f.write("#define %-30s %u\n" % + (chibios_dma_define_name(key)+'CHAN', streamchan[2])) + break # now generate UARTDriver.cpp DMA config lines f.write("\n\n// generated UART DMA configuration lines\n")